UNPKG

@kamino-finance/klend-sdk

Version:

Typescript SDK for interacting with the Kamino Lending (klend) protocol

302 lines (284 loc) 10.5 kB
import { PublicKey, Connection } from "@solana/web3.js" import BN from "bn.js" // eslint-disable-line @typescript-eslint/no-unused-vars import * as borsh from "@coral-xyz/borsh" // eslint-disable-line @typescript-eslint/no-unused-vars import * as types from "../types" // eslint-disable-line @typescript-eslint/no-unused-vars import { PROGRAM_ID } from "../programId" export interface UserStateFields { userId: BN farmState: PublicKey owner: PublicKey /** Indicate if this user state is part of a delegated farm */ isFarmDelegated: number padding0: Array<number> /** * Rewards tally used for computation of gained rewards * (scaled from `Decimal` representation). */ rewardsTallyScaled: Array<BN> /** Number of reward tokens ready for claim */ rewardsIssuedUnclaimed: Array<BN> lastClaimTs: Array<BN> /** * User stake deposited and usable, generating rewards and fees. * (scaled from `Decimal` representation). */ activeStakeScaled: BN /** * User stake deposited but not usable and not generating rewards yet. * (scaled from `Decimal` representation). */ pendingDepositStakeScaled: BN /** * After this timestamp, pending user stake can be moved to user stake * Initialized to now() + delayed user stake period */ pendingDepositStakeTs: BN /** * User deposits unstaked, pending for withdrawal, not usable and not generating rewards. * (scaled from `Decimal` representation). */ pendingWithdrawalUnstakeScaled: BN /** After this timestamp, user can withdraw their deposit. */ pendingWithdrawalUnstakeTs: BN /** User bump used for account address validation */ bump: BN /** Delegatee used for initialisation - useful to check against */ delegatee: PublicKey lastStakeTs: BN padding1: Array<BN> } export interface UserStateJSON { userId: string farmState: string owner: string /** Indicate if this user state is part of a delegated farm */ isFarmDelegated: number padding0: Array<number> /** * Rewards tally used for computation of gained rewards * (scaled from `Decimal` representation). */ rewardsTallyScaled: Array<string> /** Number of reward tokens ready for claim */ rewardsIssuedUnclaimed: Array<string> lastClaimTs: Array<string> /** * User stake deposited and usable, generating rewards and fees. * (scaled from `Decimal` representation). */ activeStakeScaled: string /** * User stake deposited but not usable and not generating rewards yet. * (scaled from `Decimal` representation). */ pendingDepositStakeScaled: string /** * After this timestamp, pending user stake can be moved to user stake * Initialized to now() + delayed user stake period */ pendingDepositStakeTs: string /** * User deposits unstaked, pending for withdrawal, not usable and not generating rewards. * (scaled from `Decimal` representation). */ pendingWithdrawalUnstakeScaled: string /** After this timestamp, user can withdraw their deposit. */ pendingWithdrawalUnstakeTs: string /** User bump used for account address validation */ bump: string /** Delegatee used for initialisation - useful to check against */ delegatee: string lastStakeTs: string padding1: Array<string> } export class UserState { readonly userId: BN readonly farmState: PublicKey readonly owner: PublicKey /** Indicate if this user state is part of a delegated farm */ readonly isFarmDelegated: number readonly padding0: Array<number> /** * Rewards tally used for computation of gained rewards * (scaled from `Decimal` representation). */ readonly rewardsTallyScaled: Array<BN> /** Number of reward tokens ready for claim */ readonly rewardsIssuedUnclaimed: Array<BN> readonly lastClaimTs: Array<BN> /** * User stake deposited and usable, generating rewards and fees. * (scaled from `Decimal` representation). */ readonly activeStakeScaled: BN /** * User stake deposited but not usable and not generating rewards yet. * (scaled from `Decimal` representation). */ readonly pendingDepositStakeScaled: BN /** * After this timestamp, pending user stake can be moved to user stake * Initialized to now() + delayed user stake period */ readonly pendingDepositStakeTs: BN /** * User deposits unstaked, pending for withdrawal, not usable and not generating rewards. * (scaled from `Decimal` representation). */ readonly pendingWithdrawalUnstakeScaled: BN /** After this timestamp, user can withdraw their deposit. */ readonly pendingWithdrawalUnstakeTs: BN /** User bump used for account address validation */ readonly bump: BN /** Delegatee used for initialisation - useful to check against */ readonly delegatee: PublicKey readonly lastStakeTs: BN readonly padding1: Array<BN> static readonly discriminator = Buffer.from([ 72, 177, 85, 249, 76, 167, 186, 126, ]) static readonly layout = borsh.struct([ borsh.u64("userId"), borsh.publicKey("farmState"), borsh.publicKey("owner"), borsh.u8("isFarmDelegated"), borsh.array(borsh.u8(), 7, "padding0"), borsh.array(borsh.u128(), 10, "rewardsTallyScaled"), borsh.array(borsh.u64(), 10, "rewardsIssuedUnclaimed"), borsh.array(borsh.u64(), 10, "lastClaimTs"), borsh.u128("activeStakeScaled"), borsh.u128("pendingDepositStakeScaled"), borsh.u64("pendingDepositStakeTs"), borsh.u128("pendingWithdrawalUnstakeScaled"), borsh.u64("pendingWithdrawalUnstakeTs"), borsh.u64("bump"), borsh.publicKey("delegatee"), borsh.u64("lastStakeTs"), borsh.array(borsh.u64(), 50, "padding1"), ]) constructor(fields: UserStateFields) { this.userId = fields.userId this.farmState = fields.farmState this.owner = fields.owner this.isFarmDelegated = fields.isFarmDelegated this.padding0 = fields.padding0 this.rewardsTallyScaled = fields.rewardsTallyScaled this.rewardsIssuedUnclaimed = fields.rewardsIssuedUnclaimed this.lastClaimTs = fields.lastClaimTs this.activeStakeScaled = fields.activeStakeScaled this.pendingDepositStakeScaled = fields.pendingDepositStakeScaled this.pendingDepositStakeTs = fields.pendingDepositStakeTs this.pendingWithdrawalUnstakeScaled = fields.pendingWithdrawalUnstakeScaled this.pendingWithdrawalUnstakeTs = fields.pendingWithdrawalUnstakeTs this.bump = fields.bump this.delegatee = fields.delegatee this.lastStakeTs = fields.lastStakeTs this.padding1 = fields.padding1 } static async fetch( c: Connection, address: PublicKey, programId: PublicKey = PROGRAM_ID ): Promise<UserState | null> { const info = await c.getAccountInfo(address) if (info === null) { return null } if (!info.owner.equals(programId)) { throw new Error("account doesn't belong to this program") } return this.decode(info.data) } static async fetchMultiple( c: Connection, addresses: PublicKey[], programId: PublicKey = PROGRAM_ID ): Promise<Array<UserState | null>> { const infos = await c.getMultipleAccountsInfo(addresses) return infos.map((info) => { if (info === null) { return null } if (!info.owner.equals(programId)) { throw new Error("account doesn't belong to this program") } return this.decode(info.data) }) } static decode(data: Buffer): UserState { if (!data.slice(0, 8).equals(UserState.discriminator)) { throw new Error("invalid account discriminator") } const dec = UserState.layout.decode(data.slice(8)) return new UserState({ userId: dec.userId, farmState: dec.farmState, owner: dec.owner, isFarmDelegated: dec.isFarmDelegated, padding0: dec.padding0, rewardsTallyScaled: dec.rewardsTallyScaled, rewardsIssuedUnclaimed: dec.rewardsIssuedUnclaimed, lastClaimTs: dec.lastClaimTs, activeStakeScaled: dec.activeStakeScaled, pendingDepositStakeScaled: dec.pendingDepositStakeScaled, pendingDepositStakeTs: dec.pendingDepositStakeTs, pendingWithdrawalUnstakeScaled: dec.pendingWithdrawalUnstakeScaled, pendingWithdrawalUnstakeTs: dec.pendingWithdrawalUnstakeTs, bump: dec.bump, delegatee: dec.delegatee, lastStakeTs: dec.lastStakeTs, padding1: dec.padding1, }) } toJSON(): UserStateJSON { return { userId: this.userId.toString(), farmState: this.farmState.toString(), owner: this.owner.toString(), isFarmDelegated: this.isFarmDelegated, padding0: this.padding0, rewardsTallyScaled: this.rewardsTallyScaled.map((item) => item.toString() ), rewardsIssuedUnclaimed: this.rewardsIssuedUnclaimed.map((item) => item.toString() ), lastClaimTs: this.lastClaimTs.map((item) => item.toString()), activeStakeScaled: this.activeStakeScaled.toString(), pendingDepositStakeScaled: this.pendingDepositStakeScaled.toString(), pendingDepositStakeTs: this.pendingDepositStakeTs.toString(), pendingWithdrawalUnstakeScaled: this.pendingWithdrawalUnstakeScaled.toString(), pendingWithdrawalUnstakeTs: this.pendingWithdrawalUnstakeTs.toString(), bump: this.bump.toString(), delegatee: this.delegatee.toString(), lastStakeTs: this.lastStakeTs.toString(), padding1: this.padding1.map((item) => item.toString()), } } static fromJSON(obj: UserStateJSON): UserState { return new UserState({ userId: new BN(obj.userId), farmState: new PublicKey(obj.farmState), owner: new PublicKey(obj.owner), isFarmDelegated: obj.isFarmDelegated, padding0: obj.padding0, rewardsTallyScaled: obj.rewardsTallyScaled.map((item) => new BN(item)), rewardsIssuedUnclaimed: obj.rewardsIssuedUnclaimed.map( (item) => new BN(item) ), lastClaimTs: obj.lastClaimTs.map((item) => new BN(item)), activeStakeScaled: new BN(obj.activeStakeScaled), pendingDepositStakeScaled: new BN(obj.pendingDepositStakeScaled), pendingDepositStakeTs: new BN(obj.pendingDepositStakeTs), pendingWithdrawalUnstakeScaled: new BN( obj.pendingWithdrawalUnstakeScaled ), pendingWithdrawalUnstakeTs: new BN(obj.pendingWithdrawalUnstakeTs), bump: new BN(obj.bump), delegatee: new PublicKey(obj.delegatee), lastStakeTs: new BN(obj.lastStakeTs), padding1: obj.padding1.map((item) => new BN(item)), }) } }