UNPKG

@kamino-finance/kliquidity-sdk

Version:

Typescript SDK for interacting with the Kamino Liquidity (kliquidity) protocol

254 lines (236 loc) 8.41 kB
/* eslint-disable @typescript-eslint/no-unused-vars */ import { address, Address, fetchEncodedAccount, fetchEncodedAccounts, GetAccountInfoApi, GetMultipleAccountsApi, Rpc, } from "@solana/kit" /* eslint-enable @typescript-eslint/no-unused-vars */ 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 { borshAddress } from "../utils" // 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 WhirlpoolFields { whirlpoolsConfig: Address whirlpoolBump: Array<number> tickSpacing: number tickSpacingSeed: Array<number> feeRate: number protocolFeeRate: number liquidity: BN sqrtPrice: BN tickCurrentIndex: number protocolFeeOwedA: BN protocolFeeOwedB: BN tokenMintA: Address tokenVaultA: Address feeGrowthGlobalA: BN tokenMintB: Address tokenVaultB: Address feeGrowthGlobalB: BN rewardLastUpdatedTimestamp: BN rewardInfos: Array<types.WhirlpoolRewardInfoFields> } export interface WhirlpoolJSON { whirlpoolsConfig: string whirlpoolBump: Array<number> tickSpacing: number tickSpacingSeed: Array<number> feeRate: number protocolFeeRate: number liquidity: string sqrtPrice: string tickCurrentIndex: number protocolFeeOwedA: string protocolFeeOwedB: string tokenMintA: string tokenVaultA: string feeGrowthGlobalA: string tokenMintB: string tokenVaultB: string feeGrowthGlobalB: string rewardLastUpdatedTimestamp: string rewardInfos: Array<types.WhirlpoolRewardInfoJSON> } /** External types */ export class Whirlpool { readonly whirlpoolsConfig: Address readonly whirlpoolBump: Array<number> readonly tickSpacing: number readonly tickSpacingSeed: Array<number> readonly feeRate: number readonly protocolFeeRate: number readonly liquidity: BN readonly sqrtPrice: BN readonly tickCurrentIndex: number readonly protocolFeeOwedA: BN readonly protocolFeeOwedB: BN readonly tokenMintA: Address readonly tokenVaultA: Address readonly feeGrowthGlobalA: BN readonly tokenMintB: Address readonly tokenVaultB: Address readonly feeGrowthGlobalB: BN readonly rewardLastUpdatedTimestamp: BN readonly rewardInfos: Array<types.WhirlpoolRewardInfo> static readonly discriminator = Buffer.from([ 63, 149, 209, 12, 225, 128, 99, 9, ]) static readonly layout = borsh.struct<Whirlpool>([ borshAddress("whirlpoolsConfig"), borsh.array(borsh.u8(), 1, "whirlpoolBump"), borsh.u16("tickSpacing"), borsh.array(borsh.u8(), 2, "tickSpacingSeed"), borsh.u16("feeRate"), borsh.u16("protocolFeeRate"), borsh.u128("liquidity"), borsh.u128("sqrtPrice"), borsh.i32("tickCurrentIndex"), borsh.u64("protocolFeeOwedA"), borsh.u64("protocolFeeOwedB"), borshAddress("tokenMintA"), borshAddress("tokenVaultA"), borsh.u128("feeGrowthGlobalA"), borshAddress("tokenMintB"), borshAddress("tokenVaultB"), borsh.u128("feeGrowthGlobalB"), borsh.u64("rewardLastUpdatedTimestamp"), borsh.array(types.WhirlpoolRewardInfo.layout(), 3, "rewardInfos"), ]) constructor(fields: WhirlpoolFields) { this.whirlpoolsConfig = fields.whirlpoolsConfig this.whirlpoolBump = fields.whirlpoolBump this.tickSpacing = fields.tickSpacing this.tickSpacingSeed = fields.tickSpacingSeed this.feeRate = fields.feeRate this.protocolFeeRate = fields.protocolFeeRate this.liquidity = fields.liquidity this.sqrtPrice = fields.sqrtPrice this.tickCurrentIndex = fields.tickCurrentIndex this.protocolFeeOwedA = fields.protocolFeeOwedA this.protocolFeeOwedB = fields.protocolFeeOwedB this.tokenMintA = fields.tokenMintA this.tokenVaultA = fields.tokenVaultA this.feeGrowthGlobalA = fields.feeGrowthGlobalA this.tokenMintB = fields.tokenMintB this.tokenVaultB = fields.tokenVaultB this.feeGrowthGlobalB = fields.feeGrowthGlobalB this.rewardLastUpdatedTimestamp = fields.rewardLastUpdatedTimestamp this.rewardInfos = fields.rewardInfos.map( (item) => new types.WhirlpoolRewardInfo({ ...item }) ) } static async fetch( rpc: Rpc<GetAccountInfoApi>, address: Address, programId: Address = PROGRAM_ID ): Promise<Whirlpool | null> { const info = await fetchEncodedAccount(rpc, address) if (!info.exists) { return null } if (info.programAddress !== programId) { throw new Error("account doesn't belong to this program") } return this.decode(Buffer.from(info.data)) } static async fetchMultiple( rpc: Rpc<GetMultipleAccountsApi>, addresses: Address[], programId: Address = PROGRAM_ID ): Promise<Array<Whirlpool | null>> { const infos = await fetchEncodedAccounts(rpc, addresses) return infos.map((info) => { if (!info.exists) { return null } if (info.programAddress !== programId) { throw new Error("account doesn't belong to this program") } return this.decode(Buffer.from(info.data)) }) } static decode(data: Buffer): Whirlpool { if (!data.slice(0, 8).equals(Whirlpool.discriminator)) { throw new Error("invalid account discriminator") } const dec = Whirlpool.layout.decode(data.slice(8)) return new Whirlpool({ whirlpoolsConfig: dec.whirlpoolsConfig, whirlpoolBump: dec.whirlpoolBump, tickSpacing: dec.tickSpacing, tickSpacingSeed: dec.tickSpacingSeed, feeRate: dec.feeRate, protocolFeeRate: dec.protocolFeeRate, liquidity: dec.liquidity, sqrtPrice: dec.sqrtPrice, tickCurrentIndex: dec.tickCurrentIndex, protocolFeeOwedA: dec.protocolFeeOwedA, protocolFeeOwedB: dec.protocolFeeOwedB, tokenMintA: dec.tokenMintA, tokenVaultA: dec.tokenVaultA, feeGrowthGlobalA: dec.feeGrowthGlobalA, tokenMintB: dec.tokenMintB, tokenVaultB: dec.tokenVaultB, feeGrowthGlobalB: dec.feeGrowthGlobalB, rewardLastUpdatedTimestamp: dec.rewardLastUpdatedTimestamp, rewardInfos: dec.rewardInfos.map( ( item: any /* eslint-disable-line @typescript-eslint/no-explicit-any */ ) => types.WhirlpoolRewardInfo.fromDecoded(item) ), }) } toJSON(): WhirlpoolJSON { return { whirlpoolsConfig: this.whirlpoolsConfig, whirlpoolBump: this.whirlpoolBump, tickSpacing: this.tickSpacing, tickSpacingSeed: this.tickSpacingSeed, feeRate: this.feeRate, protocolFeeRate: this.protocolFeeRate, liquidity: this.liquidity.toString(), sqrtPrice: this.sqrtPrice.toString(), tickCurrentIndex: this.tickCurrentIndex, protocolFeeOwedA: this.protocolFeeOwedA.toString(), protocolFeeOwedB: this.protocolFeeOwedB.toString(), tokenMintA: this.tokenMintA, tokenVaultA: this.tokenVaultA, feeGrowthGlobalA: this.feeGrowthGlobalA.toString(), tokenMintB: this.tokenMintB, tokenVaultB: this.tokenVaultB, feeGrowthGlobalB: this.feeGrowthGlobalB.toString(), rewardLastUpdatedTimestamp: this.rewardLastUpdatedTimestamp.toString(), rewardInfos: this.rewardInfos.map((item) => item.toJSON()), } } static fromJSON(obj: WhirlpoolJSON): Whirlpool { return new Whirlpool({ whirlpoolsConfig: address(obj.whirlpoolsConfig), whirlpoolBump: obj.whirlpoolBump, tickSpacing: obj.tickSpacing, tickSpacingSeed: obj.tickSpacingSeed, feeRate: obj.feeRate, protocolFeeRate: obj.protocolFeeRate, liquidity: new BN(obj.liquidity), sqrtPrice: new BN(obj.sqrtPrice), tickCurrentIndex: obj.tickCurrentIndex, protocolFeeOwedA: new BN(obj.protocolFeeOwedA), protocolFeeOwedB: new BN(obj.protocolFeeOwedB), tokenMintA: address(obj.tokenMintA), tokenVaultA: address(obj.tokenVaultA), feeGrowthGlobalA: new BN(obj.feeGrowthGlobalA), tokenMintB: address(obj.tokenMintB), tokenVaultB: address(obj.tokenVaultB), feeGrowthGlobalB: new BN(obj.feeGrowthGlobalB), rewardLastUpdatedTimestamp: new BN(obj.rewardLastUpdatedTimestamp), rewardInfos: obj.rewardInfos.map((item) => types.WhirlpoolRewardInfo.fromJSON(item) ), }) } }