@suzaku-network/suzaku-cli 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +96 -0
- package/README.md +1080 -0
- package/bin/cli.js +3 -0
- package/defaults/.env.anvil +4 -0
- package/defaults/.env.dexalot +7 -0
- package/defaults/.env.fuji +4 -0
- package/defaults/.env.kiteai +2 -0
- package/defaults/.env.mainnet +4 -0
- package/defaults/.env.template +10 -0
- package/dist/abis/AccessControl.d.ts +176 -0
- package/dist/abis/AccessControl.js +230 -0
- package/dist/abis/AccessControl.js.map +1 -0
- package/dist/abis/BalancerValidatorManager.d.ts +1121 -0
- package/dist/abis/BalancerValidatorManager.js +1469 -0
- package/dist/abis/BalancerValidatorManager.js.map +1 -0
- package/dist/abis/DefaultCollateral.d.ts +620 -0
- package/dist/abis/DefaultCollateral.js +811 -0
- package/dist/abis/DefaultCollateral.js.map +1 -0
- package/dist/abis/ERC20.d.ts +635 -0
- package/dist/abis/ERC20.js +831 -0
- package/dist/abis/ERC20.js.map +1 -0
- package/dist/abis/IWarpMessenger.d.ts +104 -0
- package/dist/abis/IWarpMessenger.js +139 -0
- package/dist/abis/IWarpMessenger.js.map +1 -0
- package/dist/abis/KiteStakingManager.d.ts +1459 -0
- package/dist/abis/KiteStakingManager.js +1886 -0
- package/dist/abis/KiteStakingManager.js.map +1 -0
- package/dist/abis/L1Middleware.d.ts +1712 -0
- package/dist/abis/L1Middleware.js +2242 -0
- package/dist/abis/L1Middleware.js.map +1 -0
- package/dist/abis/L1Registry.d.ts +415 -0
- package/dist/abis/L1Registry.js +544 -0
- package/dist/abis/L1Registry.js.map +1 -0
- package/dist/abis/L1RestakeDelegator.d.ts +865 -0
- package/dist/abis/L1RestakeDelegator.js +1118 -0
- package/dist/abis/L1RestakeDelegator.js.map +1 -0
- package/dist/abis/OperatorL1OptInService.d.ts +288 -0
- package/dist/abis/OperatorL1OptInService.js +374 -0
- package/dist/abis/OperatorL1OptInService.js.map +1 -0
- package/dist/abis/OperatorRegistry.d.ts +125 -0
- package/dist/abis/OperatorRegistry.js +166 -0
- package/dist/abis/OperatorRegistry.js.map +1 -0
- package/dist/abis/OperatorVaultOptInService.d.ts +288 -0
- package/dist/abis/OperatorVaultOptInService.js +374 -0
- package/dist/abis/OperatorVaultOptInService.js.map +1 -0
- package/dist/abis/Ownable.d.ts +59 -0
- package/dist/abis/Ownable.js +79 -0
- package/dist/abis/Ownable.js.map +1 -0
- package/dist/abis/PoASecurityModule.d.ts +225 -0
- package/dist/abis/PoASecurityModule.js +299 -0
- package/dist/abis/PoASecurityModule.js.map +1 -0
- package/dist/abis/RewardsNativeToken.d.ts +1334 -0
- package/dist/abis/RewardsNativeToken.js +1749 -0
- package/dist/abis/RewardsNativeToken.js.map +1 -0
- package/dist/abis/StakingVault.d.ts +2913 -0
- package/dist/abis/StakingVault.js +3780 -0
- package/dist/abis/StakingVault.js.map +1 -0
- package/dist/abis/StakingVaultOperations.d.ts +980 -0
- package/dist/abis/StakingVaultOperations.js +1270 -0
- package/dist/abis/StakingVaultOperations.js.map +1 -0
- package/dist/abis/UptimeTracker.d.ts +300 -0
- package/dist/abis/UptimeTracker.js +397 -0
- package/dist/abis/UptimeTracker.js.map +1 -0
- package/dist/abis/ValidatorManager.d.ts +842 -0
- package/dist/abis/ValidatorManager.js +1101 -0
- package/dist/abis/ValidatorManager.js.map +1 -0
- package/dist/abis/VaultFactory.d.ts +288 -0
- package/dist/abis/VaultFactory.js +378 -0
- package/dist/abis/VaultFactory.js.map +1 -0
- package/dist/abis/VaultManager.d.ts +519 -0
- package/dist/abis/VaultManager.js +678 -0
- package/dist/abis/VaultManager.js.map +1 -0
- package/dist/abis/VaultTokenized.d.ts +1626 -0
- package/dist/abis/VaultTokenized.js +2114 -0
- package/dist/abis/VaultTokenized.js.map +1 -0
- package/dist/abis/abi-selectors.json +700 -0
- package/dist/abis/index.d.ts +18356 -0
- package/dist/abis/index.js +58 -0
- package/dist/abis/index.js.map +1 -0
- package/dist/accessControl.d.ts +15 -0
- package/dist/accessControl.js +36 -0
- package/dist/accessControl.js.map +1 -0
- package/dist/balancer.d.ts +25 -0
- package/dist/balancer.js +42 -0
- package/dist/balancer.js.map +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +3183 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.mjs +31343 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/client.d.ts +34 -0
- package/dist/client.js +76 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +63 -0
- package/dist/config.js.map +1 -0
- package/dist/delegator.d.ts +4 -0
- package/dist/delegator.js +16 -0
- package/dist/delegator.js.map +1 -0
- package/dist/index.d.mts +19770 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +27451 -0
- package/dist/index.mjs.map +1 -0
- package/dist/keyStore.d.ts +3 -0
- package/dist/keyStore.js +105 -0
- package/dist/keyStore.js.map +1 -0
- package/dist/kiteStaking.d.ts +91 -0
- package/dist/kiteStaking.js +731 -0
- package/dist/kiteStaking.js.map +1 -0
- package/dist/l1.d.ts +5 -0
- package/dist/l1.js +22 -0
- package/dist/l1.js.map +1 -0
- package/dist/lib/autoCompletion.d.ts +3 -0
- package/dist/lib/autoCompletion.js +55 -0
- package/dist/lib/autoCompletion.js.map +1 -0
- package/dist/lib/cChainUtils.d.ts +42 -0
- package/dist/lib/cChainUtils.js +271 -0
- package/dist/lib/cChainUtils.js.map +1 -0
- package/dist/lib/castUtils.d.ts +18 -0
- package/dist/lib/castUtils.js +81 -0
- package/dist/lib/castUtils.js.map +1 -0
- package/dist/lib/chainList.d.ts +5 -0
- package/dist/lib/chainList.js +86 -0
- package/dist/lib/chainList.js.map +1 -0
- package/dist/lib/cliParser.d.ts +27 -0
- package/dist/lib/cliParser.js +167 -0
- package/dist/lib/cliParser.js.map +1 -0
- package/dist/lib/commandUtils.d.ts +13 -0
- package/dist/lib/commandUtils.js +38 -0
- package/dist/lib/commandUtils.js.map +1 -0
- package/dist/lib/coreWalletUtils.d.ts +3 -0
- package/dist/lib/coreWalletUtils.js +74 -0
- package/dist/lib/coreWalletUtils.js.map +1 -0
- package/dist/lib/justification.d.ts +90 -0
- package/dist/lib/justification.js +577 -0
- package/dist/lib/justification.js.map +1 -0
- package/dist/lib/ledgerUtils.d.ts +4 -0
- package/dist/lib/ledgerUtils.js +258 -0
- package/dist/lib/ledgerUtils.js.map +1 -0
- package/dist/lib/logger.d.ts +46 -0
- package/dist/lib/logger.js +226 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/pChainUtils.d.ts +128 -0
- package/dist/lib/pChainUtils.js +436 -0
- package/dist/lib/pChainUtils.js.map +1 -0
- package/dist/lib/pass.d.ts +81 -0
- package/dist/lib/pass.js +353 -0
- package/dist/lib/pass.js.map +1 -0
- package/dist/lib/safeUtils.d.ts +25 -0
- package/dist/lib/safeUtils.js +93 -0
- package/dist/lib/safeUtils.js.map +1 -0
- package/dist/lib/transferUtils.d.ts +643 -0
- package/dist/lib/transferUtils.js +141 -0
- package/dist/lib/transferUtils.js.map +1 -0
- package/dist/lib/utils.d.ts +28 -0
- package/dist/lib/utils.js +166 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/viemUtils.d.ts +80 -0
- package/dist/lib/viemUtils.js +317 -0
- package/dist/lib/viemUtils.js.map +1 -0
- package/dist/lib/warpUtils.d.ts +76 -0
- package/dist/lib/warpUtils.js +448 -0
- package/dist/lib/warpUtils.js.map +1 -0
- package/dist/middleware.d.ts +75 -0
- package/dist/middleware.js +430 -0
- package/dist/middleware.js.map +1 -0
- package/dist/operator.d.ts +4 -0
- package/dist/operator.js +22 -0
- package/dist/operator.js.map +1 -0
- package/dist/operatorOptIn.d.ts +8 -0
- package/dist/operatorOptIn.js +39 -0
- package/dist/operatorOptIn.js.map +1 -0
- package/dist/rewards.d.ts +116 -0
- package/dist/rewards.js +244 -0
- package/dist/rewards.js.map +1 -0
- package/dist/securityModule.d.ts +8 -0
- package/dist/securityModule.js +305 -0
- package/dist/securityModule.js.map +1 -0
- package/dist/stakingVault.d.ts +184 -0
- package/dist/stakingVault.js +1224 -0
- package/dist/stakingVault.js.map +1 -0
- package/dist/uptime.d.ts +54 -0
- package/dist/uptime.js +246 -0
- package/dist/uptime.js.map +1 -0
- package/dist/vault.d.ts +16 -0
- package/dist/vault.js +131 -0
- package/dist/vault.js.map +1 -0
- package/dist/vaultManager.d.ts +8 -0
- package/dist/vaultManager.js +40 -0
- package/dist/vaultManager.js.map +1 -0
- package/package.json +62 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,3183 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
// Temporarly rm warning from SafeSDK dependencies
|
|
8
|
+
const _originalWarn = console.warn.bind(console);
|
|
9
|
+
console.warn = function (...args) {
|
|
10
|
+
const msg = args.join(" ");
|
|
11
|
+
if (msg.includes("gelatonetwork")) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
return _originalWarn(...args);
|
|
15
|
+
};
|
|
16
|
+
const extra_typings_1 = require("@commander-js/extra-typings");
|
|
17
|
+
const viem_1 = require("viem");
|
|
18
|
+
const l1_1 = require("./l1");
|
|
19
|
+
const operator_1 = require("./operator");
|
|
20
|
+
const config_1 = require("./config");
|
|
21
|
+
const client_1 = require("./client");
|
|
22
|
+
const logger_1 = require("./lib/logger");
|
|
23
|
+
const vaultManager_1 = require("./vaultManager");
|
|
24
|
+
const vault_1 = require("./vault");
|
|
25
|
+
const delegator_1 = require("./delegator");
|
|
26
|
+
const middleware_1 = require("./middleware");
|
|
27
|
+
const operatorOptIn_1 = require("./operatorOptIn");
|
|
28
|
+
const balancer_1 = require("./balancer");
|
|
29
|
+
const uptime_1 = require("./uptime");
|
|
30
|
+
const rewards_1 = require("./rewards");
|
|
31
|
+
const transferUtils_1 = require("./lib/transferUtils");
|
|
32
|
+
const utils_1 = require("./lib/utils");
|
|
33
|
+
const keyStore_1 = require("./keyStore");
|
|
34
|
+
const cliParser_1 = require("./lib/cliParser");
|
|
35
|
+
const pChainUtils_1 = require("./lib/pChainUtils");
|
|
36
|
+
const ts_belt_1 = require("@mobily/ts-belt");
|
|
37
|
+
const securityModule_1 = require("./securityModule");
|
|
38
|
+
const kiteStaking_1 = require("./kiteStaking");
|
|
39
|
+
const stakingVault_1 = require("./stakingVault");
|
|
40
|
+
const avalanchejs_1 = require("@avalabs/avalanchejs");
|
|
41
|
+
const justification_1 = require("./lib/justification");
|
|
42
|
+
const autoCompletion_1 = require("./lib/autoCompletion");
|
|
43
|
+
const accessControl_1 = require("./accessControl");
|
|
44
|
+
const viemUtils_1 = require("./lib/viemUtils");
|
|
45
|
+
require("./lib/commandUtils");
|
|
46
|
+
const child_process_1 = require("child_process");
|
|
47
|
+
const chainList_1 = require("./lib/chainList");
|
|
48
|
+
const fs_1 = require("fs");
|
|
49
|
+
const package_json_1 = __importDefault(require("../package.json"));
|
|
50
|
+
// Main function to set up the CLI commands
|
|
51
|
+
async function main() {
|
|
52
|
+
const program = new extra_typings_1.Command()
|
|
53
|
+
.name('suzaku-cli')
|
|
54
|
+
.addOption(new extra_typings_1.Option('-n, --network <network>')
|
|
55
|
+
.choices(Object.keys(chainList_1.chainList))
|
|
56
|
+
.default('mainnet'))
|
|
57
|
+
.addOption(new extra_typings_1.Option('-r, --rpc-url <rpcUrl>', 'RPC URL for a custom network (automatically sets --network to custom)'))
|
|
58
|
+
.addOption(new extra_typings_1.Option('-k, --private-key <privateKey>', 'Private key in Hex format')
|
|
59
|
+
.env('PK').argParser(cliParser_1.ParserPrivateKey).conflicts(['secretName', 'ledger']))
|
|
60
|
+
.addOption(new extra_typings_1.Option('-s, --secret-name <secretName>', 'The keystore secret name containing the private key')
|
|
61
|
+
.conflicts(['privateKey', 'ledger'])
|
|
62
|
+
.argParser(cliParser_1.parseSecretName))
|
|
63
|
+
.addOption(new extra_typings_1.Option('-l, --ledger', 'Use Ledger hardware wallet for signing').conflicts(['privateKey', 'secretName']))
|
|
64
|
+
.addOption(new extra_typings_1.Option('-w, --wait <confirmations>', 'Number of confirmations to wait after a write transaction')
|
|
65
|
+
.default(2)
|
|
66
|
+
.argParser(cliParser_1.ParserNumber))
|
|
67
|
+
.addOption(new extra_typings_1.Option("--json", "Output logs in JSON format"))
|
|
68
|
+
.addOption(new extra_typings_1.Option('-y, --yes', 'Automatic yes to prompts'))
|
|
69
|
+
.addOption((0, cliParser_1.OptAddress)('--safe <address>', 'Use safe smart account for transactions'))
|
|
70
|
+
.addOption(new extra_typings_1.Option('--skip-abi-validation', 'Skip the ABI validation for used contract'))
|
|
71
|
+
.addOption(new extra_typings_1.Option('--cast', 'Output equivalent Foundry cast commands instead of executing write transactions').conflicts(['safe']))
|
|
72
|
+
.version(package_json_1.default.version)
|
|
73
|
+
.configureOutput({
|
|
74
|
+
writeOut: (str) => process.stdout.write(str),
|
|
75
|
+
writeErr: (str) => { str.includes('Usage: suzaku-cli') ? process.stdout.write(str) : process.stderr.write(str); },
|
|
76
|
+
});
|
|
77
|
+
// Set cast mode and handle --rpc-url/custom network before any command runs
|
|
78
|
+
program.hook('preSubcommand', async (thisCommand) => {
|
|
79
|
+
const opts = program.opts();
|
|
80
|
+
if (opts.cast)
|
|
81
|
+
(0, viemUtils_1.setCastMode)(true);
|
|
82
|
+
// Block manually private key on mainnet
|
|
83
|
+
if (opts.privateKey && chainList_1.chainList[opts.network].testnet === false) {
|
|
84
|
+
logger_1.logger.error("Using private key on mainnet is not allowed. Use the secret keystore or a ledger instead.");
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
if (opts.rpcUrl) {
|
|
88
|
+
await (0, chainList_1.setCustomChainRpcUrl)(opts.rpcUrl);
|
|
89
|
+
thisCommand.setOptionValue('network', 'custom');
|
|
90
|
+
}
|
|
91
|
+
else if (opts.network === 'custom') {
|
|
92
|
+
logger_1.logger.error('Error: --rpc-url is required when using --network custom');
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
// Activate json output if --json is provided
|
|
96
|
+
logger_1.logger.setJsonMode(opts.json);
|
|
97
|
+
});
|
|
98
|
+
program.hook("preAction", () => {
|
|
99
|
+
const opts = program.opts();
|
|
100
|
+
// Ensure privateKey is set if opts.secret or ledger is provided
|
|
101
|
+
if (opts.secretName) {
|
|
102
|
+
program.setOptionValue('privateKey', opts.secretName);
|
|
103
|
+
}
|
|
104
|
+
else if (opts.ledger) {
|
|
105
|
+
program.setOptionValue('privateKey', 'ledger');
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
program
|
|
109
|
+
.command('verify-abi')
|
|
110
|
+
.description('Verify that a contract at a given address matches the expected Suzaku ABI (5% tolerance)')
|
|
111
|
+
.addArgument((0, cliParser_1.ArgAddress)("address", "Contract address to test"))
|
|
112
|
+
.argument('abi', 'ABI name to test')
|
|
113
|
+
.asyncAction(async (config, address, abi) => {
|
|
114
|
+
await config.contracts[abi](address);
|
|
115
|
+
logger_1.logger.log(`Verified ABI for contract ${abi} at address ${address} ✅`);
|
|
116
|
+
});
|
|
117
|
+
/* --------------------------------------------------
|
|
118
|
+
* Common Args
|
|
119
|
+
* -------------------------------------------------- */
|
|
120
|
+
// Contract
|
|
121
|
+
const argValidatorManagerAddress = (0, cliParser_1.ArgAddress)("validatorManagerAddress", "L1 validator manager contract address");
|
|
122
|
+
const argBalancerAddress = (0, cliParser_1.ArgAddress)("balancerAddress", "Balancer validator manager contract address");
|
|
123
|
+
const argPoaSecurityModuleAddress = (0, cliParser_1.ArgAddress)("poaSecurityModuleAddress", "POA Security Module contract address");
|
|
124
|
+
const argMiddlewareAddress = (0, cliParser_1.ArgAddress)("middlewareAddress", "Middleware contract address");
|
|
125
|
+
const argMiddlewareVaultManagerAddress = (0, cliParser_1.ArgAddress)("middlewareVaultManagerAddress", "Middleware vault manager contract address");
|
|
126
|
+
const argVaultAddress = (0, cliParser_1.ArgAddress)("vaultAddress", "Vault contract address");
|
|
127
|
+
const argUptimeTrackerAddress = (0, cliParser_1.ArgAddress)("uptimeTrackerAddress", "UptimeTracker contract address");
|
|
128
|
+
const argRewardsAddress = (0, cliParser_1.ArgAddress)("rewardsAddress", "Rewards contract address");
|
|
129
|
+
const argRewardTokenAddress = (0, cliParser_1.ArgAddress)("rewardTokenAddress", "Reward token contract address");
|
|
130
|
+
const optKiteStakingManagerAddress = (0, cliParser_1.OptAddress)("--staking-manager-address <address>", "KiteStakingManager contract address");
|
|
131
|
+
const optStakingVaultAddress = (0, cliParser_1.OptAddress)("--staking-vault-address <address>", "Staking vault contract address");
|
|
132
|
+
const argAccessControlAddress = (0, cliParser_1.ArgAddress)("accessControlAddress", "A contract address with AccessControl functionalities");
|
|
133
|
+
// EOA
|
|
134
|
+
const argOperatorAddress = (0, cliParser_1.ArgAddress)("operator", "Operator address");
|
|
135
|
+
/* --------------------------------------------------
|
|
136
|
+
* Generic L1 Commands
|
|
137
|
+
* -------------------------------------------------- */
|
|
138
|
+
// topUpAllOperatorNodes
|
|
139
|
+
program
|
|
140
|
+
.command("top-up-l1-validators")
|
|
141
|
+
.description("Top up all/selected l1 validators to meet a target continuous fee balance")
|
|
142
|
+
.addArgument((0, cliParser_1.ArgCB58)("subnetID", "Subnet ID of the L1"))
|
|
143
|
+
.argument("targetBalance", "Target continuous fee balance per validator (in AVAX)")
|
|
144
|
+
.addOption(new extra_typings_1.Option("--node-id <nodeId>", "Add a validator to be topped up").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserNodeID)))
|
|
145
|
+
.asyncAction({ signer: true }, async (config, subnetID, targetBalance, options) => {
|
|
146
|
+
const opts = program.opts();
|
|
147
|
+
const client = await (0, client_1.generateClient)(opts.network, opts.privateKey, opts.safe);
|
|
148
|
+
const targetBalanceWei = (0, viem_1.parseUnits)(targetBalance, 9); // AVAX has 9 decimals
|
|
149
|
+
if (targetBalanceWei <= BigInt(1e7)) { // 0.01 AVAX min
|
|
150
|
+
throw new Error("Target balance must be greater than 0.01 AVAX");
|
|
151
|
+
}
|
|
152
|
+
const validators = await (0, pChainUtils_1.getCurrentValidators)(config.client, subnetID);
|
|
153
|
+
const validatorsToTopUp = validators.reduce((acc, validator) => {
|
|
154
|
+
if (options.nodeId && options.nodeId.length > 0 && !options.nodeId.includes(validator.nodeID)) {
|
|
155
|
+
return acc;
|
|
156
|
+
}
|
|
157
|
+
if (validator.balance < Number(targetBalanceWei) - 1e7) { // 0.01 AVAX min diff
|
|
158
|
+
acc.push({
|
|
159
|
+
validationId: validator.validationID,
|
|
160
|
+
topup: targetBalanceWei - BigInt(validator.balance),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return acc;
|
|
164
|
+
}, []);
|
|
165
|
+
const totalTopUp = validatorsToTopUp.reduce((acc, v) => acc + v.topup, 0n);
|
|
166
|
+
if (validatorsToTopUp.length === 0) {
|
|
167
|
+
logger_1.logger.log("All l1 validators have sufficient balance. No top-up needed.");
|
|
168
|
+
logger_1.logger.addData('total_amount', 0);
|
|
169
|
+
logger_1.logger.addData('validators', []);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
logger_1.logger.log(`${validatorsToTopUp.length} validators to top-up:`);
|
|
173
|
+
await (0, transferUtils_1.requirePChainBallance)(config.client, totalTopUp + BigInt(2e4) * BigInt(validatorsToTopUp.length), opts.yes); // extra 20000 for fees
|
|
174
|
+
if (!opts.yes) {
|
|
175
|
+
const response = await logger_1.logger.prompt(`Proceed with topping up validators? (y/n): `);
|
|
176
|
+
if (response.toLowerCase() !== 'y') {
|
|
177
|
+
logger_1.logger.log("Operation cancelled by user.");
|
|
178
|
+
process.exit(0);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
for (const { validationId, topup } of validatorsToTopUp) {
|
|
182
|
+
logger_1.logger.log(`\nTopping up validator ${validationId}`);
|
|
183
|
+
const amount = Number(topup) / 1e9;
|
|
184
|
+
(0, ts_belt_1.pipe)(await (0, pChainUtils_1.increasePChainValidatorBalance)(config.client, amount, validationId, false), ts_belt_1.R.tapError(err => { logger_1.logger.error(err); process.exit(1); }));
|
|
185
|
+
}
|
|
186
|
+
logger_1.logger.log("\nCompleted top-up of validators.");
|
|
187
|
+
logger_1.logger.addData('total_amount', totalTopUp);
|
|
188
|
+
logger_1.logger.addData('validators', validatorsToTopUp);
|
|
189
|
+
});
|
|
190
|
+
/* --------------------------------------------------
|
|
191
|
+
* L1 REGISTRY COMMANDS
|
|
192
|
+
* -------------------------------------------------- */
|
|
193
|
+
const l1RegistryCmd = program
|
|
194
|
+
.command("l1-registry")
|
|
195
|
+
.description("Commands to interact with the Suzaku L1 Registry contract");
|
|
196
|
+
l1RegistryCmd
|
|
197
|
+
.command("register")
|
|
198
|
+
.description("Register a new L1 in the L1 registry")
|
|
199
|
+
.addArgument(argMiddlewareAddress)
|
|
200
|
+
.addArgument((0, cliParser_1.ArgURI)("metadataUrl", "Metadata URL for the L1"))
|
|
201
|
+
.asyncAction({ signer: true }, async (config, l1Middleware, metadataUrl) => {
|
|
202
|
+
const middleware = await config.contracts.L1Middleware(l1Middleware);
|
|
203
|
+
const balancerAddress = await middleware.read.BALANCER();
|
|
204
|
+
// instantiate L1Registry and call
|
|
205
|
+
const l1Registry = await config.contracts.L1Registry();
|
|
206
|
+
await (0, l1_1.registerL1)(l1Registry, balancerAddress, l1Middleware, metadataUrl, config.client.account);
|
|
207
|
+
});
|
|
208
|
+
l1RegistryCmd
|
|
209
|
+
.command("get-all")
|
|
210
|
+
.description("List all L1s registered in the L1 registry")
|
|
211
|
+
.asyncAction(async (config) => {
|
|
212
|
+
const l1Registry = await config.contracts.L1Registry();
|
|
213
|
+
const l1s = await l1Registry.read.getAllL1s();
|
|
214
|
+
// l1s: [balancerAddress[], middleware[], metadataUrl[]]
|
|
215
|
+
const data = [];
|
|
216
|
+
for (let i = 0; i < l1s[0].length; i++) {
|
|
217
|
+
data.push({
|
|
218
|
+
MetadataUrl: l1s[2][i],
|
|
219
|
+
Balancer: l1s[0][i],
|
|
220
|
+
Middleware: l1s[1][i],
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
logger_1.logger.logJsonTree(data);
|
|
224
|
+
});
|
|
225
|
+
l1RegistryCmd
|
|
226
|
+
.command("set-metadata-url")
|
|
227
|
+
.description("Set metadata URL for an L1 in the L1 registry")
|
|
228
|
+
.addArgument(argValidatorManagerAddress)
|
|
229
|
+
.addArgument((0, cliParser_1.ArgURI)("metadataUrl", "New metadata URL"))
|
|
230
|
+
.asyncAction({ signer: true }, async (config, l1Address, metadataUrl) => {
|
|
231
|
+
const l1Reg = await config.contracts.L1Registry();
|
|
232
|
+
await (0, l1_1.setL1MetadataUrl)(l1Reg, l1Address, metadataUrl);
|
|
233
|
+
});
|
|
234
|
+
l1RegistryCmd
|
|
235
|
+
.command("set-middleware")
|
|
236
|
+
.description("Set middleware address for an L1 in the L1 registry")
|
|
237
|
+
.addArgument(argValidatorManagerAddress)
|
|
238
|
+
.addArgument((0, cliParser_1.ArgAddress)("l1Middleware", "New L1 middleware address"))
|
|
239
|
+
.asyncAction({ signer: true }, async (config, l1Address, l1Middleware) => {
|
|
240
|
+
const l1Reg2 = await config.contracts.L1Registry();
|
|
241
|
+
await (0, l1_1.setL1Middleware)(l1Reg2, l1Address, l1Middleware);
|
|
242
|
+
});
|
|
243
|
+
/* --------------------------------------------------
|
|
244
|
+
* OPERATOR REGISTRY COMMANDS
|
|
245
|
+
* -------------------------------------------------- */
|
|
246
|
+
const operatorRegistryCmd = program
|
|
247
|
+
.command("operator-registry")
|
|
248
|
+
.description("Commands to interact with the Suzaku Operator Registry contract");
|
|
249
|
+
operatorRegistryCmd
|
|
250
|
+
.command("register")
|
|
251
|
+
.description("Register a new operator in the operator registry")
|
|
252
|
+
.addArgument((0, cliParser_1.ArgURI)("metadataUrl", "Operator metadata URL"))
|
|
253
|
+
.asyncAction({ signer: true }, async (config, metadataUrl) => {
|
|
254
|
+
const opReg = await config.contracts.OperatorRegistry();
|
|
255
|
+
await (0, operator_1.registerOperator)(opReg, metadataUrl);
|
|
256
|
+
});
|
|
257
|
+
operatorRegistryCmd
|
|
258
|
+
.command("get-all")
|
|
259
|
+
.description("List all operators registered in the operator registry")
|
|
260
|
+
.asyncAction(async (config) => {
|
|
261
|
+
const opReg2 = await config.contracts.OperatorRegistry();
|
|
262
|
+
await (0, operator_1.listOperators)(opReg2);
|
|
263
|
+
});
|
|
264
|
+
/* --------------------------------------------------
|
|
265
|
+
* VAULT MANAGER
|
|
266
|
+
* -------------------------------------------------- */
|
|
267
|
+
const vaultManagerCmd = program
|
|
268
|
+
.command("vault-manager")
|
|
269
|
+
.description("Commands to interact with the Vault Manager contract of an L1");
|
|
270
|
+
vaultManagerCmd
|
|
271
|
+
.command("register-vault-l1")
|
|
272
|
+
.description("Register a vault for L1 staking")
|
|
273
|
+
.addArgument(argMiddlewareVaultManagerAddress)
|
|
274
|
+
.addArgument(argVaultAddress)
|
|
275
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClass", "Collateral class ID"))
|
|
276
|
+
.argument("maxLimit", "Maximum limit (in decimal format)")
|
|
277
|
+
.asyncAction({ signer: true }, async (config, middlewareVaultManagerAddress, vaultAddress, collateralClass, maxLimit) => {
|
|
278
|
+
// instantiate VaultManager contract
|
|
279
|
+
const vaultManager = await config.contracts.VaultManager(middlewareVaultManagerAddress);
|
|
280
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
281
|
+
const maxLimitWei = (0, viem_1.parseUnits)(maxLimit, await vault.read.decimals());
|
|
282
|
+
await (0, vaultManager_1.registerVaultL1)(vaultManager, vaultAddress, collateralClass, maxLimitWei, config.client.account);
|
|
283
|
+
});
|
|
284
|
+
vaultManagerCmd
|
|
285
|
+
.command("update-vault-max-l1-limit")
|
|
286
|
+
.description("Update the maximum L1 limit for a vault")
|
|
287
|
+
.addArgument(argMiddlewareVaultManagerAddress)
|
|
288
|
+
.addArgument(argVaultAddress)
|
|
289
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClass", "Collateral class ID"))
|
|
290
|
+
.argument("maxLimit", "Maximum limit")
|
|
291
|
+
.asyncAction({ signer: true }, async (config, middlewareVaultManagerAddress, vaultAddress, collateralClass, maxLimit) => {
|
|
292
|
+
const vaultManager = await config.contracts.VaultManager(middlewareVaultManagerAddress);
|
|
293
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
294
|
+
const maxLimitWei = (0, viem_1.parseUnits)(maxLimit, await vault.read.decimals());
|
|
295
|
+
await (0, vaultManager_1.updateVaultMaxL1Limit)(vaultManager, vaultAddress, collateralClass, maxLimitWei, config.client.account);
|
|
296
|
+
});
|
|
297
|
+
vaultManagerCmd
|
|
298
|
+
.command("remove-vault")
|
|
299
|
+
.description("Remove a vault from L1 staking")
|
|
300
|
+
.addArgument(argMiddlewareVaultManagerAddress)
|
|
301
|
+
.addArgument(argVaultAddress)
|
|
302
|
+
.asyncAction({ signer: true }, async (config, middlewareVaultManager, vaultAddress) => {
|
|
303
|
+
const vaultManager = await config.contracts.VaultManager(middlewareVaultManager);
|
|
304
|
+
await (0, vaultManager_1.removeVault)(vaultManager, vaultAddress, config.client.account);
|
|
305
|
+
});
|
|
306
|
+
vaultManagerCmd
|
|
307
|
+
.command("get-vault-count")
|
|
308
|
+
.description("Get the number of vaults registered for L1 staking")
|
|
309
|
+
.addArgument(argMiddlewareVaultManagerAddress)
|
|
310
|
+
.asyncAction(async (config, middlewareVaultManager) => {
|
|
311
|
+
const vaultManager = await config.contracts.VaultManager(middlewareVaultManager);
|
|
312
|
+
await (0, vaultManager_1.getVaultCount)(vaultManager);
|
|
313
|
+
});
|
|
314
|
+
vaultManagerCmd
|
|
315
|
+
.command("get-vault-at-with-times")
|
|
316
|
+
.description("Get the vault address at a specific index along with its registration and removal times")
|
|
317
|
+
.addArgument(argMiddlewareVaultManagerAddress)
|
|
318
|
+
.addArgument((0, cliParser_1.ArgBigInt)("index", "Vault index"))
|
|
319
|
+
.asyncAction(async (config, middlewareVaultManager, index) => {
|
|
320
|
+
const vaultManager = await config.contracts.VaultManager(middlewareVaultManager);
|
|
321
|
+
await (0, vaultManager_1.getVaultAtWithTimes)(vaultManager, index);
|
|
322
|
+
});
|
|
323
|
+
vaultManagerCmd
|
|
324
|
+
.command("get-vault-collateral-class")
|
|
325
|
+
.description("Get the collateral class ID associated with a vault")
|
|
326
|
+
.addArgument(argMiddlewareVaultManagerAddress)
|
|
327
|
+
.addArgument(argVaultAddress)
|
|
328
|
+
.asyncAction(async (config, middlewareVaultManager, vaultAddress) => {
|
|
329
|
+
const vaultManager = await config.contracts.VaultManager(middlewareVaultManager);
|
|
330
|
+
await (0, vaultManager_1.getVaultCollateralClass)(vaultManager, vaultAddress);
|
|
331
|
+
});
|
|
332
|
+
/* --------------------------------------------------
|
|
333
|
+
* VAULT DEPOSIT/WITHDRAW/CLAIM/GRANT
|
|
334
|
+
* -------------------------------------------------- */
|
|
335
|
+
const vaultCmd = program
|
|
336
|
+
.command("vault")
|
|
337
|
+
.description("Commands to interact with a Vault and L1 Re-stake Delegator contracts");
|
|
338
|
+
vaultCmd
|
|
339
|
+
.command("deposit")
|
|
340
|
+
.description("Deposit tokens into the vault")
|
|
341
|
+
.addArgument(argVaultAddress)
|
|
342
|
+
.argument("amount", "Amount of token to deposit in the vault")
|
|
343
|
+
.addOption(new extra_typings_1.Option("--onBehalfOf <behalfOf>", "Optional onBehalfOf address").argParser(cliParser_1.ParserAddress))
|
|
344
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, amount, options) => {
|
|
345
|
+
const onBehalfOf = options.onBehalfOf ?? config.client.account.address;
|
|
346
|
+
await (0, vault_1.depositVault)(config, vaultAddress, onBehalfOf, amount);
|
|
347
|
+
});
|
|
348
|
+
vaultCmd
|
|
349
|
+
.command("withdraw")
|
|
350
|
+
.description("Withdraw tokens from the vault")
|
|
351
|
+
.addArgument(argVaultAddress)
|
|
352
|
+
.argument("amount", "Amount of token to withdraw in the vault")
|
|
353
|
+
.addOption(new extra_typings_1.Option("--claimer <claimer>", "Optional claimer").argParser(cliParser_1.ParserAddress))
|
|
354
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, amount, options) => {
|
|
355
|
+
const claimer = options.claimer ?? config.client.account.address;
|
|
356
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
357
|
+
const amountWei = (0, viem_1.parseUnits)(amount, await vault.read.decimals());
|
|
358
|
+
await (0, vault_1.withdrawVault)(vault, claimer, amountWei);
|
|
359
|
+
});
|
|
360
|
+
vaultCmd
|
|
361
|
+
.command("claim")
|
|
362
|
+
.description("Claim withdrawn tokens from the vault for a specific epoch")
|
|
363
|
+
.addArgument(argVaultAddress)
|
|
364
|
+
.addArgument((0, cliParser_1.ArgBigInt)("epoch", "Epoch number"))
|
|
365
|
+
.addOption(new extra_typings_1.Option("--recipient <recipient>", "Optional recipient").argParser(cliParser_1.ParserAddress))
|
|
366
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, epoch, options) => {
|
|
367
|
+
const recipient = options.recipient ?? config.client.account.address;
|
|
368
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
369
|
+
await (0, vault_1.claimVault)(vault, recipient, epoch);
|
|
370
|
+
});
|
|
371
|
+
vaultCmd
|
|
372
|
+
.command("grant-staker-role")
|
|
373
|
+
.description("Grant staker role on a vault to an account")
|
|
374
|
+
.addArgument(argVaultAddress)
|
|
375
|
+
.addArgument((0, cliParser_1.ArgAddress)("account", "Account to grant the role to"))
|
|
376
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, account) => {
|
|
377
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
378
|
+
await vault.safeWrite.grantRole([await vault.read.DEPOSITOR_WHITELIST_ROLE(), account], {
|
|
379
|
+
chain: null,
|
|
380
|
+
account: config.client.account,
|
|
381
|
+
});
|
|
382
|
+
logger_1.logger.log(`Granted staker role to ${account} on vault (${await vault.read.name()}) ${vaultAddress}`);
|
|
383
|
+
});
|
|
384
|
+
vaultCmd
|
|
385
|
+
.command("revoke-staker-role")
|
|
386
|
+
.description("Revoke staker role on a vault from an account")
|
|
387
|
+
.addArgument(argVaultAddress)
|
|
388
|
+
.addArgument((0, cliParser_1.ArgAddress)("account", "Account to revoke the role from"))
|
|
389
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, account) => {
|
|
390
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
391
|
+
await vault.safeWrite.revokeRole([await vault.read.DEPOSITOR_WHITELIST_ROLE(), account], {
|
|
392
|
+
chain: null,
|
|
393
|
+
account: config.client.account,
|
|
394
|
+
});
|
|
395
|
+
logger_1.logger.log(`Revoked staker role from ${account} on vault (${await vault.read.name()}) ${vaultAddress}`);
|
|
396
|
+
});
|
|
397
|
+
vaultCmd
|
|
398
|
+
.command("collateral-deposit")
|
|
399
|
+
.description("Approve and deposit tokens into the collateral contract associated with a vault")
|
|
400
|
+
.addArgument((0, cliParser_1.ArgAddress)("collateralAddress", "Collateral contract address"))
|
|
401
|
+
.argument("amount", "Amount of token to deposit in the collateral")
|
|
402
|
+
.asyncAction({ signer: true }, async (_, collateralAddress, amount) => {
|
|
403
|
+
const opts = program.opts();
|
|
404
|
+
const client = await (0, client_1.generateClient)(opts.network, opts.privateKey, opts.safe);
|
|
405
|
+
const config = (0, config_1.getConfig)(client, opts.wait, true); // skip abi validation as erc20 are commonly different
|
|
406
|
+
await (0, vault_1.approveAndDepositCollateral)(config, collateralAddress, amount);
|
|
407
|
+
});
|
|
408
|
+
// setIsDepositLimit
|
|
409
|
+
vaultCmd
|
|
410
|
+
.command("set-deposit-limit")
|
|
411
|
+
.description("Set deposit limit for a vault (0 will disable the limit)")
|
|
412
|
+
.addArgument(argVaultAddress)
|
|
413
|
+
.argument("limit", "Deposit limit amount")
|
|
414
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, limit) => {
|
|
415
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
416
|
+
const limitWei = (0, viem_1.parseUnits)(limit, await vault.read.decimals());
|
|
417
|
+
const isLimitShouldBeEnabled = limitWei > 0n;
|
|
418
|
+
const isLimitEnabled = await vault.read.isDepositLimit();
|
|
419
|
+
if (isLimitShouldBeEnabled !== isLimitEnabled) {
|
|
420
|
+
await vault.safeWrite.setIsDepositLimit([isLimitShouldBeEnabled], {
|
|
421
|
+
chain: null,
|
|
422
|
+
account: config.client.account,
|
|
423
|
+
});
|
|
424
|
+
logger_1.logger.log(`Set deposit limit enabled to ${isLimitShouldBeEnabled} for vault (${await vault.read.name()}) ${vaultAddress}`);
|
|
425
|
+
}
|
|
426
|
+
await vault.safeWrite.setDepositLimit([limitWei], {
|
|
427
|
+
chain: null,
|
|
428
|
+
account: config.client.account,
|
|
429
|
+
});
|
|
430
|
+
logger_1.logger.log(`Set deposit limit to ${limit} for vault (${await vault.read.name()}) ${vaultAddress}`);
|
|
431
|
+
});
|
|
432
|
+
// increaseLimit of the collateral
|
|
433
|
+
vaultCmd
|
|
434
|
+
.command("collateral-increase-limit")
|
|
435
|
+
.description("Set deposit limit for a collateral")
|
|
436
|
+
.addArgument(argVaultAddress)
|
|
437
|
+
.argument("limit", "Deposit limit amount")
|
|
438
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, limit) => {
|
|
439
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
440
|
+
const collateralAddress = await vault.read.collateral();
|
|
441
|
+
const collateral = await config.contracts.DefaultCollateral(collateralAddress);
|
|
442
|
+
const limitWei = (0, viem_1.parseUnits)(limit, await collateral.read.decimals());
|
|
443
|
+
await collateral.safeWrite.increaseLimit([limitWei], {
|
|
444
|
+
chain: null,
|
|
445
|
+
account: config.client.account,
|
|
446
|
+
});
|
|
447
|
+
logger_1.logger.log(`Collateral (${collateralAddress}) limit increased to ${limit} (${await collateral.read.name()})`);
|
|
448
|
+
});
|
|
449
|
+
/* --------------------------------------------------
|
|
450
|
+
* VAULT READ COMMANDS
|
|
451
|
+
* -------------------------------------------------- */
|
|
452
|
+
vaultCmd
|
|
453
|
+
.command("get-collateral")
|
|
454
|
+
.description("Get the collateral token address of a vault")
|
|
455
|
+
.addArgument(argVaultAddress)
|
|
456
|
+
.asyncAction(async (config, vaultAddress) => {
|
|
457
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
458
|
+
await (0, vault_1.getVaultCollateral)(vault);
|
|
459
|
+
});
|
|
460
|
+
vaultCmd
|
|
461
|
+
.command("get-delegator")
|
|
462
|
+
.description("Get the delegator address of a vault")
|
|
463
|
+
.addArgument(argVaultAddress)
|
|
464
|
+
.asyncAction(async (config, vaultAddress) => {
|
|
465
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
466
|
+
const delegator = await (0, vault_1.getVaultDelegator)(vault);
|
|
467
|
+
logger_1.logger.log("Vault delegator:", delegator);
|
|
468
|
+
});
|
|
469
|
+
vaultCmd
|
|
470
|
+
.command("get-balance")
|
|
471
|
+
.description("Get vault token balance for an account")
|
|
472
|
+
.addArgument(argVaultAddress)
|
|
473
|
+
.addOption(new extra_typings_1.Option("--account <account>", "Account to check balance for").argParser(cliParser_1.ParserAddress))
|
|
474
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, options) => {
|
|
475
|
+
const account = options.account ?? config.client.account.address;
|
|
476
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
477
|
+
await (0, vault_1.getVaultBalanceOf)(vault, account);
|
|
478
|
+
});
|
|
479
|
+
vaultCmd
|
|
480
|
+
.command("get-active-balance")
|
|
481
|
+
.description("Get active vault balance for an account")
|
|
482
|
+
.addArgument(argVaultAddress)
|
|
483
|
+
.addOption(new extra_typings_1.Option("--account <account>", "Account to check balance for").argParser(cliParser_1.ParserAddress))
|
|
484
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, options) => {
|
|
485
|
+
const account = options.account ?? config.client.account.address;
|
|
486
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
487
|
+
await (0, vault_1.getVaultActiveBalanceOf)(vault, account);
|
|
488
|
+
});
|
|
489
|
+
vaultCmd
|
|
490
|
+
.command("get-total-supply")
|
|
491
|
+
.description("Get total supply of vault tokens")
|
|
492
|
+
.addArgument(argVaultAddress)
|
|
493
|
+
.asyncAction(async (config, vaultAddress) => {
|
|
494
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
495
|
+
await (0, vault_1.getVaultTotalSupply)(vault);
|
|
496
|
+
});
|
|
497
|
+
vaultCmd
|
|
498
|
+
.command("get-withdrawal-shares")
|
|
499
|
+
.description("Get withdrawal shares for an account at a specific epoch")
|
|
500
|
+
.addArgument(argVaultAddress)
|
|
501
|
+
.addArgument((0, cliParser_1.ArgBigInt)("epoch", "Epoch number"))
|
|
502
|
+
.addOption(new extra_typings_1.Option("--account <account>", "Account to check").argParser(cliParser_1.ParserAddress))
|
|
503
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, epoch, options) => {
|
|
504
|
+
const account = options.account ?? config.client.account.address;
|
|
505
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
506
|
+
await (0, vault_1.getVaultWithdrawalSharesOf)(vault, epoch, account);
|
|
507
|
+
});
|
|
508
|
+
vaultCmd
|
|
509
|
+
.command("get-withdrawals")
|
|
510
|
+
.description("Get withdrawal amount for an account at a specific epoch")
|
|
511
|
+
.addArgument(argVaultAddress)
|
|
512
|
+
.addArgument((0, cliParser_1.ArgBigInt)("epoch", "Epoch number"))
|
|
513
|
+
.addOption(new extra_typings_1.Option("--account <account>", "Account to check").argParser(cliParser_1.ParserAddress))
|
|
514
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, epoch, options) => {
|
|
515
|
+
const account = options.account ?? config.client.account.address;
|
|
516
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
517
|
+
await (0, vault_1.getVaultWithdrawalsOf)(vault, epoch, account);
|
|
518
|
+
});
|
|
519
|
+
// Get deposit limit
|
|
520
|
+
vaultCmd
|
|
521
|
+
.command("get-deposit-limit")
|
|
522
|
+
.description("Get deposit limit for a vault")
|
|
523
|
+
.addArgument(argVaultAddress)
|
|
524
|
+
.asyncAction(async (config, vaultAddress) => {
|
|
525
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
526
|
+
const limit = await vault.read.depositLimit();
|
|
527
|
+
const isLimitEnabled = await vault.read.isDepositLimit();
|
|
528
|
+
logger_1.logger.log(`Deposit limit for vault ${vaultAddress}: ${(0, viem_1.formatUnits)(limit, await vault.read.decimals())} (enabled: ${isLimitEnabled})`);
|
|
529
|
+
});
|
|
530
|
+
/* --------------------------------------------------
|
|
531
|
+
* L1RestakeDelegator (set-l1-limit / set-operator-l1-shares)
|
|
532
|
+
* -------------------------------------------------- */
|
|
533
|
+
vaultCmd
|
|
534
|
+
.command("set-l1-limit")
|
|
535
|
+
.description("Set the L1 limit for a vault's delegator")
|
|
536
|
+
.addArgument(argVaultAddress)
|
|
537
|
+
.addArgument(argValidatorManagerAddress)
|
|
538
|
+
.argument("limit", "Limit amount")
|
|
539
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClass", "Collateral class ID"))
|
|
540
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, l1Address, limit, collateralClass) => {
|
|
541
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
542
|
+
const delegatorAddress = await vault.read.delegator();
|
|
543
|
+
// instantiate L1RestakeDelegator contract
|
|
544
|
+
const delegator = await config.contracts.L1RestakeDelegator(delegatorAddress);
|
|
545
|
+
const limitWei = (0, viem_1.parseUnits)(limit, await vault.read.decimals());
|
|
546
|
+
await (0, delegator_1.setL1Limit)(delegator, l1Address, collateralClass, limitWei);
|
|
547
|
+
});
|
|
548
|
+
vaultCmd
|
|
549
|
+
.command("set-operator-l1-shares")
|
|
550
|
+
.description("Set the L1 shares for an operator in a delegator")
|
|
551
|
+
.addArgument(argVaultAddress)
|
|
552
|
+
.addArgument(argValidatorManagerAddress)
|
|
553
|
+
.addArgument(argOperatorAddress)
|
|
554
|
+
.addArgument((0, cliParser_1.ArgBigInt)("shares", "Shares amount"))
|
|
555
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClass", "Collateral class ID"))
|
|
556
|
+
.asyncAction({ signer: true }, async (config, vaultAddress, l1Address, operatorAddress, shares, collateralClass) => {
|
|
557
|
+
// instantiate L1RestakeDelegator contract
|
|
558
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
559
|
+
const delegatorAddress = await vault.read.delegator();
|
|
560
|
+
const delegator = await config.contracts.L1RestakeDelegator(delegatorAddress);
|
|
561
|
+
await (0, delegator_1.setOperatorL1Shares)(delegator, l1Address, collateralClass, operatorAddress, shares);
|
|
562
|
+
});
|
|
563
|
+
vaultCmd
|
|
564
|
+
.command("get-l1-limit")
|
|
565
|
+
.description("Get L1 limit for a vault's delegator")
|
|
566
|
+
.addArgument(argVaultAddress)
|
|
567
|
+
.addArgument(argValidatorManagerAddress)
|
|
568
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClass", "Collateral class ID"))
|
|
569
|
+
.asyncAction(async (config, vaultAddress, l1Address, collateralClass) => {
|
|
570
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
571
|
+
const delegatorAddress = await vault.read.delegator();
|
|
572
|
+
// instantiate L1RestakeDelegator contract
|
|
573
|
+
const delegator = await config.contracts.L1RestakeDelegator(delegatorAddress);
|
|
574
|
+
const limit = await delegator.read.l1Limit([l1Address, collateralClass]);
|
|
575
|
+
logger_1.logger.log(`L1 limit for vault ${vaultAddress} on L1 ${l1Address} (collateral class ${collateralClass}): ${(0, viem_1.formatUnits)(limit, await vault.read.decimals())}`);
|
|
576
|
+
});
|
|
577
|
+
vaultCmd
|
|
578
|
+
.command("get-operator-l1-shares")
|
|
579
|
+
.description("Get L1 shares for an operator in a vault's delegator")
|
|
580
|
+
.addArgument(argVaultAddress)
|
|
581
|
+
.addArgument(argValidatorManagerAddress)
|
|
582
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClass", "Collateral class ID"))
|
|
583
|
+
.addArgument(argOperatorAddress)
|
|
584
|
+
.asyncAction(async (config, vaultAddress, l1Address, collateralClass, operatorAddress) => {
|
|
585
|
+
const vault = await config.contracts.VaultTokenized(vaultAddress);
|
|
586
|
+
const delegatorAddress = await vault.read.delegator();
|
|
587
|
+
// instantiate L1RestakeDelegator contract
|
|
588
|
+
const delegator = await config.contracts.L1RestakeDelegator(delegatorAddress);
|
|
589
|
+
const shares = await delegator.read.operatorL1Shares([l1Address, collateralClass, operatorAddress]);
|
|
590
|
+
logger_1.logger.log(`L1 shares for operator ${operatorAddress} in vault ${vaultAddress} on L1 ${l1Address} (collateral class ${collateralClass}): ${shares}`);
|
|
591
|
+
});
|
|
592
|
+
/* --------------------------------------------------
|
|
593
|
+
* MIDDLEWARE
|
|
594
|
+
* -------------------------------------------------- */
|
|
595
|
+
const middlewareCmd = program
|
|
596
|
+
.command("middleware")
|
|
597
|
+
.description("Commands to interact with the L1 Middleware contract");
|
|
598
|
+
// Add secondary collateral class
|
|
599
|
+
middlewareCmd
|
|
600
|
+
.command("add-collateral-class")
|
|
601
|
+
.description("Add a new collateral class to the middleware")
|
|
602
|
+
.addArgument(argMiddlewareAddress)
|
|
603
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClassId", "Collateral class ID"))
|
|
604
|
+
.argument("minValidatorStake", "Minimum validator stake amount")
|
|
605
|
+
.argument("maxValidatorStake", "Maximum validator stake amount")
|
|
606
|
+
.addArgument((0, cliParser_1.ArgAddress)("initialCollateral", "Initial collateral address"))
|
|
607
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, collateralClassId, minValidatorStake, maxValidatorStake, initialCollateral) => {
|
|
608
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
609
|
+
const collateral = await config.contracts.DefaultCollateral(initialCollateral);
|
|
610
|
+
const decimals = await collateral.read.decimals();
|
|
611
|
+
const minStakeWei = (0, viem_1.parseUnits)(minValidatorStake, decimals);
|
|
612
|
+
const maxStakeWei = (0, viem_1.parseUnits)(maxValidatorStake, decimals);
|
|
613
|
+
await middlewareSvc.safeWrite.addCollateralClass([collateralClassId, minStakeWei, maxStakeWei, initialCollateral], {
|
|
614
|
+
chain: null,
|
|
615
|
+
account: config.client.account,
|
|
616
|
+
});
|
|
617
|
+
logger_1.logger.log(`Added collateral class ${collateralClassId} with min stake ${minValidatorStake} and max stake ${maxValidatorStake} using collateral at ${initialCollateral}`);
|
|
618
|
+
});
|
|
619
|
+
// Add collateral to class
|
|
620
|
+
middlewareCmd
|
|
621
|
+
.command("add-collateral-to-class")
|
|
622
|
+
.description("Add a new collateral address to an existing collateral class")
|
|
623
|
+
.addArgument(argMiddlewareAddress)
|
|
624
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClassId", "Collateral class ID"))
|
|
625
|
+
.addArgument((0, cliParser_1.ArgAddress)("collateralAddress", "Collateral address to add"))
|
|
626
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, collateralClassId, collateralAddress) => {
|
|
627
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
628
|
+
await middlewareSvc.safeWrite.addAssetToClass([collateralClassId, collateralAddress], {
|
|
629
|
+
chain: null,
|
|
630
|
+
account: config.client.account,
|
|
631
|
+
});
|
|
632
|
+
logger_1.logger.log(`Added collateral ${collateralAddress} to class ${collateralClassId}`);
|
|
633
|
+
});
|
|
634
|
+
// removeAssetFromClass
|
|
635
|
+
middlewareCmd
|
|
636
|
+
.command("remove-collateral-from-class")
|
|
637
|
+
.description("Remove a collateral address from an existing collateral class")
|
|
638
|
+
.addArgument(argMiddlewareAddress)
|
|
639
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClassId", "Collateral class ID"))
|
|
640
|
+
.addArgument((0, cliParser_1.ArgAddress)("collateralAddress", "Collateral address to remove"))
|
|
641
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, collateralClassId, collateralAddress) => {
|
|
642
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
643
|
+
const tx = await middlewareSvc.safeWrite.removeAssetFromClass([collateralClassId, collateralAddress], {
|
|
644
|
+
chain: null,
|
|
645
|
+
account: config.client.account,
|
|
646
|
+
});
|
|
647
|
+
logger_1.logger.log(`Removed collateral ${collateralAddress} from class ${collateralClassId}`);
|
|
648
|
+
logger_1.logger.log("tx hash:", tx);
|
|
649
|
+
});
|
|
650
|
+
// removeCollateralClass
|
|
651
|
+
middlewareCmd
|
|
652
|
+
.command("remove-collateral-class")
|
|
653
|
+
.description("Remove an existing secondary collateral class")
|
|
654
|
+
.addArgument(argMiddlewareAddress)
|
|
655
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClassId", "Collateral class ID"))
|
|
656
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, collateralClassId) => {
|
|
657
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
658
|
+
await middlewareSvc.safeWrite.removeCollateralClass([collateralClassId], {
|
|
659
|
+
chain: null,
|
|
660
|
+
account: config.client.account,
|
|
661
|
+
});
|
|
662
|
+
logger_1.logger.log(`Removed collateral class ${collateralClassId}`);
|
|
663
|
+
});
|
|
664
|
+
// activateSecondaryCollateralClass
|
|
665
|
+
middlewareCmd
|
|
666
|
+
.command("activate-collateral-class")
|
|
667
|
+
.description("Activate a secondary collateral class")
|
|
668
|
+
.addArgument(argMiddlewareAddress)
|
|
669
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClassId", "Collateral class ID"))
|
|
670
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, collateralClassId) => {
|
|
671
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
672
|
+
await middlewareSvc.safeWrite.activateSecondaryCollateralClass([collateralClassId], {
|
|
673
|
+
chain: null,
|
|
674
|
+
account: config.client.account,
|
|
675
|
+
});
|
|
676
|
+
logger_1.logger.log(`Activated collateral class ${collateralClassId}`);
|
|
677
|
+
});
|
|
678
|
+
// deactivateSecondaryCollateralClass
|
|
679
|
+
middlewareCmd
|
|
680
|
+
.command("deactivate-collateral-class")
|
|
681
|
+
.description("Deactivate a secondary collateral class")
|
|
682
|
+
.addArgument(argMiddlewareAddress)
|
|
683
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClassId", "Collateral class ID"))
|
|
684
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, collateralClassId) => {
|
|
685
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
686
|
+
await middlewareSvc.safeWrite.deactivateSecondaryCollateralClass([collateralClassId], {
|
|
687
|
+
chain: null,
|
|
688
|
+
account: config.client.account,
|
|
689
|
+
});
|
|
690
|
+
logger_1.logger.log(`Deactivated collateral class ${collateralClassId}`);
|
|
691
|
+
});
|
|
692
|
+
// Register operator
|
|
693
|
+
middlewareCmd
|
|
694
|
+
.command("register-operator")
|
|
695
|
+
.description("Register an operator to operate on this L1")
|
|
696
|
+
.addArgument(argMiddlewareAddress)
|
|
697
|
+
.addArgument(argOperatorAddress)
|
|
698
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, operator) => {
|
|
699
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
700
|
+
await (0, middleware_1.middlewareRegisterOperator)(middlewareSvc, operator);
|
|
701
|
+
});
|
|
702
|
+
// Disable operator
|
|
703
|
+
middlewareCmd
|
|
704
|
+
.command("disable-operator")
|
|
705
|
+
.description("Disable an operator to prevent it from operating on this L1")
|
|
706
|
+
.addArgument(argMiddlewareAddress)
|
|
707
|
+
.addArgument(argOperatorAddress)
|
|
708
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, operator) => {
|
|
709
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
710
|
+
await (0, middleware_1.middlewareDisableOperator)(middlewareSvc, operator);
|
|
711
|
+
});
|
|
712
|
+
// Remove operator
|
|
713
|
+
middlewareCmd
|
|
714
|
+
.command("remove-operator")
|
|
715
|
+
.description("Remove an operator from this L1")
|
|
716
|
+
.addArgument(argMiddlewareAddress)
|
|
717
|
+
.addArgument(argOperatorAddress)
|
|
718
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, operator) => {
|
|
719
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
720
|
+
await (0, middleware_1.middlewareRemoveOperator)(middlewareSvc, operator);
|
|
721
|
+
});
|
|
722
|
+
// Process node stake cache
|
|
723
|
+
middlewareCmd
|
|
724
|
+
.command("process-node-stake-cache")
|
|
725
|
+
.description("Manually process node stake cache for one or more epochs")
|
|
726
|
+
.addArgument(argMiddlewareAddress)
|
|
727
|
+
.addOption(new extra_typings_1.Option("--epochs <epochs>", "Number of epochs to process (default: all)").default(0).argParser(cliParser_1.ParserNumber))
|
|
728
|
+
.addOption(new extra_typings_1.Option("--loop-epochs <count>", "Loop through multiple epochs, processing --epochs at a time").argParser(cliParser_1.ParserNumber))
|
|
729
|
+
.addOption(new extra_typings_1.Option("--delay <milliseconds>", "Delay between loop iterations in milliseconds (default: 1000)").default(1000).argParser(cliParser_1.ParserNumber))
|
|
730
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, options) => {
|
|
731
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
732
|
+
let epochsPerCall;
|
|
733
|
+
let loopCount;
|
|
734
|
+
if (options.epochs || options.loopEpochs) { // Fully specified by user
|
|
735
|
+
epochsPerCall = options.epochs || 1;
|
|
736
|
+
loopCount = options.loopEpochs || 1;
|
|
737
|
+
}
|
|
738
|
+
else { // Automatic calculation
|
|
739
|
+
epochsPerCall = await middlewareSvc.read.getCurrentEpoch() - await middlewareSvc.read.lastGlobalNodeStakeUpdateEpoch();
|
|
740
|
+
loopCount = epochsPerCall > 50 ? Math.ceil(epochsPerCall / 50) : 1; // Limit number of epochs processed in a single call to avoid gas issues
|
|
741
|
+
epochsPerCall = Math.ceil(epochsPerCall / loopCount);
|
|
742
|
+
}
|
|
743
|
+
logger_1.logger.log(`Processing node stake cache: ${loopCount} iterations of ${epochsPerCall} epoch(s) each`);
|
|
744
|
+
for (let i = 0; i < loopCount; i++) {
|
|
745
|
+
logger_1.logger.log(`\nIteration ${i + 1}/${loopCount}`);
|
|
746
|
+
await (0, middleware_1.middlewareManualProcessNodeStakeCache)(middlewareSvc, epochsPerCall);
|
|
747
|
+
if (i < loopCount - 1 && options.delay > 0) {
|
|
748
|
+
logger_1.logger.log(`Waiting ${options.delay}ms before next iteration...`);
|
|
749
|
+
await new Promise(resolve => setTimeout(resolve, options.delay));
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
logger_1.logger.log(`\nCompleted processing ${loopCount * epochsPerCall} total epochs`);
|
|
753
|
+
});
|
|
754
|
+
// Add node
|
|
755
|
+
middlewareCmd
|
|
756
|
+
.command("add-node")
|
|
757
|
+
.description("Add a new node to an L1")
|
|
758
|
+
.addArgument(argMiddlewareAddress)
|
|
759
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
760
|
+
.addArgument((0, cliParser_1.ArgHex)("blsKey", "BLS public key"))
|
|
761
|
+
.addOption(new extra_typings_1.Option("--initial-stake <initialStake>", "Initial stake amount (default: 0)").default('0'))
|
|
762
|
+
.addOption(new extra_typings_1.Option("--registration-expiry <expiry>", "Expiry timestamp (default: now + 12 hours)"))
|
|
763
|
+
.addOption(new extra_typings_1.Option("--pchain-remaining-balance-owner-threshold <threshold>", "P-Chain remaining balance owner threshold").default(1).argParser(cliParser_1.ParserNumber))
|
|
764
|
+
.addOption(new extra_typings_1.Option("--pchain-disable-owner-threshold <threshold>", "P-Chain disable owner threshold").default(1).argParser(cliParser_1.ParserNumber))
|
|
765
|
+
.addOption(new extra_typings_1.Option("--pchain-remaining-balance-owner-address <address>", "P-Chain remaining balance owner address").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserAddress)))
|
|
766
|
+
.addOption(new extra_typings_1.Option("--pchain-disable-owner-address <address>", "P-Chain disable owner address").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserAddress)))
|
|
767
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, nodeId, blsKey, options) => {
|
|
768
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
769
|
+
const defaultOwnerAddress = (0, viem_1.fromBytes)(avalanchejs_1.utils.bech32ToBytes(config.client.addresses.P), 'hex');
|
|
770
|
+
// Default registration expiry to now + 12 hours if not provided
|
|
771
|
+
// const registrationExpiry = options.registrationExpiry
|
|
772
|
+
// ? BigInt(options.registrationExpiry)
|
|
773
|
+
// : BigInt(Math.floor(Date.now() / 1000) + 12 * 60 * 60); // current time + 12 hours in seconds
|
|
774
|
+
// Build remainingBalanceOwner and disableOwner PChainOwner structs
|
|
775
|
+
// If pchainRemainingBalanceOwnerAddress or pchainDisableOwnerAddress are empty (not provided), use the client account
|
|
776
|
+
const remainingBalanceOwnerAddress = options.pchainRemainingBalanceOwnerAddress.length > 0 ? options.pchainRemainingBalanceOwnerAddress : [defaultOwnerAddress];
|
|
777
|
+
const disableOwnerAddress = options.pchainDisableOwnerAddress.length > 0 ? options.pchainDisableOwnerAddress : [defaultOwnerAddress];
|
|
778
|
+
const remainingBalanceOwner = [
|
|
779
|
+
Number(options.pchainRemainingBalanceOwnerThreshold),
|
|
780
|
+
remainingBalanceOwnerAddress
|
|
781
|
+
];
|
|
782
|
+
const disableOwner = [
|
|
783
|
+
Number(options.pchainDisableOwnerThreshold),
|
|
784
|
+
disableOwnerAddress
|
|
785
|
+
];
|
|
786
|
+
const primaryCollateralAddress = await middlewareSvc.read.PRIMARY_ASSET();
|
|
787
|
+
const primaryCollateral = await config.contracts.DefaultCollateral(primaryCollateralAddress);
|
|
788
|
+
const initialStakeWei = (0, viem_1.parseUnits)(options.initialStake.toString(), await primaryCollateral.read.decimals());
|
|
789
|
+
// Call middlewareAddNode
|
|
790
|
+
await (0, middleware_1.middlewareAddNode)(middlewareSvc, nodeId, blsKey, remainingBalanceOwner, disableOwner, initialStakeWei);
|
|
791
|
+
});
|
|
792
|
+
// Complete validator registration
|
|
793
|
+
middlewareCmd
|
|
794
|
+
.command("complete-validator-registration")
|
|
795
|
+
.description("Complete validator registration on the P-Chain and on the middleware after adding a node")
|
|
796
|
+
.addArgument(argMiddlewareAddress)
|
|
797
|
+
.addArgument((0, cliParser_1.ArgHex)("addNodeTxHash", "Add node transaction hash"))
|
|
798
|
+
.addArgument((0, cliParser_1.ArgBLSPOP)())
|
|
799
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
800
|
+
.addOption(new extra_typings_1.Option("--initial-balance <initialBalance>", "Node initial balance to pay for continuous fee").default('0.01')) // In decimals
|
|
801
|
+
.addOption(new extra_typings_1.Option("--skip-wait-api", "Don't wait for the validator to be visible through the P-Chain API"))
|
|
802
|
+
.asyncAction(async (_, middlewareAddress, addNodeTxHash, blsProofOfPossession, options) => {
|
|
803
|
+
const opts = program.opts();
|
|
804
|
+
// If pchainTxPrivateKey is not provided, use the private key
|
|
805
|
+
if (!options.pchainTxPrivateKey) {
|
|
806
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
807
|
+
}
|
|
808
|
+
const initialBalance = (0, cliParser_1.ParseUnits)(options.initialBalance, 9, 'Invalid initial balance');
|
|
809
|
+
const client = await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey, opts.safe);
|
|
810
|
+
const config = (0, config_1.getConfig)(client, opts.wait, opts.skipAbiValidation);
|
|
811
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
812
|
+
const balancerSvc = await config.contracts.BalancerValidatorManager(await middlewareSvc.read.balancerValidatorManager());
|
|
813
|
+
// Check if P-Chain address have 0.1 AVAX for tx fees but some times it can be less than 0.000050000 AVAX (perhaps when the validator was removed recently)
|
|
814
|
+
// await requirePChainBallance(config.client, BigInt(Math.round((50000 + Number(initialBalance)))), opts.yes);
|
|
815
|
+
// Call middlewareCompleteValidatorRegistration (no safe for pChain txs)
|
|
816
|
+
await (0, securityModule_1.completeValidatorRegistration)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : client, middlewareSvc, balancerSvc, config, blsProofOfPossession, addNodeTxHash, initialBalance, !options.skipWaitApi);
|
|
817
|
+
});
|
|
818
|
+
// Remove node
|
|
819
|
+
middlewareCmd
|
|
820
|
+
.command("remove-node")
|
|
821
|
+
.description("Remove a node from an L1")
|
|
822
|
+
.addArgument(argMiddlewareAddress)
|
|
823
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
824
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, nodeId) => {
|
|
825
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
826
|
+
await (0, middleware_1.middlewareRemoveNode)(middlewareSvc, nodeId);
|
|
827
|
+
});
|
|
828
|
+
// Complete validator removal
|
|
829
|
+
middlewareCmd
|
|
830
|
+
.command("complete-validator-removal")
|
|
831
|
+
.description("Complete validator removal on the P-Chain and on the middleware after removing a node")
|
|
832
|
+
.addArgument(argMiddlewareAddress)
|
|
833
|
+
.addArgument((0, cliParser_1.ArgHex)("removeNodeTxHash", "Remove node transaction hash"))
|
|
834
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
835
|
+
.addOption(new extra_typings_1.Option("--skip-wait-api", "Don't wait for the validator to be visible through the P-Chain API"))
|
|
836
|
+
.addOption(new extra_typings_1.Option("--node-id <nodeId>", "Node ID of the validator being removed").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserNodeID)))
|
|
837
|
+
.addOption(new extra_typings_1.Option("--add-node-tx <addNodeTx>", "Add node transaction hash").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserHex)))
|
|
838
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, removeNodeTxHash, options) => {
|
|
839
|
+
const opts = program.opts();
|
|
840
|
+
if (!options.pchainTxPrivateKey)
|
|
841
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
842
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
843
|
+
const balancerSvc = await config.contracts.BalancerValidatorManager(await middlewareSvc.read.balancerValidatorManager());
|
|
844
|
+
// Check if P-Chain address have 0.01 AVAX for tx fees but some times it can be less than 0.000050000 AVAX (perhaps when the validator was added recently)
|
|
845
|
+
await (0, transferUtils_1.requirePChainBallance)(config.client, 50000n, opts.yes);
|
|
846
|
+
await (0, securityModule_1.completeValidatorRemoval)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : config.client, middlewareSvc, balancerSvc, config, removeNodeTxHash, !options.skipWaitApi, options.nodeId.length > 0 ? options.nodeId : undefined, options.addNodeTx.length > 0 ? options.addNodeTx : undefined);
|
|
847
|
+
});
|
|
848
|
+
// Init stake update
|
|
849
|
+
middlewareCmd
|
|
850
|
+
.command("init-stake-update")
|
|
851
|
+
.description("Initialize validator stake update and lock")
|
|
852
|
+
.addArgument(argMiddlewareAddress)
|
|
853
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
854
|
+
.argument("newStake", "New stake amount")
|
|
855
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, nodeId, newStake) => {
|
|
856
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
857
|
+
const primaryCollateral = await middlewareSvc.read.PRIMARY_ASSET();
|
|
858
|
+
const collateral = await config.contracts.DefaultCollateral(primaryCollateral);
|
|
859
|
+
const decimals = await collateral.read.decimals();
|
|
860
|
+
const newStakeWei = (0, viem_1.parseUnits)(newStake, decimals);
|
|
861
|
+
await (0, middleware_1.middlewareInitStakeUpdate)(middlewareSvc, nodeId, newStakeWei);
|
|
862
|
+
});
|
|
863
|
+
// Complete stake update
|
|
864
|
+
middlewareCmd
|
|
865
|
+
.command("complete-stake-update")
|
|
866
|
+
.description("Complete validator stake update of all or specified node IDs")
|
|
867
|
+
.addArgument(argMiddlewareAddress)
|
|
868
|
+
.addArgument((0, cliParser_1.ArgHex)("validatorStakeUpdateTxHash", "Validator stake update transaction hash"))
|
|
869
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
870
|
+
.addOption(new extra_typings_1.Option("--node-id <nodeId>", "Node ID of the validator being removed").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserNodeID)))
|
|
871
|
+
.asyncAction(async (_, middlewareAddress, validatorStakeUpdateTxHash, options) => {
|
|
872
|
+
const opts = program.opts();
|
|
873
|
+
// If pchainTxPrivateKey is not provided, use the private key
|
|
874
|
+
if (!options.pchainTxPrivateKey) {
|
|
875
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
876
|
+
}
|
|
877
|
+
const client = await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey, opts.safe);
|
|
878
|
+
const config = (0, config_1.getConfig)(client, opts.wait, opts.skipAbiValidation);
|
|
879
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
880
|
+
// Check if P-Chain address have 0.000050000 AVAX for tx fees
|
|
881
|
+
await (0, transferUtils_1.requirePChainBallance)(client, 50000n, opts.yes);
|
|
882
|
+
await (0, securityModule_1.completeWeightUpdate)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : client, middlewareSvc, config, validatorStakeUpdateTxHash, options.nodeId.length > 0 ? options.nodeId : undefined);
|
|
883
|
+
});
|
|
884
|
+
// Operator cache / calcAndCacheStakes
|
|
885
|
+
middlewareCmd
|
|
886
|
+
.command("calc-operator-cache")
|
|
887
|
+
.description("Calculate and cache stakes for operators")
|
|
888
|
+
.addArgument(argMiddlewareAddress)
|
|
889
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch number"))
|
|
890
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClass", "Collateral class ID"))
|
|
891
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, epoch, collateralClass) => {
|
|
892
|
+
logger_1.logger.log("Calculating and caching stakes...");
|
|
893
|
+
if (!config.client.account) {
|
|
894
|
+
throw new Error('Client account is required');
|
|
895
|
+
}
|
|
896
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
897
|
+
const hash = await middlewareSvc.safeWrite.calcAndCacheStakes([epoch, collateralClass], {
|
|
898
|
+
chain: null,
|
|
899
|
+
account: config.client.account,
|
|
900
|
+
});
|
|
901
|
+
logger_1.logger.log("calcAndCacheStakes done, tx hash:", hash);
|
|
902
|
+
});
|
|
903
|
+
// calcAndCacheNodeStakeForAllOperators
|
|
904
|
+
middlewareCmd
|
|
905
|
+
.command("calc-node-stakes")
|
|
906
|
+
.description("Calculate and cache node stakes for all operators")
|
|
907
|
+
.addArgument(argMiddlewareAddress)
|
|
908
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress) => {
|
|
909
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
910
|
+
await (0, middleware_1.middlewareCalcNodeStakes)(middlewareSvc);
|
|
911
|
+
});
|
|
912
|
+
// forceUpdateNodes
|
|
913
|
+
middlewareCmd
|
|
914
|
+
.command("force-update-nodes")
|
|
915
|
+
.description("Force update operator nodes with stake limit")
|
|
916
|
+
.addArgument(argMiddlewareAddress)
|
|
917
|
+
.addArgument(argOperatorAddress)
|
|
918
|
+
.addOption(new extra_typings_1.Option("--limit-stake <stake>", "Stake limit").default(0n).argParser(cliParser_1.ParserAVAX))
|
|
919
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, operator, options) => {
|
|
920
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
921
|
+
await (0, middleware_1.middlewareForceUpdateNodes)(middlewareSvc, operator, options.limitStake);
|
|
922
|
+
});
|
|
923
|
+
// topUpAllOperatorNodes
|
|
924
|
+
middlewareCmd
|
|
925
|
+
.command("top-up-operator-validators")
|
|
926
|
+
.description("Top up all operator validators to meet a target continuous fee balance")
|
|
927
|
+
.addArgument(argMiddlewareAddress)
|
|
928
|
+
.addArgument(argOperatorAddress)
|
|
929
|
+
.argument("targetBalance", "Target continuous fee balance per validator (in AVAX)")
|
|
930
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, operator, targetBalance) => {
|
|
931
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
932
|
+
const targetBalanceWei = (0, viem_1.parseUnits)(targetBalance, 9); // AVAX has 9 decimals
|
|
933
|
+
if (targetBalanceWei <= BigInt(1e7)) { // 0.01 AVAX min
|
|
934
|
+
throw new Error("Target balance must be greater than 0.01 AVAX");
|
|
935
|
+
}
|
|
936
|
+
const balancerAddress = await middlewareSvc.read.BALANCER();
|
|
937
|
+
const balancer = await config.contracts.BalancerValidatorManager(balancerAddress);
|
|
938
|
+
const [nodeCount, subnetID] = await Promise.all([middlewareSvc.read.getOperatorNodesLength([operator]), balancer.read.subnetID()]);
|
|
939
|
+
const validators = await (0, pChainUtils_1.getCurrentValidators)(config.client, avalanchejs_1.utils.base58check.encode((0, justification_1.hexToUint8Array)(subnetID)));
|
|
940
|
+
const validatorsToCheck = await Promise.all(ts_belt_1.A.range(0, Number(nodeCount) - 1)
|
|
941
|
+
.map(async (index) => {
|
|
942
|
+
const nodeIdHex = await middlewareSvc.read.operatorNodesArray([operator, BigInt(index)]);
|
|
943
|
+
return validators.find(v => v.nodeID === (0, utils_1.encodeNodeID)(nodeIdHex));
|
|
944
|
+
}));
|
|
945
|
+
const validatorsToTopUp = validatorsToCheck.reduce((acc, validator) => {
|
|
946
|
+
if (validator && validator.balance < targetBalanceWei - BigInt(1e7)) { // 0.01 AVAX min diff
|
|
947
|
+
acc.push({
|
|
948
|
+
validationId: validator.validationID,
|
|
949
|
+
topup: targetBalanceWei - BigInt(validator.balance),
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
return acc;
|
|
953
|
+
}, []);
|
|
954
|
+
const totalTopUp = validatorsToTopUp.reduce((acc, v) => acc + v.topup, 0n);
|
|
955
|
+
if (validatorsToTopUp.length === 0) {
|
|
956
|
+
logger_1.logger.log("All operator validators have sufficient balance. No top-up needed.");
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
959
|
+
logger_1.logger.log(`${validatorsToTopUp.length} validators to top-up for a total of ${(0, viem_1.formatUnits)(totalTopUp, 9)} AVAX.`);
|
|
960
|
+
await (0, transferUtils_1.requirePChainBallance)(config.client, totalTopUp + BigInt(2e4) * nodeCount, program.opts().yes); // extra 20000 for fees
|
|
961
|
+
if (!program.opts().yes) {
|
|
962
|
+
const response = await logger_1.logger.prompt(`Proceed with topping up validators? (y/n): `);
|
|
963
|
+
if (response.toLowerCase() !== 'y') {
|
|
964
|
+
logger_1.logger.log("Operation cancelled by user.");
|
|
965
|
+
process.exit(0);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
for (const { validationId, topup } of validatorsToTopUp) {
|
|
969
|
+
logger_1.logger.log(`\nTopping up validator ${validationId}`);
|
|
970
|
+
const amount = Number(topup) / 1e9;
|
|
971
|
+
(0, ts_belt_1.pipe)(await (0, pChainUtils_1.increasePChainValidatorBalance)(config.client, amount, validationId, false), ts_belt_1.R.tapError(err => { logger_1.logger.error(err); process.exit(1); }));
|
|
972
|
+
}
|
|
973
|
+
logger_1.logger.log("\nCompleted top-up of operator validators.");
|
|
974
|
+
logger_1.logger.addData('total_amount', totalTopUp);
|
|
975
|
+
logger_1.logger.addData('validators', validatorsToTopUp);
|
|
976
|
+
});
|
|
977
|
+
// getOperatorStake (read)
|
|
978
|
+
middlewareCmd
|
|
979
|
+
.command("get-operator-stake")
|
|
980
|
+
.description("Get operator stake for a specific epoch and collateral class")
|
|
981
|
+
.addArgument(argMiddlewareAddress)
|
|
982
|
+
.addArgument(argOperatorAddress)
|
|
983
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch number"))
|
|
984
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClass", "Collateral class ID"))
|
|
985
|
+
.asyncAction(async (config, middlewareAddress, operator, epoch, collateralClass) => {
|
|
986
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
987
|
+
await (0, middleware_1.middlewareGetOperatorStake)(middlewareSvc, operator, epoch, collateralClass);
|
|
988
|
+
});
|
|
989
|
+
middlewareCmd
|
|
990
|
+
.command("get-operator-nodes")
|
|
991
|
+
.description("Get operator nodes")
|
|
992
|
+
.addArgument(argMiddlewareAddress)
|
|
993
|
+
.addArgument(argOperatorAddress)
|
|
994
|
+
.asyncAction(async (config, middlewareAddress, operator) => {
|
|
995
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
996
|
+
const nodeCount = await middlewareSvc.read.getOperatorNodesLength([operator]);
|
|
997
|
+
const abi = [(0, viem_1.getAbiItem)({ abi: middlewareSvc.abi, name: 'operatorNodesArray' })];
|
|
998
|
+
const multicallResult = await config.client.multicall({
|
|
999
|
+
contracts: ts_belt_1.A.range(0, Number(nodeCount) - 1).map(i => { return { args: [operator, BigInt(i)], abi, address: middlewareAddress, functionName: 'operatorNodesArray' }; })
|
|
1000
|
+
});
|
|
1001
|
+
const nodes = multicallResult.map((node) => node.error ? "error" : (0, utils_1.encodeNodeID)(node.result));
|
|
1002
|
+
logger_1.logger.log(nodes);
|
|
1003
|
+
logger_1.logger.addData('nodes', nodes);
|
|
1004
|
+
});
|
|
1005
|
+
// getCurrentEpoch (read)
|
|
1006
|
+
middlewareCmd
|
|
1007
|
+
.command("get-current-epoch")
|
|
1008
|
+
.description("Get current epoch number")
|
|
1009
|
+
.addArgument(argMiddlewareAddress)
|
|
1010
|
+
.asyncAction(async (config, middlewareAddress) => {
|
|
1011
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1012
|
+
await (0, middleware_1.middlewareGetCurrentEpoch)(middlewareSvc);
|
|
1013
|
+
});
|
|
1014
|
+
// getEpochStartTs (read)
|
|
1015
|
+
middlewareCmd
|
|
1016
|
+
.command("get-epoch-start-ts")
|
|
1017
|
+
.description("Get epoch start timestamp")
|
|
1018
|
+
.addArgument(argMiddlewareAddress)
|
|
1019
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch number"))
|
|
1020
|
+
.asyncAction(async (config, middlewareAddress, epoch) => {
|
|
1021
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1022
|
+
await (0, middleware_1.middlewareGetEpochStartTs)(middlewareSvc, epoch);
|
|
1023
|
+
});
|
|
1024
|
+
// getActiveNodesForEpoch (read)
|
|
1025
|
+
middlewareCmd
|
|
1026
|
+
.command("get-active-nodes-for-epoch")
|
|
1027
|
+
.description("Get active nodes for an operator in a specific epoch")
|
|
1028
|
+
.addArgument(argMiddlewareAddress)
|
|
1029
|
+
.addArgument(argOperatorAddress)
|
|
1030
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch number"))
|
|
1031
|
+
.asyncAction(async (config, middlewareAddress, operator, epoch) => {
|
|
1032
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1033
|
+
await (0, middleware_1.middlewareGetActiveNodesForEpoch)(middlewareSvc, operator, epoch);
|
|
1034
|
+
});
|
|
1035
|
+
// getOperatorNodesLength (read)
|
|
1036
|
+
middlewareCmd
|
|
1037
|
+
.command("get-operator-nodes-length")
|
|
1038
|
+
.description("Get current number of nodes for an operator")
|
|
1039
|
+
.addArgument(argMiddlewareAddress)
|
|
1040
|
+
.addArgument(argOperatorAddress)
|
|
1041
|
+
.asyncAction(async (config, middlewareAddress, operator) => {
|
|
1042
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1043
|
+
await (0, middleware_1.middlewareGetOperatorNodesLength)(middlewareSvc, operator);
|
|
1044
|
+
});
|
|
1045
|
+
// getNodeStakeCache (read)
|
|
1046
|
+
middlewareCmd
|
|
1047
|
+
.command("get-node-stake-cache")
|
|
1048
|
+
.description("Get node stake cache for a specific epoch and validator")
|
|
1049
|
+
.addArgument(argMiddlewareAddress)
|
|
1050
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch number"))
|
|
1051
|
+
.addArgument((0, cliParser_1.ArgHex)("validationId", "Validation ID"))
|
|
1052
|
+
.asyncAction(async (config, middlewareAddress, epoch, validationId) => {
|
|
1053
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1054
|
+
await (0, middleware_1.middlewareGetNodeStakeCache)(middlewareSvc, epoch, validationId);
|
|
1055
|
+
});
|
|
1056
|
+
// getOperatorLockedStake (read)
|
|
1057
|
+
middlewareCmd
|
|
1058
|
+
.command("get-operator-locked-stake")
|
|
1059
|
+
.description("Get operator locked stake")
|
|
1060
|
+
.addArgument(argMiddlewareAddress)
|
|
1061
|
+
.addArgument(argOperatorAddress)
|
|
1062
|
+
.asyncAction(async (config, middlewareAddress, operator) => {
|
|
1063
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1064
|
+
await (0, middleware_1.middlewareGetOperatorLockedStake)(middlewareSvc, operator);
|
|
1065
|
+
});
|
|
1066
|
+
// nodePendingRemoval (read)
|
|
1067
|
+
middlewareCmd
|
|
1068
|
+
.command("node-pending-removal")
|
|
1069
|
+
.description("Check if node is pending removal")
|
|
1070
|
+
.addArgument(argMiddlewareAddress)
|
|
1071
|
+
.addArgument((0, cliParser_1.ArgHex)("validationId", "Validation ID"))
|
|
1072
|
+
.asyncAction(async (config, middlewareAddress, validationId) => {
|
|
1073
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1074
|
+
await (0, middleware_1.middlewareNodePendingRemoval)(middlewareSvc, validationId);
|
|
1075
|
+
});
|
|
1076
|
+
// getOperatorUsedStakeCached (read)
|
|
1077
|
+
middlewareCmd
|
|
1078
|
+
.command("get-operator-used-stake")
|
|
1079
|
+
.description("Get operator used stake from cache")
|
|
1080
|
+
.addArgument(argMiddlewareAddress)
|
|
1081
|
+
.addArgument(argOperatorAddress)
|
|
1082
|
+
.asyncAction(async (config, middlewareAddress, operator) => {
|
|
1083
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1084
|
+
await (0, middleware_1.middlewareGetOperatorUsedStake)(middlewareSvc, operator);
|
|
1085
|
+
});
|
|
1086
|
+
// getOperatorAvailableStake (read)
|
|
1087
|
+
middlewareCmd
|
|
1088
|
+
.command("get-operator-available-stake")
|
|
1089
|
+
.description("Get operator available stake")
|
|
1090
|
+
.addArgument(argMiddlewareAddress)
|
|
1091
|
+
.addArgument(argOperatorAddress)
|
|
1092
|
+
.asyncAction(async (config, middlewareAddress, operator) => {
|
|
1093
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1094
|
+
const availableStake = await middlewareSvc.read.getOperatorAvailableStake([operator]);
|
|
1095
|
+
logger_1.logger.log(`Operator ${operator} available stake: ${availableStake}`);
|
|
1096
|
+
});
|
|
1097
|
+
// getAllOperators (read)
|
|
1098
|
+
middlewareCmd
|
|
1099
|
+
.command("get-all-operators")
|
|
1100
|
+
.description("Get all operators registered")
|
|
1101
|
+
.addArgument(argMiddlewareAddress)
|
|
1102
|
+
.asyncAction(async (config, middlewareAddress) => {
|
|
1103
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1104
|
+
await (0, middleware_1.middlewareGetAllOperators)(middlewareSvc);
|
|
1105
|
+
});
|
|
1106
|
+
// getCollateralClassIds (read)
|
|
1107
|
+
middlewareCmd
|
|
1108
|
+
.command("get-collateral-class-ids")
|
|
1109
|
+
.description("Get all collateral class IDs from the middleware")
|
|
1110
|
+
.addArgument(argMiddlewareAddress)
|
|
1111
|
+
.asyncAction(async (config, middlewareAddress) => {
|
|
1112
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1113
|
+
await (0, middleware_1.getCollateralClassIds)(middlewareSvc);
|
|
1114
|
+
});
|
|
1115
|
+
// getActiveCollateralClasses (read)
|
|
1116
|
+
middlewareCmd
|
|
1117
|
+
.command("get-active-collateral-classes")
|
|
1118
|
+
.description("Get active collateral classes (primary and secondary)")
|
|
1119
|
+
.addArgument(argMiddlewareAddress)
|
|
1120
|
+
.asyncAction(async (config, middlewareAddress) => {
|
|
1121
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1122
|
+
await (0, middleware_1.getActiveCollateralClasses)(middlewareSvc);
|
|
1123
|
+
});
|
|
1124
|
+
middlewareCmd
|
|
1125
|
+
.command("node-logs")
|
|
1126
|
+
.description("Get middleware node logs")
|
|
1127
|
+
.addArgument(argMiddlewareAddress)
|
|
1128
|
+
.addOption(new extra_typings_1.Option("--node-id <nodeId>", "Node ID to filter logs").default(undefined).argParser(cliParser_1.ParserNodeID))
|
|
1129
|
+
.addOption(new extra_typings_1.Option('--snowscan-api-key <string>', "Snowscan API key").default(""))
|
|
1130
|
+
.asyncAction(async (config, middlewareAddress, options) => {
|
|
1131
|
+
logger_1.logger.log(`nodeId: ${options.nodeId}`);
|
|
1132
|
+
const middleware = await config.contracts.L1Middleware(middlewareAddress);
|
|
1133
|
+
await (0, middleware_1.middlewareGetNodeLogs)(config.client, middleware, config, options.nodeId, options.snowscanApiKey);
|
|
1134
|
+
});
|
|
1135
|
+
middlewareCmd
|
|
1136
|
+
.command("get-last-node-validation-id")
|
|
1137
|
+
.description("Set middleware log level")
|
|
1138
|
+
.addArgument(argMiddlewareAddress)
|
|
1139
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
1140
|
+
.asyncAction(async (config, middlewareAddress, nodeId) => {
|
|
1141
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1142
|
+
const balancerAddress = await middlewareSvc.read.balancerValidatorManager();
|
|
1143
|
+
const balancerSvc = await config.contracts.BalancerValidatorManager(balancerAddress);
|
|
1144
|
+
logger_1.logger.log(`Fetching last validation ID`);
|
|
1145
|
+
const validationId = await (0, middleware_1.middlewareLastValidationId)(config.client, middlewareSvc, balancerSvc, nodeId);
|
|
1146
|
+
logger_1.logger.log(`Last validationID: ${validationId}`);
|
|
1147
|
+
});
|
|
1148
|
+
middlewareCmd
|
|
1149
|
+
.command("to-vault-epoch")
|
|
1150
|
+
.description("convert middleware epoch to a vault epoch")
|
|
1151
|
+
.addArgument(argMiddlewareAddress)
|
|
1152
|
+
.addArgument(argVaultAddress)
|
|
1153
|
+
.addArgument((0, cliParser_1.ArgNumber)("middlewareEpoch", "Middleware epoch number"))
|
|
1154
|
+
.asyncAction(async (config, middlewareAddress, vaultAddress, middlewareEpoch) => {
|
|
1155
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1156
|
+
const vaultSvc = await config.contracts.VaultTokenized(vaultAddress);
|
|
1157
|
+
const middlewareEpochTs = await middlewareSvc.read.getEpochStartTs([middlewareEpoch]);
|
|
1158
|
+
const vaultEpoch = await vaultSvc.read.epochAt([middlewareEpochTs]);
|
|
1159
|
+
logger_1.logger.log(`Vault epoch at middleware epoch ${middlewareEpoch} (timestamp: ${middlewareEpochTs}) is ${vaultEpoch}`);
|
|
1160
|
+
});
|
|
1161
|
+
middlewareCmd
|
|
1162
|
+
.command("update-window-ends-ts")
|
|
1163
|
+
.description("Get the end timestamp of the last completed middleware epoch window")
|
|
1164
|
+
.addArgument(argMiddlewareAddress)
|
|
1165
|
+
.asyncAction(async (config, middlewareAddress) => {
|
|
1166
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1167
|
+
const [currentEpoch, updateWindow] = await middlewareSvc.multicall(['getCurrentEpoch', 'UPDATE_WINDOW']);
|
|
1168
|
+
const lastEpochStartTs = await middlewareSvc.read.getEpochStartTs([currentEpoch]);
|
|
1169
|
+
logger_1.logger.log(`Window ends at: ${lastEpochStartTs + updateWindow}`);
|
|
1170
|
+
});
|
|
1171
|
+
middlewareCmd
|
|
1172
|
+
.command("vault-to-middleware-epoch")
|
|
1173
|
+
.description("convert vault epoch to a middleware epoch")
|
|
1174
|
+
.addArgument(argMiddlewareAddress)
|
|
1175
|
+
.addArgument(argVaultAddress)
|
|
1176
|
+
.addArgument((0, cliParser_1.ArgNumber)("vaultEpoch", "Vault epoch number"))
|
|
1177
|
+
.asyncAction(async (config, middlewareAddress, vaultAddress, vaultEpoch) => {
|
|
1178
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1179
|
+
const vaultSvc = await config.contracts.VaultTokenized(vaultAddress);
|
|
1180
|
+
const vaultEpochStartTs = await vaultSvc.read.epochDuration() * vaultEpoch + await vaultSvc.read.epochDurationInit();
|
|
1181
|
+
const middlewareEpoch = await middlewareSvc.read.getEpochAtTs([vaultEpochStartTs]);
|
|
1182
|
+
logger_1.logger.log(`Middleware epoch at vault epoch ${vaultEpoch} (timestamp: ${vaultEpochStartTs}) is ${middlewareEpoch}`);
|
|
1183
|
+
});
|
|
1184
|
+
middlewareCmd
|
|
1185
|
+
.command("set-vault-manager")
|
|
1186
|
+
.description("Set vault manager")
|
|
1187
|
+
.addArgument(argMiddlewareAddress)
|
|
1188
|
+
.addArgument(argMiddlewareVaultManagerAddress)
|
|
1189
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, vaultManagerAddress) => {
|
|
1190
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1191
|
+
await middlewareSvc.safeWrite.setVaultManager([vaultManagerAddress]);
|
|
1192
|
+
logger_1.logger.log(`Set vault manager to ${vaultManagerAddress} on middleware ${middlewareAddress} ok`);
|
|
1193
|
+
});
|
|
1194
|
+
middlewareCmd
|
|
1195
|
+
.command("get-operator-validation-ids")
|
|
1196
|
+
.description("Get operator validation IDs")
|
|
1197
|
+
.addArgument(argMiddlewareAddress)
|
|
1198
|
+
.addArgument(argOperatorAddress)
|
|
1199
|
+
.asyncAction(async (config, middlewareAddress, operator) => {
|
|
1200
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1201
|
+
const validationIDs = await middlewareSvc.read.getOperatorValidationIDs([operator]);
|
|
1202
|
+
logger_1.logger.log(`Validation IDs for operator ${operator}: ${validationIDs.join(', ')}`);
|
|
1203
|
+
});
|
|
1204
|
+
middlewareCmd
|
|
1205
|
+
.command("account-info")
|
|
1206
|
+
.description("Get account info")
|
|
1207
|
+
.addArgument(argMiddlewareAddress)
|
|
1208
|
+
.addArgument((0, cliParser_1.ArgAddress)("account", "Account address"))
|
|
1209
|
+
.asyncAction(async (config, middlewareAddress, account) => {
|
|
1210
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1211
|
+
const [owner, operators, epoch, balancerAddress] = await middlewareSvc.multicall(['owner', 'getAllOperators', 'getCurrentEpoch', 'BALANCER']);
|
|
1212
|
+
const roles = (0, accessControl_1.getRoles)(middlewareSvc);
|
|
1213
|
+
const accessControl = await config.contracts.AccessControl(middlewareAddress);
|
|
1214
|
+
const hasRole = await accessControl.multicall(roles.map(role => { return { name: 'hasRole', args: [(0, accessControl_1.ensureRoleHex)(role), account] }; }));
|
|
1215
|
+
logger_1.logger.log(`Account ${account} has the following rights: `);
|
|
1216
|
+
if (account === owner) {
|
|
1217
|
+
logger_1.logger.log(`L1 owner`);
|
|
1218
|
+
}
|
|
1219
|
+
if (hasRole.some(role => role)) {
|
|
1220
|
+
logger_1.logger.log(`Middleware roles: `);
|
|
1221
|
+
logger_1.logger.log(" " + roles.filter((_, index) => hasRole[index]).join('\n '));
|
|
1222
|
+
}
|
|
1223
|
+
if (operators.includes(account)) {
|
|
1224
|
+
const balancerSvc = await config.contracts.BalancerValidatorManager(balancerAddress);
|
|
1225
|
+
const [stake, validationIDs] = await middlewareSvc.multicall([
|
|
1226
|
+
{ name: 'getOperatorStake', args: [account, 1, BigInt(epoch)] },
|
|
1227
|
+
{ name: 'getOperatorValidationIDs', args: [account] }
|
|
1228
|
+
]);
|
|
1229
|
+
const validators = await balancerSvc.multicall(validationIDs.flatMap(id => { return [{ name: 'getValidator', args: [id] }, { name: 'isValidatorPendingWeightUpdate', args: [id] }]; }));
|
|
1230
|
+
logger_1.logger.log(`Operator with stake ${stake} and the following validators: `);
|
|
1231
|
+
const subnetIdHex = await balancerSvc.read.subnetID();
|
|
1232
|
+
const pChainValidators = await (0, pChainUtils_1.getCurrentValidators)(config.client, avalanchejs_1.utils.base58check.encode((0, viem_1.hexToBytes)(subnetIdHex)));
|
|
1233
|
+
const formated = {};
|
|
1234
|
+
for (let i = 0; i < validators.length; i += 2) {
|
|
1235
|
+
const validator = validators[i];
|
|
1236
|
+
const pendingWeightUpdate = validators[i + 1];
|
|
1237
|
+
const status = balancer_1.ValidatorStatusNames[validator.status == balancer_1.ValidatorStatus.Active && pendingWeightUpdate ? balancer_1.ValidatorStatus.PendingStakeUpdated : validator.status];
|
|
1238
|
+
const pChainValidator = pChainValidators.find(v => v.nodeID === validator.nodeID);
|
|
1239
|
+
formated[(0, utils_1.encodeNodeID)(validator.nodeID)] = { NodeID: (0, utils_1.encodeNodeID)(validator.nodeID), status, weight: validator.weight, ValidationId: validationIDs[i / 2], continuousAVAXBalance: (0, viem_1.parseUnits)(pChainValidator?.balance?.toString() ?? '0', 9) };
|
|
1240
|
+
}
|
|
1241
|
+
logger_1.logger.logJsonTree(formated);
|
|
1242
|
+
}
|
|
1243
|
+
});
|
|
1244
|
+
middlewareCmd
|
|
1245
|
+
.command("info")
|
|
1246
|
+
.description("Get general information about the middleware")
|
|
1247
|
+
.addArgument(argMiddlewareAddress)
|
|
1248
|
+
.asyncAction(async (config, middlewareAddress) => {
|
|
1249
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
1250
|
+
await (0, middleware_1.middlewareInfo)(middlewareSvc);
|
|
1251
|
+
});
|
|
1252
|
+
middlewareCmd
|
|
1253
|
+
.command('weight-sync')
|
|
1254
|
+
.description('Watch for operators weight changes')
|
|
1255
|
+
.addArgument(argMiddlewareAddress)
|
|
1256
|
+
.addOption(new extra_typings_1.Option('-e, --epochs <number>', 'Number of epochs to watch').argParser(Number))
|
|
1257
|
+
.addOption(new extra_typings_1.Option('-l, --loop-epochs <number>', 'Number of epochs to loop').argParser(Number))
|
|
1258
|
+
.asyncAction({ signer: true }, async (config, middlewareAddress, options) => {
|
|
1259
|
+
await (0, middleware_1.weightSync)(await config.contracts.L1Middleware(middlewareAddress), config, { epochs: options.epochs, loopEpochs: options.loopEpochs });
|
|
1260
|
+
});
|
|
1261
|
+
/**
|
|
1262
|
+
* --------------------------------------------------
|
|
1263
|
+
* OPERATOR → L1: optIn / optOut / check
|
|
1264
|
+
* --------------------------------------------------
|
|
1265
|
+
*/
|
|
1266
|
+
const operatorOptInCmd = program
|
|
1267
|
+
.command("opt-in")
|
|
1268
|
+
.description("Commands for operator opt-in services");
|
|
1269
|
+
operatorOptInCmd
|
|
1270
|
+
.command("l1-in")
|
|
1271
|
+
.description("Operator opts in to a given L1")
|
|
1272
|
+
.addArgument(argValidatorManagerAddress)
|
|
1273
|
+
.asyncAction({ signer: true }, async (config, l1Address) => {
|
|
1274
|
+
const service = await config.contracts.OperatorL1OptInService();
|
|
1275
|
+
await (0, operatorOptIn_1.optInL1)(service, l1Address);
|
|
1276
|
+
});
|
|
1277
|
+
operatorOptInCmd
|
|
1278
|
+
.command("l1-out")
|
|
1279
|
+
.description("Operator opts out from a given L1")
|
|
1280
|
+
.addArgument(argValidatorManagerAddress)
|
|
1281
|
+
.asyncAction({ signer: true }, async (config, l1Address) => {
|
|
1282
|
+
const service = await config.contracts.OperatorL1OptInService();
|
|
1283
|
+
await (0, operatorOptIn_1.optOutL1)(service, l1Address);
|
|
1284
|
+
});
|
|
1285
|
+
operatorOptInCmd
|
|
1286
|
+
.command("check-l1")
|
|
1287
|
+
.description("Check if an operator is opted in to a given L1")
|
|
1288
|
+
.addArgument(argOperatorAddress)
|
|
1289
|
+
.addArgument(argValidatorManagerAddress)
|
|
1290
|
+
.asyncAction(async (config, operator, l1Address) => {
|
|
1291
|
+
const service = await config.contracts.OperatorL1OptInService();
|
|
1292
|
+
await (0, operatorOptIn_1.checkOptInL1)(service, operator, l1Address);
|
|
1293
|
+
});
|
|
1294
|
+
/**
|
|
1295
|
+
* --------------------------------------------------
|
|
1296
|
+
* OPERATOR → Vault: optIn / optOut / check
|
|
1297
|
+
* --------------------------------------------------
|
|
1298
|
+
*/
|
|
1299
|
+
operatorOptInCmd
|
|
1300
|
+
.command("vault-in")
|
|
1301
|
+
.description("Operator opts in to a given Vault")
|
|
1302
|
+
.addArgument(argVaultAddress)
|
|
1303
|
+
.asyncAction({ signer: true }, async (config, vaultAddress) => {
|
|
1304
|
+
const service = await config.contracts.OperatorVaultOptInService();
|
|
1305
|
+
await (0, operatorOptIn_1.optInVault)(service, vaultAddress);
|
|
1306
|
+
});
|
|
1307
|
+
operatorOptInCmd
|
|
1308
|
+
.command("vault-out")
|
|
1309
|
+
.description("Operator opts out from a given Vault")
|
|
1310
|
+
.addArgument(argVaultAddress)
|
|
1311
|
+
.asyncAction({ signer: true }, async (config, vaultAddress) => {
|
|
1312
|
+
const service = await config.contracts.OperatorVaultOptInService();
|
|
1313
|
+
await (0, operatorOptIn_1.optOutVault)(service, vaultAddress);
|
|
1314
|
+
});
|
|
1315
|
+
operatorOptInCmd
|
|
1316
|
+
.command("check-vault")
|
|
1317
|
+
.description("Check if an operator is opted in to a given Vault")
|
|
1318
|
+
.addArgument(argOperatorAddress)
|
|
1319
|
+
.addArgument(argVaultAddress)
|
|
1320
|
+
.asyncAction(async (config, operator, vaultAddress) => {
|
|
1321
|
+
const service = await config.contracts.OperatorVaultOptInService();
|
|
1322
|
+
await (0, operatorOptIn_1.checkOptInVault)(service, operator, vaultAddress);
|
|
1323
|
+
});
|
|
1324
|
+
/**
|
|
1325
|
+
* --------------------------------------------------
|
|
1326
|
+
* Validator Manager
|
|
1327
|
+
* --------------------------------------------------
|
|
1328
|
+
*/
|
|
1329
|
+
const validatorManagerCmd = program
|
|
1330
|
+
.command("vmc")
|
|
1331
|
+
.description("Commands to interact with ValidatorManager contracts");
|
|
1332
|
+
validatorManagerCmd
|
|
1333
|
+
.command("info")
|
|
1334
|
+
.description("Get summary informations of a ValidatorManager contract")
|
|
1335
|
+
.addArgument(argValidatorManagerAddress)
|
|
1336
|
+
.asyncAction(async (config, validatorManagerAddress) => {
|
|
1337
|
+
// instantiate ValidatorManager contract
|
|
1338
|
+
const validatorManager = await config.contracts.ValidatorManager(validatorManagerAddress);
|
|
1339
|
+
const results = await validatorManager.multicall([
|
|
1340
|
+
'getChurnTracker',
|
|
1341
|
+
'getChurnPeriodSeconds',
|
|
1342
|
+
'l1TotalWeight',
|
|
1343
|
+
'owner',
|
|
1344
|
+
'subnetID'
|
|
1345
|
+
], { details: true });
|
|
1346
|
+
logger_1.logger.log(results.reduce((acc, r) => ({ ...acc, [r.name]: r.result }), {}));
|
|
1347
|
+
});
|
|
1348
|
+
validatorManagerCmd
|
|
1349
|
+
.command("transfer-ownership")
|
|
1350
|
+
.description("Transfer the ownership of a ValidatorManager contract")
|
|
1351
|
+
.addArgument(argValidatorManagerAddress)
|
|
1352
|
+
.addArgument((0, cliParser_1.ArgAddress)("owner", "Owner address"))
|
|
1353
|
+
.asyncAction({ signer: true }, async (config, validatorManagerAddress, owner) => {
|
|
1354
|
+
// instantiate ValidatorManager contract
|
|
1355
|
+
const validatorManager = await config.contracts.ValidatorManager(validatorManagerAddress);
|
|
1356
|
+
await validatorManager.safeWrite.transferOwnership([owner]);
|
|
1357
|
+
});
|
|
1358
|
+
validatorManagerCmd
|
|
1359
|
+
.command("complete-validator-removal")
|
|
1360
|
+
.description("Complete the removal of a validator that has been pending removal")
|
|
1361
|
+
.addArgument(argValidatorManagerAddress)
|
|
1362
|
+
.addArgument((0, cliParser_1.ArgHex)("removalTxId", "Removal transaction ID"))
|
|
1363
|
+
.asyncAction({ signer: true }, async (config, validatorManagerAddress, removalTxId) => {
|
|
1364
|
+
// instantiate ValidatorManager contract
|
|
1365
|
+
const validatorManager = await config.contracts.ValidatorManager(validatorManagerAddress);
|
|
1366
|
+
logger_1.logger.error("Not implemented yet");
|
|
1367
|
+
});
|
|
1368
|
+
/**
|
|
1369
|
+
* --------------------------------------------------
|
|
1370
|
+
* BALANCER
|
|
1371
|
+
* --------------------------------------------------
|
|
1372
|
+
*/
|
|
1373
|
+
const balancerCmd = program
|
|
1374
|
+
.command("balancer")
|
|
1375
|
+
.description("Commands to interact with BalancerValidatorManager contracts");
|
|
1376
|
+
balancerCmd
|
|
1377
|
+
.command("set-up-security-module")
|
|
1378
|
+
.description("Set up a security module")
|
|
1379
|
+
.addArgument(argBalancerAddress)
|
|
1380
|
+
.addArgument(argMiddlewareAddress)
|
|
1381
|
+
.addArgument((0, cliParser_1.ArgBigInt)("maxWeight", "Maximum weight"))
|
|
1382
|
+
.asyncAction({ signer: true }, async (config, balancerValidatorManagerAddress, middlewareAddress, maxWeight) => {
|
|
1383
|
+
// instantiate BalancerValidatorManager contract
|
|
1384
|
+
const balancer = await config.contracts.BalancerValidatorManager(balancerValidatorManagerAddress);
|
|
1385
|
+
await (0, balancer_1.setUpSecurityModule)(balancer, middlewareAddress, maxWeight);
|
|
1386
|
+
});
|
|
1387
|
+
balancerCmd
|
|
1388
|
+
.command("get-security-modules")
|
|
1389
|
+
.description("Get all security modules")
|
|
1390
|
+
.addArgument(argBalancerAddress)
|
|
1391
|
+
.asyncAction(async (config, balancerValidatorManagerAddress) => {
|
|
1392
|
+
const balancer = await config.contracts.BalancerValidatorManager(balancerValidatorManagerAddress);
|
|
1393
|
+
await (0, balancer_1.getSecurityModules)(balancer);
|
|
1394
|
+
});
|
|
1395
|
+
balancerCmd
|
|
1396
|
+
.command("get-security-module-weights")
|
|
1397
|
+
.description("Get security module weights")
|
|
1398
|
+
.addArgument(argBalancerAddress)
|
|
1399
|
+
.addArgument((0, cliParser_1.ArgAddress)("securityModule", "Security module address"))
|
|
1400
|
+
.asyncAction(async (config, balancerValidatorManagerAddress, securityModule) => {
|
|
1401
|
+
const balancer = await config.contracts.BalancerValidatorManager(balancerValidatorManagerAddress);
|
|
1402
|
+
await (0, balancer_1.getSecurityModuleWeights)(balancer, securityModule);
|
|
1403
|
+
});
|
|
1404
|
+
balancerCmd
|
|
1405
|
+
.command("get-validator-status")
|
|
1406
|
+
.description("Get validator status by node ID")
|
|
1407
|
+
.addArgument(argBalancerAddress)
|
|
1408
|
+
.addArgument((0, cliParser_1.ArgNodeID)("nodeId", "Node ID"))
|
|
1409
|
+
.asyncAction(async (config, balancerAddress, nodeId) => {
|
|
1410
|
+
const balancer = await config.contracts.BalancerValidatorManager(balancerAddress);
|
|
1411
|
+
const validationId = await balancer.read.getNodeValidationID([(0, utils_1.parseNodeID)(nodeId, false)]);
|
|
1412
|
+
if (Number(validationId) === 0) {
|
|
1413
|
+
logger_1.logger.log("Validator status: NotRegistered");
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
const [validator, PendingWeightUpdate] = await Promise.all([balancer.read.getValidator([validationId]), balancer.read.isValidatorPendingWeightUpdate([validationId])]);
|
|
1417
|
+
const status = validator.status == balancer_1.ValidatorStatus.Active && PendingWeightUpdate ? balancer_1.ValidatorStatus.PendingStakeUpdated : validator.status;
|
|
1418
|
+
logger_1.logger.log("Validator status:", balancer_1.ValidatorStatusNames[status]);
|
|
1419
|
+
logger_1.logger.addData("status", balancer_1.ValidatorStatusNames[status]);
|
|
1420
|
+
logger_1.logger.addData("statusId", status);
|
|
1421
|
+
logger_1.logger.addData("validationId", validationId);
|
|
1422
|
+
logger_1.logger.addData("nodeId", nodeId);
|
|
1423
|
+
});
|
|
1424
|
+
balancerCmd
|
|
1425
|
+
.command("resend-validator-registration")
|
|
1426
|
+
.description("Resend validator registration transaction")
|
|
1427
|
+
.addArgument(argBalancerAddress)
|
|
1428
|
+
.addArgument((0, cliParser_1.ArgNodeID)("nodeId", "Node ID"))
|
|
1429
|
+
.asyncAction({ signer: true }, async (config, balancerAddress, nodeId) => {
|
|
1430
|
+
const balancer = await config.contracts.BalancerValidatorManager(balancerAddress);
|
|
1431
|
+
const nodeIdHex32 = (0, utils_1.parseNodeID)(nodeId, false);
|
|
1432
|
+
const validationId = await balancer.read.getNodeValidationID([nodeIdHex32]);
|
|
1433
|
+
const hash = await balancer.safeWrite.resendRegisterValidatorMessage([validationId]);
|
|
1434
|
+
logger_1.logger.log("resendValidatorRegistration executed successfully, tx hash:", hash);
|
|
1435
|
+
});
|
|
1436
|
+
balancerCmd
|
|
1437
|
+
.command("resend-weight-update")
|
|
1438
|
+
.description("Resend validator weight update transaction")
|
|
1439
|
+
.addArgument(argBalancerAddress)
|
|
1440
|
+
.addArgument((0, cliParser_1.ArgNodeID)("nodeId", "Node ID"))
|
|
1441
|
+
.asyncAction({ signer: true }, async (config, balancerAddress, nodeId) => {
|
|
1442
|
+
const balancer = await config.contracts.BalancerValidatorManager(balancerAddress);
|
|
1443
|
+
const nodeIdHex32 = (0, utils_1.parseNodeID)(nodeId, false);
|
|
1444
|
+
const validationId = await balancer.read.getNodeValidationID([nodeIdHex32]);
|
|
1445
|
+
const hash = await balancer.safeWrite.resendValidatorWeightUpdate([validationId]);
|
|
1446
|
+
logger_1.logger.log("resendWeightUpdate executed successfully, tx hash:", hash);
|
|
1447
|
+
});
|
|
1448
|
+
balancerCmd
|
|
1449
|
+
.command("resend-validator-removal")
|
|
1450
|
+
.description("Resend validator removal transaction")
|
|
1451
|
+
.addArgument(argBalancerAddress)
|
|
1452
|
+
.addArgument((0, cliParser_1.ArgNodeID)("nodeId", "Node ID"))
|
|
1453
|
+
.asyncAction({ signer: true }, async (config, balancerAddress, nodeId) => {
|
|
1454
|
+
const balancer = await config.contracts.BalancerValidatorManager(balancerAddress);
|
|
1455
|
+
const nodeIdHex32 = (0, utils_1.parseNodeID)(nodeId, false);
|
|
1456
|
+
const validationId = await balancer.read.getNodeValidationID([nodeIdHex32]);
|
|
1457
|
+
const hash = await balancer.safeWrite.resendValidatorRemovalMessage([validationId]);
|
|
1458
|
+
logger_1.logger.log("resendValidatorRemoval executed successfully, tx hash:", hash);
|
|
1459
|
+
});
|
|
1460
|
+
balancerCmd
|
|
1461
|
+
.command("transfer-l1-ownership")
|
|
1462
|
+
.description("Transfer Validator manager, balancer and its security modules ownership to a new owner")
|
|
1463
|
+
.addArgument(argBalancerAddress)
|
|
1464
|
+
.addArgument((0, cliParser_1.ArgAddress)("newOwner", "New owner address"))
|
|
1465
|
+
.asyncAction({ signer: true }, async (config, balancerAddress, newOwner) => {
|
|
1466
|
+
const balancer = await config.contracts.BalancerValidatorManager(balancerAddress);
|
|
1467
|
+
const VMTx = await balancer.safeWrite.transferValidatorManagerOwnership([newOwner]);
|
|
1468
|
+
logger_1.logger.log("transferValidatorManagerOwnership executed successfully, tx hash:", VMTx);
|
|
1469
|
+
const BTx = await balancer.safeWrite.transferOwnership([newOwner]);
|
|
1470
|
+
logger_1.logger.log("transferOwnership of balancer executed successfully, tx hash:", BTx);
|
|
1471
|
+
const securityModules = await balancer.read.getSecurityModules();
|
|
1472
|
+
for (const smAddress of securityModules) {
|
|
1473
|
+
const smOwnable = await config.contracts.Ownable(smAddress);
|
|
1474
|
+
const SMTx = await smOwnable.safeWrite.transferOwnership([newOwner]);
|
|
1475
|
+
logger_1.logger.log(`transferOwnership of security module ${smAddress} executed successfully, tx hash:`, SMTx);
|
|
1476
|
+
const smAccessControl = await config.contracts.AccessControl(smAddress);
|
|
1477
|
+
const isAccessControl = await smAccessControl.read.supportsInterface(["0x7965db0b"]);
|
|
1478
|
+
if (isAccessControl) {
|
|
1479
|
+
const ROLETX = await smAccessControl.safeWrite.grantRole([await smAccessControl.read.DEFAULT_ADMIN_ROLE(), newOwner]);
|
|
1480
|
+
logger_1.logger.log(`grantRole DEFAULT_ADMIN_ROLE to ${newOwner} on security module ${smAddress} executed successfully, tx hash:`, ROLETX);
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
});
|
|
1484
|
+
/**
|
|
1485
|
+
* --------------------------------------------------
|
|
1486
|
+
* POA-Security-Module
|
|
1487
|
+
* --------------------------------------------------
|
|
1488
|
+
* This section is for the POA Security Module commands.
|
|
1489
|
+
* It includes commands to add or remove validators
|
|
1490
|
+
*/
|
|
1491
|
+
const poaCmd = program
|
|
1492
|
+
.command("poa")
|
|
1493
|
+
.description("Commands to interact with POA Security Module contracts");
|
|
1494
|
+
poaCmd
|
|
1495
|
+
.command("add-node")
|
|
1496
|
+
.description("Add a new node to an L1")
|
|
1497
|
+
.addArgument(argPoaSecurityModuleAddress)
|
|
1498
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
1499
|
+
.addArgument((0, cliParser_1.ArgHex)("blsKey", "BLS public key"))
|
|
1500
|
+
.addArgument((0, cliParser_1.ArgBigInt)("initialWeight", "Initial weight of the validator"))
|
|
1501
|
+
.addOption(new extra_typings_1.Option("--registration-expiry <expiry>", "Expiry timestamp (default: now + 12 hours)"))
|
|
1502
|
+
.addOption(new extra_typings_1.Option("--pchain-remaining-balance-owner-threshold <threshold>", "P-Chain remaining balance owner threshold").default(1).argParser(cliParser_1.ParserNumber))
|
|
1503
|
+
.addOption(new extra_typings_1.Option("--pchain-disable-owner-threshold <threshold>", "P-Chain disable owner threshold").default(1).argParser(cliParser_1.ParserNumber))
|
|
1504
|
+
.addOption(new extra_typings_1.Option("--pchain-remaining-balance-owner-address <address>", "P-Chain remaining balance owner address").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserAddress)))
|
|
1505
|
+
.addOption(new extra_typings_1.Option("--pchain-disable-owner-address <address>", "P-Chain disable owner address").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserAddress)))
|
|
1506
|
+
.asyncAction({ signer: true }, async (config, poaSecurityModule, nodeId, blsKey, initialWeight, options) => {
|
|
1507
|
+
const poaSM = await config.contracts.PoASecurityModule(poaSecurityModule);
|
|
1508
|
+
const defaultOwnerAddress = (0, viem_1.fromBytes)(avalanchejs_1.utils.bech32ToBytes(config.client.addresses.P), 'hex');
|
|
1509
|
+
// Default registration expiry to now + 12 hours if not provided
|
|
1510
|
+
// const registrationExpiry = options.registrationExpiry
|
|
1511
|
+
// ? BigInt(options.registrationExpiry)
|
|
1512
|
+
// : BigInt(Math.floor(Date.now() / 1000) + 12 * 60 * 60); // current time + 12 hours in seconds
|
|
1513
|
+
// Build remainingBalanceOwner and disableOwner PChainOwner structs
|
|
1514
|
+
// If pchainRemainingBalanceOwnerAddress or pchainDisableOwnerAddress are empty (not provided), use the client account
|
|
1515
|
+
const remainingBalanceOwnerAddress = options.pchainRemainingBalanceOwnerAddress.length > 0 ? options.pchainRemainingBalanceOwnerAddress : [defaultOwnerAddress];
|
|
1516
|
+
const disableOwnerAddress = options.pchainDisableOwnerAddress.length > 0 ? options.pchainDisableOwnerAddress : [defaultOwnerAddress];
|
|
1517
|
+
const remainingBalanceOwner = [
|
|
1518
|
+
Number(options.pchainRemainingBalanceOwnerThreshold),
|
|
1519
|
+
remainingBalanceOwnerAddress
|
|
1520
|
+
];
|
|
1521
|
+
const disableOwner = [
|
|
1522
|
+
Number(options.pchainDisableOwnerThreshold),
|
|
1523
|
+
disableOwnerAddress
|
|
1524
|
+
];
|
|
1525
|
+
const nodeIdHex32 = (0, utils_1.parseNodeID)(nodeId, false);
|
|
1526
|
+
const hash = await poaSM.safeWrite.initiateValidatorRegistration([nodeIdHex32, blsKey, { threshold: remainingBalanceOwner[0], addresses: remainingBalanceOwner[1] }, { threshold: disableOwner[0], addresses: disableOwner[1] }, initialWeight]);
|
|
1527
|
+
logger_1.logger.log("addNode executed successfully, tx hash:", hash);
|
|
1528
|
+
});
|
|
1529
|
+
poaCmd
|
|
1530
|
+
.command("complete-validator-registration")
|
|
1531
|
+
.description("Complete validator registration on the P-Chain and on the middleware after adding a node")
|
|
1532
|
+
.addArgument(argPoaSecurityModuleAddress)
|
|
1533
|
+
.addArgument((0, cliParser_1.ArgHex)("addNodeTxHash", "Add node transaction hash"))
|
|
1534
|
+
.addArgument((0, cliParser_1.ArgBLSPOP)())
|
|
1535
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
1536
|
+
.addOption(new extra_typings_1.Option("--initial-balance <initialBalance>", "Node initial balance to pay for continuous fee").default('0.01'))
|
|
1537
|
+
.addOption(new extra_typings_1.Option("--skip-wait-api", "Don't wait for the validator to be visible through the P-Chain API"))
|
|
1538
|
+
.asyncAction({ signer: true }, async (config, poaSecurityModuleAddress, addNodeTxHash, blsProofOfPossession, options) => {
|
|
1539
|
+
const opts = program.opts();
|
|
1540
|
+
// If pchainTxPrivateKey is not provided, use the private key
|
|
1541
|
+
if (!options.pchainTxPrivateKey) {
|
|
1542
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
1543
|
+
}
|
|
1544
|
+
const poaSecurityModule = await config.contracts.PoASecurityModule(poaSecurityModuleAddress);
|
|
1545
|
+
const balancerSvc = await config.contracts.BalancerValidatorManager(await poaSecurityModule.read.balancerValidatorManager());
|
|
1546
|
+
const initialBalance = (0, cliParser_1.ParseUnits)(options.initialBalance, 9, 'Invalid initial balance');
|
|
1547
|
+
// Check if P-Chain address have 0.1 AVAX for tx fees but some times it can be less than 0.000050000 AVAX (perhaps when the validator was removed recently)
|
|
1548
|
+
await (0, transferUtils_1.requirePChainBallance)(config.client, BigInt(Math.round((50000 + Number(initialBalance)))), opts.yes);
|
|
1549
|
+
// Call middlewareCompleteValidatorRegistration
|
|
1550
|
+
await (0, securityModule_1.completeValidatorRegistration)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : config.client, poaSecurityModule, balancerSvc, config, blsProofOfPossession, addNodeTxHash, initialBalance, !options.skipWaitApi);
|
|
1551
|
+
});
|
|
1552
|
+
poaCmd
|
|
1553
|
+
.command("remove-node")
|
|
1554
|
+
.description("Initiate validator removal")
|
|
1555
|
+
.addArgument(argPoaSecurityModuleAddress)
|
|
1556
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
1557
|
+
.asyncAction({ signer: true }, async (config, poaSecurityModuleAddress, nodeID) => {
|
|
1558
|
+
const poaSecurityModule = await config.contracts.PoASecurityModule(poaSecurityModuleAddress);
|
|
1559
|
+
const balancerValidatorManagerAddress = await poaSecurityModule.read.balancerValidatorManager();
|
|
1560
|
+
const balancer = await config.contracts.BalancerValidatorManager(balancerValidatorManagerAddress);
|
|
1561
|
+
// Convert nodeID to Hex if necessary
|
|
1562
|
+
const nodeIdHex = (0, utils_1.parseNodeID)(nodeID, false);
|
|
1563
|
+
logger_1.logger.log(nodeIdHex);
|
|
1564
|
+
const validationId = await balancer.read.getNodeValidationID([nodeIdHex]);
|
|
1565
|
+
const txHash = await poaSecurityModule.safeWrite.initiateValidatorRemoval([validationId], {
|
|
1566
|
+
chain: null,
|
|
1567
|
+
account: config.client.account,
|
|
1568
|
+
});
|
|
1569
|
+
logger_1.logger.log(`End validation initialized for node ${nodeID}. Transaction hash: ${txHash}`);
|
|
1570
|
+
});
|
|
1571
|
+
poaCmd
|
|
1572
|
+
.command("complete-validator-removal")
|
|
1573
|
+
.description("Complete validator removal in the P-Chain and in the POA Security Module")
|
|
1574
|
+
.addArgument(argPoaSecurityModuleAddress)
|
|
1575
|
+
.addArgument((0, cliParser_1.ArgHex)("removeNodeTxHash", "Remove node transaction hash"))
|
|
1576
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
1577
|
+
.addOption(new extra_typings_1.Option("--skip-wait-api", "Don't wait for the validator to be visible through the P-Chain API"))
|
|
1578
|
+
.addOption(new extra_typings_1.Option("--node-id <nodeId>", "Node ID of the validator being removed").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserNodeID)))
|
|
1579
|
+
.addOption(new extra_typings_1.Option("--add-node-tx <addNodeTx>", "Add node transaction hash").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserHex)))
|
|
1580
|
+
.asyncAction({ signer: true }, async (config, poaSecurityModuleAddress, removeNodeTxHash, options) => {
|
|
1581
|
+
const opts = program.opts();
|
|
1582
|
+
if (!options.pchainTxPrivateKey)
|
|
1583
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
1584
|
+
const poaSecurityModule = await config.contracts.PoASecurityModule(poaSecurityModuleAddress);
|
|
1585
|
+
const balancerSvc = await config.contracts.BalancerValidatorManager(await poaSecurityModule.read.balancerValidatorManager());
|
|
1586
|
+
// Check if P-Chain address have 0.000050000 AVAX for tx fees
|
|
1587
|
+
await (0, transferUtils_1.requirePChainBallance)(config.client, 50000n, opts.yes);
|
|
1588
|
+
const txHash = await (0, securityModule_1.completeValidatorRemoval)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : config.client, poaSecurityModule, balancerSvc, config, removeNodeTxHash, !options.skipWaitApi, options.nodeId.length > 0 ? options.nodeId : undefined, options.addNodeTx.length > 0 ? options.addNodeTx : undefined);
|
|
1589
|
+
logger_1.logger.log(`End validation initialized for node . Transaction hash: ${txHash}`);
|
|
1590
|
+
});
|
|
1591
|
+
poaCmd
|
|
1592
|
+
.command("init-weight-update")
|
|
1593
|
+
.description("Update validator weight")
|
|
1594
|
+
.addArgument(argPoaSecurityModuleAddress)
|
|
1595
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
1596
|
+
.addArgument((0, cliParser_1.ArgBigInt)("newWeight", "New weight"))
|
|
1597
|
+
.asyncAction({ signer: true }, async (config, poaSecurityModuleAddress, nodeId, newWeight) => {
|
|
1598
|
+
const poaSecurityModule = await config.contracts.PoASecurityModule(poaSecurityModuleAddress);
|
|
1599
|
+
logger_1.logger.log("Calling function initializeValidatorStakeUpdate...");
|
|
1600
|
+
// Parse NodeID to bytes32 format
|
|
1601
|
+
const nodeIdHex32 = (0, utils_1.parseNodeID)(nodeId);
|
|
1602
|
+
const hash = await poaSecurityModule.safeWrite.initiateValidatorWeightUpdate([nodeIdHex32, newWeight]);
|
|
1603
|
+
logger_1.logger.log("initiateValidatorWeightUpdate executed successfully, tx hash:", hash);
|
|
1604
|
+
});
|
|
1605
|
+
poaCmd
|
|
1606
|
+
.command("complete-weight-update")
|
|
1607
|
+
.description("Complete validator weight update of all or specified node IDs")
|
|
1608
|
+
.addArgument(argMiddlewareAddress)
|
|
1609
|
+
.addArgument((0, cliParser_1.ArgHex)("validatorStakeUpdateTxHash", "Validator stake update transaction hash"))
|
|
1610
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
1611
|
+
.addOption(new extra_typings_1.Option("--node-id <nodeId>", "Node ID of the validator being removed").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserNodeID)))
|
|
1612
|
+
.asyncAction({ signer: true }, async (config, poaSecurityModuleAddress, weightUpdateTxHash, options) => {
|
|
1613
|
+
const opts = program.opts();
|
|
1614
|
+
if (!options.pchainTxPrivateKey)
|
|
1615
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
1616
|
+
const poaSecurityModule = await config.contracts.PoASecurityModule(poaSecurityModuleAddress);
|
|
1617
|
+
// Check if P-Chain address have 0.000050000 AVAX for tx fees
|
|
1618
|
+
await (0, transferUtils_1.requirePChainBallance)(config.client, 50000n, opts.yes);
|
|
1619
|
+
const txHash = await (0, securityModule_1.completeWeightUpdate)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : config.client, poaSecurityModule, config, weightUpdateTxHash, options.nodeId.length > 0 ? options.nodeId : undefined);
|
|
1620
|
+
logger_1.logger.log(`Weight update completed for node . Transaction hash: ${txHash}`);
|
|
1621
|
+
});
|
|
1622
|
+
/**
|
|
1623
|
+
* --------------------------------------------------
|
|
1624
|
+
* KITE STAKING MANAGER
|
|
1625
|
+
* --------------------------------------------------
|
|
1626
|
+
*/
|
|
1627
|
+
const kiteStakingManagerCmd = program
|
|
1628
|
+
.command("kite-staking-manager")
|
|
1629
|
+
.alias("ksm")
|
|
1630
|
+
.description("Commands to interact with KiteStakingManager contracts")
|
|
1631
|
+
.hook("preSubcommand", () => {
|
|
1632
|
+
const opts = program.opts();
|
|
1633
|
+
const newNet = opts.network === "custom" ? opts.network : chainList_1.chainList[opts.network].testnet ? "kiteaitestnet" : "kiteai";
|
|
1634
|
+
program.setOptionValue("network", newNet);
|
|
1635
|
+
});
|
|
1636
|
+
kiteStakingManagerCmd
|
|
1637
|
+
.command("info")
|
|
1638
|
+
.description("Get global configuration from KiteStakingManager")
|
|
1639
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1640
|
+
.asyncAction(async (config, options) => {
|
|
1641
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1642
|
+
const info = await (0, kiteStaking_1.getKiteStakingManagerInfo)(kiteStakingManager);
|
|
1643
|
+
logger_1.logger.logJsonTree(info);
|
|
1644
|
+
});
|
|
1645
|
+
kiteStakingManagerCmd
|
|
1646
|
+
.command("validator-info")
|
|
1647
|
+
.description("Get comprehensive information for a validator on KiteStakingManager")
|
|
1648
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1649
|
+
.addArgument((0, cliParser_1.ArgHex)("validationID", "Validation ID of the validator"))
|
|
1650
|
+
.asyncAction(async (config, validationID, options) => {
|
|
1651
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1652
|
+
const info = await (0, kiteStaking_1.getValidatorFullInfo)(kiteStakingManager, validationID);
|
|
1653
|
+
logger_1.logger.logJsonTree(info);
|
|
1654
|
+
});
|
|
1655
|
+
kiteStakingManagerCmd
|
|
1656
|
+
.command("delegator-info")
|
|
1657
|
+
.description("Get comprehensive information for a delegator on KiteStakingManager")
|
|
1658
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1659
|
+
.addArgument((0, cliParser_1.ArgHex)("delegationID", "Delegation ID of the delegator"))
|
|
1660
|
+
.asyncAction(async (config, delegationID, options) => {
|
|
1661
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1662
|
+
const info = await (0, kiteStaking_1.getDelegatorFullInfo)(kiteStakingManager, delegationID);
|
|
1663
|
+
logger_1.logger.logJsonTree(info);
|
|
1664
|
+
});
|
|
1665
|
+
kiteStakingManagerCmd
|
|
1666
|
+
.command("update-staking-config")
|
|
1667
|
+
.description("Update staking configuration")
|
|
1668
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1669
|
+
.argument("minimumStakeAmount", "Minimum stake amount")
|
|
1670
|
+
.argument("maximumStakeAmount", "Maximum stake amount")
|
|
1671
|
+
.argument("minimumStakeDuration", "Minimum stake duration in seconds")
|
|
1672
|
+
.addArgument((0, cliParser_1.ArgNumber)("minimumDelegationFeeBips", "Minimum delegation fee in basis points"))
|
|
1673
|
+
.addArgument((0, cliParser_1.ArgNumber)("maximumStakeMultiplier", "Maximum stake multiplier"))
|
|
1674
|
+
.asyncAction({ signer: true }, async (config, minimumStakeAmount, maximumStakeAmount, minimumStakeDuration, minimumDelegationFeeBips, maximumStakeMultiplier, options) => {
|
|
1675
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1676
|
+
// Get staking config to determine decimals - typically 18 for native tokens
|
|
1677
|
+
// For now, assume 18 decimals (1e18) for stake amounts
|
|
1678
|
+
const minimumStakeAmountWei = (0, viem_1.parseUnits)(minimumStakeAmount, 18);
|
|
1679
|
+
const maximumStakeAmountWei = (0, viem_1.parseUnits)(maximumStakeAmount, 18);
|
|
1680
|
+
const minimumStakeDurationBigInt = BigInt(minimumStakeDuration);
|
|
1681
|
+
await (0, kiteStaking_1.updateStakingConfig)(kiteStakingManager, minimumStakeAmountWei, maximumStakeAmountWei, minimumStakeDurationBigInt, minimumDelegationFeeBips, maximumStakeMultiplier);
|
|
1682
|
+
});
|
|
1683
|
+
kiteStakingManagerCmd
|
|
1684
|
+
.command("initiate-validator-registration")
|
|
1685
|
+
.description("Initiate validator registration on KiteStakingManager")
|
|
1686
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1687
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
1688
|
+
.addArgument((0, cliParser_1.ArgHex)("blsKey", "BLS public key"))
|
|
1689
|
+
.addArgument((0, cliParser_1.ArgNumber)("delegationFeeBips", "Delegation fee in basis points"))
|
|
1690
|
+
.argument("minStakeDuration", "Minimum stake duration in seconds")
|
|
1691
|
+
.addArgument((0, cliParser_1.ArgAddress)("rewardRecipient", "Reward recipient address"))
|
|
1692
|
+
.argument("stakeAmount", "Initial stake amount")
|
|
1693
|
+
.addOption(new extra_typings_1.Option("--pchain-remaining-balance-owner-threshold <threshold>", "P-Chain remaining balance owner threshold").default(1).argParser(cliParser_1.ParserNumber))
|
|
1694
|
+
.addOption(new extra_typings_1.Option("--pchain-disable-owner-threshold <threshold>", "P-Chain disable owner threshold").default(1).argParser(cliParser_1.ParserNumber))
|
|
1695
|
+
.addOption(new extra_typings_1.Option("--pchain-remaining-balance-owner-address <address>", "P-Chain remaining balance owner address").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserAddress)))
|
|
1696
|
+
.addOption(new extra_typings_1.Option("--pchain-disable-owner-address <address>", "P-Chain disable owner address").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserAddress)))
|
|
1697
|
+
.asyncAction({ signer: true }, async (config, nodeId, blsKey, delegationFeeBips, minStakeDuration, rewardRecipient, stakeAmount, options) => {
|
|
1698
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1699
|
+
const defaultOwnerAddress = (0, viem_1.fromBytes)(avalanchejs_1.utils.bech32ToBytes(config.client.addresses.P), 'hex');
|
|
1700
|
+
// Build remainingBalanceOwner and disableOwner PChainOwner structs
|
|
1701
|
+
const remainingBalanceOwnerAddress = options.pchainRemainingBalanceOwnerAddress.length > 0 ? options.pchainRemainingBalanceOwnerAddress : [defaultOwnerAddress];
|
|
1702
|
+
const disableOwnerAddress = options.pchainDisableOwnerAddress.length > 0 ? options.pchainDisableOwnerAddress : [defaultOwnerAddress];
|
|
1703
|
+
const remainingBalanceOwner = [
|
|
1704
|
+
Number(options.pchainRemainingBalanceOwnerThreshold),
|
|
1705
|
+
remainingBalanceOwnerAddress
|
|
1706
|
+
];
|
|
1707
|
+
const disableOwner = [
|
|
1708
|
+
Number(options.pchainDisableOwnerThreshold),
|
|
1709
|
+
disableOwnerAddress
|
|
1710
|
+
];
|
|
1711
|
+
// Get staking config to determine decimals for initial stake
|
|
1712
|
+
// For now, assume 18 decimals (1e18) for stake amounts
|
|
1713
|
+
const stakeAmountWei = (0, viem_1.parseUnits)(stakeAmount, 18);
|
|
1714
|
+
const minStakeDurationBigInt = BigInt(minStakeDuration);
|
|
1715
|
+
await (0, kiteStaking_1.initiateValidatorRegistration)(kiteStakingManager, nodeId, blsKey, remainingBalanceOwner, disableOwner, delegationFeeBips, minStakeDurationBigInt, rewardRecipient, stakeAmountWei);
|
|
1716
|
+
});
|
|
1717
|
+
kiteStakingManagerCmd
|
|
1718
|
+
.command("complete-validator-registration")
|
|
1719
|
+
.description("Complete validator registration on the P-Chain and on the KiteStakingManager after initiating registration")
|
|
1720
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1721
|
+
.addArgument((0, cliParser_1.ArgHex)("initiateTxHash", "Initiate validator registration transaction hash"))
|
|
1722
|
+
.addArgument((0, cliParser_1.ArgBLSPOP)())
|
|
1723
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
1724
|
+
.addOption(new extra_typings_1.Option("--initial-balance <initialBalance>", "Node initial balance to pay for continuous fee").default('0.01'))
|
|
1725
|
+
.addOption(new extra_typings_1.Option("--skip-wait-api", "Don't wait for the validator to be visible through the P-Chain API"))
|
|
1726
|
+
.asyncAction(async (_, initiateTxHash, blsProofOfPossession, options) => {
|
|
1727
|
+
const opts = program.opts();
|
|
1728
|
+
// If pchainTxPrivateKey is not provided, use the private key
|
|
1729
|
+
if (!options.pchainTxPrivateKey) {
|
|
1730
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
1731
|
+
}
|
|
1732
|
+
const initialBalance = (0, cliParser_1.ParseUnits)(options.initialBalance, 9, 'Invalid initial balance');
|
|
1733
|
+
const client = await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey, opts.safe);
|
|
1734
|
+
const config = (0, config_1.getConfig)(client, opts.wait, opts.skipAbiValidation);
|
|
1735
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1736
|
+
await (0, kiteStaking_1.completeValidatorRegistration)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : client, kiteStakingManager, config, blsProofOfPossession, initiateTxHash, initialBalance, !options.skipWaitApi);
|
|
1737
|
+
});
|
|
1738
|
+
kiteStakingManagerCmd
|
|
1739
|
+
.command("initiate-delegator-registration")
|
|
1740
|
+
.description("Initiate delegator registration on KiteStakingManager")
|
|
1741
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1742
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
1743
|
+
.addArgument((0, cliParser_1.ArgAddress)("rewardRecipient", "Reward recipient address"))
|
|
1744
|
+
.argument("stakeAmount", "Initial stake amount")
|
|
1745
|
+
.asyncAction({ signer: true }, async (config, nodeId, rewardRecipient, stakeAmount, options) => {
|
|
1746
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1747
|
+
// Get staking config to determine decimals for stake amount
|
|
1748
|
+
// For now, assume 18 decimals (1e18) for stake amounts
|
|
1749
|
+
const stakeAmountWei = (0, viem_1.parseUnits)(stakeAmount, 18);
|
|
1750
|
+
await (0, kiteStaking_1.initiateDelegatorRegistration)(kiteStakingManager, config, nodeId, rewardRecipient, stakeAmountWei);
|
|
1751
|
+
});
|
|
1752
|
+
kiteStakingManagerCmd
|
|
1753
|
+
.command("complete-delegator-registration")
|
|
1754
|
+
.description("Complete delegator registration on the P-Chain and on the KiteStakingManager after initiating registration")
|
|
1755
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1756
|
+
.addArgument((0, cliParser_1.ArgHex)("initiateTxHash", "Initiate delegator registration transaction hash"))
|
|
1757
|
+
.argument("rpcUrl", "RPC URL for getting validator uptime")
|
|
1758
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
1759
|
+
.asyncAction({ signer: true }, async (config, initiateTxHash, rpcUrl, options) => {
|
|
1760
|
+
const opts = program.opts();
|
|
1761
|
+
if (!options.pchainTxPrivateKey)
|
|
1762
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
1763
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1764
|
+
await (0, kiteStaking_1.completeDelegatorRegistration)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : config.client, kiteStakingManager, config, initiateTxHash, rpcUrl);
|
|
1765
|
+
});
|
|
1766
|
+
kiteStakingManagerCmd
|
|
1767
|
+
.command("initiate-delegator-removal")
|
|
1768
|
+
.description("Initiate delegator removal on KiteStakingManager")
|
|
1769
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1770
|
+
.addArgument((0, cliParser_1.ArgHex)("delegationID", "Delegation ID"))
|
|
1771
|
+
.addOption(new extra_typings_1.Option("--include-uptime-proof", "Include uptime proof in the removal").default(false))
|
|
1772
|
+
.addOption(new extra_typings_1.Option("--rpc-url <rpcUrl>", "RPC URL for getting validator uptime (required if --include-uptime-proof is true)"))
|
|
1773
|
+
.asyncAction({ signer: true }, async (config, delegationID, options) => {
|
|
1774
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1775
|
+
await (0, kiteStaking_1.initiateDelegatorRemoval)(kiteStakingManager, config, delegationID, options.includeUptimeProof, options.rpcUrl);
|
|
1776
|
+
});
|
|
1777
|
+
kiteStakingManagerCmd
|
|
1778
|
+
.command("complete-delegator-removal")
|
|
1779
|
+
.description("Complete delegator removal on the P-Chain and on the KiteStakingManager after initiating removal")
|
|
1780
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1781
|
+
.addArgument((0, cliParser_1.ArgHex)("initiateRemovalTxHash", "Initiate delegator removal transaction hash"))
|
|
1782
|
+
.argument("rpcUrl", "RPC URL for getting validator uptime")
|
|
1783
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
1784
|
+
.addOption(new extra_typings_1.Option("--skip-wait-api", "Don't wait for the validator to be visible through the P-Chain API"))
|
|
1785
|
+
.addOption(new extra_typings_1.Option("--delegation-id <delegationID>", "Delegation ID of the delegator being removed").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserHex)))
|
|
1786
|
+
.addOption(new extra_typings_1.Option("--initiate-tx <initiateTx>", "Initiate delegator registration transaction hash"))
|
|
1787
|
+
.asyncAction({ signer: true }, async (config, initiateRemovalTxHash, rpcUrl, options) => {
|
|
1788
|
+
const opts = program.opts();
|
|
1789
|
+
if (!options.pchainTxPrivateKey)
|
|
1790
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
1791
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1792
|
+
// Check if P-Chain address have 0.000050000 AVAX for tx fees
|
|
1793
|
+
await (0, transferUtils_1.requirePChainBallance)(config.client, 50000n, opts.yes);
|
|
1794
|
+
await (0, kiteStaking_1.completeDelegatorRemoval)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : config.client, kiteStakingManager, config, initiateRemovalTxHash, rpcUrl, !options.skipWaitApi, options.delegationId.length > 0 ? options.delegationId : undefined, options.initiateTx ? options.initiateTx : undefined);
|
|
1795
|
+
});
|
|
1796
|
+
kiteStakingManagerCmd
|
|
1797
|
+
.command("initiate-validator-removal")
|
|
1798
|
+
.description("Initiate validator removal on KiteStakingManager")
|
|
1799
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1800
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
1801
|
+
.addOption(new extra_typings_1.Option("--include-uptime-proof", "Include uptime proof in the removal").default(false))
|
|
1802
|
+
.asyncAction({ signer: true }, async (config, nodeId, options) => {
|
|
1803
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1804
|
+
await (0, kiteStaking_1.initiateValidatorRemoval)(kiteStakingManager, config, nodeId, options.includeUptimeProof);
|
|
1805
|
+
});
|
|
1806
|
+
kiteStakingManagerCmd
|
|
1807
|
+
.command("complete-validator-removal")
|
|
1808
|
+
.description("Complete validator removal on the P-Chain and on the KiteStakingManager after initiating removal")
|
|
1809
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1810
|
+
.addArgument((0, cliParser_1.ArgHex)("initiateRemovalTxHash", "Initiate validator removal transaction hash"))
|
|
1811
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
1812
|
+
.addOption(new extra_typings_1.Option("--skip-wait-api", "Don't wait for the validator to be visible through the P-Chain API"))
|
|
1813
|
+
.addOption(new extra_typings_1.Option("--node-id <nodeId>", "Node ID of the validator being removed").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserNodeID)))
|
|
1814
|
+
.addOption(new extra_typings_1.Option("--initiate-tx <initiateTx>", "Initiate validator registration transaction hash").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserHex)))
|
|
1815
|
+
.asyncAction({ signer: true }, async (config, initiateRemovalTxHash, options) => {
|
|
1816
|
+
const opts = program.opts();
|
|
1817
|
+
if (!options.pchainTxPrivateKey)
|
|
1818
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
1819
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1820
|
+
// Check if P-Chain address have 0.000050000 AVAX for tx fees
|
|
1821
|
+
await (0, transferUtils_1.requirePChainBallance)(config.client, 50000n, opts.yes);
|
|
1822
|
+
await (0, kiteStaking_1.completeValidatorRemoval)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : config.client, kiteStakingManager, config, initiateRemovalTxHash, !options.skipWaitApi, options.nodeId.length > 0 ? options.nodeId : undefined, options.initiateTx.length > 0 ? options.initiateTx : undefined);
|
|
1823
|
+
});
|
|
1824
|
+
kiteStakingManagerCmd
|
|
1825
|
+
.command("submit-uptime-proof")
|
|
1826
|
+
.description("Submit uptime proof for a validator")
|
|
1827
|
+
.addOption(optKiteStakingManagerAddress)
|
|
1828
|
+
.addArgument((0, cliParser_1.ArgNodeID)("nodeId", "Node ID of the validator"))
|
|
1829
|
+
.argument("rpcUrl", "RPC URL for getting validator uptime")
|
|
1830
|
+
.asyncAction({ signer: true }, async (config, nodeId, rpcUrl, options) => {
|
|
1831
|
+
const kiteStakingManager = await config.contracts.KiteStakingManager(options.stakingManagerAddress);
|
|
1832
|
+
await (0, kiteStaking_1.submitUptimeProof)(config, kiteStakingManager, rpcUrl, nodeId);
|
|
1833
|
+
});
|
|
1834
|
+
/**
|
|
1835
|
+
* --------------------------------------------------
|
|
1836
|
+
* STAKING VAULT
|
|
1837
|
+
* --------------------------------------------------
|
|
1838
|
+
*/
|
|
1839
|
+
const stakingVaultCmd = program
|
|
1840
|
+
.command("staking-vault")
|
|
1841
|
+
.alias("sv")
|
|
1842
|
+
.description("Commands to interact with StakingVault contracts")
|
|
1843
|
+
.hook("preSubcommand", () => {
|
|
1844
|
+
const opts = program.opts();
|
|
1845
|
+
const newNet = opts.network === "custom" ? opts.network : chainList_1.chainList[opts.network].testnet ? "kiteaitestnet" : "kiteai";
|
|
1846
|
+
program.setOptionValue("network", newNet);
|
|
1847
|
+
});
|
|
1848
|
+
stakingVaultCmd
|
|
1849
|
+
.command("deposit")
|
|
1850
|
+
.description("Deposit native tokens (AVAX) into the StakingVault")
|
|
1851
|
+
.addOption(optStakingVaultAddress)
|
|
1852
|
+
.argument("amount", "Amount to deposit in AVAX")
|
|
1853
|
+
.addArgument((0, cliParser_1.ArgBigInt)("minShares", "Minimum shares expected from the deposit (slippage protection)"))
|
|
1854
|
+
.asyncAction({ signer: true }, async (config, amount, minShares, options) => {
|
|
1855
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
1856
|
+
await (0, stakingVault_1.depositStakingVault)(config.client, stakingVault, amount, minShares);
|
|
1857
|
+
});
|
|
1858
|
+
stakingVaultCmd
|
|
1859
|
+
.command("request-withdrawal")
|
|
1860
|
+
.description("Request withdrawal from the StakingVault")
|
|
1861
|
+
.addOption(optStakingVaultAddress)
|
|
1862
|
+
.argument("shares", "Amount of shares to withdraw")
|
|
1863
|
+
.asyncAction({ signer: true }, async (config, shares, options) => {
|
|
1864
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
1865
|
+
await (0, stakingVault_1.requestWithdrawalStakingVault)(config.client, stakingVault, shares);
|
|
1866
|
+
});
|
|
1867
|
+
stakingVaultCmd
|
|
1868
|
+
.command("claim-withdrawal")
|
|
1869
|
+
.description("Claim a withdrawal from the StakingVault")
|
|
1870
|
+
.addOption(optStakingVaultAddress)
|
|
1871
|
+
.addArgument((0, cliParser_1.ArgBigInt)("requestId", "Withdrawal request ID to claim"))
|
|
1872
|
+
.asyncAction({ signer: true }, async (config, requestId, options) => {
|
|
1873
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
1874
|
+
await (0, stakingVault_1.claimWithdrawalStakingVault)(config.client, stakingVault, requestId);
|
|
1875
|
+
});
|
|
1876
|
+
stakingVaultCmd
|
|
1877
|
+
.command("claim-withdrawal-for")
|
|
1878
|
+
.description("Claim a withdrawal for a request ID (permissionless)")
|
|
1879
|
+
.addOption(optStakingVaultAddress)
|
|
1880
|
+
.addArgument((0, cliParser_1.ArgBigInt)("requestId", "Withdrawal request ID to claim"))
|
|
1881
|
+
.asyncAction({ signer: true }, async (config, requestId, options) => {
|
|
1882
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
1883
|
+
const hash = await stakingVault.safeWrite.claimWithdrawalFor([requestId]);
|
|
1884
|
+
logger_1.logger.log("claimWithdrawalFor tx hash:", hash);
|
|
1885
|
+
logger_1.logger.log("claimWithdrawalFor executed successfully");
|
|
1886
|
+
});
|
|
1887
|
+
stakingVaultCmd
|
|
1888
|
+
.command("claim-withdrawals-for")
|
|
1889
|
+
.description("Claim multiple withdrawals for request IDs (permissionless)")
|
|
1890
|
+
.addOption(optStakingVaultAddress)
|
|
1891
|
+
.argument("requestIds...", "Withdrawal request IDs to claim")
|
|
1892
|
+
.asyncAction({ signer: true }, async (config, requestIds, options) => {
|
|
1893
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
1894
|
+
const ids = requestIds.map((id) => BigInt(id));
|
|
1895
|
+
const hash = await stakingVault.safeWrite.claimWithdrawalsFor([ids]);
|
|
1896
|
+
logger_1.logger.log("claimWithdrawalsFor tx hash:", hash);
|
|
1897
|
+
logger_1.logger.log("claimWithdrawalsFor executed successfully");
|
|
1898
|
+
});
|
|
1899
|
+
stakingVaultCmd
|
|
1900
|
+
.command("claim-escrowed-withdrawal")
|
|
1901
|
+
.description("Claim escrowed withdrawal to a recipient")
|
|
1902
|
+
.addOption(optStakingVaultAddress)
|
|
1903
|
+
.addArgument((0, cliParser_1.ArgAddress)("recipient", "Recipient address"))
|
|
1904
|
+
.asyncAction({ signer: true }, async (config, recipient, options) => {
|
|
1905
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
1906
|
+
const hash = await stakingVault.safeWrite.claimEscrowedWithdrawal([recipient]);
|
|
1907
|
+
logger_1.logger.log("claimEscrowedWithdrawal tx hash:", hash);
|
|
1908
|
+
logger_1.logger.log("claimEscrowedWithdrawal executed successfully");
|
|
1909
|
+
});
|
|
1910
|
+
stakingVaultCmd
|
|
1911
|
+
.command("process-epoch")
|
|
1912
|
+
.description("Process the current epoch in the StakingVault")
|
|
1913
|
+
.addOption(optStakingVaultAddress)
|
|
1914
|
+
.asyncAction({ signer: true }, async (config, options) => {
|
|
1915
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
1916
|
+
await (0, stakingVault_1.processEpochStakingVault)(config.client, stakingVault);
|
|
1917
|
+
});
|
|
1918
|
+
stakingVaultCmd
|
|
1919
|
+
.command("initiate-validator-registration")
|
|
1920
|
+
.description("Initiate validator registration in the StakingVault")
|
|
1921
|
+
.addOption(optStakingVaultAddress)
|
|
1922
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
1923
|
+
.addArgument((0, cliParser_1.ArgHex)("blsKey", "BLS public key"))
|
|
1924
|
+
.argument("stakeAmount", "Stake amount in AVAX")
|
|
1925
|
+
.addOption(new extra_typings_1.Option("--pchain-remaining-balance-owner-threshold <threshold>", "P-Chain remaining balance owner threshold").default(1).argParser(cliParser_1.ParserNumber))
|
|
1926
|
+
.addOption(new extra_typings_1.Option("--pchain-disable-owner-threshold <threshold>", "P-Chain disable owner threshold").default(1).argParser(cliParser_1.ParserNumber))
|
|
1927
|
+
.addOption(new extra_typings_1.Option("--pchain-remaining-balance-owner-address <address>", "P-Chain remaining balance owner address").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserAddress)))
|
|
1928
|
+
.addOption(new extra_typings_1.Option("--pchain-disable-owner-address <address>", "P-Chain disable owner address").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserAddress)))
|
|
1929
|
+
.asyncAction({ signer: true }, async (config, nodeId, blsKey, stakeAmount, options) => {
|
|
1930
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
1931
|
+
const defaultOwnerAddress = (0, viem_1.fromBytes)(avalanchejs_1.utils.bech32ToBytes(config.client.addresses.P), 'hex');
|
|
1932
|
+
// Build remainingBalanceOwner and disableOwner PChainOwner structs
|
|
1933
|
+
const remainingBalanceOwnerAddress = options.pchainRemainingBalanceOwnerAddress.length > 0 ? options.pchainRemainingBalanceOwnerAddress : [defaultOwnerAddress];
|
|
1934
|
+
const disableOwnerAddress = options.pchainDisableOwnerAddress.length > 0 ? options.pchainDisableOwnerAddress : [defaultOwnerAddress];
|
|
1935
|
+
const remainingBalanceOwner = [
|
|
1936
|
+
Number(options.pchainRemainingBalanceOwnerThreshold),
|
|
1937
|
+
remainingBalanceOwnerAddress
|
|
1938
|
+
];
|
|
1939
|
+
const disableOwner = [
|
|
1940
|
+
Number(options.pchainDisableOwnerThreshold),
|
|
1941
|
+
disableOwnerAddress
|
|
1942
|
+
];
|
|
1943
|
+
await (0, stakingVault_1.initiateValidatorRegistrationStakingVault)(config.client, stakingVault, nodeId, blsKey, remainingBalanceOwner, disableOwner, stakeAmount);
|
|
1944
|
+
});
|
|
1945
|
+
stakingVaultCmd
|
|
1946
|
+
.command("add-operator")
|
|
1947
|
+
.description("Add an operator to the StakingVault")
|
|
1948
|
+
.addOption(optStakingVaultAddress)
|
|
1949
|
+
.addArgument(argOperatorAddress)
|
|
1950
|
+
.argument("allocationBips", "Allocation in basis points (1 bips = 0.01%)")
|
|
1951
|
+
.addArgument((0, cliParser_1.ArgAddress)("feeRecipient", "Fee recipient address"))
|
|
1952
|
+
.asyncAction({ signer: true }, async (config, operator, allocationBips, feeRecipient, options) => {
|
|
1953
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
1954
|
+
const allocationBipsBigInt = BigInt(allocationBips);
|
|
1955
|
+
await (0, stakingVault_1.addOperatorStakingVault)(config.client, stakingVault, operator, allocationBipsBigInt, feeRecipient);
|
|
1956
|
+
});
|
|
1957
|
+
stakingVaultCmd
|
|
1958
|
+
.command("remove-operator")
|
|
1959
|
+
.description("Remove an operator from the StakingVault")
|
|
1960
|
+
.addOption(optStakingVaultAddress)
|
|
1961
|
+
.addArgument(argOperatorAddress)
|
|
1962
|
+
.asyncAction({ signer: true }, async (config, operator, options) => {
|
|
1963
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
1964
|
+
const hash = await stakingVault.safeWrite.removeOperator([operator]);
|
|
1965
|
+
logger_1.logger.log("removeOperator tx hash:", hash);
|
|
1966
|
+
logger_1.logger.log("removeOperator executed successfully");
|
|
1967
|
+
});
|
|
1968
|
+
stakingVaultCmd
|
|
1969
|
+
.command("complete-validator-registration")
|
|
1970
|
+
.description("Complete validator registration on the P-Chain and on the StakingVault after initiating registration")
|
|
1971
|
+
.addOption(optStakingVaultAddress)
|
|
1972
|
+
.addArgument((0, cliParser_1.ArgHex)("initiateTxHash", "Initiate validator registration transaction hash"))
|
|
1973
|
+
.addArgument((0, cliParser_1.ArgBLSPOP)())
|
|
1974
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
1975
|
+
.addOption(new extra_typings_1.Option("--initial-balance <initialBalance>", "Node initial balance to pay for continuous fee").default('0.01'))
|
|
1976
|
+
.addOption(new extra_typings_1.Option("--skip-wait-api", "Don't wait for the validator to be visible through the P-Chain API"))
|
|
1977
|
+
.asyncAction(async (_, initiateTxHash, blsProofOfPossession, options) => {
|
|
1978
|
+
const opts = program.opts();
|
|
1979
|
+
// If pchainTxPrivateKey is not provided, use the private key
|
|
1980
|
+
if (!options.pchainTxPrivateKey) {
|
|
1981
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
1982
|
+
}
|
|
1983
|
+
const initialBalance = (0, cliParser_1.ParseUnits)(options.initialBalance, 9, 'Invalid initial balance');
|
|
1984
|
+
const client = await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey, opts.safe);
|
|
1985
|
+
const config = (0, config_1.getConfig)(client, opts.wait, opts.skipAbiValidation);
|
|
1986
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
1987
|
+
const { validatorManagerAddress } = await (0, stakingVault_1.getValidatorManagerAddress)(config, stakingVault);
|
|
1988
|
+
const validatorManager = await config.contracts.ValidatorManager(validatorManagerAddress);
|
|
1989
|
+
await (0, stakingVault_1.completeValidatorRegistrationStakingVault)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : client, config, stakingVault, validatorManager, blsProofOfPossession, initiateTxHash, initialBalance, !options.skipWaitApi);
|
|
1990
|
+
});
|
|
1991
|
+
stakingVaultCmd
|
|
1992
|
+
.command("initiate-validator-removal")
|
|
1993
|
+
.description("Initiate validator removal in the StakingVault")
|
|
1994
|
+
.addOption(optStakingVaultAddress)
|
|
1995
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
1996
|
+
.asyncAction({ signer: true }, async (config, nodeId, options) => {
|
|
1997
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
1998
|
+
const { validatorManagerAddress } = await (0, stakingVault_1.getValidatorManagerAddress)(config, stakingVault);
|
|
1999
|
+
const validatorManager = await config.contracts.ValidatorManager(validatorManagerAddress);
|
|
2000
|
+
await (0, stakingVault_1.initiateValidatorRemovalStakingVault)(config.client, stakingVault, validatorManager, nodeId);
|
|
2001
|
+
});
|
|
2002
|
+
stakingVaultCmd
|
|
2003
|
+
.command("complete-validator-removal")
|
|
2004
|
+
.description("Complete validator removal on the P-Chain and on the StakingVault after initiating removal")
|
|
2005
|
+
.addOption(optStakingVaultAddress)
|
|
2006
|
+
.addArgument((0, cliParser_1.ArgHex)("initiateRemovalTxHash", "Initiate validator removal transaction hash"))
|
|
2007
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
2008
|
+
.addOption(new extra_typings_1.Option("--skip-wait-api", "Don't wait for the validator to be removed from the P-Chain API"))
|
|
2009
|
+
.addOption(new extra_typings_1.Option("--node-id <nodeId>", "Node ID of the validator being removed").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserNodeID)))
|
|
2010
|
+
.addOption(new extra_typings_1.Option("--initiate-tx <initiateTx>", "Initiate validator registration transaction hash").argParser((value) => value))
|
|
2011
|
+
.asyncAction({ signer: true }, async (config, initiateRemovalTxHash, options) => {
|
|
2012
|
+
const opts = program.opts();
|
|
2013
|
+
if (!options.pchainTxPrivateKey)
|
|
2014
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
2015
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2016
|
+
const { validatorManagerAddress } = await (0, stakingVault_1.getValidatorManagerAddress)(config, stakingVault);
|
|
2017
|
+
const validatorManager = await config.contracts.ValidatorManager(validatorManagerAddress);
|
|
2018
|
+
// Check if P-Chain address have 0.000050000 AVAX for tx fees
|
|
2019
|
+
await (0, transferUtils_1.requirePChainBallance)(config.client, 50000n, opts.yes);
|
|
2020
|
+
await (0, stakingVault_1.completeValidatorRemovalStakingVault)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : config.client, config, stakingVault, validatorManager, initiateRemovalTxHash, !options.skipWaitApi, options.nodeId.length > 0 ? options.nodeId : undefined, options.initiateTx);
|
|
2021
|
+
});
|
|
2022
|
+
stakingVaultCmd
|
|
2023
|
+
.command("force-remove-validator")
|
|
2024
|
+
.description("Force remove a validator from the StakingVault (admin/emergency operation)")
|
|
2025
|
+
.addOption(optStakingVaultAddress)
|
|
2026
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
2027
|
+
.asyncAction({ signer: true }, async (config, nodeId, options) => {
|
|
2028
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2029
|
+
const { validatorManagerAddress } = await (0, stakingVault_1.getValidatorManagerAddress)(config, stakingVault);
|
|
2030
|
+
const validatorManager = await config.contracts.ValidatorManager(validatorManagerAddress);
|
|
2031
|
+
await (0, stakingVault_1.forceRemoveValidatorStakingVault)(config.client, stakingVault, validatorManager, nodeId);
|
|
2032
|
+
});
|
|
2033
|
+
stakingVaultCmd
|
|
2034
|
+
.command("initiate-delegator-registration")
|
|
2035
|
+
.description("Initiate delegator registration in the StakingVault")
|
|
2036
|
+
.addOption(optStakingVaultAddress)
|
|
2037
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
2038
|
+
.argument("amount", "Stake amount in AVAX")
|
|
2039
|
+
.asyncAction({ signer: true }, async (config, nodeId, amount, options) => {
|
|
2040
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2041
|
+
const { validatorManagerAddress } = await (0, stakingVault_1.getValidatorManagerAddress)(config, stakingVault);
|
|
2042
|
+
const validatorManager = await config.contracts.ValidatorManager(validatorManagerAddress);
|
|
2043
|
+
await (0, stakingVault_1.initiateDelegatorRegistrationStakingVault)(config.client, stakingVault, validatorManager, nodeId, amount);
|
|
2044
|
+
});
|
|
2045
|
+
stakingVaultCmd
|
|
2046
|
+
.command("complete-delegator-registration")
|
|
2047
|
+
.description("Complete delegator registration on the P-Chain and on the StakingVault after initiating registration")
|
|
2048
|
+
.addOption(optStakingVaultAddress)
|
|
2049
|
+
.addArgument((0, cliParser_1.ArgHex)("initiateTxHash", "Initiate delegator registration transaction hash"))
|
|
2050
|
+
.argument("rpcUrl", "RPC URL for getting validator uptime (e.g. http(s)://domainOrIp:portIfNeeded)")
|
|
2051
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
2052
|
+
.asyncAction({ signer: true }, async (config, initiateTxHash, rpcUrl, options) => {
|
|
2053
|
+
const opts = program.opts();
|
|
2054
|
+
if (!options.pchainTxPrivateKey)
|
|
2055
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
2056
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2057
|
+
const { validatorManagerAddress, stakingManager, stakingManagerStorageLocation } = await (0, stakingVault_1.getValidatorManagerAddress)(config, stakingVault);
|
|
2058
|
+
const uptimeBlockchainID = await config.client.getStorageAt({ address: stakingManager.address, slot: `0x${(BigInt(stakingManagerStorageLocation) + 6n).toString(16).padStart(64, '0')}` });
|
|
2059
|
+
if (!uptimeBlockchainID || uptimeBlockchainID === "0x0") {
|
|
2060
|
+
throw new Error("Could not get uptime blockchain ID");
|
|
2061
|
+
}
|
|
2062
|
+
const validatorManager = await config.contracts.ValidatorManager(validatorManagerAddress);
|
|
2063
|
+
await (0, stakingVault_1.completeDelegatorRegistrationStakingVault)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : config.client, config, stakingVault, validatorManager, initiateTxHash, rpcUrl, uptimeBlockchainID);
|
|
2064
|
+
});
|
|
2065
|
+
stakingVaultCmd
|
|
2066
|
+
.command("initiate-delegator-removal")
|
|
2067
|
+
.description("Initiate delegator removal in the StakingVault")
|
|
2068
|
+
.addOption(optStakingVaultAddress)
|
|
2069
|
+
.addArgument((0, cliParser_1.ArgHex)("delegationID", "Delegation ID"))
|
|
2070
|
+
.asyncAction({ signer: true }, async (config, delegationID, options) => {
|
|
2071
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2072
|
+
await (0, stakingVault_1.initiateDelegatorRemovalStakingVault)(config.client, stakingVault, delegationID);
|
|
2073
|
+
});
|
|
2074
|
+
stakingVaultCmd
|
|
2075
|
+
.command("force-remove-delegator")
|
|
2076
|
+
.description("Force remove a delegator from the StakingVault (admin/emergency operation)")
|
|
2077
|
+
.addOption(optStakingVaultAddress)
|
|
2078
|
+
.addArgument((0, cliParser_1.ArgHex)("delegationID", "Delegation ID"))
|
|
2079
|
+
.asyncAction({ signer: true }, async (config, delegationID, options) => {
|
|
2080
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2081
|
+
await (0, stakingVault_1.forceRemoveDelegatorStakingVault)(config.client, stakingVault, delegationID);
|
|
2082
|
+
});
|
|
2083
|
+
stakingVaultCmd
|
|
2084
|
+
.command("complete-delegator-removal")
|
|
2085
|
+
.description("Complete delegator removal on the P-Chain and on the StakingVault after initiating removal")
|
|
2086
|
+
.addOption(optStakingVaultAddress)
|
|
2087
|
+
.addArgument((0, cliParser_1.ArgHex)("initiateRemovalTxHash", "Initiate delegator removal transaction hash"))
|
|
2088
|
+
.addOption(new extra_typings_1.Option("--pchain-tx-private-key <pchainTxPrivateKey>", "P-Chain transaction private key/secret name or 'ledger'. Defaults to the private key.").argParser(cliParser_1.ParserPrivateKey))
|
|
2089
|
+
.addOption(new extra_typings_1.Option("--skip-wait-api", "Don't wait for the validator to be removed from the P-Chain API"))
|
|
2090
|
+
.addOption(new extra_typings_1.Option("--delegation-id <delegationID>", "Delegation ID of the delegator being removed").default([]).argParser((0, cliParser_1.collectMultiple)(cliParser_1.ParserHex)))
|
|
2091
|
+
.addOption(new extra_typings_1.Option("--initiate-tx <initiateTx>", "Initiate delegator registration transaction hash").argParser((value) => value))
|
|
2092
|
+
.asyncAction({ signer: true }, async (config, initiateRemovalTxHash, options) => {
|
|
2093
|
+
const opts = program.opts();
|
|
2094
|
+
if (!options.pchainTxPrivateKey)
|
|
2095
|
+
options.pchainTxPrivateKey = opts.privateKey;
|
|
2096
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2097
|
+
const { validatorManagerAddress } = await (0, stakingVault_1.getValidatorManagerAddress)(config, stakingVault);
|
|
2098
|
+
const validatorManager = await config.contracts.ValidatorManager(validatorManagerAddress);
|
|
2099
|
+
// Check if P-Chain address have 0.000050000 AVAX for tx fees
|
|
2100
|
+
await (0, transferUtils_1.requirePChainBallance)(config.client, 50000n, opts.yes);
|
|
2101
|
+
await (0, stakingVault_1.completeDelegatorRemovalStakingVault)(options.pchainTxPrivateKey ? await (0, client_1.generateClient)(opts.network, options.pchainTxPrivateKey) : config.client, config, stakingVault, validatorManager, initiateRemovalTxHash, options.delegationId.length > 0 ? options.delegationId : undefined, options.initiateTx);
|
|
2102
|
+
});
|
|
2103
|
+
stakingVaultCmd
|
|
2104
|
+
.command("update-operator-allocations")
|
|
2105
|
+
.description("Update operator allocations in the StakingVault")
|
|
2106
|
+
.addOption(optStakingVaultAddress)
|
|
2107
|
+
.addArgument(argOperatorAddress)
|
|
2108
|
+
.argument("allocationBips", "Allocation in basis points (1 bips = 0.01%)")
|
|
2109
|
+
.asyncAction({ signer: true }, async (config, operator, allocationBips, options) => {
|
|
2110
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2111
|
+
const allocationBipsBigInt = BigInt(allocationBips);
|
|
2112
|
+
await stakingVault.safeWrite.updateOperatorAllocations([[operator], [allocationBipsBigInt]]);
|
|
2113
|
+
});
|
|
2114
|
+
stakingVaultCmd
|
|
2115
|
+
.command("claim-operator-fees")
|
|
2116
|
+
.description("Claim operator fees for the caller")
|
|
2117
|
+
.addOption(optStakingVaultAddress)
|
|
2118
|
+
.asyncAction({ signer: true }, async (config, options) => {
|
|
2119
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2120
|
+
const hash = await stakingVault.safeWrite.claimOperatorFees([]);
|
|
2121
|
+
logger_1.logger.log("claimOperatorFees executed successfully, tx hash:", hash);
|
|
2122
|
+
});
|
|
2123
|
+
stakingVaultCmd
|
|
2124
|
+
.command("force-claim-operator-fees")
|
|
2125
|
+
.description("Force claim operator fees for an operator (admin)")
|
|
2126
|
+
.addOption(optStakingVaultAddress)
|
|
2127
|
+
.addArgument(argOperatorAddress)
|
|
2128
|
+
.asyncAction({ signer: true }, async (config, operator, options) => {
|
|
2129
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2130
|
+
const hash = await stakingVault.safeWrite.forceClaimOperatorFees([operator]);
|
|
2131
|
+
logger_1.logger.log("forceClaimOperatorFees executed successfully, tx hash:", hash);
|
|
2132
|
+
});
|
|
2133
|
+
stakingVaultCmd
|
|
2134
|
+
.command("claim-pending-protocol-fees")
|
|
2135
|
+
.description("Claim pending protocol fees")
|
|
2136
|
+
.addOption(optStakingVaultAddress)
|
|
2137
|
+
.asyncAction({ signer: true }, async (config, options) => {
|
|
2138
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2139
|
+
const hash = await stakingVault.safeWrite.claimPendingProtocolFees([]);
|
|
2140
|
+
logger_1.logger.log("claimPendingProtocolFees executed successfully, tx hash:", hash);
|
|
2141
|
+
});
|
|
2142
|
+
stakingVaultCmd
|
|
2143
|
+
.command("harvest")
|
|
2144
|
+
.description("Harvest rewards")
|
|
2145
|
+
.addOption(optStakingVaultAddress)
|
|
2146
|
+
.asyncAction({ signer: true }, async (config, options) => {
|
|
2147
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2148
|
+
const hash = await stakingVault.safeWrite.harvest([]);
|
|
2149
|
+
logger_1.logger.log("harvest executed successfully, tx hash:", hash);
|
|
2150
|
+
});
|
|
2151
|
+
stakingVaultCmd
|
|
2152
|
+
.command("harvest-validators")
|
|
2153
|
+
.description("Harvest validator rewards in batches")
|
|
2154
|
+
.addOption(optStakingVaultAddress)
|
|
2155
|
+
.addArgument((0, cliParser_1.ArgBigInt)("operatorIndex", "Operator index"))
|
|
2156
|
+
.addArgument((0, cliParser_1.ArgBigInt)("start", "Validator list start index"))
|
|
2157
|
+
.addArgument((0, cliParser_1.ArgBigInt)("batchSize", "Validator batch size"))
|
|
2158
|
+
.asyncAction({ signer: true }, async (config, operatorIndex, start, batchSize, options) => {
|
|
2159
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2160
|
+
const hash = await stakingVault.safeWrite.harvestValidators([operatorIndex, start, batchSize]);
|
|
2161
|
+
logger_1.logger.log("harvestValidators executed successfully, tx hash:", hash);
|
|
2162
|
+
});
|
|
2163
|
+
stakingVaultCmd
|
|
2164
|
+
.command("harvest-delegators")
|
|
2165
|
+
.description("Harvest delegator rewards in batches")
|
|
2166
|
+
.addOption(optStakingVaultAddress)
|
|
2167
|
+
.addArgument((0, cliParser_1.ArgBigInt)("operatorIndex", "Operator index"))
|
|
2168
|
+
.addArgument((0, cliParser_1.ArgBigInt)("start", "Delegator list start index"))
|
|
2169
|
+
.addArgument((0, cliParser_1.ArgBigInt)("batchSize", "Delegator batch size"))
|
|
2170
|
+
.asyncAction({ signer: true }, async (config, operatorIndex, start, batchSize, options) => {
|
|
2171
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2172
|
+
const hash = await stakingVault.safeWrite.harvestDelegators([operatorIndex, start, batchSize]);
|
|
2173
|
+
logger_1.logger.log("harvestDelegators executed successfully, tx hash:", hash);
|
|
2174
|
+
});
|
|
2175
|
+
stakingVaultCmd
|
|
2176
|
+
.command("prepare-withdrawals")
|
|
2177
|
+
.description("Prepare withdrawals by initiating stake removals")
|
|
2178
|
+
.addOption(optStakingVaultAddress)
|
|
2179
|
+
.asyncAction({ signer: true }, async (config, options) => {
|
|
2180
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2181
|
+
const hash = await stakingVault.safeWrite.prepareWithdrawals([]);
|
|
2182
|
+
logger_1.logger.log("prepareWithdrawals executed successfully, tx hash:", hash);
|
|
2183
|
+
});
|
|
2184
|
+
stakingVaultCmd
|
|
2185
|
+
.command("pause")
|
|
2186
|
+
.description("Pause the StakingVault")
|
|
2187
|
+
.addOption(optStakingVaultAddress)
|
|
2188
|
+
.asyncAction({ signer: true }, async (config, options) => {
|
|
2189
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2190
|
+
const hash = await stakingVault.safeWrite.pause([]);
|
|
2191
|
+
logger_1.logger.log("pause executed successfully, tx hash:", hash);
|
|
2192
|
+
});
|
|
2193
|
+
stakingVaultCmd
|
|
2194
|
+
.command("unpause")
|
|
2195
|
+
.description("Unpause the StakingVault")
|
|
2196
|
+
.addOption(optStakingVaultAddress)
|
|
2197
|
+
.asyncAction({ signer: true }, async (config, options) => {
|
|
2198
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2199
|
+
const hash = await stakingVault.safeWrite.unpause([]);
|
|
2200
|
+
logger_1.logger.log("unpause executed successfully, tx hash:", hash);
|
|
2201
|
+
});
|
|
2202
|
+
/**
|
|
2203
|
+
* Setters
|
|
2204
|
+
*/
|
|
2205
|
+
stakingVaultCmd
|
|
2206
|
+
.command("set-liquidity-buffer-bips")
|
|
2207
|
+
.description("Set the liquidity buffer in basis points")
|
|
2208
|
+
.addOption(optStakingVaultAddress)
|
|
2209
|
+
.addArgument((0, cliParser_1.ArgBigInt)("liquidityBufferBips", "Liquidity buffer in basis points"))
|
|
2210
|
+
.asyncAction({ signer: true }, async (config, liquidityBufferBips, options) => {
|
|
2211
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2212
|
+
const hash = await stakingVault.safeWrite.setLiquidityBufferBips([liquidityBufferBips]);
|
|
2213
|
+
logger_1.logger.log("setLiquidityBufferBips executed successfully, tx hash:", hash);
|
|
2214
|
+
});
|
|
2215
|
+
stakingVaultCmd
|
|
2216
|
+
.command("set-withdrawal-request-fee")
|
|
2217
|
+
.description("Set the withdrawal request fee")
|
|
2218
|
+
.addOption(optStakingVaultAddress)
|
|
2219
|
+
.addArgument((0, cliParser_1.ArgBigInt)("fee", "Withdrawal request fee"))
|
|
2220
|
+
.asyncAction({ signer: true }, async (config, fee, options) => {
|
|
2221
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2222
|
+
const hash = await stakingVault.safeWrite.setWithdrawalRequestFee([fee]);
|
|
2223
|
+
logger_1.logger.log("setWithdrawalRequestFee executed successfully, tx hash:", hash);
|
|
2224
|
+
});
|
|
2225
|
+
stakingVaultCmd
|
|
2226
|
+
.command("set-max-operators")
|
|
2227
|
+
.description("Set the maximum number of operators")
|
|
2228
|
+
.addOption(optStakingVaultAddress)
|
|
2229
|
+
.addArgument((0, cliParser_1.ArgBigInt)("maxOperators", "Maximum number of operators"))
|
|
2230
|
+
.asyncAction({ signer: true }, async (config, maxOperators, options) => {
|
|
2231
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2232
|
+
const hash = await stakingVault.safeWrite.setMaxOperators([maxOperators]);
|
|
2233
|
+
logger_1.logger.log("setMaxOperators executed successfully, tx hash:", hash);
|
|
2234
|
+
});
|
|
2235
|
+
stakingVaultCmd
|
|
2236
|
+
.command("set-max-validators-per-operator")
|
|
2237
|
+
.description("Set the maximum number of validators per operator")
|
|
2238
|
+
.addOption(optStakingVaultAddress)
|
|
2239
|
+
.addArgument((0, cliParser_1.ArgBigInt)("maxValidatorsPerOperator", "Maximum number of validators per operator"))
|
|
2240
|
+
.asyncAction({ signer: true }, async (config, maxValidatorsPerOperator, options) => {
|
|
2241
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2242
|
+
const hash = await stakingVault.safeWrite.setMaxValidatorsPerOperator([maxValidatorsPerOperator]);
|
|
2243
|
+
logger_1.logger.log("setMaxValidatorsPerOperator executed successfully, tx hash:", hash);
|
|
2244
|
+
});
|
|
2245
|
+
stakingVaultCmd
|
|
2246
|
+
.command("set-maximum-delegator-stake")
|
|
2247
|
+
.description("Set the maximum stake amount for a delegator")
|
|
2248
|
+
.addOption(optStakingVaultAddress)
|
|
2249
|
+
.addArgument((0, cliParser_1.ArgBigInt)("maximumDelegatorStake", "Maximum stake amount for a delegator"))
|
|
2250
|
+
.asyncAction({ signer: true }, async (config, maximumDelegatorStake, options) => {
|
|
2251
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2252
|
+
const hash = await stakingVault.safeWrite.setMaximumDelegatorStake([maximumDelegatorStake]);
|
|
2253
|
+
logger_1.logger.log("setMaximumDelegatorStake executed successfully, tx hash:", hash);
|
|
2254
|
+
});
|
|
2255
|
+
stakingVaultCmd
|
|
2256
|
+
.command("set-maximum-validator-stake")
|
|
2257
|
+
.description("Set the maximum stake amount for a validator")
|
|
2258
|
+
.addOption(optStakingVaultAddress)
|
|
2259
|
+
.addArgument((0, cliParser_1.ArgBigInt)("maximumValidatorStake", "Maximum stake amount for a validator"))
|
|
2260
|
+
.asyncAction({ signer: true }, async (config, maximumValidatorStake, options) => {
|
|
2261
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2262
|
+
const hash = await stakingVault.safeWrite.setMaximumValidatorStake([maximumValidatorStake]);
|
|
2263
|
+
logger_1.logger.log("setMaximumValidatorStake executed successfully, tx hash:", hash);
|
|
2264
|
+
});
|
|
2265
|
+
stakingVaultCmd
|
|
2266
|
+
.command("set-operations-impl")
|
|
2267
|
+
.description("Set the operations implementation")
|
|
2268
|
+
.addOption(optStakingVaultAddress)
|
|
2269
|
+
.addArgument((0, cliParser_1.ArgAddress)("operationsImpl", "Operations implementation"))
|
|
2270
|
+
.asyncAction({ signer: true }, async (config, operationsImpl, options) => {
|
|
2271
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2272
|
+
const hash = await stakingVault.safeWrite.setOperationsImpl([operationsImpl]);
|
|
2273
|
+
logger_1.logger.log("setOperationsImpl executed successfully, tx hash:", hash);
|
|
2274
|
+
});
|
|
2275
|
+
stakingVaultCmd
|
|
2276
|
+
.command("set-operator-fee-bips")
|
|
2277
|
+
.description("Set the operator fee in basis points")
|
|
2278
|
+
.addOption(optStakingVaultAddress)
|
|
2279
|
+
.addArgument((0, cliParser_1.ArgBigInt)("operatorFeeBips", "Operator fee in basis points"))
|
|
2280
|
+
.asyncAction({ signer: true }, async (config, operatorFeeBips, options) => {
|
|
2281
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2282
|
+
const hash = await stakingVault.safeWrite.setOperatorFeeBips([operatorFeeBips]);
|
|
2283
|
+
logger_1.logger.log("setOperatorFeeBips executed successfully, tx hash:", hash);
|
|
2284
|
+
});
|
|
2285
|
+
stakingVaultCmd
|
|
2286
|
+
.command("set-operator-fee-recipient")
|
|
2287
|
+
.description("Set the operator fee recipient")
|
|
2288
|
+
.addOption(optStakingVaultAddress)
|
|
2289
|
+
.addArgument((0, cliParser_1.ArgAddress)("operatorFeeRecipient", "Operator fee recipient"))
|
|
2290
|
+
.asyncAction({ signer: true }, async (config, operatorFeeRecipient, options) => {
|
|
2291
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2292
|
+
const hash = await stakingVault.safeWrite.setOperatorFeeRecipient([operatorFeeRecipient]);
|
|
2293
|
+
logger_1.logger.log("setOperatorFeeRecipient executed successfully, tx hash:", hash);
|
|
2294
|
+
});
|
|
2295
|
+
stakingVaultCmd
|
|
2296
|
+
.command("set-protocol-fee-bips")
|
|
2297
|
+
.description("Set the protocol fee in basis points")
|
|
2298
|
+
.addOption(optStakingVaultAddress)
|
|
2299
|
+
.addArgument((0, cliParser_1.ArgBigInt)("protocolFeeBips", "Protocol fee in basis points"))
|
|
2300
|
+
.asyncAction({ signer: true }, async (config, protocolFeeBips, options) => {
|
|
2301
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2302
|
+
const hash = await stakingVault.safeWrite.setProtocolFeeBips([protocolFeeBips]);
|
|
2303
|
+
logger_1.logger.log("setProtocolFeeBips executed successfully, tx hash:", hash);
|
|
2304
|
+
});
|
|
2305
|
+
stakingVaultCmd
|
|
2306
|
+
.command("set-protocol-fee-recipient")
|
|
2307
|
+
.description("Set the protocol fee recipient")
|
|
2308
|
+
.addOption(optStakingVaultAddress)
|
|
2309
|
+
.addArgument((0, cliParser_1.ArgAddress)("protocolFeeRecipient", "Protocol fee recipient"))
|
|
2310
|
+
.asyncAction({ signer: true }, async (config, protocolFeeRecipient, options) => {
|
|
2311
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2312
|
+
const hash = await stakingVault.safeWrite.setProtocolFeeRecipient([protocolFeeRecipient]);
|
|
2313
|
+
logger_1.logger.log("setProtocolFeeRecipient executed successfully, tx hash:", hash);
|
|
2314
|
+
});
|
|
2315
|
+
stakingVaultCmd
|
|
2316
|
+
.command("get-withdrawal-request-fee")
|
|
2317
|
+
.description("Get the withdrawal request fee")
|
|
2318
|
+
.addOption(optStakingVaultAddress)
|
|
2319
|
+
.asyncAction(async (config, options) => {
|
|
2320
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2321
|
+
const fee = await stakingVault.read.getWithdrawalRequestFee();
|
|
2322
|
+
logger_1.logger.log("Withdrawal request fee:", fee);
|
|
2323
|
+
});
|
|
2324
|
+
stakingVaultCmd
|
|
2325
|
+
.command("info")
|
|
2326
|
+
.description("Get general overview of the StakingVault")
|
|
2327
|
+
.addOption(optStakingVaultAddress)
|
|
2328
|
+
.asyncAction({ signer: true }, async (config, options) => {
|
|
2329
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2330
|
+
await (0, stakingVault_1.getGeneralInfo)(stakingVault, config.client);
|
|
2331
|
+
});
|
|
2332
|
+
stakingVaultCmd
|
|
2333
|
+
.command("fees-info")
|
|
2334
|
+
.description("Get fees configuration of the StakingVault")
|
|
2335
|
+
.addOption(optStakingVaultAddress)
|
|
2336
|
+
.asyncAction(async (config, options) => {
|
|
2337
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2338
|
+
await (0, stakingVault_1.getFeesInfo)(stakingVault);
|
|
2339
|
+
});
|
|
2340
|
+
stakingVaultCmd
|
|
2341
|
+
.command("operators-info")
|
|
2342
|
+
.description("Get operators details of the StakingVault")
|
|
2343
|
+
.addOption(optStakingVaultAddress)
|
|
2344
|
+
.asyncAction(async (config, options) => {
|
|
2345
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2346
|
+
await (0, stakingVault_1.getOperatorsInfo)(stakingVault);
|
|
2347
|
+
});
|
|
2348
|
+
stakingVaultCmd
|
|
2349
|
+
.command("validators-info")
|
|
2350
|
+
.description("Get validators details per operator of the StakingVault")
|
|
2351
|
+
.addOption(optStakingVaultAddress)
|
|
2352
|
+
.asyncAction(async (config, options) => {
|
|
2353
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2354
|
+
await (0, stakingVault_1.getValidatorsInfo)(stakingVault);
|
|
2355
|
+
});
|
|
2356
|
+
stakingVaultCmd
|
|
2357
|
+
.command("delegators-info")
|
|
2358
|
+
.description("Get delegations details per operator of the StakingVault")
|
|
2359
|
+
.addOption(optStakingVaultAddress)
|
|
2360
|
+
.asyncAction(async (config, options) => {
|
|
2361
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2362
|
+
await (0, stakingVault_1.getDelegatorsInfo)(stakingVault);
|
|
2363
|
+
});
|
|
2364
|
+
stakingVaultCmd
|
|
2365
|
+
.command("withdrawals-info")
|
|
2366
|
+
.description("Get withdrawal queue info of the StakingVault")
|
|
2367
|
+
.addOption(optStakingVaultAddress)
|
|
2368
|
+
.asyncAction(async (config, options) => {
|
|
2369
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2370
|
+
await (0, stakingVault_1.getWithdrawalsInfo)(stakingVault);
|
|
2371
|
+
});
|
|
2372
|
+
stakingVaultCmd
|
|
2373
|
+
.command("epoch-info")
|
|
2374
|
+
.description("Get epoch info of the StakingVault")
|
|
2375
|
+
.addOption(optStakingVaultAddress)
|
|
2376
|
+
.asyncAction(async (config, options) => {
|
|
2377
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2378
|
+
await (0, stakingVault_1.getEpochInfo)(stakingVault);
|
|
2379
|
+
});
|
|
2380
|
+
stakingVaultCmd
|
|
2381
|
+
.command("full-info")
|
|
2382
|
+
.description("Get all information about the StakingVault")
|
|
2383
|
+
.addOption(optStakingVaultAddress)
|
|
2384
|
+
.asyncAction(async (config, options) => {
|
|
2385
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2386
|
+
await (0, stakingVault_1.getGeneralInfo)(stakingVault, config.client);
|
|
2387
|
+
await (0, stakingVault_1.getFeesInfo)(stakingVault);
|
|
2388
|
+
await (0, stakingVault_1.getOperatorsInfo)(stakingVault);
|
|
2389
|
+
await (0, stakingVault_1.getValidatorsInfo)(stakingVault);
|
|
2390
|
+
await (0, stakingVault_1.getDelegatorsInfo)(stakingVault);
|
|
2391
|
+
await (0, stakingVault_1.getWithdrawalsInfo)(stakingVault);
|
|
2392
|
+
await (0, stakingVault_1.getEpochInfo)(stakingVault);
|
|
2393
|
+
});
|
|
2394
|
+
stakingVaultCmd
|
|
2395
|
+
.command("get-current-epoch")
|
|
2396
|
+
.description("Get current epoch number of the StakingVault")
|
|
2397
|
+
.addOption(optStakingVaultAddress)
|
|
2398
|
+
.asyncAction(async (config, options) => {
|
|
2399
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2400
|
+
const currentEpoch = await stakingVault.read.getCurrentEpoch();
|
|
2401
|
+
logger_1.logger.log(`Current epoch: ${currentEpoch}`);
|
|
2402
|
+
});
|
|
2403
|
+
stakingVaultCmd
|
|
2404
|
+
.command("get-epoch-duration")
|
|
2405
|
+
.description("Get epoch duration in seconds of the StakingVault")
|
|
2406
|
+
.addOption(optStakingVaultAddress)
|
|
2407
|
+
.asyncAction(async (config, options) => {
|
|
2408
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2409
|
+
const epochDuration = await stakingVault.read.getEpochDuration();
|
|
2410
|
+
logger_1.logger.log(`Epoch duration (seconds): ${epochDuration}`);
|
|
2411
|
+
});
|
|
2412
|
+
stakingVaultCmd
|
|
2413
|
+
.command("get-next-epoch-start-time")
|
|
2414
|
+
.description("Get next epoch start time (timestamp) of the StakingVault")
|
|
2415
|
+
.addOption(optStakingVaultAddress)
|
|
2416
|
+
.asyncAction(async (config, options) => {
|
|
2417
|
+
const stakingVault = await config.contracts.StakingVault(options.stakingVaultAddress);
|
|
2418
|
+
const startTime = await stakingVault.read.getStartTime();
|
|
2419
|
+
const [epochDuration, currentEpoch] = await stakingVault.multicall(["getEpochDuration", "getCurrentEpoch"]);
|
|
2420
|
+
const nextEpochStartTime = startTime + (epochDuration * (currentEpoch + 1n));
|
|
2421
|
+
const nextEpochStartDate = new Date(Number(nextEpochStartTime) * 1000);
|
|
2422
|
+
logger_1.logger.log(`Next epoch start time (timestamp): ${nextEpochStartTime} => ${nextEpochStartDate.toLocaleString()}`);
|
|
2423
|
+
});
|
|
2424
|
+
/**
|
|
2425
|
+
* --------------------------------------------------
|
|
2426
|
+
* OP-STAKES: enumerates the vaults and attempts to read stake for <operator>
|
|
2427
|
+
* --------------------------------------------------
|
|
2428
|
+
*/
|
|
2429
|
+
vaultManagerCmd
|
|
2430
|
+
.command("opstakes")
|
|
2431
|
+
.description("Show operator stakes across L1s, enumerating each L1 the operator is opted into.")
|
|
2432
|
+
.addArgument(argMiddlewareVaultManagerAddress)
|
|
2433
|
+
.addArgument(argOperatorAddress)
|
|
2434
|
+
.description("Show operator stakes across L1s, enumerating each L1 the operator is opted into.")
|
|
2435
|
+
.asyncAction(async (config, middlewareVaultManager, operatorAddress) => {
|
|
2436
|
+
const operator = operatorAddress;
|
|
2437
|
+
logger_1.logger.log(`Operator: ${operator}`);
|
|
2438
|
+
// 1) Read total vaults from VaultManager
|
|
2439
|
+
const vaultManager = await config.contracts.VaultManager(middlewareVaultManager);
|
|
2440
|
+
const vaultCount = await vaultManager.read.getVaultCount();
|
|
2441
|
+
logger_1.logger.log(`Found ${vaultCount} vault(s).`);
|
|
2442
|
+
// This map accumulates the total stake for each collateral
|
|
2443
|
+
const totalStakesByCollateral = {};
|
|
2444
|
+
// 2) Let's get all L1 addresses from the L1Registry (similar to your Python code)
|
|
2445
|
+
const l1Registry = await config.contracts.L1Registry();
|
|
2446
|
+
const totalL1s = await l1Registry.read.totalL1s();
|
|
2447
|
+
// We'll store them in an array
|
|
2448
|
+
const l1Array = [];
|
|
2449
|
+
for (let i = 0n; i < totalL1s; i++) {
|
|
2450
|
+
// e.g. getL1At(i) might return [address, metadataUrl], adjust as needed
|
|
2451
|
+
const [l1Address, _] = await l1Registry.read.getL1At([i]);
|
|
2452
|
+
l1Array.push(l1Address);
|
|
2453
|
+
}
|
|
2454
|
+
// 3) For each vault in [0..vaultCount-1], read collateralClass, delegator, collateral
|
|
2455
|
+
for (let i = 0n; i < vaultCount; i++) {
|
|
2456
|
+
const [vaultAddress] = await vaultManager.read.getVaultAtWithTimes([i]);
|
|
2457
|
+
logger_1.logger.log(`\nVault #${i}: ${vaultAddress}`);
|
|
2458
|
+
// read the collateralClass
|
|
2459
|
+
const collateralClass = await vaultManager.read.getVaultCollateralClass([vaultAddress]);
|
|
2460
|
+
// read delegator
|
|
2461
|
+
const vaultTokenized = await config.contracts.VaultTokenized(vaultAddress);
|
|
2462
|
+
const delegator = await vaultTokenized.read.delegator();
|
|
2463
|
+
if (delegator === '0x0000000000000000000000000000000000000000') {
|
|
2464
|
+
logger_1.logger.log(" (No delegator set, skipping)");
|
|
2465
|
+
continue;
|
|
2466
|
+
}
|
|
2467
|
+
const l1RestakeDelegator = await config.contracts.L1RestakeDelegator(delegator);
|
|
2468
|
+
// read collateral
|
|
2469
|
+
const collateral = await vaultTokenized.read.collateral();
|
|
2470
|
+
// 4) For each L1 in l1Array, check if operator is opted in
|
|
2471
|
+
for (const l1Address of l1Array) {
|
|
2472
|
+
const operatorL1OptInService = await config.contracts.OperatorL1OptInService();
|
|
2473
|
+
const isOptedIn = await operatorL1OptInService.read.isOptedIn([operator, l1Address]);
|
|
2474
|
+
if (isOptedIn) {
|
|
2475
|
+
// read stake
|
|
2476
|
+
const stakeValue = await l1RestakeDelegator.read.stake([l1Address, collateralClass, operator]);
|
|
2477
|
+
if (stakeValue > 0n) {
|
|
2478
|
+
logger_1.logger.log(` L1: ${l1Address} => stake = ${stakeValue.toString()} (vault=${vaultAddress})`);
|
|
2479
|
+
// sum into totalStakesByCollateral
|
|
2480
|
+
const oldVal = totalStakesByCollateral[collateral] || 0n;
|
|
2481
|
+
totalStakesByCollateral[collateral] = oldVal + stakeValue;
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
// 5) Finally, print aggregated totals
|
|
2487
|
+
logger_1.logger.log("\nAggregated stakes by collateral:");
|
|
2488
|
+
if (Object.keys(totalStakesByCollateral).length === 0) {
|
|
2489
|
+
logger_1.logger.log(" No stakes found or operator not opted into any L1s this way.");
|
|
2490
|
+
}
|
|
2491
|
+
else {
|
|
2492
|
+
for (const [collateralAddr, totalWei] of Object.entries(totalStakesByCollateral)) {
|
|
2493
|
+
// optional: look up decimals for that collateral if you want a float
|
|
2494
|
+
const decimals = 18; // or read from chain
|
|
2495
|
+
const floatAmount = Number(totalWei) / 10 ** decimals;
|
|
2496
|
+
logger_1.logger.log(` Collateral=${collateralAddr} totalStakeWei=${totalWei} => ${floatAmount}`);
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
});
|
|
2500
|
+
vaultManagerCmd
|
|
2501
|
+
.command("l1stakes")
|
|
2502
|
+
.description("Show L1 stakes for a given validator manager")
|
|
2503
|
+
.addArgument(argValidatorManagerAddress)
|
|
2504
|
+
.description("Show L1 stakes for a given validator manager")
|
|
2505
|
+
.asyncAction(async (config) => {
|
|
2506
|
+
// TODO: Implement
|
|
2507
|
+
});
|
|
2508
|
+
// --------------------------------------------------
|
|
2509
|
+
// "UpTime" Commands
|
|
2510
|
+
// These commands help with reporting validator uptime to the UptimeTracker contract
|
|
2511
|
+
// They include fetching the signed uptime message from a validator and submitting it to the contract
|
|
2512
|
+
// --------------------------------------------------
|
|
2513
|
+
const uptimeCmd = program
|
|
2514
|
+
.command("uptime")
|
|
2515
|
+
.description("Commands related to validator uptime reporting");
|
|
2516
|
+
uptimeCmd
|
|
2517
|
+
.command("get-validation-uptime-message")
|
|
2518
|
+
.description("Get the validation uptime message for a given validator in the given L1 RPC")
|
|
2519
|
+
.addArgument((0, cliParser_1.ArgURI)("rpcUrl", "RPC URL like 'http(s)://<domain or ip and port>'"))
|
|
2520
|
+
.addArgument((0, cliParser_1.ArgCB58)("blockchainId", "Blockchain ID"))
|
|
2521
|
+
.addArgument((0, cliParser_1.ArgNodeID)())
|
|
2522
|
+
.asyncAction(async (config, rpcUrl, blockchainId, nodeId) => {
|
|
2523
|
+
rpcUrl = rpcUrl + "/ext/bc/" + blockchainId;
|
|
2524
|
+
const opts = program.opts();
|
|
2525
|
+
const client = await (0, client_1.generateClient)(opts.network);
|
|
2526
|
+
await (0, uptime_1.getValidationUptimeMessage)(config.client, rpcUrl, nodeId, config.client.network === "fuji" ? 5 : 1, blockchainId);
|
|
2527
|
+
});
|
|
2528
|
+
uptimeCmd
|
|
2529
|
+
.command('compute-validator-uptime')
|
|
2530
|
+
.addArgument(argUptimeTrackerAddress)
|
|
2531
|
+
.addArgument((0, cliParser_1.ArgHex)("signedUptimeHex", "Signed uptime hex"))
|
|
2532
|
+
.asyncAction({ signer: true }, async (config, uptimeTrackerAddress, signedUptimeHex) => {
|
|
2533
|
+
await (0, uptime_1.computeValidatorUptime)(await config.contracts.UptimeTracker(uptimeTrackerAddress), signedUptimeHex);
|
|
2534
|
+
});
|
|
2535
|
+
// ---- Combined Uptime Reporting Command ----
|
|
2536
|
+
uptimeCmd
|
|
2537
|
+
.command("report-uptime-validator")
|
|
2538
|
+
.description("Gets a validator's signed uptime message and submits it to the UptimeTracker contract.")
|
|
2539
|
+
.addArgument((0, cliParser_1.ArgURI)("rpcUrl", "RPC URL like 'http(s)://<domain or ip and port>'"))
|
|
2540
|
+
.addArgument((0, cliParser_1.ArgCB58)("blockchainId", "The Blockchain ID for which the uptime is being reported"))
|
|
2541
|
+
.addArgument((0, cliParser_1.ArgNodeID)("nodeId", "The NodeID of the validator"))
|
|
2542
|
+
.addArgument(argUptimeTrackerAddress)
|
|
2543
|
+
.asyncAction({ signer: true }, async (config, rpcUrl, blockchainId, nodeId, uptimeTrackerAddress) => {
|
|
2544
|
+
const opts = program.opts();
|
|
2545
|
+
if (!opts.privateKey) {
|
|
2546
|
+
logger_1.logger.error("Error: Private key is required. Use -k or set PK environment variable.");
|
|
2547
|
+
process.exit(1);
|
|
2548
|
+
}
|
|
2549
|
+
rpcUrl = rpcUrl + "/ext/bc/" + blockchainId;
|
|
2550
|
+
await (0, uptime_1.reportAndSubmitValidatorUptime)(config.client, rpcUrl, nodeId, blockchainId, await config.contracts.UptimeTracker(uptimeTrackerAddress));
|
|
2551
|
+
});
|
|
2552
|
+
// ---- Adding new commands for operator uptime ----
|
|
2553
|
+
uptimeCmd
|
|
2554
|
+
.command("compute-operator-uptime")
|
|
2555
|
+
.description("Compute uptime for an operator at a specific epoch")
|
|
2556
|
+
.addArgument(argUptimeTrackerAddress)
|
|
2557
|
+
.addArgument(argOperatorAddress)
|
|
2558
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch number"))
|
|
2559
|
+
.asyncAction({ signer: true }, async (config, uptimeTrackerAddress, operator, epoch) => {
|
|
2560
|
+
const opts = program.opts();
|
|
2561
|
+
if (!opts.privateKey) {
|
|
2562
|
+
logger_1.logger.error("Error: Private key is required. Use -k or set PK environment variable.");
|
|
2563
|
+
process.exit(1);
|
|
2564
|
+
}
|
|
2565
|
+
const uptimeTracker = await config.contracts.UptimeTracker(uptimeTrackerAddress);
|
|
2566
|
+
await (0, uptime_1.computeOperatorUptimeAtEpoch)(uptimeTracker, operator, epoch);
|
|
2567
|
+
});
|
|
2568
|
+
uptimeCmd
|
|
2569
|
+
.command("compute-operator-uptime-range")
|
|
2570
|
+
.description("Compute uptime for an operator over a range of epochs (client-side looping)")
|
|
2571
|
+
.addArgument(argUptimeTrackerAddress)
|
|
2572
|
+
.addArgument(argOperatorAddress)
|
|
2573
|
+
.addArgument((0, cliParser_1.ArgNumber)("startEpoch", "Starting epoch number"))
|
|
2574
|
+
.addArgument((0, cliParser_1.ArgNumber)("endEpoch", "Ending epoch number"))
|
|
2575
|
+
.asyncAction({ signer: true }, async (config, uptimeTrackerAddress, operator, startEpoch, endEpoch) => {
|
|
2576
|
+
const opts = program.opts();
|
|
2577
|
+
if (!opts.privateKey) {
|
|
2578
|
+
logger_1.logger.error("Error: Private key is required. Use -k or set PK environment variable.");
|
|
2579
|
+
process.exit(1);
|
|
2580
|
+
}
|
|
2581
|
+
const uptimeTracker = await config.contracts.UptimeTracker(uptimeTrackerAddress);
|
|
2582
|
+
await (0, uptime_1.computeOperatorUptimeForEpochs)(uptimeTracker, operator, startEpoch, endEpoch);
|
|
2583
|
+
});
|
|
2584
|
+
// ---- Read-only commands for uptime data ----
|
|
2585
|
+
uptimeCmd
|
|
2586
|
+
.command("get-validator-uptime")
|
|
2587
|
+
.description("Get the recorded uptime for a validator at a specific epoch")
|
|
2588
|
+
.addArgument(argUptimeTrackerAddress)
|
|
2589
|
+
.addArgument((0, cliParser_1.ArgHex)("validationID", "Validation ID of the validator"))
|
|
2590
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch number"))
|
|
2591
|
+
.asyncAction(async (config, uptimeTrackerAddress, validationID, epoch) => {
|
|
2592
|
+
const uptimeTracker = await config.contracts.UptimeTracker(uptimeTrackerAddress);
|
|
2593
|
+
const uptime = await (0, uptime_1.getValidatorUptimeForEpoch)(uptimeTracker, validationID, epoch);
|
|
2594
|
+
logger_1.logger.log(`Validator uptime for epoch ${epoch}: ${uptime.toString()} seconds`);
|
|
2595
|
+
});
|
|
2596
|
+
uptimeCmd
|
|
2597
|
+
.command("check-validator-uptime-set")
|
|
2598
|
+
.description("Check if uptime data is set for a validator at a specific epoch")
|
|
2599
|
+
.addArgument(argUptimeTrackerAddress)
|
|
2600
|
+
.addArgument((0, cliParser_1.ArgHex)("validationID", "Validation ID of the validator"))
|
|
2601
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch number"))
|
|
2602
|
+
.asyncAction(async (config, uptimeTrackerAddress, validationID, epoch) => {
|
|
2603
|
+
const uptimeTracker = await config.contracts.UptimeTracker(uptimeTrackerAddress);
|
|
2604
|
+
const isSet = await (0, uptime_1.isValidatorUptimeSetForEpoch)(uptimeTracker, validationID, epoch);
|
|
2605
|
+
logger_1.logger.log(`Validator uptime is ${isSet ? 'set' : 'not set'} for epoch ${epoch}`);
|
|
2606
|
+
});
|
|
2607
|
+
uptimeCmd
|
|
2608
|
+
.command("get-operator-uptime")
|
|
2609
|
+
.description("Get the recorded uptime for an operator at a specific epoch")
|
|
2610
|
+
.addArgument(argUptimeTrackerAddress)
|
|
2611
|
+
.addArgument(argOperatorAddress)
|
|
2612
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch number"))
|
|
2613
|
+
.asyncAction(async (config, uptimeTrackerAddress, operator, epoch) => {
|
|
2614
|
+
const uptimeTracker = await config.contracts.UptimeTracker(uptimeTrackerAddress);
|
|
2615
|
+
const uptime = await (0, uptime_1.getOperatorUptimeForEpoch)(uptimeTracker, operator, epoch);
|
|
2616
|
+
logger_1.logger.log(`Operator uptime for epoch ${epoch}: ${uptime.toString()} seconds`);
|
|
2617
|
+
});
|
|
2618
|
+
uptimeCmd
|
|
2619
|
+
.command("check-operator-uptime-set")
|
|
2620
|
+
.description("Check if uptime data is set for an operator at a specific epoch")
|
|
2621
|
+
.addArgument(argUptimeTrackerAddress)
|
|
2622
|
+
.addArgument(argOperatorAddress)
|
|
2623
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch number"))
|
|
2624
|
+
.asyncAction(async (config, uptimeTrackerAddress, operator, epoch) => {
|
|
2625
|
+
const uptimeTracker = await config.contracts.UptimeTracker(uptimeTrackerAddress);
|
|
2626
|
+
const isSet = await (0, uptime_1.isOperatorUptimeSetForEpoch)(uptimeTracker, operator, epoch);
|
|
2627
|
+
logger_1.logger.log(`Operator uptime is ${isSet ? 'set' : 'not set'} for epoch ${epoch}`);
|
|
2628
|
+
});
|
|
2629
|
+
uptimeCmd
|
|
2630
|
+
.command("uptime-sync")
|
|
2631
|
+
.description("Report uptime for all validators")
|
|
2632
|
+
.addArgument(argUptimeTrackerAddress)
|
|
2633
|
+
.addArgument(argMiddlewareAddress)
|
|
2634
|
+
.argument("rpcUrl", "RPC URL of the network")
|
|
2635
|
+
.addArgument((0, cliParser_1.ArgCB58)("blockchainId", "The Blockchain ID for which the uptime is being reported"))
|
|
2636
|
+
.addOption(new extra_typings_1.Option("--epoch <epoch>", "Epoch number to check (defaults to current epoch)").argParser(cliParser_1.ParserNumber))
|
|
2637
|
+
.asyncAction({ signer: true }, async (config, uptimeTrackerAddress, middlewareAddress, rpcUrl, blockchainId, options) => {
|
|
2638
|
+
const uptimeTracker = await config.contracts.UptimeTracker(uptimeTrackerAddress);
|
|
2639
|
+
const middlewareSvc = await config.contracts.L1Middleware(middlewareAddress);
|
|
2640
|
+
await (0, uptime_1.uptimeSync)(config.client, uptimeTracker, middlewareSvc, rpcUrl, blockchainId);
|
|
2641
|
+
});
|
|
2642
|
+
/* --------------------------------------------------
|
|
2643
|
+
* REWARDS COMMANDS
|
|
2644
|
+
* -------------------------------------------------- */
|
|
2645
|
+
const rewardsCmd = program
|
|
2646
|
+
.command("rewards")
|
|
2647
|
+
.description("Commands for managing rewards");
|
|
2648
|
+
rewardsCmd
|
|
2649
|
+
.command("distribute")
|
|
2650
|
+
.description("Distribute rewards for a specific epoch")
|
|
2651
|
+
.addArgument(argRewardsAddress)
|
|
2652
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch to distribute rewards for"))
|
|
2653
|
+
.addArgument((0, cliParser_1.ArgNumber)("batchSize", "Number of operators to process in this batch"))
|
|
2654
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, epoch, batchSize) => {
|
|
2655
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2656
|
+
const txHash = await (0, rewards_1.distributeRewards)(rewardsContract, epoch, batchSize);
|
|
2657
|
+
logger_1.logger.log(`Rewards distributed for epoch ${epoch}. tx hash: ${txHash}`);
|
|
2658
|
+
});
|
|
2659
|
+
rewardsCmd
|
|
2660
|
+
.command("claim")
|
|
2661
|
+
.description("Claim rewards for a staker in batch of 64 epochs")
|
|
2662
|
+
.addArgument(argRewardsAddress)
|
|
2663
|
+
.addOption(new extra_typings_1.Option("--recipient <recipient>", "Optional recipient address").argParser(cliParser_1.ParserAddress))
|
|
2664
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, options) => {
|
|
2665
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2666
|
+
const recipient = options.recipient ?? config.client.account.address;
|
|
2667
|
+
let hashs = [];
|
|
2668
|
+
for (const _ of Array.from({ length: await (0, rewards_1.getRewardsClaimsCount)(rewardsContract, config, 'Staker', config.client.account) })) {
|
|
2669
|
+
hashs.push(await (0, rewards_1.claimRewards)(rewardsContract, recipient));
|
|
2670
|
+
}
|
|
2671
|
+
if (hashs.length === 0) {
|
|
2672
|
+
logger_1.logger.log("No rewards to claim");
|
|
2673
|
+
return;
|
|
2674
|
+
}
|
|
2675
|
+
const logs = await Promise.all(hashs.map(hash => (0, transferUtils_1.getERC20Events)(hash, config)));
|
|
2676
|
+
logs.flat().forEach((log) => {
|
|
2677
|
+
if (log.eventName === "Transfer") {
|
|
2678
|
+
const { from, to, value } = log.args;
|
|
2679
|
+
logger_1.logger.log(`Rewards claimed: ${value.toString()} tokens transferred from ${from} to ${to}`);
|
|
2680
|
+
}
|
|
2681
|
+
});
|
|
2682
|
+
});
|
|
2683
|
+
rewardsCmd
|
|
2684
|
+
.command("claim-operator-fee")
|
|
2685
|
+
.description("Claim operator fees in batch of 64 epochs")
|
|
2686
|
+
.addArgument(argRewardsAddress)
|
|
2687
|
+
.addOption(new extra_typings_1.Option("--recipient <recipient>", "Optional recipient address").argParser(cliParser_1.ParserAddress))
|
|
2688
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, options) => {
|
|
2689
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2690
|
+
const recipient = options.recipient ?? config.client.account.address;
|
|
2691
|
+
let hashs = [];
|
|
2692
|
+
for (const _ of Array.from({ length: await (0, rewards_1.getRewardsClaimsCount)(rewardsContract, config, 'Operator', config.client.account) })) {
|
|
2693
|
+
hashs.push(await (0, rewards_1.claimOperatorFee)(rewardsContract, recipient));
|
|
2694
|
+
}
|
|
2695
|
+
if (hashs.length === 0) {
|
|
2696
|
+
logger_1.logger.log("No operator fees to claim");
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
const logs = await Promise.all(hashs.map(hash => (0, transferUtils_1.getERC20Events)(hash, config)));
|
|
2700
|
+
logs.flat().forEach((log) => {
|
|
2701
|
+
if (log.eventName === "Transfer") {
|
|
2702
|
+
const { from, to, value } = log.args;
|
|
2703
|
+
logger_1.logger.log(`Rewards claimed: ${value.toString()} tokens transferred from ${from} to ${to}`);
|
|
2704
|
+
}
|
|
2705
|
+
});
|
|
2706
|
+
});
|
|
2707
|
+
rewardsCmd
|
|
2708
|
+
.command("claim-curator-fee")
|
|
2709
|
+
.description("Claim all curator fees in batch of 64 epochs")
|
|
2710
|
+
.addArgument(argRewardsAddress)
|
|
2711
|
+
.addOption(new extra_typings_1.Option("--recipient <recipient>", "Optional recipient address").argParser(cliParser_1.ParserAddress))
|
|
2712
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, options) => {
|
|
2713
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2714
|
+
const recipient = options.recipient ?? config.client.account.address;
|
|
2715
|
+
let hashs = [];
|
|
2716
|
+
for (const _ of Array.from({ length: await (0, rewards_1.getRewardsClaimsCount)(rewardsContract, config, 'Curator', config.client.account) })) {
|
|
2717
|
+
hashs.push(await (0, rewards_1.claimCuratorFee)(rewardsContract, recipient));
|
|
2718
|
+
}
|
|
2719
|
+
if (hashs.length === 0) {
|
|
2720
|
+
logger_1.logger.log("No curator fees to claim");
|
|
2721
|
+
return;
|
|
2722
|
+
}
|
|
2723
|
+
const logs = await Promise.all(hashs.map(hash => (0, transferUtils_1.getERC20Events)(hash, config)));
|
|
2724
|
+
logs.flat().forEach((log) => {
|
|
2725
|
+
if (log.eventName === "Transfer") {
|
|
2726
|
+
const { from, to, value } = log.args;
|
|
2727
|
+
logger_1.logger.log(`Rewards claimed: ${value.toString()} tokens transferred from ${from} to ${to}`);
|
|
2728
|
+
}
|
|
2729
|
+
});
|
|
2730
|
+
});
|
|
2731
|
+
rewardsCmd
|
|
2732
|
+
.command("claim-protocol-fee")
|
|
2733
|
+
.description("Claim protocol fees (only for protocol owner)")
|
|
2734
|
+
.addArgument(argRewardsAddress)
|
|
2735
|
+
.addOption(new extra_typings_1.Option("--recipient <recipient>", "Optional recipient address").argParser(cliParser_1.ParserAddress))
|
|
2736
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, options) => {
|
|
2737
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2738
|
+
const recipient = options.recipient ?? config.client.account.address;
|
|
2739
|
+
const hash = await (0, rewards_1.claimProtocolFee)(rewardsContract, recipient);
|
|
2740
|
+
if (!hash) {
|
|
2741
|
+
logger_1.logger.log("No protocol fees to claim");
|
|
2742
|
+
return;
|
|
2743
|
+
}
|
|
2744
|
+
const logs = await (0, transferUtils_1.getERC20Events)(hash, config);
|
|
2745
|
+
logs.forEach((log) => {
|
|
2746
|
+
if (log.eventName === "Transfer") {
|
|
2747
|
+
const { from, to, value } = log.args;
|
|
2748
|
+
logger_1.logger.log(`Rewards claimed: ${value.toString()} tokens transferred from ${from} to ${to}`);
|
|
2749
|
+
}
|
|
2750
|
+
});
|
|
2751
|
+
});
|
|
2752
|
+
rewardsCmd
|
|
2753
|
+
.command("claim-undistributed")
|
|
2754
|
+
.description("Claim undistributed rewards (admin only)")
|
|
2755
|
+
.addArgument(argRewardsAddress)
|
|
2756
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch to claim undistributed rewards for"))
|
|
2757
|
+
.addOption(new extra_typings_1.Option("--recipient <recipient>", "Optional recipient address").argParser(cliParser_1.ParserAddress))
|
|
2758
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, epoch, options) => {
|
|
2759
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2760
|
+
const recipient = options.recipient ?? config.client.account.address;
|
|
2761
|
+
const hash = await (0, rewards_1.claimUndistributedRewards)(rewardsContract, epoch, recipient);
|
|
2762
|
+
if (!hash) {
|
|
2763
|
+
logger_1.logger.log("No undistributed rewards to claim");
|
|
2764
|
+
return;
|
|
2765
|
+
}
|
|
2766
|
+
const logs = await (0, transferUtils_1.getERC20Events)(hash, config);
|
|
2767
|
+
logs.forEach((log) => {
|
|
2768
|
+
if (log.eventName === "Transfer") {
|
|
2769
|
+
const { from, to, value } = log.args;
|
|
2770
|
+
logger_1.logger.log(`Rewards claimed: ${value.toString()} tokens transferred from ${from} to ${to}`);
|
|
2771
|
+
}
|
|
2772
|
+
});
|
|
2773
|
+
});
|
|
2774
|
+
rewardsCmd
|
|
2775
|
+
.command("set-amount")
|
|
2776
|
+
.description("Set rewards amount for epochs")
|
|
2777
|
+
.addArgument(argRewardsAddress)
|
|
2778
|
+
.addArgument((0, cliParser_1.ArgNumber)("startEpoch", "Starting epoch"))
|
|
2779
|
+
.addArgument((0, cliParser_1.ArgNumber)("numberOfEpochs", "Number of epochs"))
|
|
2780
|
+
.argument("rewardsAmount", "Amount of rewards in decimal format")
|
|
2781
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, startEpoch, numberOfEpochs, rewardsAmount) => {
|
|
2782
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2783
|
+
if (rewardsContract.name !== 'RewardsNativeToken') {
|
|
2784
|
+
throw new Error('Rewards contract is not a RewardsNativeToken');
|
|
2785
|
+
}
|
|
2786
|
+
const tokenAddress = await rewardsContract.read.rewardsToken();
|
|
2787
|
+
const token = await config.contracts.ERC20(tokenAddress);
|
|
2788
|
+
const decimals = await token.read.decimals();
|
|
2789
|
+
const rewardsAmountWei = (0, viem_1.parseUnits)(rewardsAmount, decimals);
|
|
2790
|
+
const amountToApprove = rewardsAmountWei * BigInt(numberOfEpochs);
|
|
2791
|
+
await token.safeWrite.approve([rewardsAddress, amountToApprove], {
|
|
2792
|
+
chain: null,
|
|
2793
|
+
account: config.client.account,
|
|
2794
|
+
});
|
|
2795
|
+
const txHash = await (0, rewards_1.setRewardsAmountForEpochs)(rewardsContract, startEpoch, numberOfEpochs, rewardsAmountWei);
|
|
2796
|
+
logger_1.logger.log(`setRewardsAmountForEpochs tx hash: ${txHash}`);
|
|
2797
|
+
});
|
|
2798
|
+
rewardsCmd
|
|
2799
|
+
.command("set-bips-collateral-class")
|
|
2800
|
+
.description("Set rewards bips for collateral class")
|
|
2801
|
+
.addArgument(argRewardsAddress)
|
|
2802
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClass", "Collateral class ID"))
|
|
2803
|
+
.addArgument((0, cliParser_1.ArgNumber)("bips", "Bips in basis points (100 = 1%)"))
|
|
2804
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, collateralClass, bips) => {
|
|
2805
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2806
|
+
const hash = await (0, rewards_1.setRewardsBipsForCollateralClass)(rewardsContract, collateralClass, bips);
|
|
2807
|
+
logger_1.logger.log(`setRewardsBipsForCollateralClass tx hash: ${hash}`);
|
|
2808
|
+
});
|
|
2809
|
+
rewardsCmd
|
|
2810
|
+
.command("set-min-uptime")
|
|
2811
|
+
.description("Set minimum required uptime for rewards eligibility")
|
|
2812
|
+
.addArgument(argRewardsAddress)
|
|
2813
|
+
.addArgument((0, cliParser_1.ArgBigInt)("minUptime", "Minimum uptime in seconds"))
|
|
2814
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, minUptime) => {
|
|
2815
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2816
|
+
const hash = await (0, rewards_1.setMinRequiredUptime)(rewardsContract, minUptime);
|
|
2817
|
+
logger_1.logger.log(`setMinRequiredUptime tx hash: ${hash}`);
|
|
2818
|
+
});
|
|
2819
|
+
rewardsCmd
|
|
2820
|
+
.command("set-protocol-owner")
|
|
2821
|
+
.description("Set protocol owner (DEFAULT_ADMIN_ROLE only)")
|
|
2822
|
+
.addArgument(argRewardsAddress)
|
|
2823
|
+
.addArgument((0, cliParser_1.ArgAddress)("newOwner", "New protocol owner address"))
|
|
2824
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, newOwner) => {
|
|
2825
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2826
|
+
const hash = await (0, rewards_1.setProtocolOwner)(rewardsContract, newOwner);
|
|
2827
|
+
logger_1.logger.log(`setProtocolOwner tx hash: ${hash}`);
|
|
2828
|
+
});
|
|
2829
|
+
rewardsCmd
|
|
2830
|
+
.command("update-protocol-fee")
|
|
2831
|
+
.description("Update protocol fee")
|
|
2832
|
+
.addArgument(argRewardsAddress)
|
|
2833
|
+
.addArgument((0, cliParser_1.ArgNumber)("newFee", "New fee in basis points (100 = 1%)"))
|
|
2834
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, newFee) => {
|
|
2835
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2836
|
+
const hash = await (0, rewards_1.updateProtocolFee)(rewardsContract, newFee);
|
|
2837
|
+
logger_1.logger.log(`updateProtocolFee tx hash: ${hash}`);
|
|
2838
|
+
});
|
|
2839
|
+
rewardsCmd
|
|
2840
|
+
.command("update-operator-fee")
|
|
2841
|
+
.description("Update operator fee")
|
|
2842
|
+
.addArgument(argRewardsAddress)
|
|
2843
|
+
.addArgument((0, cliParser_1.ArgNumber)("newFee", "New fee in basis points (100 = 1%)"))
|
|
2844
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, newFee) => {
|
|
2845
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2846
|
+
const hash = await (0, rewards_1.updateOperatorFee)(rewardsContract, newFee);
|
|
2847
|
+
logger_1.logger.log(`updateOperatorFee tx hash: ${hash}`);
|
|
2848
|
+
});
|
|
2849
|
+
rewardsCmd
|
|
2850
|
+
.command("update-curator-fee")
|
|
2851
|
+
.description("Update curator fee")
|
|
2852
|
+
.addArgument(argRewardsAddress)
|
|
2853
|
+
.addArgument((0, cliParser_1.ArgNumber)("newFee", "New fee in basis points (100 = 1%)"))
|
|
2854
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, newFee) => {
|
|
2855
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2856
|
+
const hash = await (0, rewards_1.updateCuratorFee)(rewardsContract, newFee);
|
|
2857
|
+
logger_1.logger.log(`updateCuratorFee tx hash: ${hash}`);
|
|
2858
|
+
});
|
|
2859
|
+
rewardsCmd
|
|
2860
|
+
.command("update-all-fees")
|
|
2861
|
+
.description("Update all fees at once (protocol, operator, curator)")
|
|
2862
|
+
.addArgument(argRewardsAddress)
|
|
2863
|
+
.addArgument((0, cliParser_1.ArgNumber)("protocolFee", "New protocol fee in basis points (100 = 1%)"))
|
|
2864
|
+
.addArgument((0, cliParser_1.ArgNumber)("operatorFee", "New operator fee in basis points (100 = 1%)"))
|
|
2865
|
+
.addArgument((0, cliParser_1.ArgNumber)("curatorFee", "New curator fee in basis points (100 = 1%)"))
|
|
2866
|
+
.asyncAction({ signer: true }, async (config, rewardsAddress, protocolFee, operatorFee, curatorFee) => {
|
|
2867
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2868
|
+
const hash = await (0, rewards_1.updateAllFees)(rewardsContract, protocolFee, operatorFee, curatorFee);
|
|
2869
|
+
logger_1.logger.log(`updateAllFees tx hash: ${hash}`);
|
|
2870
|
+
});
|
|
2871
|
+
rewardsCmd
|
|
2872
|
+
.command("get-epoch-rewards")
|
|
2873
|
+
.description("Get rewards amount for a specific epoch")
|
|
2874
|
+
.addArgument(argRewardsAddress)
|
|
2875
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch to query"))
|
|
2876
|
+
.asyncAction(async (config, rewardsAddress, epoch) => {
|
|
2877
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2878
|
+
await (0, rewards_1.getEpochRewards)(rewardsContract, epoch);
|
|
2879
|
+
});
|
|
2880
|
+
rewardsCmd
|
|
2881
|
+
.command("get-operator-shares")
|
|
2882
|
+
.description("Get operator shares for a specific epoch")
|
|
2883
|
+
.addArgument(argRewardsAddress)
|
|
2884
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch to query"))
|
|
2885
|
+
.addArgument(argOperatorAddress)
|
|
2886
|
+
.asyncAction(async (config, rewardsAddress, epoch, operator) => {
|
|
2887
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2888
|
+
await (0, rewards_1.getOperatorShares)(rewardsContract, epoch, operator);
|
|
2889
|
+
});
|
|
2890
|
+
rewardsCmd
|
|
2891
|
+
.command("get-vault-shares")
|
|
2892
|
+
.description("Get vault shares for a specific epoch")
|
|
2893
|
+
.addArgument(argRewardsAddress)
|
|
2894
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch to query"))
|
|
2895
|
+
.addArgument(argVaultAddress)
|
|
2896
|
+
.asyncAction(async (config, rewardsAddress, epoch, vault) => {
|
|
2897
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2898
|
+
await (0, rewards_1.getVaultShares)(rewardsContract, epoch, vault);
|
|
2899
|
+
});
|
|
2900
|
+
rewardsCmd
|
|
2901
|
+
.command("get-curator-shares")
|
|
2902
|
+
.description("Get curator shares for a specific epoch")
|
|
2903
|
+
.addArgument(argRewardsAddress)
|
|
2904
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch to query"))
|
|
2905
|
+
.addArgument((0, cliParser_1.ArgAddress)("curator", "Curator address"))
|
|
2906
|
+
.asyncAction(async (config, rewardsAddress, epoch, curator) => {
|
|
2907
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2908
|
+
await (0, rewards_1.getCuratorShares)(rewardsContract, epoch, curator);
|
|
2909
|
+
});
|
|
2910
|
+
rewardsCmd
|
|
2911
|
+
.command("get-protocol-rewards")
|
|
2912
|
+
.description("Get protocol rewards for a token")
|
|
2913
|
+
.addArgument(argRewardsAddress)
|
|
2914
|
+
.addArgument((0, cliParser_1.ArgAddress)("token", "Token address"))
|
|
2915
|
+
.asyncAction(async (config, rewardsAddress, token) => {
|
|
2916
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2917
|
+
await (0, rewards_1.getProtocolRewards)(rewardsContract);
|
|
2918
|
+
});
|
|
2919
|
+
rewardsCmd
|
|
2920
|
+
.command("get-distribution-batch")
|
|
2921
|
+
.description("Get distribution batch status for an epoch")
|
|
2922
|
+
.addArgument(argRewardsAddress)
|
|
2923
|
+
.addArgument((0, cliParser_1.ArgNumber)("epoch", "Epoch to query"))
|
|
2924
|
+
.asyncAction(async (config, rewardsAddress, epoch) => {
|
|
2925
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2926
|
+
await (0, rewards_1.getDistributionBatch)(rewardsContract, epoch);
|
|
2927
|
+
});
|
|
2928
|
+
rewardsCmd
|
|
2929
|
+
.command("get-fees-config")
|
|
2930
|
+
.description("Get current fees configuration")
|
|
2931
|
+
.addArgument(argRewardsAddress)
|
|
2932
|
+
.asyncAction(async (config, rewardsAddress) => {
|
|
2933
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2934
|
+
await (0, rewards_1.getFeesConfiguration)(rewardsContract);
|
|
2935
|
+
});
|
|
2936
|
+
rewardsCmd
|
|
2937
|
+
.command("get-bips-collateral-class")
|
|
2938
|
+
.description("Get rewards bips for collateral class")
|
|
2939
|
+
.addArgument(argRewardsAddress)
|
|
2940
|
+
.addArgument((0, cliParser_1.ArgBigInt)("collateralClass", "Collateral class ID"))
|
|
2941
|
+
.asyncAction(async (config, rewardsAddress, collateralClass) => {
|
|
2942
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2943
|
+
await (0, rewards_1.getRewardsBipsForCollateralClass)(rewardsContract, collateralClass);
|
|
2944
|
+
});
|
|
2945
|
+
rewardsCmd
|
|
2946
|
+
.command("get-min-uptime")
|
|
2947
|
+
.description("Get minimum required uptime for rewards eligibility")
|
|
2948
|
+
.addArgument(argRewardsAddress)
|
|
2949
|
+
.asyncAction(async (config, rewardsAddress) => {
|
|
2950
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2951
|
+
await (0, rewards_1.getMinRequiredUptime)(rewardsContract);
|
|
2952
|
+
});
|
|
2953
|
+
rewardsCmd
|
|
2954
|
+
.command("get-last-claimed-staker")
|
|
2955
|
+
.description("Get last claimed epoch for a staker")
|
|
2956
|
+
.addArgument(argRewardsAddress)
|
|
2957
|
+
.addArgument((0, cliParser_1.ArgAddress)("staker", "Staker address"))
|
|
2958
|
+
.addArgument(argRewardTokenAddress)
|
|
2959
|
+
.asyncAction(async (config, rewardsAddress, staker, rewardToken) => {
|
|
2960
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2961
|
+
await (0, rewards_1.getLastEpochClaimedStaker)(rewardsContract, staker);
|
|
2962
|
+
});
|
|
2963
|
+
rewardsCmd
|
|
2964
|
+
.command("get-last-claimed-operator")
|
|
2965
|
+
.description("Get last claimed epoch for an operator")
|
|
2966
|
+
.addArgument(argRewardsAddress)
|
|
2967
|
+
.addArgument(argOperatorAddress)
|
|
2968
|
+
.addArgument(argRewardTokenAddress)
|
|
2969
|
+
.asyncAction(async (config, rewardsAddress, operator, rewardToken) => {
|
|
2970
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2971
|
+
await (0, rewards_1.getLastEpochClaimedOperator)(rewardsContract, operator);
|
|
2972
|
+
});
|
|
2973
|
+
rewardsCmd
|
|
2974
|
+
.command("get-last-claimed-curator")
|
|
2975
|
+
.description("Get last claimed epoch for a curator")
|
|
2976
|
+
.addArgument(argRewardsAddress)
|
|
2977
|
+
.addArgument((0, cliParser_1.ArgAddress)("curator", "Curator address"))
|
|
2978
|
+
.addArgument(argRewardTokenAddress)
|
|
2979
|
+
.asyncAction(async (config, rewardsAddress, curator, rewardToken) => {
|
|
2980
|
+
const rewardsContract = await config.contracts.RewardsNativeToken(rewardsAddress);
|
|
2981
|
+
await (0, rewards_1.getLastEpochClaimedCurator)(rewardsContract, curator);
|
|
2982
|
+
});
|
|
2983
|
+
(0, keyStore_1.buildCommands)(program
|
|
2984
|
+
.command("key")
|
|
2985
|
+
.description("Manage the cli keystore (advanced users can use pass directly)"));
|
|
2986
|
+
function printIndentedHelp(cmd, indent = 0) {
|
|
2987
|
+
const pad = " ".repeat(indent);
|
|
2988
|
+
let newLineToLog = false;
|
|
2989
|
+
let hasSubCmds = false;
|
|
2990
|
+
cmd.commands.forEach((sub) => {
|
|
2991
|
+
const args = sub.args?.map(a => `<${a}>`).join(" ");
|
|
2992
|
+
const desc = sub.description() ? sub.description() : "";
|
|
2993
|
+
console.log(`${newLineToLog ? "\n" : ""}${pad}${sub.name()} ${args.padEnd(31 - sub.name().length)} ${desc}`);
|
|
2994
|
+
if (sub.commands.length > 0) {
|
|
2995
|
+
newLineToLog = printIndentedHelp(sub, indent + 2);
|
|
2996
|
+
hasSubCmds = true;
|
|
2997
|
+
}
|
|
2998
|
+
});
|
|
2999
|
+
if (!hasSubCmds || hasSubCmds && !newLineToLog)
|
|
3000
|
+
newLineToLog = true;
|
|
3001
|
+
return newLineToLog;
|
|
3002
|
+
}
|
|
3003
|
+
const accessControlCmd = program
|
|
3004
|
+
.command("access-control")
|
|
3005
|
+
.description("Commands for managing access control");
|
|
3006
|
+
accessControlCmd
|
|
3007
|
+
.command("grant-role")
|
|
3008
|
+
.description("Grant a role to an account")
|
|
3009
|
+
.addArgument(argAccessControlAddress)
|
|
3010
|
+
.argument("role", "Role hash or name case unsensitive without '()'")
|
|
3011
|
+
.addArgument((0, cliParser_1.ArgAddress)("account", "Account address to grant the role to"))
|
|
3012
|
+
.asyncAction({ signer: true }, async (config, contractAddress, role, account) => {
|
|
3013
|
+
const accessControl = await config.contracts.AccessControl(contractAddress);
|
|
3014
|
+
if (!await (0, accessControl_1.isAccessControl)(accessControl)) {
|
|
3015
|
+
throw new Error("Contract does not implement AccessControl interface");
|
|
3016
|
+
}
|
|
3017
|
+
const txHash = await (0, accessControl_1.grantRole)(accessControl, role, account);
|
|
3018
|
+
logger_1.logger.log(`Role granted. tx hash: ${txHash}`);
|
|
3019
|
+
});
|
|
3020
|
+
accessControlCmd
|
|
3021
|
+
.command("revoke-role")
|
|
3022
|
+
.description("Revoke a role from an account")
|
|
3023
|
+
.addArgument(argAccessControlAddress)
|
|
3024
|
+
.argument("role", "Role hash or name case unsensitive")
|
|
3025
|
+
.addArgument((0, cliParser_1.ArgAddress)("account", "Account address to revoke the role from"))
|
|
3026
|
+
.asyncAction({ signer: true }, async (config, contractAddress, role, account) => {
|
|
3027
|
+
const accessControl = await config.contracts.AccessControl(contractAddress);
|
|
3028
|
+
if (!await (0, accessControl_1.isAccessControl)(accessControl)) {
|
|
3029
|
+
throw new Error("Contract does not implement AccessControl interface");
|
|
3030
|
+
}
|
|
3031
|
+
const txHash = await (0, accessControl_1.revokeRole)(accessControl, role, account);
|
|
3032
|
+
logger_1.logger.log(`Role revoked. tx hash: ${txHash}`);
|
|
3033
|
+
});
|
|
3034
|
+
accessControlCmd
|
|
3035
|
+
.command("has-role")
|
|
3036
|
+
.description("Check if an account has a specific role")
|
|
3037
|
+
.addArgument(argAccessControlAddress)
|
|
3038
|
+
.argument("role", "Role hash or name case unsensitive")
|
|
3039
|
+
.addArgument((0, cliParser_1.ArgAddress)("account", "Account address to check"))
|
|
3040
|
+
.asyncAction(async (config, contractAddress, role, account) => {
|
|
3041
|
+
const accessControl = await config.contracts.AccessControl(contractAddress);
|
|
3042
|
+
if (!await (0, accessControl_1.isAccessControl)(accessControl)) {
|
|
3043
|
+
throw new Error("Contract does not implement AccessControl interface");
|
|
3044
|
+
}
|
|
3045
|
+
const hasRoleResult = await (0, accessControl_1.hasRole)(accessControl, role, account);
|
|
3046
|
+
logger_1.logger.log(`Account ${account} has role ${role}: ${hasRoleResult}`);
|
|
3047
|
+
});
|
|
3048
|
+
accessControlCmd
|
|
3049
|
+
.command("get-role-admin")
|
|
3050
|
+
.description("Get the admin role that controls a specific role")
|
|
3051
|
+
.addArgument(argAccessControlAddress)
|
|
3052
|
+
.argument("role", "Role hash or name case unsensitive")
|
|
3053
|
+
.asyncAction(async (config, contractAddress, role) => {
|
|
3054
|
+
const accessControl = await config.contracts.AccessControl(contractAddress);
|
|
3055
|
+
if (!await (0, accessControl_1.isAccessControl)(accessControl)) {
|
|
3056
|
+
throw new Error("Contract does not implement AccessControl interface");
|
|
3057
|
+
}
|
|
3058
|
+
const adminRole = await (0, accessControl_1.getRoleAdmin)(accessControl, role);
|
|
3059
|
+
logger_1.logger.log(`Admin role for role ${role} is: ${adminRole}`);
|
|
3060
|
+
});
|
|
3061
|
+
const ledgerCmd = program
|
|
3062
|
+
.command("ledger")
|
|
3063
|
+
.description("Commands for ledger");
|
|
3064
|
+
ledgerCmd
|
|
3065
|
+
.command("addresses")
|
|
3066
|
+
.description("Get ledger addresses")
|
|
3067
|
+
.asyncAction(async () => {
|
|
3068
|
+
const opts = program.opts();
|
|
3069
|
+
const client = await (0, client_1.generateClient)(opts.network, 'ledger');
|
|
3070
|
+
logger_1.logger.log(client.addresses);
|
|
3071
|
+
});
|
|
3072
|
+
ledgerCmd
|
|
3073
|
+
.command('fix-usb-rules')
|
|
3074
|
+
.description('Fix ledger usb rules on linux')
|
|
3075
|
+
.asyncAction(async (config) => {
|
|
3076
|
+
logger_1.logger.log("Fixing ledger usb rules...");
|
|
3077
|
+
try {
|
|
3078
|
+
// Execute system command to fix ledger usb rules (https://github.com/LedgerHQ/ledger-live-desktop/issues/2873#issuecomment-674844905)
|
|
3079
|
+
const result = (0, child_process_1.execSync)('wget -q -O - https://raw.githubusercontent.com/LedgerHQ/udev-rules/master/add_udev_rules.sh | sudo bash');
|
|
3080
|
+
logger_1.logger.log(result.toString());
|
|
3081
|
+
}
|
|
3082
|
+
catch (error) {
|
|
3083
|
+
logger_1.logger.error("Failed to fix ledger usb rules");
|
|
3084
|
+
logger_1.logger.error(error);
|
|
3085
|
+
}
|
|
3086
|
+
});
|
|
3087
|
+
const safeCmd = program
|
|
3088
|
+
.command("safe")
|
|
3089
|
+
.description("Commands for safe");
|
|
3090
|
+
safeCmd
|
|
3091
|
+
.command("nonce")
|
|
3092
|
+
.description("Get safe nonce")
|
|
3093
|
+
.addArgument((0, cliParser_1.ArgAddress)("safeAddress", "Address of the safe"))
|
|
3094
|
+
.asyncAction(async (config, safeAddress) => {
|
|
3095
|
+
logger_1.logger.log((await config.client.safe.getNonce()).toString());
|
|
3096
|
+
});
|
|
3097
|
+
safeCmd
|
|
3098
|
+
.command("get-role")
|
|
3099
|
+
.description("Get user role in the safe")
|
|
3100
|
+
.addOption((0, cliParser_1.OptAddress)("--account <account>", "Account address to check"))
|
|
3101
|
+
.asyncAction({ signer: true }, async (config, options) => {
|
|
3102
|
+
const addressToCheck = options.account || config.client.account.address;
|
|
3103
|
+
const owners = await config.client.safe.getOwners();
|
|
3104
|
+
const delegates = await config.client.safe.apiKit.getSafeDelegates({ safeAddress: program.opts().safe });
|
|
3105
|
+
if (owners.find(owner => owner.toLowerCase() === addressToCheck.toLowerCase())) {
|
|
3106
|
+
logger_1.logger.log("Owner");
|
|
3107
|
+
}
|
|
3108
|
+
else if (delegates.results.find(delegate => delegate.delegate.toLowerCase() === addressToCheck.toLowerCase())) {
|
|
3109
|
+
logger_1.logger.log("Delegate");
|
|
3110
|
+
}
|
|
3111
|
+
else {
|
|
3112
|
+
logger_1.logger.log("No role");
|
|
3113
|
+
}
|
|
3114
|
+
});
|
|
3115
|
+
program.
|
|
3116
|
+
command('create-network', { hidden: true })
|
|
3117
|
+
.description('Create a new network')
|
|
3118
|
+
.argument('chainName', 'Name of the chain')
|
|
3119
|
+
.argument('genesisFile', 'Path to the genesis file')
|
|
3120
|
+
.option('--vm-id <vmId>', 'subnet-evm custom id')
|
|
3121
|
+
.asyncAction({ signer: true }, async (config, chainName, genesisFile, options) => {
|
|
3122
|
+
const subnetId = await (0, pChainUtils_1.createSubnet)({ client: config.client });
|
|
3123
|
+
const genesisData = (0, fs_1.readFileSync)(genesisFile).toString('utf-8');
|
|
3124
|
+
const chainId = await (0, pChainUtils_1.createChain)({
|
|
3125
|
+
client: config.client,
|
|
3126
|
+
chainName,
|
|
3127
|
+
subnetId,
|
|
3128
|
+
genesisData,
|
|
3129
|
+
SubnetEVMId: options.vmId
|
|
3130
|
+
});
|
|
3131
|
+
logger_1.logger.log(`Network created:`);
|
|
3132
|
+
logger_1.logger.log(` Chain ID: ${chainId}`);
|
|
3133
|
+
logger_1.logger.log(` Subnet ID: ${subnetId}`);
|
|
3134
|
+
logger_1.logger.addData('network', { chainId, subnetId });
|
|
3135
|
+
});
|
|
3136
|
+
program
|
|
3137
|
+
.command('subnet-to-l1', { hidden: true })
|
|
3138
|
+
.description('Convert a subnet to L1')
|
|
3139
|
+
.addArgument((0, cliParser_1.ArgCB58)('subnetId', 'Subnet ID of the subnet'))
|
|
3140
|
+
.addArgument((0, cliParser_1.ArgCB58)('chainId', 'Chain ID of the subnet'))
|
|
3141
|
+
.addArgument((0, cliParser_1.ArgAddress)('validatorManagerAddress', 'Validator manager of the subnet'))
|
|
3142
|
+
.addArgument((0, cliParser_1.ArgCB58)('vmcChainId', 'Validator Manager Contract Chain ID'))
|
|
3143
|
+
.addOption(new extra_typings_1.Option('--validatorConfig <validatorConfig>', 'Validator config file path (json)').default([]).argParser((0, cliParser_1.collectMultiple)(String)).makeOptionMandatory())
|
|
3144
|
+
.addOption((0, cliParser_1.OptHex)('--convertTx <convertTx>', 'Existing convert transaction hash to reuse'))
|
|
3145
|
+
.addOption(new extra_typings_1.Option('--init-vmc', 'Initialize the VMC before conversion'))
|
|
3146
|
+
.asyncAction({ signer: true }, async (config, subnetId, chainId, validatorManagerAddress, vmcChainId, options) => {
|
|
3147
|
+
// const validatorManager = await config.contracts.ValidatorManager(validatorManagerAddress)
|
|
3148
|
+
await (0, pChainUtils_1.convertSubnetToL1)({ client: config.client, subnetId, chainId, validatorManager: validatorManagerAddress, validatorManagerBlockchainID: vmcChainId, validators: options.validatorConfig.map(v => JSON.parse((0, fs_1.readFileSync)(v).toString('utf-8'))), convertTx: options.convertTx, init: options.initVmc });
|
|
3149
|
+
});
|
|
3150
|
+
program
|
|
3151
|
+
.command("help-all")
|
|
3152
|
+
.description("Display help for all commands and sub-commands")
|
|
3153
|
+
.action(() => {
|
|
3154
|
+
console.log(`Suzaku CLI - version ${program.version()}`);
|
|
3155
|
+
console.log(program.description());
|
|
3156
|
+
console.log("Commands:\n");
|
|
3157
|
+
printIndentedHelp(program);
|
|
3158
|
+
});
|
|
3159
|
+
program
|
|
3160
|
+
.command("completion install")
|
|
3161
|
+
.description("Install autocompletion for Bash/Zsh")
|
|
3162
|
+
.action(() => (0, autoCompletion_1.installCompletion)(program));
|
|
3163
|
+
program
|
|
3164
|
+
.command("__complete")
|
|
3165
|
+
.description("internal completion helper")
|
|
3166
|
+
.option("--line <line>")
|
|
3167
|
+
.action(({ line }) => {
|
|
3168
|
+
line = line || "";
|
|
3169
|
+
const parts = line.trim().split(/\s+/).slice(1);
|
|
3170
|
+
let node = program;
|
|
3171
|
+
for (const part of parts) {
|
|
3172
|
+
const found = node.commands.find(c => c.name() === part);
|
|
3173
|
+
if (!found)
|
|
3174
|
+
break;
|
|
3175
|
+
node = found;
|
|
3176
|
+
}
|
|
3177
|
+
const suggestions = node.commands.map(c => c.name());
|
|
3178
|
+
console.log(suggestions.join(" "));
|
|
3179
|
+
});
|
|
3180
|
+
program.parse(process.argv);
|
|
3181
|
+
}
|
|
3182
|
+
main();
|
|
3183
|
+
//# sourceMappingURL=cli.js.map
|