blub-sdk
Version:
A modular SDK for interacting with the BLUB ecosystem on the Sui blockchain.
281 lines (280 loc) • 12.8 kB
JavaScript
"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();