UNPKG

blub-sdk

Version:

A modular SDK for interacting with the BLUB ecosystem on the Sui blockchain.

281 lines (280 loc) 12.8 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _StakingClient_config, _StakingClient_address; Object.defineProperty(exports, "__esModule", { value: true }); exports.StakingClient = void 0; const transactions_1 = require("@mysten/sui/transactions"); const dotenv_1 = __importDefault(require("dotenv")); const config_1 = require("./query/config"); const reward_1 = require("./query/reward"); const staking_1 = require("./query/staking"); const config_2 = require("./transactions/config"); const staking_2 = require("./transactions/staking"); const vault_1 = require("./transactions/vault"); const coin_1 = require("./utils/coin"); const config_3 = require("./utils/config"); const contract_1 = require("./utils/contract"); dotenv_1.default.config(); /** * StakingClient class for managing Staking operations. */ class StakingClient { /** * @param {SuiClient} client SuiClient instance * @param {string} address Address of the client * @param {Environment} env Environment configuration */ constructor({ client, env, address, }) { _StakingClient_config.set(this, void 0); _StakingClient_address.set(this, void 0); this.client = client; __classPrivateFieldSet(this, _StakingClient_address, address, "f"); // console.log("Activate wallet address:", this.#address); __classPrivateFieldSet(this, _StakingClient_config, new config_3.StakingConfig({ address: __classPrivateFieldGet(this, _StakingClient_address, "f"), env, }), "f"); this.config = new config_2.ConfigModule(__classPrivateFieldGet(this, _StakingClient_config, "f"), client); this.vault = new vault_1.VaultModule(__classPrivateFieldGet(this, _StakingClient_config, "f")); this.staking = new staking_2.StakingModule(__classPrivateFieldGet(this, _StakingClient_config, "f")); this.allCoins = new Map(); } get address() { return __classPrivateFieldGet(this, _StakingClient_address, "f"); } // buildAccount() { // if (process.env.SUI_WALLET_SECRET) { // const secret = process.env.SUI_WALLET_SECRET; // const keypair = Ed25519Keypair.fromSecretKey( // fromBase64(secret).slice(1, 33) // ); // this.keypair = keypair; // } // if (process.env.SUI_WALLET_PHRASE) { // const phrase = process.env.SUI_WALLET_PHRASE; // const keypair = Ed25519Keypair.deriveKeypair(phrase); // this.keypair = keypair; // } // throw new Error("No wallet secret or phrase found"); // } async signAndExecuteTransaction(txb) { const res = await this.client.signAndExecuteTransaction({ transaction: txb, signer: this.keypair, options: { showEffects: true, showEvents: true, showInput: true, showBalanceChanges: true, }, }); return res; } async devInspectTransactionBlock(txb) { const res = await this.client.devInspectTransactionBlock({ transactionBlock: txb, sender: __classPrivateFieldGet(this, _StakingClient_address, "f"), }); return res; } async sendTransaction(txb) { const devInspectRes = await this.devInspectTransactionBlock(txb); if (devInspectRes.effects.status.status !== "success") { // console.log("transaction failed"); // console.log(devInspectRes); return; } const txRes = await this.signAndExecuteTransaction(txb); // console.log(txRes); return txRes; } async getCoins(coinType, refresh = true) { if (__classPrivateFieldGet(this, _StakingClient_address, "f") === "") { throw new Error("Signer is required, but not provided."); } let cursor = null; const limit = 50; if (!refresh) { const gotFromCoins = this.allCoins.get(coinType); if (gotFromCoins) { return gotFromCoins; } } const allCoins = []; while (true) { const gotCoins = await this.client.getCoins({ owner: __classPrivateFieldGet(this, _StakingClient_address, "f"), coinType, cursor, limit, }); for (const coin of gotCoins.data) { allCoins.push({ coinAddress: (0, contract_1.extractStructTagFromType)(coin.coinType).source_address, coinObjectId: coin.coinObjectId, balance: BigInt(coin.balance), }); } if (gotCoins.data.length < limit) { break; } cursor = gotCoins.data[limit - 1].coinObjectId; } this.allCoins.set(coinType, allCoins); return allCoins; } startStaking(params, txb) { const tx = txb ?? new transactions_1.Transaction(); this.config.startStakingMoveCall(params, tx); return tx; } stopStaking(params, txb) { const tx = txb ?? new transactions_1.Transaction(); this.config.stopStakingMoveCall(params, tx); return tx; } updatePackageVersion(params, txb) { const tx = txb ?? new transactions_1.Transaction(); this.config.updatePackageVersionMoveCall(params, tx); return tx; } async getProtocolConfig(protocolConfigId) { return this.config.get_protocol_config(protocolConfigId); } registerReward(params, txb) { const tx = txb ?? new transactions_1.Transaction(); this.staking.registerRewardMoveCall(params, tx); return tx; } createStakePosition(params, txb) { const tx = txb ?? new transactions_1.Transaction(); const position = this.staking.createStakePositonMoveCall(params, tx); tx.transferObjects([position], __classPrivateFieldGet(this, _StakingClient_address, "f")); return tx; } async stake(coinType, amount, positionId, txb) { const tx = txb ?? new transactions_1.Transaction(); const userPositionIds = await this.queryUserPositionIds(); if ((userPositionIds && userPositionIds.length > 0) || !positionId) { const allCoins = await this.getCoins(coinType); const inputCoin = (0, coin_1.buildInputCoin)(tx, allCoins, amount, coinType); if (!positionId) { positionId = userPositionIds[0]; } this.staking.stakeMoveCall({ position: positionId, coin: inputCoin.targetCoin, }, tx); return tx; } else { const tx = await this.createStakePositionAndStake(coinType, amount); return tx; } } claimReward(params, txb) { const tx = txb ?? new transactions_1.Transaction(); const coin = this.staking.claimRewardMoveCall(params, tx); tx.transferObjects([coin], __classPrivateFieldGet(this, _StakingClient_address, "f")); return tx; } async createStakePositionAndStake(coinType, amount, txb) { const tx = txb ?? new transactions_1.Transaction(); const allCoins = await this.getCoins(coinType); const inputCoin = (0, coin_1.buildInputCoin)(tx, allCoins, amount, coinType); const position = this.staking.createStakePositionAndStakeMoveCall({ coin: inputCoin.targetCoin, }, tx); tx.transferObjects([position], __classPrivateFieldGet(this, _StakingClient_address, "f")); return tx; } unstake(params, txb) { const tx = txb ?? new transactions_1.Transaction(); const coin = this.staking.unstakeMoveCall(params, tx); tx.transferObjects([coin], __classPrivateFieldGet(this, _StakingClient_address, "f")); return tx; } closeStakePosition(params, txb) { const tx = txb ?? new transactions_1.Transaction(); this.staking.closeStakePositionMoveCall(params, tx); return tx; } async calculatePendingReward(params, txb) { const tx = txb ?? new transactions_1.Transaction(); this.staking.calculatePendingRewardMoveCall(params, tx); const res = await this.devInspectTransactionBlock(tx); const events = res.events; const pendingRewards = []; for (const event of events) { if (event.type === `${__classPrivateFieldGet(this, _StakingClient_config, "f").BLUB_STAKING_PACKAGE_ID}::events::CalculatePendingRewardEvent`) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const pendingReward = event.parsedJson; pendingRewards.push({ coinType: pendingReward.reward_info.coin_type.name, pendingReward: BigInt(pendingReward.reward_info.pending_reward_amount), }); } } return pendingRewards; } // ======================== QUERY ======================== // async queryRewardConfigByCoinType(rewardCoinType: string) { // return queryRewardConfig(this.client, this.#config.PROTOCOL_CONFIG_ID, rewardCoinType) // } async queryProtocolConfig() { return (0, config_1.queryProtocolConfig)(this.client, __classPrivateFieldGet(this, _StakingClient_config, "f").PROTOCOL_CONFIG_ID); } async queryRewardConfigs() { const protocolConfig = await (0, config_1.queryProtocolConfig)(this.client, __classPrivateFieldGet(this, _StakingClient_config, "f").PROTOCOL_CONFIG_ID); return protocolConfig.rewardConfigs; } async queryRewardConfigByCoinType(rewardCoinType) { return (0, config_1.queryRewardConfigByCoinType)(this.client, __classPrivateFieldGet(this, _StakingClient_config, "f").PROTOCOL_CONFIG_ID, rewardCoinType); } async queryRewardManager() { return (0, reward_1.queryRewardManager)(this.client, __classPrivateFieldGet(this, _StakingClient_config, "f").REWARD_MANAGER_ID); } async queryRewardInfo(rewardCoinType) { return (0, reward_1.queryRewardInfo)(this.client, __classPrivateFieldGet(this, _StakingClient_config, "f").REWARD_MANAGER_ID, rewardCoinType); } async queryUserPositionIds() { const rewardManager = await (0, reward_1.queryRewardManager)(this.client, __classPrivateFieldGet(this, _StakingClient_config, "f").REWARD_MANAGER_ID); if (!rewardManager) { return null; } return (0, staking_1.queryUserPositionIds)(this.client, rewardManager.userPositionsRecordId, __classPrivateFieldGet(this, _StakingClient_address, "f")); } async queryUserPositions(positionIds) { const rewardManager = await (0, reward_1.queryRewardManager)(this.client, __classPrivateFieldGet(this, _StakingClient_config, "f").REWARD_MANAGER_ID); if (!rewardManager) { return null; } return (0, staking_1.queryUserPositions)(this.client, positionIds); } /** * Returns the total staked amount for a given user by summing all valid positions. * * @param userPositionRecordId - The global position record object ID * @param wallet - User wallet address * @returns Total staked amount as a BigInt */ async getUserTotalStaked(userPositionRecordId, wallet) { return (0, staking_1.getUserTotalStaked)(this.client, userPositionRecordId, wallet); } } exports.StakingClient = StakingClient; _StakingClient_config = new WeakMap(), _StakingClient_address = new WeakMap();