UNPKG

test-raydium-sdk-v2

Version:

An SDK for building applications on top of Raydium.

1 lines 412 kB
{"version":3,"sources":["../../../src/marshmallow/index.ts","../../../src/marshmallow/buffer-layout.ts","../../../src/raydium/farm/config.ts","../../../src/common/logger.ts","../../../src/common/programId.ts","../../../src/raydium/farm/layout.ts","../../../src/raydium/farm/util.ts","../../../src/common/accountInfo.ts","../../../src/common/utility.ts","../../../src/module/amount.ts","../../../src/common/bignumber.ts","../../../node_modules/decimal.js/decimal.mjs","../../../src/module/token.ts","../../../src/common/pubKey.ts","../../../src/raydium/token/constant.ts","../../../src/module/fraction.ts","../../../src/module/formatter.ts","../../../src/module/price.ts","../../../src/module/currency.ts","../../../src/module/percent.ts","../../../src/common/txTool/txTool.ts","../../../src/common/txTool/txType.ts","../../../src/common/txTool/txUtils.ts","../../../src/common/txTool/lookupTable.ts","../../../src/common/lodash.ts","../../../src/common/date.ts","../../../src/common/pda.ts","../../../src/common/transfer.ts","../../../src/raydium/account/layout.ts","../../../src/raydium/farm/instruction.ts","../../../src/raydium/farm/pda.ts"],"sourcesContent":["import { PublicKey } from \"@solana/web3.js\";\nimport BN, { isBN } from \"bn.js\";\n\nimport {\n bits,\n blob,\n Blob,\n Layout,\n offset as _offset,\n seq as _seq,\n Structure as _Structure,\n u32 as _u32,\n u8 as _u8,\n UInt,\n union as _union,\n Union as _Union,\n} from \"./buffer-layout\";\n\nexport * from \"./buffer-layout\";\nexport { blob };\n\nexport class BNLayout<P extends string = \"\"> extends Layout<BN, P> {\n blob: Layout<Buffer>;\n signed: boolean;\n\n constructor(span: number, signed: boolean, property?: P) {\n //@ts-expect-error type wrong for super()'s type different from extends, but it desn't matter\n super(span, property);\n this.blob = blob(span);\n this.signed = signed;\n }\n\n /** @override */\n decode(b: Buffer, offset = 0): BN {\n const num = new BN(this.blob.decode(b, offset), 10, \"le\");\n if (this.signed) {\n return num.fromTwos(this.span * 8).clone();\n }\n return num;\n }\n\n /** @override */\n encode(src: BN, b: Buffer, offset = 0): number {\n if (typeof src === \"number\") src = new BN(src); // src will pass a number accidently in union\n if (this.signed) {\n src = src.toTwos(this.span * 8);\n }\n return this.blob.encode(src.toArrayLike(Buffer, \"le\", this.span), b, offset);\n }\n}\n\nexport class WideBits<P extends string = \"\"> extends Layout<Record<string, boolean>, P> {\n _lower: any;\n _upper: any;\n // TODO: unknown\n constructor(property?: P) {\n //@ts-expect-error type wrong for super()'s type different from extends , but it desn't matter\n super(8, property);\n this._lower = bits(_u32(), false);\n this._upper = bits(_u32(), false);\n }\n\n addBoolean(property: string): void {\n if (this._lower.fields.length < 32) {\n this._lower.addBoolean(property);\n } else {\n this._upper.addBoolean(property);\n }\n }\n\n decode(b: Buffer, offset = 0): Record<string, boolean> {\n const lowerDecoded = this._lower.decode(b, offset);\n const upperDecoded = this._upper.decode(b, offset + this._lower.span);\n return { ...lowerDecoded, ...upperDecoded };\n }\n\n encode(src: any /* TEMP */, b: Buffer, offset = 0): any {\n return this._lower.encode(src, b, offset) + this._upper.encode(src, b, offset + this._lower.span);\n }\n}\n\nexport function u8<P extends string = \"\">(property?: P): UInt<number, P> {\n return new UInt(1, property);\n}\n\nexport function u32<P extends string = \"\">(property?: P): UInt<number, P> {\n return new UInt(4, property);\n}\n\nexport function u64<P extends string = \"\">(property?: P): BNLayout<P> {\n return new BNLayout(8, false, property);\n}\n\nexport function u128<P extends string = \"\">(property?: P): BNLayout<P> {\n return new BNLayout(16, false, property);\n}\n\nexport function i8<P extends string = \"\">(property?: P): BNLayout<P> {\n return new BNLayout(1, true, property);\n}\n\nexport function i64<P extends string = \"\">(property?: P): BNLayout<P> {\n return new BNLayout(8, true, property);\n}\n\nexport function i128<P extends string = \"\">(property?: P): BNLayout<P> {\n return new BNLayout(16, true, property);\n}\n\nexport class WrappedLayout<T, U, P extends string = \"\"> extends Layout<U, P> {\n layout: Layout<T>;\n decoder: (data: T) => U;\n encoder: (src: U) => T;\n\n constructor(layout: Layout<T>, decoder: (data: T) => U, encoder: (src: U) => T, property?: P) {\n //@ts-expect-error type wrong for super()'s type different from extends , but it desn't matter\n super(layout.span, property);\n this.layout = layout;\n this.decoder = decoder;\n this.encoder = encoder;\n }\n\n decode(b: Buffer, offset?: number): U {\n return this.decoder(this.layout.decode(b, offset));\n }\n\n encode(src: U, b: Buffer, offset?: number): number {\n return this.layout.encode(this.encoder(src), b, offset);\n }\n\n getSpan(b: Buffer, offset?: number): number {\n return this.layout.getSpan(b, offset);\n }\n}\n\nexport function publicKey<P extends string = \"\">(property?: P): Layout<PublicKey, P> {\n return new WrappedLayout(\n blob(32),\n (b: Buffer) => new PublicKey(b),\n (key: PublicKey) => key.toBuffer(),\n property,\n );\n}\n\nexport class OptionLayout<T, P> extends Layout<T | null, P> {\n layout: Layout<T>;\n discriminator: Layout<number>;\n\n constructor(layout: Layout<T>, property?: P) {\n //@ts-expect-error type wrong for super()'s type different from extends , but it desn't matter\n super(-1, property);\n this.layout = layout;\n this.discriminator = _u8();\n }\n\n encode(src: T | null, b: Buffer, offset = 0): number {\n if (src === null || src === undefined) {\n return this.discriminator.encode(0, b, offset);\n }\n this.discriminator.encode(1, b, offset);\n return this.layout.encode(src, b, offset + 1) + 1;\n }\n\n decode(b: Buffer, offset = 0): T | null {\n const discriminator = this.discriminator.decode(b, offset);\n if (discriminator === 0) {\n return null;\n } else if (discriminator === 1) {\n return this.layout.decode(b, offset + 1);\n }\n throw new Error(\"Invalid option \" + this.property);\n }\n\n getSpan(b: Buffer, offset = 0): number {\n const discriminator = this.discriminator.decode(b, offset);\n if (discriminator === 0) {\n return 1;\n } else if (discriminator === 1) {\n return this.layout.getSpan(b, offset + 1) + 1;\n }\n throw new Error(\"Invalid option \" + this.property);\n }\n}\n\nexport function option<T, P extends string = \"\">(layout: Layout<T>, property?: P): Layout<T | null, P> {\n return new OptionLayout<T, P>(layout, property);\n}\n\nexport function bool<P extends string = \"\">(property?: P): Layout<boolean, P> {\n return new WrappedLayout(_u8(), decodeBool, encodeBool, property);\n}\n\nexport function decodeBool(value: number): boolean {\n if (value === 0) {\n return false;\n } else if (value === 1) {\n return true;\n }\n throw new Error(\"Invalid bool: \" + value);\n}\n\nexport function encodeBool(value: boolean): number {\n return value ? 1 : 0;\n}\n\nexport function vec<T, P extends string = \"\">(elementLayout: Layout<T>, property?: P): Layout<T[], P> {\n const length = _u32(\"length\");\n const layout: Layout<{ values: T[] }> = struct([\n length,\n seq(elementLayout, _offset(length, -length.span), \"values\"),\n ]) as any; // Something I don't know\n return new WrappedLayout(\n layout,\n ({ values }) => values,\n (values) => ({ values }),\n property,\n );\n}\n\nexport function tagged<T, P extends string = \"\">(tag: BN, layout: Layout<T>, property?: P): Layout<T, P> {\n const wrappedLayout: Layout<{ tag: BN; data: T }> = struct([u64(\"tag\"), layout.replicate(\"data\")]) as any; // Something I don't know\n\n function decodeTag({ tag: receivedTag, data }: { tag: BN; data: T }): T {\n if (!receivedTag.eq(tag)) {\n throw new Error(\"Invalid tag, expected: \" + tag.toString(\"hex\") + \", got: \" + receivedTag.toString(\"hex\"));\n }\n return data;\n }\n\n return new WrappedLayout(wrappedLayout, decodeTag, (data) => ({ tag, data }), property);\n}\n\nexport function vecU8<P extends string = \"\">(property?: P): Layout<Buffer, P> {\n const length = _u32(\"length\");\n const layout: Layout<{ data: Buffer }> = struct([length, blob(_offset(length, -length.span), \"data\")]) as any; // Something I don't know\n return new WrappedLayout(\n layout,\n ({ data }) => data,\n (data) => ({ data }),\n property,\n );\n}\n\nexport function str<P extends string = \"\">(property?: P): Layout<string, P> {\n return new WrappedLayout(\n vecU8(),\n (data) => data.toString(\"utf-8\"),\n (s) => Buffer.from(s, \"utf-8\"),\n property,\n );\n}\n\nexport interface EnumLayout<T, P extends string = \"\"> extends Layout<T, P> {\n registry: Record<string, Layout<any>>;\n}\n\nexport function rustEnum<T, P extends string = \"\">(variants: Layout<any>[], property?: P): EnumLayout<T, P> {\n const unionLayout = _union(_u8(), property);\n variants.forEach((variant, index) => unionLayout.addVariant(index, variant, variant.property));\n return unionLayout as any; // ?why use UnionLayout? This must be a fault\n}\n\nexport function array<T, P extends string = \"\">(\n elementLayout: Layout<T>,\n length: number,\n property?: P,\n): Layout<T[], P> {\n const layout = struct([seq(elementLayout, length, \"values\")]) as any as Layout<{ values: T[] }>; // Something I don't know\n return new WrappedLayout(\n layout,\n ({ values }) => values,\n (values) => ({ values }),\n property,\n );\n}\n\nexport class Structure<T, P, D> extends _Structure<T, P, D> {\n /** @override */\n decode(b: Buffer, offset?: number): D {\n return super.decode(b, offset);\n }\n}\n\nexport function struct<T, P extends string = \"\">(\n fields: T,\n property?: P,\n decodePrefixes?: boolean,\n): T extends Layout<infer Value, infer Property>[]\n ? Structure<\n Value,\n P,\n {\n [K in Exclude<Extract<Property, string>, \"\">]: Extract<T[number], Layout<any, K>> extends Layout<infer V, any>\n ? V\n : any;\n }\n >\n : any {\n //@ts-expect-error this type is not quite satisfied the define, but, never no need to worry about.\n return new Structure(fields, property, decodePrefixes);\n}\n\nexport type GetLayoutSchemaFromStructure<T extends Structure<any, any, any>> = T extends Structure<any, any, infer S>\n ? S\n : any;\nexport type GetStructureFromLayoutSchema<S> = Structure<any, any, S>;\n\nexport class Union<Schema> extends _Union<Schema> {\n encodeInstruction(instruction: any): Buffer {\n const instructionMaxSpan = Math.max(...Object.values(this.registry).map((r) => r.span));\n const b = Buffer.alloc(instructionMaxSpan);\n return b.slice(0, this.encode(instruction, b));\n }\n\n decodeInstruction(instruction: any): Partial<Schema> {\n return this.decode(instruction);\n }\n}\nexport function union<UnionSchema extends { [key: string]: any } = any>(\n discr: any,\n defaultLayout?: any,\n property?: string,\n): Union<UnionSchema> {\n return new Union(discr, defaultLayout, property);\n}\n\nclass Zeros extends Blob {\n decode(b: Buffer, offset: number): Buffer {\n const slice = super.decode(b, offset);\n if (!slice.every((v) => v === 0)) {\n throw new Error(\"nonzero padding bytes\");\n }\n return slice;\n }\n}\n\nexport function zeros(length: number): Zeros {\n return new Zeros(length);\n}\n\nexport function seq<T, P extends string = \"\", AnotherP extends string = \"\">(\n elementLayout: Layout<T, P>,\n count: number | BN | Layout<BN | number, P>,\n property?: AnotherP,\n): Layout<T[], AnotherP> {\n let parsedCount: number;\n const superCount =\n typeof count === \"number\"\n ? count\n : isBN(count)\n ? count.toNumber()\n : new Proxy(count as unknown as Layout<number> /* pretend to be Layout<number> */, {\n get(target, property): any {\n if (!parsedCount) {\n // get count in targetLayout. note that count may be BN\n const countProperty = Reflect.get(target, \"count\");\n\n // let targetLayout's property:count be a number\n parsedCount = isBN(countProperty) ? countProperty.toNumber() : countProperty;\n\n // record the count\n Reflect.set(target, \"count\", parsedCount);\n }\n return Reflect.get(target, property);\n },\n set(target, property, value): any {\n if (property === \"count\") {\n parsedCount = value;\n }\n return Reflect.set(target, property, value);\n },\n });\n\n // @ts-expect-error force type\n return _seq(elementLayout, superCount, property);\n}\n","import {\n bits as _bits,\n BitStructure as _BitStructure,\n blob as _blob,\n Blob as _Blob,\n cstr as _cstr,\n f32 as _f32,\n f32be as _f32be,\n f64 as _f64,\n f64be as _f64be,\n greedy as _greedy,\n Layout as _Layout,\n ns64 as _ns64,\n ns64be as _ns64be,\n nu64 as _nu64,\n nu64be as _nu64be,\n offset as _offset,\n s16 as _s16,\n s16be as _s16be,\n s24 as _s24,\n s24be as _s24be,\n s32 as _s32,\n s32be as _s32be,\n s40 as _s40,\n s40be as _s40be,\n s48 as _s48,\n s48be as _s48be,\n s8 as _s8,\n seq as _seq,\n struct as _struct,\n Structure as _Structure,\n u16 as _u16,\n u16be as _u16be,\n u24 as _u24,\n u24be as _u24be,\n u32 as _u32,\n u32be as _u32be,\n u40 as _u40,\n u40be as _u40be,\n u48 as _u48,\n u48be as _u48be,\n u8 as _u8,\n UInt as _UInt,\n union as _union,\n Union as _Union,\n unionLayoutDiscriminator as _unionLayoutDiscriminator,\n utf8 as _utf8,\n} from \"@solana/buffer-layout\";\n\n//#region ------------------- Layout -------------------\nexport interface Layout<T = any, P = \"\"> {\n span: number;\n property?: P;\n decode(b: Buffer, offset?: number): T;\n encode(src: T, b: Buffer, offset?: number): number;\n getSpan(b: Buffer, offset?: number): number;\n replicate<AP extends string>(name: AP): Layout<T, AP>;\n}\nexport interface LayoutConstructor {\n new <T, P>(): Layout<T, P>; // for class extends syntex\n new <T, P>(span?: T, property?: P): Layout<T, P>;\n readonly prototype: Layout;\n}\nexport const Layout = _Layout as unknown as LayoutConstructor;\n//#endregion\n\n//#region ------------------- Structure -------------------\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport interface Structure<T = any, P = \"\", DecodeSchema extends { [key: string]: any } = any>\n extends Layout<DecodeSchema, P> {\n span: number;\n decode(b: Buffer, offset?: number): DecodeSchema;\n layoutFor<AP extends string>(property: AP): Layout<DecodeSchema[AP]>;\n offsetOf<AP extends string>(property: AP): number;\n}\ninterface StructureConstructor {\n new <T = any, P = \"\", DecodeSchema extends { [key: string]: any } = any>(): Structure<T, P, DecodeSchema>;\n new <T = any, P = \"\", DecodeSchema extends { [key: string]: any } = any>(\n fields: T,\n property?: P,\n decodePrefixes?: boolean,\n ): Structure<T, P, DecodeSchema>;\n}\nexport const Structure = _Structure as unknown as StructureConstructor;\n//#endregion\n\n//#region ------------------- Union -------------------\nexport interface Union<UnionSchema extends { [key: string]: any } = any> extends Layout {\n registry: object;\n decode(b: Buffer, offset?: number): Partial<UnionSchema>;\n addVariant(\n variant: number,\n layout: Structure<any, any, Partial<UnionSchema>> | Layout<any, keyof UnionSchema>,\n property?: string,\n ): any /* TEMP: code in Layout.js 1809 */;\n}\ninterface UnionConstructor {\n new <UnionSchema extends { [key: string]: any } = any>(): Union<UnionSchema>;\n new <UnionSchema extends { [key: string]: any } = any>(\n discr: Layout<any, any>,\n defaultLayout: Layout<any, any>,\n property?: string,\n ): Union<UnionSchema>;\n}\nexport const Union = _Union as unknown as UnionConstructor;\n//#endregion\n\n//#region ------------------- BitStructure -------------------\nexport type BitStructure<T = unknown /* TEMP */, P = \"\"> = Layout<T, P>;\ninterface BitStructureConstructor {\n new (...params: any[]): BitStructure;\n}\nexport const BitStructure = _BitStructure as BitStructureConstructor;\n//#endregion\n\n//#region ------------------- UInt -------------------\nexport type UInt<T = any, P = \"\"> = Layout<T, P>;\ninterface UIntConstructor {\n new <T, P>(span?: T, property?: P): UInt<T, P>;\n}\nexport const UInt = _UInt as UIntConstructor;\n//#endregion\n\n//#region ------------------- Blob -------------------\nexport type Blob<P extends string = \"\"> = Layout<Buffer, P>;\ninterface BlobConstructor {\n new (...params: ConstructorParameters<LayoutConstructor>): Blob;\n}\nexport const Blob = _Blob as unknown as BlobConstructor;\n//#endregion\n\nexport const greedy = _greedy as <P extends string = \"\">(elementSpan?: number, property?: P) => Layout<number, P>;\nexport const u8 = _u8 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u16 = _u16 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u24 = _u24 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u32 = _u32 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u40 = _u40 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u48 = _u48 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const nu64 = _nu64 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u16be = _u16be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u24be = _u24be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u32be = _u32be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u40be = _u40be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u48be = _u48be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const nu64be = _nu64be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s8 = _s8 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s16 = _s16 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s24 = _s24 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s32 = _s32 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s40 = _s40 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s48 = _s48 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const ns64 = _ns64 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s16be = _s16be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s24be = _s24be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s32be = _s32be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s40be = _s40be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s48be = _s48be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const ns64be = _ns64be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const f32 = _f32 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const f32be = _f32be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const f64 = _f64 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const f64be = _f64be as <P extends string = \"\">(property?: P) => Layout<number, P>;\n\nexport const struct = _struct as <T, P extends string = \"\">(\n fields: T,\n property?: P,\n decodePrefixes?: boolean,\n) => T extends Layout<infer Value, infer Property>[]\n ? Structure<\n Value,\n P,\n {\n [K in Exclude<Extract<Property, string>, \"\">]: Extract<T[number], Layout<any, K>> extends Layout<infer V, any>\n ? V\n : any;\n }\n >\n : any;\n\nexport const seq = _seq as unknown as <T, P>(\n elementLayout: Layout<T, string>,\n count: number | Layout<number, string>,\n property?: P,\n) => Layout<T[]>;\nexport const union = _union as <UnionSchema extends { [key: string]: any } = any>(\n discr: Layout<any, any>,\n defaultLayout?: any,\n property?: string,\n) => Union<UnionSchema>;\nexport const unionLayoutDiscriminator = _unionLayoutDiscriminator as <P extends string = \"\">(\n layout: Layout<any, P>,\n property?: P,\n) => any;\nexport const blob = _blob as unknown as <P extends string = \"\">(\n length: number | Layout<number, P>,\n property?: P,\n) => Blob<P>;\nexport const cstr = _cstr as <P extends string = \"\">(property?: P) => Layout<string, P>;\nexport const utf8 = _utf8 as <P extends string = \"\">(maxSpan: number, property?: P) => Layout<string, P>;\nexport const bits = _bits as unknown as <T, P extends string = \"\">(\n word: Layout<T>,\n msb?: boolean,\n property?: P,\n) => BitStructure<T, P>; // TODO: not quite sure\nexport const offset = _offset as unknown as <T, P extends string = \"\">(\n layout: Layout<T, P>,\n offset?: number,\n property?: P,\n) => Layout<T, P>;\n\nexport type GetStructureSchema<T extends Structure> = T extends Structure<any, any, infer S> ? S : unknown;\n","import { PublicKey } from \"@solana/web3.js\";\n\nimport { createLogger } from \"@/common/logger\";\nimport { FARM_PROGRAM_ID_V3, FARM_PROGRAM_ID_V5, FARM_PROGRAM_ID_V6 } from \"@/common/programId\";\nimport { ApiV3Token, RewardInfoV345, RewardInfoV6 } from \"@/api/type\";\n\nimport {\n FarmLedgerLayout,\n farmLedgerLayoutV3_2,\n farmLedgerLayoutV5_2,\n farmLedgerLayoutV6_1,\n FarmStateLayout,\n farmStateV3Layout,\n farmStateV5Layout,\n farmStateV6Layout,\n} from \"./layout\";\n\nconst logger = createLogger(\"Raydium_farm_config\");\n\nexport type FarmVersion = 3 | 4 | 5 | 6;\nexport const FARM_LOCK_MINT = new PublicKey(\"4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R\");\nexport const FARM_LOCK_VAULT = new PublicKey(\"FrspKwj8i3pNmKwXreTveC4fu7KL5ZbGeXdZBe2XViu1\");\n\n/* ================= index ================= */\n// version => farm state layout\nexport const FARM_VERSION_TO_STATE_LAYOUT: {\n [version in FarmVersion]?: FarmStateLayout;\n} = {\n 3: farmStateV3Layout,\n 5: farmStateV5Layout,\n 6: farmStateV6Layout,\n};\n\n// version => farm ledger layout\nexport const FARM_VERSION_TO_LEDGER_LAYOUT: {\n [version in FarmVersion]?: FarmLedgerLayout;\n} = {\n 3: farmLedgerLayoutV3_2,\n 5: farmLedgerLayoutV5_2,\n 6: farmLedgerLayoutV6_1,\n};\n\nexport const isValidFarmVersion = (version: number): boolean => [3, 5, 6].indexOf(version) !== -1;\n\nexport const validateFarmRewards = (params: {\n version: number;\n rewardInfos: { mint: ApiV3Token }[];\n rewardTokenAccountsPublicKeys: PublicKey[];\n}): (() => string | undefined) => {\n const { version, rewardInfos, rewardTokenAccountsPublicKeys } = params;\n\n const infoMsg = `rewardInfo:${JSON.stringify(rewardInfos)}, rewardAccount:${JSON.stringify(\n rewardTokenAccountsPublicKeys,\n )}`;\n\n const validator = {\n 3: (): string | undefined => {\n if (rewardInfos.length !== 1 || rewardTokenAccountsPublicKeys.length !== 1) {\n return `rewardInfos or rewardTokenAccounts lengths not equal 1: ${infoMsg}`;\n }\n },\n 5: (): string | undefined => {\n if (rewardInfos.length !== rewardTokenAccountsPublicKeys.length) {\n return `rewardInfos and rewardTokenAccounts lengths not equal: ${infoMsg}`;\n }\n },\n 6: (): string | undefined => {\n if (!rewardTokenAccountsPublicKeys.length || rewardInfos.length !== rewardTokenAccountsPublicKeys.length) {\n return `no rewardTokenAccounts or rewardInfos and rewardTokenAccounts lengths not equal: ${infoMsg}`;\n }\n },\n };\n\n return validator[version]?.();\n};\n\nexport const poolTypeV6 = { \"Standard SPL\": 0, \"Option tokens\": 1 };\n\nexport const FARM_PROGRAM_TO_VERSION: Record<string, 3 | 5 | 6> = {\n [FARM_PROGRAM_ID_V3.toString()]: 3,\n [FARM_PROGRAM_ID_V5.toString()]: 5,\n [FARM_PROGRAM_ID_V6.toString()]: 6,\n};\n","import { get, set } from \"lodash\";\nimport dayjs from \"dayjs\";\nimport utc from \"dayjs/plugin/utc\";\ndayjs.extend(utc);\n\nexport type ModuleName = \"Common.Api\";\n\nexport enum LogLevel {\n Error,\n Warning,\n Info,\n Debug,\n}\nexport class Logger {\n private logLevel: LogLevel;\n private name: string;\n constructor(params: { name: string; logLevel?: LogLevel }) {\n this.logLevel = params.logLevel !== undefined ? params.logLevel : LogLevel.Error;\n this.name = params.name;\n }\n\n set level(logLevel: LogLevel) {\n this.logLevel = logLevel;\n }\n get time(): string {\n return dayjs().utc().format(\"YYYY/MM/DD HH:mm:ss UTC\");\n }\n get moduleName(): string {\n return this.name;\n }\n\n private isLogLevel(level: LogLevel): boolean {\n return level <= this.logLevel;\n }\n\n public error(...props): Logger {\n if (!this.isLogLevel(LogLevel.Error)) return this;\n console.error(this.time, this.name, \"sdk logger error\", ...props);\n return this;\n }\n\n public logWithError(...props): Logger {\n // this.error(...props)\n const msg = props.map((arg) => (typeof arg === \"object\" ? JSON.stringify(arg) : arg)).join(\", \");\n throw new Error(msg);\n }\n\n public warning(...props): Logger {\n if (!this.isLogLevel(LogLevel.Warning)) return this;\n console.warn(this.time, this.name, \"sdk logger warning\", ...props);\n return this;\n }\n\n public info(...props): Logger {\n if (!this.isLogLevel(LogLevel.Info)) return this;\n console.info(this.time, this.name, \"sdk logger info\", ...props);\n return this;\n }\n\n public debug(...props): Logger {\n if (!this.isLogLevel(LogLevel.Debug)) return this;\n console.debug(this.time, this.name, \"sdk logger debug\", ...props);\n return this;\n }\n}\n\nconst moduleLoggers: { [key in ModuleName]?: Logger } = {};\nconst moduleLevels: { [key in ModuleName]?: LogLevel } = {};\n\nexport function createLogger(moduleName: string): Logger {\n let logger = get(moduleLoggers, moduleName);\n if (!logger) {\n // default level is error\n const logLevel = get(moduleLevels, moduleName);\n\n logger = new Logger({ name: moduleName, logLevel });\n set(moduleLoggers, moduleName, logger);\n }\n\n return logger;\n}\n\nexport function setLoggerLevel(moduleName: string, level: LogLevel): void {\n set(moduleLevels, moduleName, level);\n\n const logger = get(moduleLoggers, moduleName);\n if (logger) logger.level = level;\n}\n","import { PublicKey } from \"@solana/web3.js\";\n\n// raydium\nexport const FARM_PROGRAM_ID_V3 = new PublicKey(\"EhhTKczWMGQt46ynNeRX1WfeagwwJd7ufHvCDjRxjo5Q\");\n// \"fusion\"\nexport const FARM_PROGRAM_ID_V5 = new PublicKey(\"9KEPoZmtHUrBbhWN1v1KWLMkkvwY6WLtAVUCPRtRjP4z\");\n// echosystem\nexport const FARM_PROGRAM_ID_V6 = new PublicKey(\"FarmqiPv5eAj3j1GMdMCMUGXqPUvmquZtMy86QH6rzhG\");\n\nexport const UTIL1216 = new PublicKey(\"CLaimxFqjHzgTJtAGHU47NPhg6qrc5sCnpC4tBLyABQS\");\n\nexport const OPEN_BOOK_PROGRAM = new PublicKey(\"srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX\");\nexport const SERUM_PROGRAM_ID_V3 = new PublicKey(\"9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin\");\n\nexport const AMM_V4 = new PublicKey(\"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8\");\nexport const AMM_STABLE = new PublicKey(\"5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h\");\nexport const CLMM_PROGRAM_ID = new PublicKey(\"CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK\");\nexport const Router = new PublicKey(\"routeUGWgWzqBWFcrCfv8tritsqukccJPu3q5GPP3xS\");\n\nexport const IDO_PROGRAM_ID_V1 = new PublicKey(\"6FJon3QE27qgPVggARueB22hLvoh22VzJpXv4rBEoSLF\");\nexport const IDO_PROGRAM_ID_V2 = new PublicKey(\"CC12se5To1CdEuw7fDS27B7Geo5jJyL7t5UK2B44NgiH\");\nexport const IDO_PROGRAM_ID_V3 = new PublicKey(\"9HzJyW1qZsEiSfMUf6L2jo3CcTKAyBmSyKdwQeYisHrC\");\nexport const IDO_PROGRAM_ID_V4 = new PublicKey(\"DropEU8AvevN3UrXWXTMuz3rqnMczQVNjq3kcSdW2SQi\");\n\nexport const IDO_ALL_PROGRAM = {\n IDO_PROGRAM_ID_V1,\n IDO_PROGRAM_ID_V2,\n IDO_PROGRAM_ID_V3,\n IDO_PROGRAM_ID_V4,\n};\n\nexport const ALL_PROGRAM_ID = {\n AMM_V4,\n AMM_STABLE,\n CLMM_PROGRAM_ID,\n\n FARM_PROGRAM_ID_V3,\n FARM_PROGRAM_ID_V5,\n FARM_PROGRAM_ID_V6,\n\n OPEN_BOOK_PROGRAM,\n SERUM_PROGRAM_ID_V3,\n\n UTIL1216,\n\n Router,\n};\n\nexport type ProgramIdConfig = Partial<typeof ALL_PROGRAM_ID>;\n","import { PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\n\nimport {\n blob,\n GetLayoutSchemaFromStructure,\n GetStructureFromLayoutSchema,\n GetStructureSchema,\n publicKey,\n seq,\n struct,\n u128,\n u64,\n u8,\n i8,\n i64,\n bool,\n} from \"@/marshmallow\";\n\nimport { poolTypeV6 } from \"./config\";\nimport { RewardType } from \"./type\";\n\nexport const associatedLedgerAccountLayout = struct([u8(\"instruction\")]);\nexport const withdrawRewardLayout = struct([u8(\"instruction\")]);\n\nconst farmStateRewardInfoV6Layout = struct([\n u64(\"rewardState\"),\n u64(\"rewardOpenTime\"),\n u64(\"rewardEndTime\"),\n u64(\"rewardLastUpdateTime\"),\n u64(\"totalReward\"),\n u64(\"totalRewardEmissioned\"),\n u64(\"rewardClaimed\"),\n u64(\"rewardPerSecond\"),\n u128(\"accRewardPerShare\"),\n publicKey(\"rewardVault\"),\n publicKey(\"rewardMint\"),\n publicKey(\"rewardSender\"),\n u64(\"rewardType\"),\n seq(u64(), 15, \"padding\"),\n]);\n\nexport const realFarmStateV3Layout = struct([\n u64(\"state\"),\n u64(\"nonce\"),\n publicKey(\"lpVault\"),\n publicKey(\"rewardVault\"),\n publicKey(),\n publicKey(),\n u64(),\n u64(),\n u64(\"totalReward\"),\n u128(\"perShareReward\"),\n u64(\"lastSlot\"),\n u64(\"perSlotReward\"),\n]);\n\nexport const realFarmStateV5Layout = struct([\n u64(\"state\"),\n u64(\"nonce\"),\n publicKey(\"lpVault\"),\n publicKey(\"rewardVaultA\"),\n u64(\"totalRewardA\"),\n u128(\"perShareRewardA\"),\n u64(\"perSlotRewardA\"),\n u8(\"option\"),\n publicKey(\"rewardVaultB\"),\n blob(7),\n u64(\"totalRewardB\"),\n u128(\"perShareRewardB\"),\n u64(\"perSlotRewardB\"),\n u64(\"lastSlot\"),\n publicKey(),\n]);\n\nexport const realFarmV6Layout = struct([\n u64(),\n u64(\"state\"),\n u64(\"nonce\"),\n u64(\"validRewardTokenNum\"),\n u128(\"rewardMultiplier\"),\n u64(\"rewardPeriodMax\"),\n u64(\"rewardPeriodMin\"),\n u64(\"rewardPeriodExtend\"),\n publicKey(\"lpMint\"),\n publicKey(\"lpVault\"),\n seq(farmStateRewardInfoV6Layout, 5, \"rewardInfos\"),\n publicKey(\"creator\"),\n publicKey(),\n seq(u64(), 32, \"padding\"),\n]);\n\nexport const farmStateV3Layout = new Proxy(\n realFarmStateV3Layout as GetStructureFromLayoutSchema<\n {\n version: 3;\n rewardInfos: {\n rewardVault: PublicKey;\n totalReward: BN;\n perSlotReward: BN;\n perShareReward: BN;\n }[];\n } & GetLayoutSchemaFromStructure<typeof realFarmStateV3Layout>\n >,\n {\n get(target, p, receiver): any {\n if (p === \"decode\")\n return (...decodeParams: Parameters<typeof target[\"decode\"]>) => {\n const originalResult = target.decode(...decodeParams);\n return {\n ...originalResult,\n version: 3,\n rewardInfos: [\n {\n rewardVault: originalResult.rewardVault,\n totalReward: originalResult.totalReward,\n perSlotReward: originalResult.perSlotReward,\n perShareReward: originalResult.perShareReward,\n },\n ],\n };\n };\n else return Reflect.get(target, p, receiver);\n },\n },\n);\n\nexport const farmStateV5Layout = new Proxy(\n realFarmStateV5Layout as GetStructureFromLayoutSchema<\n {\n version: 5;\n rewardInfos: {\n rewardVault: PublicKey;\n totalReward: BN;\n perSlotReward: BN;\n perShareReward: BN;\n }[];\n } & GetLayoutSchemaFromStructure<typeof realFarmStateV5Layout>\n >,\n {\n get(target, p, receiver): any {\n if (p === \"decode\")\n return (...decodeParams: Parameters<typeof target[\"decode\"]>) => {\n const originalResult = target.decode(...decodeParams);\n return {\n ...originalResult,\n version: 5,\n rewardInfos: [\n {\n rewardVault: originalResult.rewardVaultA,\n totalReward: originalResult.totalRewardA,\n perSlotReward: originalResult.perSlotRewardA,\n perShareReward: originalResult.perShareRewardA,\n },\n {\n rewardVault: originalResult.rewardVaultB,\n totalReward: originalResult.totalRewardB,\n perSlotReward: originalResult.perSlotRewardB,\n perShareReward: originalResult.perShareRewardB,\n },\n ],\n };\n };\n else return Reflect.get(target, p, receiver);\n },\n },\n);\n\nexport const farmStateV6Layout = new Proxy(\n realFarmV6Layout as GetStructureFromLayoutSchema<\n {\n version: 6;\n rewardInfos: {\n rewardState: BN;\n rewardOpenTime: BN;\n rewardEndTime: BN;\n rewardLastUpdateTime: BN;\n totalReward: BN;\n totalRewardEmissioned: BN;\n rewardClaimed: BN;\n rewardPerSecond: BN;\n accRewardPerShare: BN;\n rewardVault: PublicKey;\n rewardMint: PublicKey;\n rewardSender: PublicKey;\n rewardType: RewardType;\n }[];\n } & GetLayoutSchemaFromStructure<typeof realFarmV6Layout>\n >,\n {\n get(target, p, receiver): any {\n if (p === \"decode\")\n return (...decodeParams: Parameters<typeof target[\"decode\"]>) => {\n const originalResult = target.decode(...decodeParams);\n return {\n ...originalResult,\n version: 6,\n rewardInfos: originalResult.rewardInfos.map((item) => ({\n ...item,\n rewardType: (Object.entries(poolTypeV6).find((i) => String(i[1]) === item.rewardType.toString()) ?? [\n \"Standard SPL\",\n ])[0],\n })),\n };\n };\n else return Reflect.get(target, p, receiver);\n },\n },\n);\n\nexport const farmRewardTimeInfoLayout = struct([\n u64(\"isSet\"),\n u64(\"rewardPerSecond\"),\n u64(\"rewardOpenTime\"),\n u64(\"rewardEndTime\"),\n u64(\"rewardType\"),\n]);\n\nexport const farmRewardLayout = struct([\n u8(\"instruction\"),\n u64(\"nonce\"),\n seq(farmRewardTimeInfoLayout, 5, \"rewardTimeInfo\"),\n]);\n\nexport const farmRewardRestartLayout = struct([\n u8(\"instruction\"),\n u64(\"rewardReopenTime\"),\n u64(\"rewardEndTime\"),\n u64(\"rewardPerSecond\"),\n]);\n\nexport const farmAddRewardLayout = struct([\n u8(\"instruction\"),\n u64(\"isSet\"),\n u64(\"rewardPerSecond\"),\n u64(\"rewardOpenTime\"),\n u64(\"rewardEndTime\"),\n u64(\"rewardType\"),\n]);\n\nexport type FarmStateLayoutV3 = typeof farmStateV3Layout;\nexport type FarmStateLayoutV5 = typeof farmStateV5Layout;\nexport type FarmStateLayoutV6 = typeof farmStateV6Layout;\n\nexport type FarmStateV3 = GetStructureSchema<FarmStateLayoutV3>;\nexport type FarmStateV5 = GetStructureSchema<FarmStateLayoutV5>;\nexport type FarmStateV6 = GetStructureSchema<FarmStateLayoutV6>;\n\nexport type FarmState = FarmStateV3 | FarmStateV5 | FarmStateV6;\n// farmStateLayoutV3\nexport type FarmStateLayout = FarmStateLayoutV3 | FarmStateLayoutV5 | FarmStateLayoutV6;\n\n/* ================= ledger layouts ================= */\nexport const farmLedgerLayoutV3_1 = struct([\n u64(\"state\"),\n publicKey(\"id\"),\n publicKey(\"owner\"),\n u64(\"deposited\"),\n seq(u64(), 1, \"rewardDebts\"),\n]);\n\nexport const farmLedgerLayoutV3_2 = struct([\n u64(\"state\"),\n publicKey(\"id\"),\n publicKey(\"owner\"),\n u64(\"deposited\"),\n seq(u128(), 1, \"rewardDebts\"),\n u64(\"\"),\n u64(\"voteLockedBalance\"),\n seq(u64(), 15),\n]);\n\nexport const farmLedgerLayoutV5_1 = struct([\n u64(\"state\"),\n publicKey(\"id\"),\n publicKey(\"owner\"),\n u64(\"deposited\"),\n seq(u64(), 2, \"rewardDebts\"),\n]);\n\nexport const farmLedgerLayoutV5_2 = struct([\n u64(\"state\"),\n publicKey(\"id\"),\n publicKey(\"owner\"),\n u64(\"deposited\"),\n seq(u128(), 2, \"rewardDebts\"),\n seq(u64(), 17),\n]);\n\nexport const farmLedgerLayoutV6_1 = struct([\n u64(),\n u64(\"state\"),\n publicKey(\"id\"),\n publicKey(\"owner\"),\n u64(\"deposited\"),\n seq(u128(), 5, \"rewardDebts\"),\n seq(u64(), 16),\n]);\n\nexport type FarmLedgerLayoutV3_1 = typeof farmLedgerLayoutV3_1;\nexport type FarmLedgerLayoutV3_2 = typeof farmLedgerLayoutV3_2;\nexport type FarmLedgerLayoutV5_1 = typeof farmLedgerLayoutV5_1;\nexport type FarmLedgerLayoutV5_2 = typeof farmLedgerLayoutV5_2;\nexport type FarmLedgerLayoutV6_1 = typeof farmLedgerLayoutV6_1;\nexport type FarmLedgerLayout =\n | FarmLedgerLayoutV3_1\n | FarmLedgerLayoutV3_2\n | FarmLedgerLayoutV5_1\n | FarmLedgerLayoutV5_2\n | FarmLedgerLayoutV6_1;\n\nexport type FarmLedgerV3_1 = GetStructureSchema<FarmLedgerLayoutV3_1>;\nexport type FarmLedgerV3_2 = GetStructureSchema<FarmLedgerLayoutV3_2>;\nexport type FarmLedgerV5_1 = GetStructureSchema<FarmLedgerLayoutV5_1>;\nexport type FarmLedgerV5_2 = GetStructureSchema<FarmLedgerLayoutV5_2>;\nexport type FarmLedgerV6_1 = GetStructureSchema<FarmLedgerLayoutV6_1>;\nexport type FarmLedger = FarmLedgerV3_1 | FarmLedgerV3_2 | FarmLedgerV5_1 | FarmLedgerV5_2 | FarmLedgerV6_1;\n\nexport const dwLayout = struct([u8(\"instruction\"), u64(\"amount\")]);\n\nexport const VoterVotingMintConfig = struct([\n publicKey(\"mint\"),\n publicKey(\"grantAuthority\"),\n u64(\"baselineVoteWeightScaledFactor\"),\n u64(\"maxExtraLockupVoteWeightScaledFactor\"),\n u64(\"lockupSaturationSecs\"),\n\n i8(\"digitShift\"), // TODO\n seq(u8(), 7, \"reserved1\"),\n seq(u64(), 7, \"reserved2\"),\n]);\n\nexport const VoterRegistrar = struct([\n blob(8),\n publicKey(\"governanceProgramId\"),\n publicKey(\"realm\"),\n publicKey(\"realmGoverningTokenMint\"),\n publicKey(\"realmAuthority\"),\n\n seq(u8(), 32, \"reserved1\"),\n seq(VoterVotingMintConfig, 4, \"votingMints\"),\n\n i64(\"timeOffset\"),\n u8(\"bump\"),\n seq(u8(), 7, \"reserved2\"),\n seq(u64(), 11, \"reserved3\"),\n]);\n\nexport const VoterLockup = struct([i64(\"startTime\"), i64(\"endTime\"), u8(\"kind\"), seq(u8(), 15, \"reserved\")]);\n\nexport const VoterDepositEntry = struct([\n seq(VoterLockup, 1, \"lockup\"),\n u64(\"amountDeposited_native\"),\n u64(\"amountInitiallyLockedNative\"),\n bool(\"isUsed\"),\n bool(\"allowClawback\"),\n u8(\"votingMintConfigIdx\"),\n seq(u8(), 29, \"reserved\"),\n]);\n\nexport const Voter = struct([\n blob(8),\n publicKey(\"voterAuthority\"),\n publicKey(\"registrar\"),\n\n seq(VoterDepositEntry, 32, \"deposits\"),\n\n u8(\"voterBump\"),\n u8(\"voterWweightRecordBump\"),\n seq(u8(), 94, \"reserved\"),\n]);\n","import { Connection, PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\n\nimport { GetMultipleAccountsInfoConfig, getMultipleAccountsInfoWithCustomFlags } from \"@/common/accountInfo\";\nimport { parseBigNumberish } from \"@/common/bignumber\";\nimport { createLogger } from \"@/common/logger\";\nimport { findProgramAddress, ProgramAddress } from \"@/common/txTool/txUtils\";\nimport { DateParam, isDateAfter, isDateBefore } from \"@/common/date\";\nimport { jsonInfo2PoolKeys } from \"@/common/utility\";\nimport { RewardInfoV6 } from \"@/api/type\";\n\nimport { splAccountLayout } from \"../account/layout\";\nimport { SplAccount } from \"../account/types\";\nimport { FARM_VERSION_TO_LEDGER_LAYOUT, FARM_VERSION_TO_STATE_LAYOUT, poolTypeV6 } from \"./config\";\nimport { FarmLedger, FarmLedgerLayout, FarmState, FarmStateLayout } from \"./layout\";\nimport { FarmRewardInfo, FarmRewardInfoConfig } from \"./type\";\n\nimport { VoterRegistrar, Voter } from \"./layout\";\n\nconst logger = createLogger(\"Raydium.farm.util\");\ninterface AssociatedLedgerPoolAccount {\n programId: PublicKey;\n poolId: PublicKey;\n mint: PublicKey;\n type: \"lpVault\" | \"rewardVault\";\n}\n\nexport function getAssociatedLedgerPoolAccount({\n programId,\n poolId,\n mint,\n type,\n}: AssociatedLedgerPoolAccount): PublicKey {\n const { publicKey } = findProgramAddress(\n [\n poolId.toBuffer(),\n mint.toBuffer(),\n Buffer.from(\n type === \"lpVault\" ? \"lp_vault_associated_seed\" : type === \"rewardVault\" ? \"reward_vault_associated_seed\" : \"\",\n \"utf-8\",\n ),\n ],\n programId,\n );\n return publicKey;\n}\n\nexport function getAssociatedLedgerAccount({\n programId,\n poolId,\n owner,\n version,\n}: {\n programId: PublicKey;\n poolId: PublicKey;\n owner: PublicKey;\n version: 6 | 5 | 3;\n}): PublicKey {\n const { publicKey } = findProgramAddress(\n [\n poolId.toBuffer(),\n owner.toBuffer(),\n Buffer.from(version === 6 ? \"farmer_info_associated_seed\" : \"staker_info_v2_associated_seed\", \"utf-8\"),\n ],\n programId,\n );\n return publicKey;\n}\n\nexport const getAssociatedAuthority = ({\n programId,\n poolId,\n}: {\n programId: PublicKey;\n poolId: PublicKey;\n}): ProgramAddress => findProgramAddress([poolId.toBuffer()], programId);\n\nexport function farmRewardInfoToConfig(data: FarmRewardInfo): FarmRewardInfoConfig {\n return {\n isSet: new BN(1),\n rewardPerSecond: parseBigNumberish(data.perSecond),\n rewardOpenTime: parseBigNumberish(data.openTime),\n rewardEndTime: parseBigNumberish(data.endTime),\n rewardType: parseBigNumberish(poolTypeV6[data.rewardType]),\n };\n}\n\nexport function calFarmRewardAmount(data: Pick<RewardInfoV6, \"openTime\" | \"endTime\"> & { perSecond: string }): BN {\n return parseBigNumberish(data.endTime).sub(parseBigNumberish(data.openTime)).mul(parseBigNumberish(data.perSecond));\n}\n\nexport function getFarmLedgerLayout(version: number): FarmLedgerLayout | undefined {\n const ledgerLayout = FARM_VERSION_TO_LEDGER_LAYOUT[version];\n if (!ledgerLayout) logger.logWithError(\"invalid version\", version);\n return ledgerLayout;\n}\n\nexport function getFarmStateLayout(version: number): FarmStateLayout | undefined {\n const stateLayout = FARM_VERSION_TO_STATE_LAYOUT[version];\n if (!stateLayout) logger.logWithError(\"invalid version\", version);\n return stateLayout;\n}\n\nexport function updateFarmPoolInfo(\n poolInfo: FarmState,\n lpVault: SplAccount,\n slot: number,\n chainTime: number,\n): FarmState {\n if (poolInfo.version === 3 || poolInfo.version === 5) {\n if (poolInfo.lastSlot.gte(new BN(slot))) return poolInfo;\n\n const spread = new BN(slot).sub(poolInfo.lastSlot);\n poolInfo.lastSlot = new BN(slot);\n\n for (const itemRewardInfo of poolInfo.rewardInfos) {\n if (lpVault.amount.eq(new BN(0))) continue;\n\n const reward = itemRewardInfo.perSlotReward.mul(spread);\n itemRewardInfo.perShareReward = itemRewardInfo.perShareReward.add(\n reward.mul(new BN(10).pow(new BN(poolInfo.version === 3 ? 9 : 15))).div(lpVault.amount),\n );\n itemRewardInfo.totalReward = itemRewardInfo.totalReward.add(reward);\n }\n } else if (poolInfo.version === 6) {\n for (const itemRewardInfo of poolInfo.rewardInfos) {\n if (itemRewardInfo.rewardState.eq(new BN(0))) continue;\n const updateTime = BN.min(new BN(chainTime), itemRewardInfo.rewardEndTime);\n if (itemRewardInfo.rewardOpenTime.gte(updateTime)) continue;\n const spread = updateTime.sub(itemRewardInfo.rewardLastUpdateTime);\n let reward = spread.mul(itemRewardInfo.rewardPerSecond);\n const leftReward = itemRewardInfo.totalReward.sub(itemRewardInfo.totalRewardEmissioned);\n if (leftReward.lt(reward)) {\n reward = leftReward;\n itemRewardInfo.rewardLastUpdateTime = itemRewardInfo.rewardLastUpdateTime.add(\n leftReward.div(itemRewardInfo.rewardPerSecond),\n );\n } else {\n itemRewardInfo.rewardLastUpdateTime = updateTime;\n }\n if (lpVault.amount.eq(new BN(0))) continue;\n itemRewardInfo.accRewardPerShare = itemRewardInfo.accRewardPerShare.add(\n reward.mul(poolInfo.rewardMultiplier).div(lpVault.amount),\n );\n itemRewardInfo.totalRewardEmissioned = itemRewardInfo.totalRewardEmissioned.add(reward);\n }\n }\n return poolInfo;\n}\n\ninterface FarmPoolsInfo {\n [id: string]: {\n state: FarmState;\n lpVault: SplAccount;\n ledger?: FarmLedger;\n wrapped?: { pendingRewards: BN[] };\n };\n}\n\nexport interface FarmFetchMultipleInfoParams {\n connection: Connection;\n farmPools: any[];\n owner?: PublicKey;\n config?: GetMultipleAccountsInfoConfig;\n chainTime: number;\n}\n\nexport async function fetchMultipleFarmInfoAndUpdate({\n connection,\n farmPools,\n owner,\n config,\n chainTime,\n}: FarmFetchMultipleInfoParams): Promise<FarmPoolsInfo> {\n let hasNotV6Pool = false;\n let hasV6Pool = false;\n const tenBN = new BN(10);\n\n const publicKeys: {\n pubkey: PublicKey;\n version: number;\n key: \"state\" | \"lpVault\" | \"ledger\";\n poolId: PublicKey;\n }[] = [];\n\n for (const poolInfo of farmPools) {\n const pool = jsonInfo2PoolKeys(poolInfo);\n if (pool.version === 6) hasV6Pool = true;\n else hasNotV6Pool = true;\n\n publicKeys.push(\n {\n pubkey: pool.id,\n version: pool.version,\n key: \"state\",\n poolId: pool.id,\n },\n {\n pubkey: pool.lpVault,\n version: pool.version,\n key: \"lpVault\",\n poolId: pool.id,\n },\n );\n\n if (owner) {\n publicKeys.push({\n pubkey: getAssociatedLedgerAccount({\n programId: pool.programId,\n poolId: pool.id,\n owner,\n version: poolInfo.version as 6 | 5 | 3,\n }),\n version: pool.version,\n key: \"ledger\",\n poolId: pool.id,\n });\n }\n }\n\n const poolsInfo: FarmPoolsInfo = {};\n const accountsInfo = await getMultipleAccountsInfoWithCustomFlags(connection, publicKeys, config);\n for (const { pubkey, version, key, poolId, accountInfo } of accountsInfo) {\n const _poolId = poolId.toBase58();\n poolsInfo[_poolId] = { ...poolsInfo[_poolId] };\n if (key === \"state\") {\n const stateLayout = getFarmStateLayout(version);\n if (!accountInfo || !accountInfo.data || accountInfo.data.length !== stateLayout!.span)\n logger.logWithError(`invalid farm state account info, pools.id, ${pubkey}`);\n poolsInfo[_poolId].state = stateLayout!.decode(accountInfo!.data);\n } else if (key === \"lpVault\") {\n if (!accountInfo || !accountInfo.data || accountInfo.data.length !== splAccountLayout.span)\n logger.logWithError(`invalid farm lp vault account info, pools.lpVault, ${pubkey}`);\n poolsInfo[_poolId].lpVault = splAccountLayout.decode(accountInfo!.data);\n } else if (key === \"ledger\") {\n const legerLayout = getFarmLedgerLayout(version)!;\n if (accountInfo && accountInfo.data) {\n if (accountInfo.data.length !== legerLayout.span)\n logger.logWithError(`invalid farm ledger account info, ledger, ${pubkey}`);\n poolsInfo[_poolId].ledger = legerLayout.decode(accountInfo.data);\n }\n }\n }\n\n const slot = hasV6Pool || hasNotV6Pool ? await connection.getSlot() : 0;\n\n for (const poolId of Object.keys(poolsInfo)) {\n if (poolsInfo[poolId] === undefined) continue;\n poolsInfo[poolId].state = updateFarmPoolInfo(poolsInfo[poolId].state, poolsInfo[poolId].lpVault, slot, chainTime);\n }\n\n for (const [poolId, { state, ledger }] of Object.entries(poolsInfo)) {\n if (ledger) {\n const multiplier =\n state.version === 6\n ? state.rewardMultiplier\n : state.rewardInfos.length === 1\n ? tenBN.pow(new BN(9))\n : tenBN.pow(new BN(15));\n\n const pendingRewards = state.rewardInfos.map((rewardInfo, index) => {\n const rewardDebt = ledger.rewardDebts[index];\n const pendingReward = ledger.deposited\n .mul(state.version === 6 ? rewardInfo.accRewardPerShare : rewardInfo.perShareReward)\n .div(multiplier)\n .sub(rewardDebt);\n\n return pendingReward;\n });\n\n poolsInfo[poolId].wrapped = {\n ...poolsInfo[poolId].wrapped,\n pendingRewards,\n };\n }\n }\n\n return poolsInfo;\n}\n/** deprecated */\nexport function judgeFarmType(\n info: any,\n currentTime: DateParam = Date.now(),\n): \"closed pool\" | \"normal fusion pool\" | \"dual fusion pool\" | undefined | \"upcoming pool\" {\n if (info.version === 6) {\n const rewardInfos = info.state.rewardInfos;\n if (rewardInfos.every(({ rewardOpenTime }) => isDateBefore(currentTime, rewardOpenTime.toNumber(), { unit: \"s\" })))\n return \"upcoming pool\";\n if (rewardInfos.every(({ rewardEndTime }) => isDateAfter(currentTime, rewardEndTime.toNumber(), { unit: \"s\" })))\n return \"closed pool\";\n } else {\n const perSlotRewards = info.state.rewardInfos.map(({ perSlotReward }) => perSlotReward);\n if (perSlotRewards.length === 2) {\n // v5\n if (String(perSlotRewards[0]) === \"0\" && String(perSlotRewards[1]) !== \"0\") {\n return \"normal fusion pool\"; // reward xxx token\n }\n if (String(p