UNPKG

@temple-wallet/everstake-wallet-sdk-polygon

Version:
1,550 lines (1,542 loc) 43.1 kB
// src/index.ts import { createPublicClient, encodeFunctionData, formatUnits, http, parseUnits, TransactionReceiptNotFoundError } from "viem"; // ../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:"; } }; // ../utils/api.ts var apiUrl = ""; function setApiUrl(url) { apiUrl = url; } var makeApiFetchFn = (fetchArgsFn, transformResponseData, errorMessagePrefix) => { return async (...args) => { try { const response = await fetch(...fetchArgsFn(...args)); if (!response.ok) { throw new Error(`Error: ${response.statusText}`); } const rawResponseBody = await response.text(); try { return transformResponseData(JSON.parse(rawResponseBody)); } catch { return transformResponseData(rawResponseBody); } } catch (error) { console.error(`${errorMessagePrefix}:`, error); throw error; } }; }; var checkToken = makeApiFetchFn( (token) => [ `${apiUrl}/everstake-wallet/token/check/${token}`, { method: "GET", headers: { "Content-Type": "application/json" } } ], (data) => data.result, "Failed to check token" ); var setStats = makeApiFetchFn( ({ token, action, amount, address, chain }) => [ `${apiUrl}/everstake-wallet/stats/set`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ token, action, amount, address, chain }) } ], () => void 0, "Failed to set stats" ); var createToken = makeApiFetchFn( (name, type) => [ `${apiUrl}/everstake-wallet/token/create`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name, type }) } ], (data) => data, "Failed to create token" ); var getAssets = makeApiFetchFn( (chain) => [ `${apiUrl}/everstake-dashboard/chain?name=${chain.toLowerCase()}`, { method: "GET" } ], (data) => data, "Failed to get assets" ); var getEthValidatorsQueueStats = makeApiFetchFn( () => [`${apiUrl}/everstake-eth-api/validators/queue`, { method: "GET" }], (data) => data, "Failed to get ETH validators queue stats" ); var getEthAccountTransactions = makeApiFetchFn( ({ account, ...restParams }) => { const url = new URL(`${apiUrl}/everstake-eth-api/transactions/${account}`); for (const key in restParams) { const typedKey = key; if (restParams[typedKey] != null) { url.searchParams.set(typedKey, restParams[typedKey].toString()); } } return [url, { method: "GET" }]; }, (data) => data, "Failed to get ETH account transactions" ); // src/constants/errors.ts var ERROR_MESSAGES = { TRANSACTION_LOADING_ERR: "Failed to check transaction.", APPROVE_ERR: "Approval failed.", DELEGATE_ERR: "Delegation failed.", GET_ALLOWANCE_ERR: "Could not fetch allowance.", UNDELEGATE_ERR: "Undelegation failed.", GET_TOTAL_DELEGATE_ERR: "Failed to get total delegated.", GET_UNBOND_ERR: "Could not get unbonding info.", GET_UNBOND_NONCE_ERR: "Failed to get unbond nonce.", GET_REWARD_ERR: "Could not fetch rewards.", ALLOWANCE_ERR: "Allowance less than amount", DELEGATED_BALANCE_ERR: "Delegated balance less than requested amount" }; var ORIGINAL_ERROR_MESSAGES = {}; // src/abi.ts var ABI_CONTRACT_APPROVE = [ { constant: true, inputs: [], name: "name", outputs: [{ name: "", type: "string" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { name: "spender", type: "address" }, { name: "value", type: "uint256" } ], name: "approve", outputs: [{ name: "", type: "bool" }], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "totalSupply", outputs: [{ name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { name: "from", type: "address" }, { name: "to", type: "address" }, { name: "value", type: "uint256" } ], name: "transferFrom", outputs: [{ name: "", type: "bool" }], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "decimals", outputs: [{ name: "", type: "uint8" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { name: "spender", type: "address" }, { name: "addedValue", type: "uint256" } ], name: "increaseAllowance", outputs: [{ name: "success", type: "bool" }], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [], name: "unpause", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [{ name: "account", type: "address" }], name: "isPauser", outputs: [{ name: "", type: "bool" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "paused", outputs: [{ name: "", type: "bool" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [], name: "renouncePauser", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [{ name: "owner", type: "address" }], name: "balanceOf", outputs: [{ name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [{ name: "account", type: "address" }], name: "addPauser", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [], name: "pause", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "symbol", outputs: [{ name: "", type: "string" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { name: "spender", type: "address" }, { name: "subtractedValue", type: "uint256" } ], name: "decreaseAllowance", outputs: [{ name: "success", type: "bool" }], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [ { name: "to", type: "address" }, { name: "value", type: "uint256" } ], name: "transfer", outputs: [{ name: "", type: "bool" }], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [ { name: "owner", type: "address" }, { name: "spender", type: "address" } ], name: "allowance", outputs: [{ name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { inputs: [ { name: "name", type: "string" }, { name: "symbol", type: "string" }, { name: "decimals", type: "uint8" }, { name: "totalSupply", type: "uint256" } ], payable: false, stateMutability: "nonpayable", type: "constructor" }, { anonymous: false, inputs: [{ indexed: false, name: "account", type: "address" }], name: "Paused", type: "event" }, { anonymous: false, inputs: [{ indexed: false, name: "account", type: "address" }], name: "Unpaused", type: "event" }, { anonymous: false, inputs: [{ indexed: true, name: "account", type: "address" }], name: "PauserAdded", type: "event" }, { anonymous: false, inputs: [{ indexed: true, name: "account", type: "address" }], name: "PauserRemoved", type: "event" }, { anonymous: false, inputs: [ { indexed: true, name: "from", type: "address" }, { indexed: true, name: "to", type: "address" }, { indexed: false, name: "value", type: "uint256" } ], name: "Transfer", type: "event" }, { anonymous: false, inputs: [ { indexed: true, name: "owner", type: "address" }, { indexed: true, name: "spender", type: "address" }, { indexed: false, name: "value", type: "uint256" } ], name: "Approval", type: "event" } ]; var ABI_CONTRACT_STAKING = [ { constant: true, inputs: [], name: "currentEpoch", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" } ]; var ABI_CONTRACT_BUY = [ { inputs: [], payable: false, stateMutability: "nonpayable", type: "constructor" }, { anonymous: false, inputs: [ { indexed: true, internalType: "address", name: "owner", type: "address" }, { indexed: true, internalType: "address", name: "spender", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "Approval", 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: "from", type: "address" }, { indexed: true, internalType: "address", name: "to", type: "address" }, { indexed: false, internalType: "uint256", name: "value", type: "uint256" } ], name: "Transfer", type: "event" }, { constant: false, inputs: [{ internalType: "bool", name: "pol", type: "bool" }], name: "_restake", outputs: [ { internalType: "uint256", name: "", type: "uint256" }, { internalType: "uint256", name: "", type: "uint256" } ], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [ { internalType: "uint256", name: "claimAmount", type: "uint256" }, { internalType: "uint256", name: "maximumSharesToBurn", type: "uint256" }, { internalType: "bool", name: "pol", type: "bool" } ], name: "_sellVoucher_new", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "activeAmount", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [ { internalType: "address", name: "owner", type: "address" }, { internalType: "address", name: "spender", type: "address" } ], name: "allowance", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { internalType: "address", name: "spender", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" } ], name: "approve", outputs: [{ internalType: "bool", name: "", type: "bool" }], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [{ internalType: "address", name: "owner", type: "address" }], name: "balanceOf", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { internalType: "uint256", name: "_amount", type: "uint256" }, { internalType: "uint256", name: "_minSharesToMint", type: "uint256" } ], name: "buyVoucher", outputs: [ { internalType: "uint256", name: "amountToDeposit", type: "uint256" } ], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [ { internalType: "uint256", name: "_amount", type: "uint256" }, { internalType: "uint256", name: "_minSharesToMint", type: "uint256" } ], name: "buyVoucherPOL", outputs: [ { internalType: "uint256", name: "amountToDeposit", type: "uint256" } ], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [ { internalType: "uint256", name: "_amount", type: "uint256" }, { internalType: "uint256", name: "_minSharesToMint", type: "uint256" }, { internalType: "uint256", name: "deadline", type: "uint256" }, { internalType: "uint8", name: "v", type: "uint8" }, { internalType: "bytes32", name: "r", type: "bytes32" }, { internalType: "bytes32", name: "s", type: "bytes32" } ], name: "buyVoucherWithPermit", outputs: [ { internalType: "uint256", name: "amountToDeposit", type: "uint256" } ], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "commissionRate_deprecated", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { internalType: "address", name: "spender", type: "address" }, { internalType: "uint256", name: "subtractedValue", type: "uint256" } ], name: "decreaseAllowance", outputs: [{ internalType: "bool", name: "", type: "bool" }], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "delegation", outputs: [{ internalType: "bool", name: "", type: "bool" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { internalType: "address", name: "token", type: "address" }, { internalType: "address payable", name: "destination", type: "address" }, { internalType: "uint256", name: "amount", type: "uint256" } ], name: "drain", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "eventsHub", outputs: [ { internalType: "contract EventsHub", name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "exchangeRate", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [{ internalType: "address", name: "user", type: "address" }], name: "getLiquidRewards", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "getRewardPerShare", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [{ internalType: "address", name: "user", type: "address" }], name: "getTotalStake", outputs: [ { internalType: "uint256", name: "", type: "uint256" }, { internalType: "uint256", name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { internalType: "address", name: "spender", type: "address" }, { internalType: "uint256", name: "addedValue", type: "uint256" } ], name: "increaseAllowance", outputs: [{ internalType: "bool", name: "", type: "bool" }], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [{ internalType: "address", name: "", type: "address" }], name: "initalRewardPerShare", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { internalType: "uint256", name: "_validatorId", type: "uint256" }, { internalType: "address", name: "_stakingLogger", type: "address" }, { internalType: "address", name: "_stakeManager", type: "address" } ], name: "initialize", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "isOwner", outputs: [{ internalType: "bool", name: "", type: "bool" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "lastCommissionUpdate_deprecated", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [], name: "lock", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "locked", outputs: [{ internalType: "bool", name: "", type: "bool" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { internalType: "address", name: "user", type: "address" }, { internalType: "uint256", name: "amount", type: "uint256" } ], name: "migrateIn", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [ { internalType: "address", name: "user", type: "address" }, { internalType: "uint256", name: "amount", type: "uint256" } ], name: "migrateOut", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "minAmount", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "owner", outputs: [{ internalType: "address", name: "", type: "address" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "polToken", outputs: [ { internalType: "contract IERC20Permit", name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [], name: "renounceOwnership", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [], name: "restake", outputs: [ { internalType: "uint256", name: "", type: "uint256" }, { internalType: "uint256", name: "", type: "uint256" } ], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [], name: "restakePOL", outputs: [ { internalType: "uint256", name: "", type: "uint256" }, { internalType: "uint256", name: "", type: "uint256" } ], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "rewardPerShare", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { internalType: "uint256", name: "claimAmount", type: "uint256" }, { internalType: "uint256", name: "maximumSharesToBurn", type: "uint256" } ], name: "sellVoucher", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [ { internalType: "uint256", name: "claimAmount", type: "uint256" }, { internalType: "uint256", name: "maximumSharesToBurn", type: "uint256" } ], name: "sellVoucherPOL", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [ { internalType: "uint256", name: "claimAmount", type: "uint256" }, { internalType: "uint256", name: "maximumSharesToBurn", type: "uint256" } ], name: "sellVoucher_new", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [ { internalType: "uint256", name: "claimAmount", type: "uint256" }, { internalType: "uint256", name: "maximumSharesToBurn", type: "uint256" } ], name: "sellVoucher_newPOL", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [ { internalType: "uint256", name: "validatorStake", type: "uint256" }, { internalType: "uint256", name: "delegatedAmount", type: "uint256" }, { internalType: "uint256", name: "totalAmountToSlash", type: "uint256" } ], name: "slash", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "stakeManager", outputs: [ { internalType: "contract IStakeManager", name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "stakingLogger", outputs: [ { internalType: "contract StakingInfo", name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "totalStake_deprecated", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "totalSupply", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [ { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" } ], name: "transfer", outputs: [{ internalType: "bool", name: "", type: "bool" }], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [ { internalType: "address", name: "from", type: "address" }, { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" } ], name: "transferFrom", outputs: [{ internalType: "bool", name: "", type: "bool" }], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [{ internalType: "address", name: "newOwner", type: "address" }], name: "transferOwnership", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [ { internalType: "address", name: "to", type: "address" }, { internalType: "uint256", name: "value", type: "uint256" } ], name: "transferPOL", outputs: [{ internalType: "bool", name: "", type: "bool" }], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [{ internalType: "address", name: "", type: "address" }], name: "unbondNonces", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [{ internalType: "address", name: "", type: "address" }], name: "unbonds", outputs: [ { internalType: "uint256", name: "shares", type: "uint256" }, { internalType: "uint256", name: "withdrawEpoch", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [ { internalType: "address", name: "", type: "address" }, { internalType: "uint256", name: "", type: "uint256" } ], name: "unbonds_new", outputs: [ { internalType: "uint256", name: "shares", type: "uint256" }, { internalType: "uint256", name: "withdrawEpoch", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [], name: "unlock", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [], name: "unstakeClaimTokens", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [], name: "unstakeClaimTokensPOL", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [{ internalType: "uint256", name: "unbondNonce", type: "uint256" }], name: "unstakeClaimTokens_new", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [{ internalType: "uint256", name: "unbondNonce", type: "uint256" }], name: "unstakeClaimTokens_newPOL", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [{ internalType: "bool", name: "_delegation", type: "bool" }], name: "updateDelegation", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "validatorId", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "validatorRewards_deprecated", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "withdrawExchangeRate", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: true, inputs: [], name: "withdrawPool", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" }, { constant: false, inputs: [], name: "withdrawRewards", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: false, inputs: [], name: "withdrawRewardsPOL", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "withdrawShares", outputs: [{ internalType: "uint256", name: "", type: "uint256" }], payable: false, stateMutability: "view", type: "function" } ]; // src/constants/index.ts import BigNumber from "bignumber.js"; var ADDRESS_CONTRACT_APPROVE = "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0"; var ADDRESS_CONTRACT_APPROVE_POL = "0x455e53CBB86018Ac2B8092FdCd39d8444aFFC3F6"; var ADDRESS_CONTRACT_STAKING = "0x5e3Ef299fDDf15eAa0432E6e66473ace8c13D908"; var ADDRESS_CONTRACT_BUY = "0xF30Cf4ed712D3734161fDAab5B1DBb49Fd2D0E5c"; var MIN_AMOUNT = new BigNumber("1000000000000000000"); var DELEGATE_BASE_GAS = 220000n; var UNDELEGATE_BASE_GAS = 300000n; var CLAIM_UNDELEGATE_BASE_GAS = 200000n; var CLAIM_REWARDS_BASE_GAS = 180000n; var RESTAKE_BASE_GAS = 220000n; var WITHDRAW_EPOCH_DELAY = 80n; var CHAIN = "polygon"; var RPC_URL = "https://ethereum-rpc.publicnode.com"; // src/index.ts import BigNumber2 from "bignumber.js"; var Polygon = class extends Blockchain { contract_approve; contract_approve_pol; contract_buy; contract_staking; client; ERROR_MESSAGES = ERROR_MESSAGES; ORIGINAL_ERROR_MESSAGES = ORIGINAL_ERROR_MESSAGES; constructor(rpcOrTransport = RPC_URL) { super(); this.client = createPublicClient({ transport: typeof rpcOrTransport === "string" ? http(rpcOrTransport, { /** Defaults to 3 */ retryCount: 1, /** Defaults to 150 */ retryDelay: 300 }) : rpcOrTransport }); this.contract_approve = { abi: ABI_CONTRACT_APPROVE, address: ADDRESS_CONTRACT_APPROVE }; this.contract_approve_pol = { abi: ABI_CONTRACT_APPROVE, address: ADDRESS_CONTRACT_APPROVE_POL }; this.contract_buy = { abi: ABI_CONTRACT_BUY, address: ADDRESS_CONTRACT_BUY }; this.contract_staking = { abi: ABI_CONTRACT_STAKING, address: ADDRESS_CONTRACT_STAKING }; } /** * Checks if a transaction is still pending or has been confirmed. * * @param {HexString} hash - The transaction hash to check. * @returns {Promise<{ result: boolean }>} * * @throws {Error} Throws an error with code `'TRANSACTION_LOADING_ERR'` if an issue occurs while fetching the transaction status. * */ async isTransactionLoading(hash) { try { try { await this.client.getTransactionReceipt({ hash }); return { result: false }; } catch (e) { if (e instanceof TransactionReceiptNotFoundError) { return { result: true }; } throw e; } } catch (error) { throw this.handleError("TRANSACTION_LOADING_ERR", error); } } /** approve returns TX loading status * @param {HexString} address - user's address * @param {string} amount - amount for approve * @param {boolean} isPOL - is POL token (false - old MATIC) * @returns {Promise<Object>} Promise object the result of boolean type */ async approve(address, amount, isPOL = false) { const amountWei = parseUnits(amount, 18); if (new BigNumber2(amountWei).isLessThan(MIN_AMOUNT) && amountWei !== 0n) { throw new Error( `Min Amount ${formatUnits(BigInt(MIN_AMOUNT.toString()), 18)} matic` ); } const contract = isPOL ? this.contract_approve_pol : this.contract_approve; try { return await this.getTransaction( encodeFunctionData({ abi: contract.abi, functionName: "approve", args: [ADDRESS_CONTRACT_STAKING, amountWei] }), address, contract.address ); } catch (error) { throw this.handleError("APPROVE_ERR", error); } } /** delegate makes unsigned delegation TX * @param {string} token - auth token * @param {HexString} address - user's address * @param {string} amount - amount for approve * @param {boolean} isPOL - is POL token (false - old MATIC) * @returns {Promise<Object>} Promise object represents the unsigned TX object */ async delegate(token, address, amount, isPOL = false) { if (await checkToken(token)) { const amountWei = parseUnits(amount, 18); if (new BigNumber2(amountWei).isLessThan(MIN_AMOUNT)) throw new Error(`Min Amount ${MIN_AMOUNT} wei matic`); try { const allowedAmount = await this.getAllowance(address, isPOL); if (allowedAmount && new BigNumber2(allowedAmount.toString()).isLessThan(amountWei)) { this.throwError("ALLOWANCE_ERR"); } const data = encodeFunctionData({ abi: this.contract_buy.abi, functionName: isPOL ? "buyVoucherPOL" : "buyVoucher", args: [amountWei, 0n] }); await setStats({ token, action: "stake", amount: Number(amount), address, chain: CHAIN }); return await this.getTransaction( data, address, ADDRESS_CONTRACT_BUY, DELEGATE_BASE_GAS ); } catch (error) { throw this.handleError("DELEGATE_ERR", error); } } else { throw new Error(COMMON_ERROR_MESSAGES.TOKEN_ERROR); } } /** undelegate makes unsigned undelegate TX * @param {string} token - auth token * @param {HexString} address - user's address * @param {string} amount - amount for approve * @param {boolean} isPOL - is POL token (false - old MATIC) * @returns {Promise<Object>} Promise object represents the unsigned TX object */ async undelegate(token, address, amount, isPOL = false) { if (await checkToken(token)) { try { const amountWei = parseUnits(amount, 18); const delegatedBalance = await this.getTotalDelegate(address); if (delegatedBalance && delegatedBalance.isLessThan(BigNumber2(amount))) { this.throwError("DELEGATED_BALANCE_ERR"); } const data = encodeFunctionData({ abi: this.contract_buy.abi, functionName: isPOL ? "sellVoucher_newPOL" : "sellVoucher_new", args: [amountWei, amountWei] }); await setStats({ token, action: "unstake", amount: Number(amount), address, chain: CHAIN }); return await this.getTransaction( data, address, ADDRESS_CONTRACT_BUY, UNDELEGATE_BASE_GAS ); } catch (error) { throw this.handleError("UNDELEGATE_ERR", error); } } else { throw new Error(COMMON_ERROR_MESSAGES.TOKEN_ERROR); } } /** claimUndelegate makes unsigned claim undelegate TX * @param {HexString} address - user's address * @param {bigint} unbondNonce - unbound nonce * @param {boolean} isPOL - is POL token (false - old MATIC) * @returns {Promise<Object>} Promise object represents the unsigned TX object */ async claimUndelegate(address, unbondNonce = 0n, isPOL = false) { const unbond = await this.getUnbond(address, unbondNonce); if (BigNumber2(unbond.amount).isZero()) throw new Error(`Nothing to claim`); const currentEpoch = await this.getCurrentEpoch(); if (BigNumber2(currentEpoch.toString()).isLessThan( BigNumber2(unbond.withdrawEpoch.toString()).plus( BigNumber2(WITHDRAW_EPOCH_DELAY.toString()) ) )) { throw new Error(`Current epoch less than withdraw delay`); } const data = encodeFunctionData({ abi: this.contract_buy.abi, functionName: isPOL ? "unstakeClaimTokens_newPOL" : "unstakeClaimTokens_new", args: [unbond.unbondNonces] }); return this.getTransaction( data, address, ADDRESS_CONTRACT_BUY, CLAIM_UNDELEGATE_BASE_GAS ); } /** reward makes unsigned claim reward TX * @param {string} address - user's address * @param {boolean} isPOL - is POL token (false - old MATIC) * @returns {Promise<Object>} Promise object represents the unsigned TX object */ async reward(address, isPOL = false) { const data = encodeFunctionData({ abi: this.contract_buy.abi, functionName: isPOL ? "withdrawRewardsPOL" : "withdrawRewards", args: [] }); return this.getTransaction( data, address, ADDRESS_CONTRACT_BUY, CLAIM_REWARDS_BASE_GAS ); } /** restake makes unsigned restake reward TX * @param {string} address - user's address * @param {boolean} isPOL - is POL token (false - old MATIC) * @returns {Promise<Object>} Promise object represents the unsigned TX object */ async restake(address, isPOL = false) { const data = encodeFunctionData({ abi: this.contract_buy.abi, functionName: isPOL ? "restakePOL" : "restake", args: [] }); return this.getTransaction( data, address, ADDRESS_CONTRACT_BUY, RESTAKE_BASE_GAS ); } /** getReward returns reward number * @param {HexString} address - user's address * @returns {Promise<BigNumber>} Promise with number of the reward */ async getReward(address) { try { const result = await this.client.readContract({ address: this.contract_buy.address, abi: this.contract_buy.abi, functionName: "getLiquidRewards", args: [address] }); return new BigNumber2(formatUnits(result, 18)); } catch (error) { throw this.handleError("GET_REWARD_ERR", error); } } /** getAllowance returns allowed number for spender * @param {string} owner - tokens owner * @param {boolean} isPOL - is POL token (false - old MATIC) * @param {string} spender - contract spender * @returns {Promise<bigint>} Promise allowed bigint for spender */ async getAllowance(owner, isPOL = false, spender = ADDRESS_CONTRACT_STAKING) { const contract = isPOL ? this.contract_approve_pol : this.contract_approve; try { return await this.client.readContract({ address: contract.address, abi: contract.abi, functionName: "allowance", args: [owner, spender] }); } catch (error) { throw this.handleError("GET_ALLOWANCE_ERR", error); } } /** getTotalDelegate returns total delegated number * @param {string} address - user's address * @returns {Promise<BigNumber>} Promise with BigNumber of the delegation */ async getTotalDelegate(address) { try { const [result] = await this.client.readContract({ address: this.contract_buy.address, abi: this.contract_buy.abi, functionName: "getTotalStake", args: [address] }); return new BigNumber2(formatUnits(result, 18)); } catch (error) { throw this.handleError("GET_TOTAL_DELEGATE_ERR", error); } } /** getUnbond returns unbound data * @param {HexString} address - user's address * @param {bigint} unbondNonce - unbound nonce * @returns {Promise<Object>} Promise Object with unbound data */ async getUnbond(address, unbondNonce = 0n) { try { const unbondNoncesRes = await this.getUnbondNonces(address); const unbondNonces = unbondNonce === 0n ? unbondNoncesRes : unbondNonce; const [res0, res1] = await this.client.readContract({ address: this.contract_buy.address, abi: this.contract_buy.abi, functionName: "unbonds_new", args: [address, unbondNonces] }); return { amount: new BigNumber2(formatUnits(res0, 18)), withdrawEpoch: res1, unbondNonces }; } catch (error) { throw this.handleError("GET_UNBOND_ERR", error); } } /** getUnbondNonces returns unbound nonce * @param {HexString} address - user's address * @returns {Promise<bigint>} Promise with unbound nonce bigint */ async getUnbondNonces(address) { try { return await this.client.readContract({ address: this.contract_buy.address, abi: this.contract_buy.abi, functionName: "unbondNonces", args: [address] }); } catch (error) { throw this.handleError("GET_UNBOND_NONCE_ERR", error); } } /** getCurrentEpoch returns current epoch * @returns {Promise<bigint>} Promise with current epoch bigint */ async getCurrentEpoch() { return this.client.readContract({ address: this.contract_staking.address, abi: this.contract_staking.abi, functionName: "currentEpoch" }); } async getTransaction(data, address, contractAddress, baseGasLimit = 0n) { const gasLimit = await this.client.estimateGas({ to: contractAddress, data, account: address }); return { from: address, to: contractAddress, gas: baseGasLimit > gasLimit ? baseGasLimit : gasLimit, data }; } }; export { MIN_AMOUNT as POLYGON_MIN_AMOUNT, WITHDRAW_EPOCH_DELAY as POLYGON_WITHDRAW_EPOCH_DELAY, Polygon, createToken, setApiUrl };