UNPKG

@everstake/wallet-sdk-ethereum

Version:
1,729 lines (1,720 loc) 65.7 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { ETH_GAS_RESERVE: () => ETH_GAS_RESERVE, ETH_MIN_AMOUNT: () => ETH_MIN_AMOUNT, ETH_NETWORK_ADDRESSES: () => ETH_NETWORK_ADDRESSES, Ethereum: () => Ethereum, MULTICALL_CONTRACT_ADDRESS: () => MULTICALL_CONTRACT_ADDRESS, UINT16_MAX: () => UINT16_MAX, ValidatorStatus: () => ValidatorStatus }); module.exports = __toCommonJS(index_exports); // src/ethereum.ts var import_web3 = __toESM(require("web3")); var import_bignumber2 = __toESM(require("bignumber.js")); var import_ethereum_multicall = require("ethereum-multicall"); var import_web32 = require("web3"); // src/constants/index.ts var import_bignumber = __toESM(require("bignumber.js")); var ETH_NETWORK_ADDRESSES = { mainnet: { addressContractAccounting: "0x7a7f0b3c23C23a31cFcb0c44709be70d4D545c6e", addressContractPool: "0xD523794C879D9eC028960a231F866758e405bE34", addressContractWithdrawTreasury: "0x19449f0f696703Aa3b1485DfA2d855F33659397a", rpcUrl: "https://mainnet.infura.io/v3/f583d4f04d384b9e8c59a7ff1c9f68f1" }, holesky: { addressContractAccounting: "0x624087DD1904ab122A32878Ce9e933C7071F53B9", addressContractPool: "0xAFA848357154a6a624686b348303EF9a13F63264", addressContractWithdrawTreasury: "0x66cb3AeD024740164EBcF04e292dB09b5B63A2e1", rpcUrl: "https://ethereum-holesky.publicnode.com" }, hoodi: { addressContractAccounting: "0x6Cf2F03804b171ef9CAFC71e302CA0e08A3FDC28", addressContractPool: "0x7967AcFc9EB46cA2d20076B61B05e224F2d0B8b3", addressContractWithdrawTreasury: "0xCDd543223b6ef6CE26E7f80F7837c5C1A88aF683", rpcUrl: "https://ethereum-hoodi-rpc.publicnode.com" } }; var ETH_GAS_RESERVE = new import_bignumber.default(22e4); var UINT16_MAX = 65535 | 0; var ETH_MIN_AMOUNT = new import_bignumber.default("100000000000000000"); var MULTICALL_CONTRACT_ADDRESS = "0xca11bde05977b3631167028862be2a173976ca11"; // src/abi.ts var ABI_CONTRACT_ACCOUNTING = [ { inputs: [{ internalType: "string", name: "field", type: "string" }], name: "InvalidParam", type: "error" }, { inputs: [{ internalType: "string", name: "field", type: "string" }], name: "InvalidValue", type: "error" }, { inputs: [{ internalType: "string", name: "field", type: "string" }], name: "ZeroValue", type: "error" }, { anonymous: false, inputs: [ { indexed: false, internalType: "uint256", name: "round", type: "uint256" } ], name: "ActivateRound", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "staker", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "AddWithdrawRequest", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "Autocompound", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "int256", name: "", type: "int256" } ], name: "ChangeExpectValidatorsToStop", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "ClaimPoolFee", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "staker", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "ClaimWithdrawRequest", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "staker", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "DepositPending", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "uint256", name: "newFee", type: "uint256" } ], name: "FeeUpdated", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "oldGovernor", type: "address" }, { indexed: false, internalType: "address", name: "newGovernor", type: "address" } ], name: "GovernorChanged", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "uint8", name: "version", type: "uint8" } ], name: "Initialized", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "staker", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "InterchangeDeposit", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "staker", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "InterchangeWithdraw", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "previousOwner", type: "address" }, { indexed: true, internalType: "address", name: "newOwner", type: "address" } ], name: "OwnershipTransferred", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "superAdmin", type: "address" } ], name: "SetSuperAdmin", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "uint256", name: "rewarderBalance", type: "uint256" }, { indexed: false, internalType: "uint256", name: "reward", type: "uint256" }, { indexed: false, internalType: "uint256", name: "fee", type: "uint256" } ], name: "Update", type: "event" }, { inputs: [], name: "BEACON_AMOUNT", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [], name: "FEE_DENOMINATOR", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [], name: "governor", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", type: "function" }, { inputs: [], name: "owner", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", type: "function" }, { inputs: [], name: "renounceOwnership", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [{ internalType: "address", name: "value", type: "address" }], name: "setSuperAdmin", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "superAdmin", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "address", name: "newOwner", type: "address" }], name: "transferOwnership", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "uint256", name: "poolFee", type: "uint256" }, { internalType: "address", name: "rewardsTreasury", type: "address" }, { internalType: "address", name: "withdrawTreasury", type: "address" }, { internalType: "address", name: "accountingGovernor", type: "address" } ], name: "initialize", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "account", type: "address" }, { internalType: "uint256", name: "depositToPendingValue", type: "uint256" } ], name: "deposit", outputs: [ { internalType: "uint256", name: "interchangedAmount", type: "uint256" }, { internalType: "uint256", name: "activatedSlots", type: "uint256" } ], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "balance", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [], name: "pendingDepositedBalance", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [], name: "pendingBalance", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "address", name: "account", type: "address" }], name: "autocompoundBalanceOf", outputs: [ { internalType: "uint256", name: "autocompoundBalance", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "address", name: "account", type: "address" }], name: "depositedBalanceOf", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "address", name: "account", type: "address" }], name: "pendingDepositedBalanceOf", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "address", name: "account", type: "address" }], name: "pendingBalanceOf", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "address", name: "account", type: "address" }, { internalType: "uint256", name: "amount", type: "uint256" } ], name: "withdrawPending", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "staker", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" } ], name: "withdraw", outputs: [ { internalType: "uint256", name: "withdrawFromPendingAmount", type: "uint256" } ], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "claimPoolFee", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "getPoolFee", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [], name: "feeBalance", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [], name: "update", outputs: [{ internalType: "bool", name: "", type: "bool" }], stateMutability: "nonpayable", type: "function" }, { inputs: [{ internalType: "uint256", name: "feeValue", type: "uint256" }], name: "setFee", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "autocompound", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "pendingRestakedRewards", outputs: [{ internalType: "uint256", name: "amount", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "address", name: "account", type: "address" }], name: "pendingRestakedRewardOf", outputs: [{ internalType: "uint256", name: "amount", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "address", name: "account", type: "address" }], name: "restakedRewardOf", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [], name: "withdrawRequestQueueParams", outputs: [ { internalType: "uint256", name: "", type: "uint256" }, { internalType: "uint256", name: "", type: "uint256" }, { internalType: "uint256", name: "", type: "uint256" }, { internalType: "uint256", name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "address", name: "staker", type: "address" }], name: "withdrawRequest", outputs: [ { internalType: "uint256", name: "", type: "uint256" }, { internalType: "uint256", name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [], name: "claimWithdrawRequest", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "readyforAutocompoundRewardsAmount", outputs: [ { internalType: "uint256", name: "unclaimedReward", type: "uint256" } ], stateMutability: "view", type: "function" }, { inputs: [], name: "closeValidatorsStat", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "uint256", name: "stakeAmount", type: "uint256" }], name: "setMinRestakeAmount", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "uint256", name: "activatedValidatorNum", type: "uint256" } ], name: "activateValidators", outputs: [], stateMutability: "nonpayable", type: "function" } ]; var ABI_CONTRACT_POOL = [ { inputs: [], stateMutability: "nonpayable", type: "constructor" }, { inputs: [{ internalType: "string", name: "field", type: "string" }], name: "InvalidAmount", type: "error" }, { inputs: [{ internalType: "string", name: "field", type: "string" }], name: "InvalidParam", type: "error" }, { inputs: [{ internalType: "string", name: "field", type: "string" }], name: "InvalidValue", type: "error" }, { inputs: [{ internalType: "string", name: "field", type: "string" }], name: "Paused", type: "error" }, { inputs: [{ internalType: "string", name: "field", type: "string" }], name: "ZeroValue", type: "error" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "oldGovernor", type: "address" }, { indexed: false, internalType: "address", name: "newGovernor", type: "address" } ], name: "GovernorChanged", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "uint8", name: "version", type: "uint8" } ], name: "Initialized", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "previousOwner", type: "address" }, { indexed: true, internalType: "address", name: "newOwner", type: "address" } ], name: "OwnershipTransferStarted", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "previousOwner", type: "address" }, { indexed: true, internalType: "address", name: "newOwner", type: "address" } ], name: "OwnershipTransferred", type: "event" }, { anonymous: false, inputs: [{ indexed: false, internalType: "bool", name: "", type: "bool" }], name: "PauseStaking", type: "event" }, { anonymous: false, inputs: [{ indexed: false, internalType: "bool", name: "", type: "bool" }], name: "PauseWithdraw", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "bytes", name: "oldPendingValidatorPubKey", type: "bytes" }, { indexed: false, internalType: "bytes", name: "newPendingValidatorPubKey", type: "bytes" } ], name: "PendingValidatorReplaced", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "uint256", name: "", type: "uint256" } ], name: "Restake", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "SetMinStakeAmount", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "superAdmin", type: "address" } ], name: "SetSuperAdmin", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "staker", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "StakeActivated", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "staker", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" }, { indexed: false, internalType: "uint64", name: "source", type: "uint64" } ], name: "StakeAdded", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "address", name: "staker", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "StakeCanceled", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "bytes", name: "validator", type: "bytes" } ], name: "StakeDeposited", type: "event" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "staker", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" }, { indexed: false, internalType: "uint64", name: "source", type: "uint64" } ], name: "Unstake", type: "event" }, { anonymous: false, inputs: [ { indexed: false, internalType: "bytes", name: "validator", type: "bytes" } ], name: "ValidatorMarkedAsExited", type: "event" }, { inputs: [], name: "BEACON_AMOUNT", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [], name: "acceptOwnership", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "governor", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", type: "function" }, { inputs: [], name: "owner", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", type: "function" }, { inputs: [], name: "pendingOwner", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", type: "function" }, { inputs: [], name: "renounceOwnership", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [{ internalType: "address", name: "value", type: "address" }], name: "setSuperAdmin", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "superAdmin", outputs: [{ internalType: "address", name: "", type: "address" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "address", name: "newOwner", type: "address" }], name: "transferOwnership", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "address", name: "depositContract", type: "address" }, { internalType: "address", name: "accountingContract", type: "address" }, { internalType: "address", name: "withdrawTreasury", type: "address" }, { internalType: "address", name: "rewardsTreasury", type: "address" }, { internalType: "address", name: "poolGovernor", type: "address" } ], name: "initialize", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [{ internalType: "uint64", name: "source", type: "uint64" }], name: "stake", outputs: [], stateMutability: "payable", type: "function" }, { inputs: [{ internalType: "uint256", name: "amount", type: "uint256" }], name: "unstakePending", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "uint256", name: "value", type: "uint256" }, { internalType: "uint16", name: "allowedInterchangeNum", type: "uint16" }, { internalType: "uint64", name: "source", type: "uint64" } ], name: "unstake", outputs: [ { internalType: "uint256", name: "unstakeFromPendingValue", type: "uint256" } ], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "activateStake", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [ { internalType: "uint256", name: "activatedSlots", type: "uint256" } ], name: "restake", outputs: [], stateMutability: "payable", type: "function" }, { inputs: [ { components: [ { internalType: "bytes", name: "pubkey", type: "bytes" }, { internalType: "bytes", name: "signature", type: "bytes" }, { internalType: "bytes32", name: "deposit_data_root", type: "bytes32" } ], internalType: "struct ValidatorList.DepositData[]", name: "pendingValidators", type: "tuple[]" } ], name: "setPendingValidators", outputs: [{ internalType: "bool", name: "", type: "bool" }], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "getPendingValidatorCount", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "uint256", name: "index", type: "uint256" }], name: "getPendingValidator", outputs: [{ internalType: "bytes", name: "", type: "bytes" }], stateMutability: "view", type: "function" }, { inputs: [], name: "getValidatorCount", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "uint256", name: "index", type: "uint256" }], name: "getValidator", outputs: [ { internalType: "bytes", name: "", type: "bytes" }, { internalType: "enum ValidatorList.ValidatorStatus", name: "", type: "uint8" } ], stateMutability: "view", type: "function" }, { inputs: [ { internalType: "uint256", name: "index", type: "uint256" }, { components: [ { internalType: "bytes", name: "pubkey", type: "bytes" }, { internalType: "bytes", name: "signature", type: "bytes" }, { internalType: "bytes32", name: "deposit_data_root", type: "bytes32" } ], internalType: "struct ValidatorList.DepositData", name: "pendingValidator", type: "tuple" } ], name: "replacePendingValidator", outputs: [{ internalType: "bool", name: "", type: "bool" }], stateMutability: "nonpayable", type: "function" }, { inputs: [{ internalType: "uint256", name: "num", type: "uint256" }], name: "markValidatorsAsExited", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [{ internalType: "uint256", name: "index", type: "uint256" }], name: "markValidatorAsExited", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "reorderPending", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [{ internalType: "bool", name: "pause", type: "bool" }], name: "pauseStaking", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [{ internalType: "bool", name: "pause", type: "bool" }], name: "pauseWithdraw", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [{ internalType: "address", name: "newGovernor", type: "address" }], name: "setGovernor", outputs: [], stateMutability: "nonpayable", type: "function" }, { inputs: [], name: "minStakeAmount", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], stateMutability: "view", type: "function" }, { inputs: [{ internalType: "uint256", name: "stakeAmount", type: "uint256" }], name: "setMinStakeAmount", outputs: [], stateMutability: "nonpayable", type: "function" } ]; // src/constants/errors.ts var ERROR_MESSAGES = { BALANCE_ERROR: "An error occurred while getting the balance", PENDING_BALANCE_ERROR: "An error occurred while getting the pending balance", PENDING_DEPOSITED_BALANCE_ERROR: "An error occurred while getting the pending deposited balance", PENDING_RESTAKED_REWARDS_ERROR: "An error occurred while getting the pending restaked rewards", READY_FOR_AUTOCOMPOUND_REWARDS_AMOUNT_ERROR: "An error occurred while getting the ready for autocompound rewards amount", PENDING_BALANCE_OF_ERROR: "An error occurred while getting the pending balance of an address", PENDING_DEPOSITED_BALANCE_OF_ERROR: "An error occurred while getting the pending deposited balance of an address", DEPOSITED_BALANCE_OF_ERROR: "An error occurred while getting the deposited balance of an address", PENDING_RESTAKED_REWARD_OF_ERROR: "An error occurred while getting the pending restaked reward of an address", RESTAKED_REWARD_OF_ERROR: "An error occurred while getting the restaked reward of an address", GET_POOL_FEE_ERROR: "An error occurred while getting the pool fee", MIN_STAKE_AMOUNT_ERROR: "An error occurred while getting the minimum stake amount", GET_VALIDATOR_ERROR: "An error occurred while getting the validator", GET_VALIDATOR_COUNT_ERROR: "An error occurred while getting the validator count", GET_PENDING_VALIDATOR_ERROR: "An error occurred while getting the pending validator", GET_PENDING_VALIDATOR_COUNT_ERROR: "An error occurred while getting the pending validator count", ACTIVATE_STAKE_ERROR: "An error occurred while activating the stake", MIN_AMOUNT_ERROR: "Min Amount {0} wei", UNSTAKE_PENDING_ERROR: "An error occurred while unstaking the pending amount", INSUFFICIENT_PENDING_BALANCE_ERROR: `Pending balance less than min stake amount {0}`, ZERO_UNSTAKE_MESSAGE: "Zero pending balance", AMOUNT_GREATER_THAN_PENDING_BALANCE_ERROR: `Amount greater than pending balance {0}`, NETWORK_NOT_SUPPORTED: `Unsupported network {0}`, NO_REWARDS_MESSAGE: "No active rewards for claim", AUTOCOMPOUND_ERROR: "An error occurred while performing the autocompound operation", AUTOCOMPOUND_BALANCE_OF_ERROR: "An error occurred while getting the autocompound balance of an address", WITHDRAW_REQUEST_QUEUE_PARAMS_ERROR: "An error occurred while getting the withdraw request queue parameters", WITHDRAW_REQUEST_ERROR: "An error occurred while getting the withdraw request info for an address", ZERO_UNSTAKE_ERROR: "No amount requested for unstake", NOT_FILLED_UNSTAKE_MESSAGE: "Unstake request not filled yet", WRONG_TYPE_MESSAGE: "Wrong input type", CLAIM_WITHDRAW_REQUEST_ERROR: "An error occurred while claiming the withdraw request for an address", CLOSE_VALIDATORS_STAT_ERROR: "An error occurred while getting the number of validators expected to stop", STAKE_ERROR: "An error occurred while staking funds into the pool", UNSTAKE_ERROR: "An error occurred while unstaking funds from the pool", SIMULATE_UNSTAKE_ERROR: "An error occurred while simulating the unstake transaction", MAX_AMOUNT_FOR_UNSTAKE_ERROR: "Max Amount For Unstake {0}", ADDRESS_FORMAT_ERROR: "Invalid Ethereum address format", USER_BALANCES_ERROR: "An error occurred while getting the user balances", POOL_BALANCES_ERROR: "An error occurred while getting the pool balances" }; var ORIGINAL_ERROR_MESSAGES = { "InvalidValue: remainder": "The remainder is less than the minimum stake amount.", "InvalidValue: amount": `The requested amount is greater than the pool's pending balance.`, "InvalidValue: pending balance": "The user has no pending balance or it is less than the requested amount.", "ZeroValue: pending": `The pool's pending balance is zero.`, "ZeroValue: claim": "There is nothing to claim.", "InvalidParam: index": "The provided index is out of range.", "InvalidParam: caller": "This action is not allowed for the current user.", "InvalidValue: zero amount": "There is nothing to activate.", "InvalidValue: share": "The requested amount is less than one share.", "InvalidValue: withdrawable balance": "The requested amount is greater than the active balance.", "Paused: withdraw claim": "Claiming unstake is currently paused.", "Paused: staking": "Staking is currently paused.", "Paused: withdraw": "Unstaking is currently paused.", "InvalidAmount: small stake": "The staked amount is less than the minimum stake amount.", "Pending validator": "There are not enough pending validators to activate.", "Returned error: execution reverted": "The operation failed. Please try again." }; // src/types/index.ts var ValidatorStatus = /* @__PURE__ */ ((ValidatorStatus2) => { ValidatorStatus2[ValidatorStatus2["Unknown"] = 0] = "Unknown"; ValidatorStatus2[ValidatorStatus2["Pending"] = 1] = "Pending"; ValidatorStatus2[ValidatorStatus2["Deposited"] = 2] = "Deposited"; return ValidatorStatus2; })(ValidatorStatus || {}); // ../utils/constants/errors.ts var COMMON_ERROR_MESSAGES = { UNKNOWN_ERROR: "An unknown error occurred", TOKEN_ERROR: "Please create or use correct token" }; // ../utils/index.ts var WalletSDKError = class extends Error { constructor(message, code, originalError) { super(message); this.code = code; this.originalError = originalError; Object.setPrototypeOf(this, new.target.prototype); } }; var Blockchain = class { /** * Handles errors that occur within the Ethereum class. * * @param {keyof typeof ERROR_MESSAGES} code - The error code associated with the error. * @param {Error | WalletSDKError | unknown} originalError - The original error that was thrown. * * If the original error is an instance of WalletSDKError, it is thrown as is. * If the original error is an instance of the built-in Error class, a new WalletSDKError is thrown with the original error as the cause. * If the original error is not an instance of WalletSDKError or Error, a new WalletSDKError is thrown with a generic message and code. */ handleError(code, originalError) { const message = this.ERROR_MESSAGES[code]; if (originalError instanceof WalletSDKError || !message || !code) { throw originalError; } if (originalError instanceof Error) { const newMessage = Object.entries(this.ORIGINAL_ERROR_MESSAGES).find( ([originalMessage]) => originalError.message.includes(originalMessage) )?.[1]; const errorMessage = newMessage || this.ERROR_MESSAGES[code] || COMMON_ERROR_MESSAGES["UNKNOWN_ERROR"]; throw new WalletSDKError(errorMessage, String(code), originalError); } throw new WalletSDKError( COMMON_ERROR_MESSAGES["UNKNOWN_ERROR"], "UNKNOWN_ERROR" ); } /** * Throws a WalletSDKError with a specified error code and message. * * @param {keyof typeof ERROR_MESSAGES} code - The error code associated with the error. * @param {...string[]} values - The values to be inserted into the error message. * * The method retrieves the error message template associated with the provided code from the ERROR_MESSAGES object. * It then replaces placeholders in the message template with provided values and throws a WalletSDKError with the final message and the provided code. */ throwError(code, ...values) { let message = this.ERROR_MESSAGES[code]; values.forEach((value, index) => { message = message?.replace(`{${index}}`, value); }); if (!message) { throw new WalletSDKError( COMMON_ERROR_MESSAGES["UNKNOWN_ERROR"], "UNKNOWN_ERROR" ); } throw new WalletSDKError(message, String(code)); } /** * Check if the URL is valid * * @param {string} url - URL * @returns a bool type result. * */ isValidURL(url) { let urlClass; try { urlClass = new URL(url); } catch (_) { return false; } return urlClass.protocol === "http:" || urlClass.protocol === "https:"; } }; // src/ethereum.ts var Ethereum = class extends Blockchain { addressContractAccounting; addressContractPool; addressContractWithdrawTreasury; contractAccounting; contractPool; rpcUrl; web3; minAmount = new import_bignumber2.default(ETH_MIN_AMOUNT); ERROR_MESSAGES = ERROR_MESSAGES; ORIGINAL_ERROR_MESSAGES = ORIGINAL_ERROR_MESSAGES; constructor(network = "mainnet", url) { super(); this.initializeNetwork(network, url); } /** * Retrieves the balance of the contract. * * This method calls the `balance` method on the `contractAccounting` contract, * converts the result from Wei to Ether, and returns the result as a `BigNumber`. * * @returns A promise that resolves to the balance of the contract as a `BigNumber`. * * @throws Will throw an error if the contract call fails. */ async balance() { try { const result = await this.contractAccounting.methods.balance().call(); return this.fromWeiToEther(result); } catch (error) { throw this.handleError("BALANCE_ERROR", error); } } /** * Fetches the pool pending balance. This balance is always less than 32 ETH. * * @returns A Promise that resolves to the pending balance in ether. * * @throws Will throw an Error if the contract call fails. */ async pendingBalance() { try { const result = await this.contractAccounting.methods.pendingBalance().call(); return this.fromWeiToEther(result); } catch (error) { throw this.handleError("PENDING_BALANCE_ERROR", error); } } /** * Fetches the pool pending deposited balance. This is the balance deposited into the Beacon deposit contract but validators are still not active. * * @returns A Promise that resolves to the pending deposited balance in ether. * * @throws Will throw an Error if the contract call fails. */ async pendingDepositedBalance() { try { const result = await this.contractAccounting.methods.pendingDepositedBalance().call(); return this.fromWeiToEther(result); } catch (error) { throw this.handleError("PENDING_DEPOSITED_BALANCE_ERROR", error); } } /** * Fetches the pool restaked rewards which are in pending status. * * @returns A Promise that resolves to the pending restaked rewards amount in ether. * * @throws Will throw an Error if the contract call fails. */ async pendingRestakedRewards() { try { const result = await this.contractAccounting.methods.pendingRestakedRewards().call(); return this.fromWeiToEther(result); } catch (error) { throw this.handleError("PENDING_RESTAKED_REWARDS_ERROR", error); } } /** * Fetches the pool unclaimed rewards amount which can be restaked. * * @returns A Promise that resolves to the unclaimed rewards amount in ether. * * @throws Will throw an Error if the contract call fails. */ async readyforAutocompoundRewardsAmount() { try { const result = await this.contractAccounting.methods.readyforAutocompoundRewardsAmount().call(); return this.fromWeiToEther(result); } catch (error) { throw this.handleError( "READY_FOR_AUTOCOMPOUND_REWARDS_AMOUNT_ERROR", error ); } } /** * Fetches the pending balance of a given address. * * @param address - The address to fetch the pending balance for. * * @returns A Promise that resolves to the pending balance in ether. * * @throws Will throw an Error if the contract call fails or address is not valid. */ async pendingBalanceOf(address) { try { if (!this.isAddress(address)) { this.throwError("ADDRESS_FORMAT_ERROR"); } const result = await this.contractAccounting.methods.pendingBalanceOf(address).call(); return this.fromWeiToEther(result); } catch (error) { throw this.handleError("PENDING_BALANCE_OF_ERROR", error); } } /** * Fetches the user's pending deposited balance. This is the balance deposited into the validator but not active yet. * Pending deposited balance can't be unstaked till validator activation. * * @param address - The address to fetch the pending deposited balance for. * * @returns A Promise that resolves to the pending deposited balance in ether. * * @throws Will throw an Error if the contract call fails. */ async pendingDepositedBalanceOf(address) { try { if (!this.isAddress(address)) { this.throwError("ADDRESS_FORMAT_ERROR"); } const result = await this.contractAccounting.methods.pendingDepositedBalanceOf(address).call(); return this.fromWeiToEther(result); } catch (error) { throw this.handleError("PENDING_DEPOSITED_BALANCE_OF_ERROR", error); } } /** * Fetches the user's active origin deposited balance. * * @param address - The address to fetch the deposited balance for. * * @returns A Promise that resolves to the deposited balance in ether. * * @throws Will throw an Error if the contract call fails. */ async depositedBalanceOf(address) { try { if (!this.isAddress(address)) { this.throwError("ADDRESS_FORMAT_ERROR"); } const result = await this.contractAccounting.methods.depositedBalanceOf(address).call(); return this.fromWeiToEther(result); } catch (error) { throw this.handleError("DEPOSITED_BALANCE_OF_ERROR", error); } } /** * Fetches the user's restaked rewards in pending state. * * @param address - The address to fetch the pending restaked rewards for. * * @returns A Promise that resolves to the pending restaked rewards in ether. * * @throws Will throw an Error if the contract call fails. */ async pendingRestakedRewardOf(address) { try { if (!this.isAddress(address)) { this.throwError("ADDRESS_FORMAT_ERROR"); } const result = await this.contractAccounting.methods.pendingRestakedRewardOf(address).call(); return this.fromWeiToEther(result); } catch (error) { throw this.handleError("PENDING_RESTAKED_REWARD_OF_ERROR", error); } } /** * Returns total user restaked rewards. Includes rewards in pending state. * * @param address - The address to fetch the restaked rewards for. * * @returns A Promise that resolves to the restaked rewards in ether. * * @throws Will throw an Error if the contract call fails. */ async restakedRewardOf(address) { try { if (!this.isAddress(address)) { this.throwError("ADDRESS_FORMAT_ERROR"); } const result = await this.contractAccounting.methods.restakedRewardOf(address).call(); return this.fromWeiToEther(result); } catch (error) { throw this.handleError("RESTAKED_REWARD_OF_ERROR", error); } } /** * Fetches the pool fee in bips (1/10000). * * @returns A Promise that resolves to the pool fee. * * @throws Will throw an Error if the contract call fails. */ async getPoolFee() { try { const poolFee = await this.contractAccounting.methods.getPoolFee().call(); const result = poolFee.toString(); return new import_bignumber2.default(result).div(1e4); } catch (error) { throw this.handleError("GET_POOL_FEE_ERROR", error); } } /** * Claims all pool rewards and restakes it into the pool. * * @param address - The address to perform the autocompound operation for. * * @returns A Promise that resolves to a transaction object. * * @throws Will throw an Error if the contract call fails or there are no rewards. */ async autocompound(address) { try { if (!this.isAddress(address)) { this.throwError("ADDRESS_FORMAT_ERROR"); } const rewards = await this.readyforAutocompoundRewardsAmount(); if (rewards.isZero()) this.throwError("NO_REWARDS_MESSAGE"); const gasConsumption = await this.contractAccounting.methods.autocompound().estimateGas({ from: address }); return { from: address, to: this.addressContractAccounting, value: 0, gasLimit: this.calculateGasLimit(gasConsumption), data: this.contractAccounting.methods.autocompound().encodeABI() }; } catch (error) { throw this.handleError("AUTOCOMPOUND_ERROR", error); } } /** * Returns total user autocompound balance. Part of this balance could be in pending state after rewards autocompound. * * @param address - The address to fetch the autocompound balance for. * * @returns A Promise that resolves to the autocompound balance in ether. * * @throws Will throw an Error if the contract call fails. */ async autocompoundBalanceOf(address) { try { if (!this.isAddress(address)) { this.throwError("ADDRESS_FORMAT_ERROR"); } const result = await this.contractAccounting.methods.autocompoundBalanceOf(address).call(); return this.fromWeiToEther(result); } catch (error) { throw this.handleError("AUTOCOMPOUND_BALANCE_OF_ERROR", error); } } /** * Returns info about withdraw requests queue. * Includes totally all-time requested withdraw amount, * actual allowed for interchange with deposits amount, * all-time withdraw treasury filled amount, * and all-time claimed by users amount. * * @returns A Promise that resolves to an object containing the withdraw request queue parameters. * * @throws Will throw an Error if the contract call fails. */ async withdrawRequestQueueParams() { try { const result = await this.contractAccounting.methods.withdrawRequestQueueParams().call(); return { // Totally all-time requested withdraw amount. withdrawRequested: this.fromWeiToEther(result[0]), // Actual allowed for interchange with deposits amount. interchangeAllowed: this.fromWeiToEther(result[1]), // All-time withdraw treasury filled amount. filled: this.fromWeiToEther(result[2]), // All-time claimed by users amount claimed: this.fromWeiToEther(result[3]) }; } catch (error) { throw this.handleError("WITHDRAW_REQUEST_QUEUE_PARAMS_ERROR", error); } } /** * Returns user withdraw request info. Includes the actual requested amount and the amount ready for claim. * * @param address - The address to fetch the withdraw request info for. * * @returns A Promise that resolves to an object containing the requested amount and the amount ready for claim in ether. * * @throws Will throw an Error if the contract call fails. */ async withdrawRequest(address) { try { if (!this.isAddress(address)) { this.throwError("ADDRESS_FORMAT_ERROR"); } const result = await this.contractAccounting.methods.withdrawRequest(address).call(); return { requested: this.fromWeiToEther(result[0]), readyForClaim: this.fromWeiToEther(result[1]) }; } catch (error) { throw this.handleError("WITHDRAW_REQUEST_ERROR", error); } } /** * Returns aggregated pool balances using multicall contract. * * @returns A Promise that resolves to a AggregatedBalances object. * * @throws Will throw an Error if the contract call fails. */ async poolBalances() { const methods = [ "balance", "pendingBalance", "pendingDepositedBalance", "pendingRestakedRewards", "readyforAutocompoundRewardsAmount" ]; const result = {}; try { const multicall = new import_ethereum_multicall.Multicall({ multicallCustomContractAddress: MULTICALL_CONTRACT_ADDRESS, web3Instance: this.web3, tryAggregate: true }); const contractCallContext = []; methods.forEach( (method) => contractCallContext.push({ reference: method, contractAddress: this.addressContractAccounting, /* eslint-disable @typescript-eslint/no-explicit-any */ abi: ABI_CONTRACT_ACCOUNTING, // TODO check it calls: [ { reference: method, methodName: method, methodParameters: [] } ] }) ); const results = await multicall.call(contractCallContext); for (const [key, value] of Object.entries(results.results)) { result[key] = this.web3.utils.fromWei( value.callsReturnContext[0]?.returnValues[0].hex, "ether" ); } } catch (error) { throw this.handleError("POOL_BALANCES_ERROR", error); } return result; } /** * Returns aggregated user balances using multicall contract. * * @param address - The user address. * * @returns A Promise that resolves to a AggregatedBalances object. * * @throws Will throw an Error if the contract call fails. */ async userBalances(address) { const methods = [ "pendingBalanceOf", "pendingDepositedBalanceOf", "pendingRestakedRewardOf", "autocompoundBalanceOf", "depositedBalanceOf" ]; const result = {}; try { const multicall = new import_ethereum_multicall.Multicall({ multicallCustomContractAddress: MULTICALL_CONTRACT_ADDRESS, web3Instance: this.web3, tryAggregate: true }); const contractCallContext = []; methods.forEach( (method) => contractCallContext.push({ reference: method, contractAddress: this.addressContractAccounting, /* eslint-disable @typescript-eslint/no-explicit-any */ abi: ABI_CONTRACT_ACCOUNTING, // TODO check it calls: [ { reference: method, methodName: method, methodParameters: [address] } ] }) ); const results = await multicall.call(contractCallContext); for (const [key, value] of Object.entries(results.results)) { result[key] = this.web3.utils.fromWei( value.callsReturnContext[0]?.returnValues