UNPKG

snapper-sdk

Version:

An SDK for building applications on top of Snapper.

1 lines 344 kB
{"version":3,"sources":["../../src/common/logger.ts","../../src/common/txTool/txTool.ts","../../src/common/txTool/lookupTable.ts","../../src/common/accountInfo.ts","../../src/common/bignumber.ts","../../node_modules/decimal.js/decimal.mjs","../../src/module/amount.ts","../../src/module/formatter.ts","../../src/module/fraction.ts","../../src/common/constant.ts","../../src/raydium/token/constant.ts","../../src/module/token.ts","../../src/common/pubKey.ts","../../src/module/currency.ts","../../src/module/percent.ts","../../src/module/price.ts","../../src/common/utility.ts","../../src/common/lodash.ts","../../src/common/pda.ts","../../src/common/txTool/txUtils.ts","../../src/common/txTool/txType.ts","../../src/common/programId.ts","../../src/common/transfer.ts","../../src/raydium/moduleBase.ts"],"sourcesContent":["import { get, set } from \"lodash\";\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 Date.now().toString();\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 {\n Commitment,\n Connection,\n PublicKey,\n sendAndConfirmTransaction,\n Signer,\n Transaction,\n TransactionInstruction,\n TransactionMessage,\n VersionedTransaction,\n} from \"@solana/web3.js\";\nimport axios from \"axios\";\n\nimport { Api } from \"../../api\";\nimport { ComputeBudgetConfig, SignAllTransactions } from \"../../raydium/type\";\nimport { Cluster } from \"../../solana\";\nimport { Owner } from \"../owner\";\nimport { CacheLTA, getMultipleLookupTableInfo, LOOKUP_TABLE_CACHE } from \"./lookupTable\";\nimport { TxVersion } from \"./txType\";\nimport {\n addComputeBudget,\n checkLegacyTxSize,\n checkV0TxSize,\n confirmTransaction,\n getRecentBlockHash,\n printSimulate,\n} from \"./txUtils\";\n\ninterface SolanaFeeInfo {\n min: number;\n max: number;\n avg: number;\n priorityTx: number;\n nonVotes: number;\n priorityRatio: number;\n avgCuPerBlock: number;\n blockspaceUsageRatio: number;\n}\ntype SolanaFeeInfoJson = {\n \"1\": SolanaFeeInfo;\n \"5\": SolanaFeeInfo;\n \"15\": SolanaFeeInfo;\n};\n\ninterface ExecuteParams {\n skipPreflight?: boolean;\n recentBlockHash?: string;\n sendAndConfirm?: boolean;\n}\n\ninterface TxBuilderInit {\n connection: Connection;\n feePayer: PublicKey;\n cluster: Cluster;\n owner?: Owner;\n blockhashCommitment?: Commitment;\n api?: Api;\n signAllTransactions?: SignAllTransactions;\n}\n\nexport interface AddInstructionParam {\n addresses?: Record<string, PublicKey>;\n instructions?: TransactionInstruction[];\n endInstructions?: TransactionInstruction[];\n lookupTableAddress?: string[];\n signers?: Signer[];\n instructionTypes?: string[];\n endInstructionTypes?: string[];\n}\n\nexport interface TxBuildData<T = Record<string, any>> {\n builder: TxBuilder;\n transaction: Transaction;\n instructionTypes: string[];\n signers: Signer[];\n execute: (params?: ExecuteParams) => Promise<{ txId: string; signedTx: Transaction }>;\n extInfo: T;\n}\n\nexport interface TxV0BuildData<T = Record<string, any>> extends Omit<TxBuildData<T>, \"transaction\" | \"execute\"> {\n builder: TxBuilder;\n transaction: VersionedTransaction;\n buildProps?: {\n lookupTableCache?: CacheLTA;\n lookupTableAddress?: string[];\n };\n execute: (params?: ExecuteParams) => Promise<{ txId: string; signedTx: VersionedTransaction }>;\n}\n\ntype TxUpdateParams = {\n txId: string;\n status: \"success\" | \"error\" | \"sent\";\n signedTx: Transaction | VersionedTransaction;\n};\nexport interface MultiTxExecuteParam extends ExecuteParams {\n sequentially: boolean;\n onTxUpdate?: (completeTxs: TxUpdateParams[]) => void;\n}\nexport interface MultiTxBuildData<T = Record<string, any>> {\n builder: TxBuilder;\n transactions: Transaction[];\n instructionTypes: string[];\n signers: Signer[][];\n execute: (executeParams?: MultiTxExecuteParam) => Promise<{ txIds: string[]; signedTxs: Transaction[] }>;\n extInfo: T;\n}\n\nexport interface MultiTxV0BuildData<T = Record<string, any>>\n extends Omit<MultiTxBuildData<T>, \"transactions\" | \"execute\"> {\n builder: TxBuilder;\n transactions: VersionedTransaction[];\n buildProps?: {\n lookupTableCache?: CacheLTA;\n lookupTableAddress?: string[];\n };\n execute: (executeParams?: MultiTxExecuteParam) => Promise<{ txIds: string[]; signedTxs: VersionedTransaction[] }>;\n}\n\nexport type MakeMultiTxData<T = TxVersion.LEGACY, O = Record<string, any>> = T extends TxVersion.LEGACY\n ? MultiTxBuildData<O>\n : MultiTxV0BuildData<O>;\n\nexport type MakeTxData<T = TxVersion.LEGACY, O = Record<string, any>> = T extends TxVersion.LEGACY\n ? TxBuildData<O>\n : TxV0BuildData<O>;\n\nexport class TxBuilder {\n private connection: Connection;\n private owner?: Owner;\n private instructions: TransactionInstruction[] = [];\n private endInstructions: TransactionInstruction[] = [];\n private lookupTableAddress: string[] = [];\n private signers: Signer[] = [];\n private instructionTypes: string[] = [];\n private endInstructionTypes: string[] = [];\n private feePayer: PublicKey;\n private cluster: Cluster;\n private signAllTransactions?: SignAllTransactions;\n private blockhashCommitment?: Commitment;\n private api?: Api;\n\n constructor(params: TxBuilderInit) {\n this.connection = params.connection;\n this.feePayer = params.feePayer;\n this.signAllTransactions = params.signAllTransactions;\n this.owner = params.owner;\n this.cluster = params.cluster;\n this.blockhashCommitment = params.blockhashCommitment;\n this.api = params.api;\n }\n\n get AllTxData(): {\n instructions: TransactionInstruction[];\n endInstructions: TransactionInstruction[];\n signers: Signer[];\n instructionTypes: string[];\n endInstructionTypes: string[];\n lookupTableAddress: string[];\n } {\n return {\n instructions: this.instructions,\n endInstructions: this.endInstructions,\n signers: this.signers,\n instructionTypes: this.instructionTypes,\n endInstructionTypes: this.endInstructionTypes,\n lookupTableAddress: this.lookupTableAddress,\n };\n }\n\n get allInstructions(): TransactionInstruction[] {\n return [...this.instructions, ...this.endInstructions];\n }\n\n public async getComputeBudgetConfig(): Promise<ComputeBudgetConfig | undefined> {\n const json = (\n await axios.get<SolanaFeeInfoJson>(`https://solanacompass.com/api/fees?cacheFreshTime=${5 * 60 * 1000}`)\n ).data;\n const { avg } = json?.[15] ?? {};\n if (!avg) return undefined;\n return {\n units: 600000,\n microLamports: Math.min(Math.ceil((avg * 1000000) / 600000), 25000),\n };\n }\n\n public addCustomComputeBudget(config?: ComputeBudgetConfig): boolean {\n if (config) {\n const { instructions, instructionTypes } = addComputeBudget(config);\n this.instructions.unshift(...instructions);\n this.instructionTypes.unshift(...instructionTypes);\n return true;\n }\n return false;\n }\n\n public async calComputeBudget({\n config: propConfig,\n defaultIns,\n }: {\n config?: ComputeBudgetConfig;\n defaultIns?: TransactionInstruction[];\n }): Promise<void> {\n try {\n const config = propConfig || (await this.getComputeBudgetConfig());\n if (this.addCustomComputeBudget(config)) return;\n defaultIns && this.instructions.unshift(...defaultIns);\n } catch {\n defaultIns && this.instructions.unshift(...defaultIns);\n }\n }\n\n public addInstruction({\n instructions = [],\n endInstructions = [],\n signers = [],\n instructionTypes = [],\n endInstructionTypes = [],\n lookupTableAddress = [],\n }: AddInstructionParam): TxBuilder {\n this.instructions.push(...instructions);\n this.endInstructions.push(...endInstructions);\n this.signers.push(...signers);\n this.instructionTypes.push(...instructionTypes);\n this.endInstructionTypes.push(...endInstructionTypes);\n this.lookupTableAddress.push(...lookupTableAddress.filter((address) => address !== PublicKey.default.toString()));\n return this;\n }\n\n public async versionBuild<O = Record<string, any>>({\n txVersion,\n extInfo,\n }: {\n txVersion?: TxVersion;\n extInfo?: O;\n }): Promise<MakeTxData<TxVersion.LEGACY, O> | MakeTxData<TxVersion.V0, O>> {\n if (txVersion === TxVersion.V0) return (await this.buildV0({ ...(extInfo || {}) })) as MakeTxData<TxVersion.V0, O>;\n return this.build<O>(extInfo) as MakeTxData<TxVersion.LEGACY, O>;\n }\n\n public build<O = Record<string, any>>(extInfo?: O): MakeTxData<TxVersion.LEGACY, O> {\n const transaction = new Transaction();\n if (this.allInstructions.length) transaction.add(...this.allInstructions);\n transaction.feePayer = this.feePayer;\n if (this.owner?.signer && !this.signers.some((s) => s.publicKey.equals(this.owner!.publicKey)))\n this.signers.push(this.owner.signer);\n\n return {\n builder: this,\n transaction,\n signers: this.signers,\n instructionTypes: [...this.instructionTypes, ...this.endInstructionTypes],\n execute: async (params) => {\n const { recentBlockHash: propBlockHash, skipPreflight = true, sendAndConfirm } = params || {};\n const recentBlockHash = propBlockHash ?? (await getRecentBlockHash(this.connection, this.blockhashCommitment));\n transaction.recentBlockhash = recentBlockHash;\n if (this.signers.length) transaction.sign(...this.signers);\n\n printSimulate([transaction]);\n if (this.owner?.isKeyPair) {\n const txId = sendAndConfirm\n ? await sendAndConfirmTransaction(\n this.connection,\n transaction,\n this.signers.find((s) => s.publicKey.equals(this.owner!.publicKey))\n ? this.signers\n : [...this.signers, this.owner.signer!],\n { skipPreflight },\n )\n : await this.connection.sendRawTransaction(transaction.serialize(), { skipPreflight });\n\n return {\n txId,\n signedTx: transaction,\n };\n }\n if (this.signAllTransactions) {\n const txs = await this.signAllTransactions([transaction]);\n return {\n txId: await this.connection.sendRawTransaction(txs[0].serialize(), { skipPreflight }),\n signedTx: txs[0],\n };\n }\n throw new Error(\"please provide owner in keypair format or signAllTransactions function\");\n },\n extInfo: extInfo || ({} as O),\n };\n }\n\n public buildMultiTx<T = Record<string, any>>(params: {\n extraPreBuildData?: MakeTxData<TxVersion.LEGACY>[];\n extInfo?: T;\n }): MultiTxBuildData {\n const { extraPreBuildData = [], extInfo } = params;\n const { transaction } = this.build(extInfo);\n\n const filterExtraBuildData = extraPreBuildData.filter((data) => data.transaction.instructions.length > 0);\n\n const allTransactions: Transaction[] = [transaction, ...filterExtraBuildData.map((data) => data.transaction)];\n const allSigners: Signer[][] = [this.signers, ...filterExtraBuildData.map((data) => data.signers)];\n const allInstructionTypes: string[] = [\n ...this.instructionTypes,\n ...filterExtraBuildData.map((data) => data.instructionTypes).flat(),\n ];\n\n if (this.owner?.signer) {\n allSigners.forEach((signers) => {\n if (!signers.some((s) => s.publicKey.equals(this.owner!.publicKey))) this.signers.push(this.owner!.signer!);\n });\n }\n\n return {\n builder: this,\n transactions: allTransactions,\n signers: allSigners,\n instructionTypes: allInstructionTypes,\n execute: async (executeParams?: MultiTxExecuteParam) => {\n const { sequentially, onTxUpdate, recentBlockHash: propBlockHash, skipPreflight = true } = executeParams || {};\n const recentBlockHash = propBlockHash ?? (await getRecentBlockHash(this.connection, this.blockhashCommitment));\n if (this.owner?.isKeyPair) {\n if (sequentially) {\n const txIds: string[] = [];\n for (const tx of allTransactions) {\n const txId = await sendAndConfirmTransaction(\n this.connection,\n tx,\n this.signers.find((s) => s.publicKey.equals(this.owner!.publicKey))\n ? this.signers\n : [...this.signers, this.owner.signer!],\n { skipPreflight },\n );\n txIds.push(txId);\n }\n\n return {\n txIds,\n signedTxs: allTransactions,\n };\n }\n return {\n txIds: await await Promise.all(\n allTransactions.map(async (tx) => {\n tx.recentBlockhash = recentBlockHash;\n return await this.connection.sendRawTransaction(tx.serialize(), { skipPreflight });\n }),\n ),\n signedTxs: allTransactions,\n };\n }\n\n if (this.signAllTransactions) {\n const partialSignedTxs = allTransactions.map((tx, idx) => {\n tx.recentBlockhash = recentBlockHash;\n if (allSigners[idx].length) tx.sign(...allSigners[idx]);\n return tx;\n });\n printSimulate(partialSignedTxs);\n const signedTxs = await this.signAllTransactions(partialSignedTxs);\n if (sequentially) {\n let i = 0;\n const processedTxs: TxUpdateParams[] = [];\n const checkSendTx = async (): Promise<void> => {\n if (!signedTxs[i]) return;\n const txId = await this.connection.sendRawTransaction(signedTxs[i].serialize(), { skipPreflight });\n processedTxs.push({ txId, status: \"sent\", signedTx: signedTxs[i] });\n onTxUpdate?.([...processedTxs]);\n i++;\n this.connection.onSignature(\n txId,\n (signatureResult) => {\n const targetTxIdx = processedTxs.findIndex((tx) => tx.txId === txId);\n if (targetTxIdx > -1) processedTxs[targetTxIdx].status = signatureResult.err ? \"error\" : \"success\";\n onTxUpdate?.([...processedTxs]);\n if (!signatureResult.err) checkSendTx();\n },\n \"processed\",\n );\n this.connection.getSignatureStatus(txId);\n };\n await checkSendTx();\n return {\n txIds: processedTxs.map((d) => d.txId),\n signedTxs,\n };\n } else {\n const txIds: string[] = [];\n for (let i = 0; i < signedTxs.length; i += 1) {\n const txId = await this.connection.sendRawTransaction(signedTxs[i].serialize(), { skipPreflight });\n txIds.push(txId);\n }\n return {\n txIds,\n signedTxs,\n };\n }\n }\n throw new Error(\"please provide owner in keypair format or signAllTransactions function\");\n },\n extInfo: extInfo || {},\n };\n }\n\n public async versionMultiBuild<T extends TxVersion, O = Record<string, any>>({\n extraPreBuildData,\n txVersion,\n extInfo,\n }: {\n extraPreBuildData?: MakeTxData<TxVersion.V0>[] | MakeTxData<TxVersion.LEGACY>[];\n txVersion?: T;\n extInfo?: O;\n }): Promise<MakeMultiTxData<T, O>> {\n if (txVersion === TxVersion.V0)\n return (await this.buildV0MultiTx({\n extraPreBuildData: extraPreBuildData as MakeTxData<TxVersion.V0>[],\n buildProps: extInfo || {},\n })) as MakeMultiTxData<T, O>;\n return this.buildMultiTx<O>({\n extraPreBuildData: extraPreBuildData as MakeTxData<TxVersion.LEGACY>[],\n extInfo,\n }) as MakeMultiTxData<T, O>;\n }\n\n public async buildV0<O = Record<string, any>>(\n props?: O & {\n lookupTableCache?: CacheLTA;\n lookupTableAddress?: string[];\n forerunCreate?: boolean;\n recentBlockhash?: string;\n },\n ): Promise<MakeTxData<TxVersion.V0, O>> {\n const {\n lookupTableCache = {},\n lookupTableAddress = [],\n forerunCreate,\n recentBlockhash: propRecentBlockhash,\n ...extInfo\n } = props || {};\n const lookupTableAddressAccount = {\n ...(this.cluster === \"devnet\" ? {} : LOOKUP_TABLE_CACHE),\n ...lookupTableCache,\n };\n const allLTA = Array.from(new Set<string>([...lookupTableAddress, ...this.lookupTableAddress]));\n const needCacheLTA: PublicKey[] = [];\n for (const item of allLTA) {\n if (lookupTableAddressAccount[item] === undefined) needCacheLTA.push(new PublicKey(item));\n }\n const newCacheLTA = await getMultipleLookupTableInfo({ connection: this.connection, address: needCacheLTA });\n for (const [key, value] of Object.entries(newCacheLTA)) lookupTableAddressAccount[key] = value;\n\n const recentBlockhash = forerunCreate\n ? PublicKey.default.toBase58()\n : propRecentBlockhash ?? (await getRecentBlockHash(this.connection, this.blockhashCommitment));\n\n const messageV0 = new TransactionMessage({\n payerKey: this.feePayer,\n recentBlockhash,\n instructions: [...this.allInstructions],\n }).compileToV0Message(Object.values(lookupTableAddressAccount));\n\n if (this.owner?.signer && !this.signers.some((s) => s.publicKey.equals(this.owner!.publicKey)))\n this.signers.push(this.owner.signer);\n const transaction = new VersionedTransaction(messageV0);\n transaction.sign(this.signers);\n return {\n builder: this,\n transaction,\n signers: this.signers,\n instructionTypes: [...this.instructionTypes, ...this.endInstructionTypes],\n execute: async (params) => {\n const { skipPreflight = true, sendAndConfirm } = params || {};\n printSimulate([transaction]);\n if (this.owner?.isKeyPair) {\n const txId = await this.connection.sendTransaction(transaction, { skipPreflight });\n if (sendAndConfirm) {\n await confirmTransaction(this.connection, txId);\n }\n\n return {\n txId,\n signedTx: transaction,\n };\n }\n if (this.signAllTransactions) {\n const txs = await this.signAllTransactions<VersionedTransaction>([transaction]);\n return {\n txId: await this.connection.sendTransaction(txs[0], { skipPreflight }),\n signedTx: txs[0],\n };\n }\n throw new Error(\"please provide owner in keypair format or signAllTransactions function\");\n },\n extInfo: (extInfo || {}) as O,\n };\n }\n\n public async buildV0MultiTx<T = Record<string, any>>(params: {\n extraPreBuildData?: MakeTxData<TxVersion.V0>[];\n buildProps?: T & {\n lookupTableCache?: CacheLTA;\n lookupTableAddress?: string[];\n forerunCreate?: boolean;\n recentBlockhash?: string;\n };\n }): Promise<MultiTxV0BuildData> {\n const { extraPreBuildData = [], buildProps } = params;\n const { transaction } = await this.buildV0(buildProps);\n\n const filterExtraBuildData = extraPreBuildData.filter((data) => data.builder.instructions.length > 0);\n\n const allTransactions: VersionedTransaction[] = [\n transaction,\n ...filterExtraBuildData.map((data) => data.transaction),\n ];\n const allSigners: Signer[][] = [this.signers, ...filterExtraBuildData.map((data) => data.signers)];\n const allInstructionTypes: string[] = [\n ...this.instructionTypes,\n ...filterExtraBuildData.map((data) => data.instructionTypes).flat(),\n ];\n\n if (this.owner?.signer) {\n allSigners.forEach((signers) => {\n if (!signers.some((s) => s.publicKey.equals(this.owner!.publicKey))) this.signers.push(this.owner!.signer!);\n });\n }\n\n allTransactions.forEach(async (tx, idx) => {\n tx.sign(allSigners[idx]);\n });\n\n return {\n builder: this,\n transactions: allTransactions,\n signers: allSigners,\n instructionTypes: allInstructionTypes,\n buildProps,\n execute: async (executeParams?: MultiTxExecuteParam) => {\n const { sequentially, onTxUpdate, recentBlockHash: propBlockHash, skipPreflight = true } = executeParams || {};\n if (propBlockHash) allTransactions.forEach((tx) => (tx.message.recentBlockhash = propBlockHash));\n printSimulate(allTransactions);\n if (this.owner?.isKeyPair) {\n if (sequentially) {\n const txIds: string[] = [];\n for (const tx of allTransactions) {\n const txId = await this.connection.sendTransaction(tx, { skipPreflight });\n await confirmTransaction(this.connection, txId);\n txIds.push(txId);\n }\n\n return { txIds, signedTxs: allTransactions };\n }\n\n return {\n txIds: await Promise.all(\n allTransactions.map(async (tx) => {\n return await this.connection.sendTransaction(tx, { skipPreflight });\n }),\n ),\n signedTxs: allTransactions,\n };\n }\n\n if (this.signAllTransactions) {\n const signedTxs = await this.signAllTransactions(allTransactions);\n\n if (sequentially) {\n let i = 0;\n const processedTxs: TxUpdateParams[] = [];\n const checkSendTx = async (): Promise<void> => {\n if (!signedTxs[i]) return;\n const txId = await this.connection.sendTransaction(signedTxs[i], { skipPreflight });\n processedTxs.push({ txId, status: \"sent\", signedTx: signedTxs[i] });\n onTxUpdate?.([...processedTxs]);\n i++;\n this.connection.onSignature(\n txId,\n (signatureResult) => {\n const targetTxIdx = processedTxs.findIndex((tx) => tx.txId === txId);\n if (targetTxIdx > -1) processedTxs[targetTxIdx].status = signatureResult.err ? \"error\" : \"success\";\n onTxUpdate?.([...processedTxs]);\n if (!signatureResult.err) checkSendTx();\n },\n \"processed\",\n );\n this.connection.getSignatureStatus(txId);\n };\n checkSendTx();\n return {\n txIds: [],\n signedTxs,\n };\n } else {\n const txIds: string[] = [];\n for (let i = 0; i < signedTxs.length; i += 1) {\n const txId = await this.connection.sendTransaction(signedTxs[i], { skipPreflight });\n txIds.push(txId);\n }\n return { txIds, signedTxs };\n }\n }\n throw new Error(\"please provide owner in keypair format or signAllTransactions function\");\n },\n extInfo: buildProps || {},\n };\n }\n\n public async sizeCheckBuild(\n props?: Record<string, any> & { computeBudgetConfig?: ComputeBudgetConfig },\n ): Promise<MultiTxBuildData> {\n const { computeBudgetConfig, ...extInfo } = props || {};\n const computeBudgetData: { instructions: TransactionInstruction[]; instructionTypes: string[] } =\n computeBudgetConfig\n ? addComputeBudget(computeBudgetConfig)\n : {\n instructions: [],\n instructionTypes: [],\n };\n\n const signerKey: { [key: string]: Signer } = this.signers.reduce(\n (acc, cur) => ({ ...acc, [cur.publicKey.toBase58()]: cur }),\n {},\n );\n\n const allTransactions: Transaction[] = [];\n const allSigners: Signer[][] = [];\n\n let instructionQueue: TransactionInstruction[] = [];\n this.allInstructions.forEach((item) => {\n const _itemIns = [...instructionQueue, item];\n const _itemInsWithCompute = computeBudgetConfig ? [...computeBudgetData.instructions, ..._itemIns] : _itemIns;\n const _signerStrs = new Set<string>(\n _itemIns.map((i) => i.keys.filter((ii) => ii.isSigner).map((ii) => ii.pubkey.toString())).flat(),\n );\n const _signer = [..._signerStrs.values()].map((i) => new PublicKey(i));\n\n if (\n (instructionQueue.length < 12 &&\n checkLegacyTxSize({ instructions: _itemInsWithCompute, payer: this.feePayer, signers: _signer })) ||\n checkLegacyTxSize({ instructions: _itemIns, payer: this.feePayer, signers: _signer })\n ) {\n // current ins add to queue still not exceed tx size limit\n instructionQueue.push(item);\n } else {\n if (instructionQueue.length === 0) throw Error(\"item ins too big\");\n\n // if add computeBudget still not exceed tx size limit\n if (\n checkLegacyTxSize({\n instructions: computeBudgetConfig\n ? [...computeBudgetData.instructions, ...instructionQueue]\n : [...instructionQueue],\n payer: this.feePayer,\n signers: _signer,\n })\n ) {\n allTransactions.push(new Transaction().add(...computeBudgetData.instructions, ...instructionQueue));\n } else {\n allTransactions.push(new Transaction().add(...instructionQueue));\n }\n allSigners.push(\n Array.from(\n new Set<string>(\n instructionQueue.map((i) => i.keys.filter((ii) => ii.isSigner).map((ii) => ii.pubkey.toString())).flat(),\n ),\n )\n .map((i) => signerKey[i])\n .filter((i) => i !== undefined),\n );\n instructionQueue = [item];\n }\n });\n\n if (instructionQueue.length > 0) {\n const _signerStrs = new Set<string>(\n instructionQueue.map((i) => i.keys.filter((ii) => ii.isSigner).map((ii) => ii.pubkey.toString())).flat(),\n );\n const _signers = [..._signerStrs.values()].map((i) => signerKey[i]).filter((i) => i !== undefined);\n\n if (\n checkLegacyTxSize({\n instructions: computeBudgetConfig\n ? [...computeBudgetData.instructions, ...instructionQueue]\n : [...instructionQueue],\n payer: this.feePayer,\n signers: _signers.map((s) => s.publicKey),\n })\n ) {\n allTransactions.push(new Transaction().add(...computeBudgetData.instructions, ...instructionQueue));\n } else {\n allTransactions.push(new Transaction().add(...instructionQueue));\n }\n allSigners.push(_signers);\n }\n allTransactions.forEach((tx) => (tx.feePayer = this.feePayer));\n\n if (this.owner?.signer) {\n allSigners.forEach((signers) => {\n if (!signers.some((s) => s.publicKey.equals(this.owner!.publicKey))) signers.push(this.owner!.signer!);\n });\n }\n\n return {\n builder: this,\n transactions: allTransactions,\n signers: allSigners,\n instructionTypes: this.instructionTypes,\n execute: async (executeParams?: MultiTxExecuteParam) => {\n const { sequentially, onTxUpdate, recentBlockHash: propBlockHash, skipPreflight = true } = executeParams || {};\n const recentBlockHash = propBlockHash ?? (await getRecentBlockHash(this.connection, this.blockhashCommitment));\n allTransactions.forEach(async (tx, idx) => {\n tx.recentBlockhash = recentBlockHash;\n if (allSigners[idx].length) tx.sign(...allSigners[idx]);\n });\n printSimulate(allTransactions);\n if (this.owner?.isKeyPair) {\n if (sequentially) {\n const txIds: string[] = [];\n for (const tx of allTransactions) {\n const txId = await sendAndConfirmTransaction(\n this.connection,\n tx,\n this.signers.find((s) => s.publicKey.equals(this.owner!.publicKey))\n ? this.signers\n : [...this.signers, this.owner.signer!],\n { skipPreflight },\n );\n txIds.push(txId);\n }\n\n return {\n txIds,\n signedTxs: allTransactions,\n };\n }\n return {\n txIds: await Promise.all(\n allTransactions.map(async (tx) => {\n return await this.connection.sendRawTransaction(tx.serialize(), { skipPreflight });\n }),\n ),\n signedTxs: allTransactions,\n };\n }\n if (this.signAllTransactions) {\n const signedTxs = await this.signAllTransactions(allTransactions);\n if (sequentially) {\n let i = 0;\n const processedTxs: TxUpdateParams[] = [];\n const checkSendTx = async (): Promise<void> => {\n if (!signedTxs[i]) return;\n const txId = await this.connection.sendRawTransaction(signedTxs[i].serialize(), { skipPreflight });\n processedTxs.push({ txId, status: \"sent\", signedTx: signedTxs[i] });\n onTxUpdate?.([...processedTxs]);\n i++;\n this.connection.onSignature(\n txId,\n (signatureResult) => {\n const targetTxIdx = processedTxs.findIndex((tx) => tx.txId === txId);\n if (targetTxIdx > -1) processedTxs[targetTxIdx].status = signatureResult.err ? \"error\" : \"success\";\n onTxUpdate?.([...processedTxs]);\n if (!signatureResult.err) checkSendTx();\n },\n \"processed\",\n );\n this.connection.getSignatureStatus(txId);\n };\n await checkSendTx();\n return {\n txIds: processedTxs.map((d) => d.txId),\n signedTxs,\n };\n } else {\n const txIds: string[] = [];\n for (let i = 0; i < signedTxs.length; i += 1) {\n const txId = await this.connection.sendRawTransaction(signedTxs[i].serialize(), { skipPreflight });\n txIds.push(txId);\n }\n return { txIds, signedTxs };\n }\n }\n throw new Error(\"please provide owner in keypair format or signAllTransactions function\");\n },\n extInfo: extInfo || {},\n };\n }\n\n public async sizeCheckBuildV0(\n props?: Record<string, any> & {\n computeBudgetConfig?: ComputeBudgetConfig;\n lookupTableCache?: CacheLTA;\n lookupTableAddress?: string[];\n },\n ): Promise<MultiTxV0BuildData> {\n const { computeBudgetConfig, lookupTableCache = {}, lookupTableAddress = [], ...extInfo } = props || {};\n const lookupTableAddressAccount = {\n ...(this.cluster === \"devnet\" ? {} : LOOKUP_TABLE_CACHE),\n ...lookupTableCache,\n };\n const allLTA = Array.from(new Set<string>([...this.lookupTableAddress, ...lookupTableAddress]));\n const needCacheLTA: PublicKey[] = [];\n for (const item of allLTA) {\n if (lookupTableAddressAccount[item] === undefined) needCacheLTA.push(new PublicKey(item));\n }\n const newCacheLTA = await getMultipleLookupTableInfo({ connection: this.connection, address: needCacheLTA });\n for (const [key, value] of Object.entries(newCacheLTA)) lookupTableAddressAccount[key] = value;\n\n const computeBudgetData: { instructions: TransactionInstruction[]; instructionTypes: string[] } =\n computeBudgetConfig\n ? addComputeBudget(computeBudgetConfig)\n : {\n instructions: [],\n instructionTypes: [],\n };\n\n const blockHash = await getRecentBlockHash(this.connection, this.blockhashCommitment);\n\n const signerKey: { [key: string]: Signer } = this.signers.reduce(\n (acc, cur) => ({ ...acc, [cur.publicKey.toBase58()]: cur }),\n {},\n );\n const allTransactions: VersionedTransaction[] = [];\n const allSigners: Signer[][] = [];\n\n let instructionQueue: TransactionInstruction[] = [];\n this.allInstructions.forEach((item) => {\n const _itemIns = [...instructionQueue, item];\n const _itemInsWithCompute = computeBudgetConfig ? [...computeBudgetData.instructions, ..._itemIns] : _itemIns;\n if (\n (instructionQueue.length < 12 &&\n checkV0TxSize({ instructions: _itemInsWithCompute, payer: this.feePayer, lookupTableAddressAccount })) ||\n checkV0TxSize({ instructions: _itemIns, payer: this.feePayer, lookupTableAddressAccount })\n ) {\n // current ins add to queue still not exceed tx size limit\n instructionQueue.push(item);\n } else {\n if (instructionQueue.length === 0) throw Error(\"item ins too big\");\n\n const lookupTableAddress: undefined | CacheLTA = {};\n for (const item of [...new Set<string>(allLTA)]) {\n if (lookupTableAddressAccount[item] !== undefined) lookupTableAddress[item] = lookupTableAddressAccount[item];\n }\n // if add computeBudget still not exceed tx size limit\n if (\n computeBudgetConfig &&\n checkV0TxSize({\n instructions: [...computeBudgetData.instructions, ...instructionQueue],\n payer: this.feePayer,\n lookupTableAddressAccount,\n recentBlockhash: blockHash,\n })\n ) {\n const messageV0 = new TransactionMessage({\n payerKey: this.feePayer,\n recentBlockhash: blockHash,\n\n instructions: [...computeBudgetData.instructions, ...instructionQueue],\n }).compileToV0Message(Object.values(lookupTableAddressAccount));\n allTransactions.push(new VersionedTransaction(messageV0));\n } else {\n const messageV0 = new TransactionMessage({\n payerKey: this.feePayer,\n recentBlockhash: blockHash,\n instructions: [...instructionQueue],\n }).compileToV0Message(Object.values(lookupTableAddressAccount));\n allTransactions.push(new VersionedTransaction(messageV0));\n }\n allSigners.push(\n Array.from(\n new Set<string>(\n instructionQueue.map((i) => i.keys.filter((ii) => ii.isSigner).map((ii) => ii.pubkey.toString())).flat(),\n ),\n )\n .map((i) => signerKey[i])\n .filter((i) => i !== undefined),\n );\n instructionQueue = [item];\n }\n });\n\n if (instructionQueue.length > 0) {\n const _signerStrs = new Set<string>(\n instructionQueue.map((i) => i.keys.filter((ii) => ii.isSigner).map((ii) => ii.pubkey.toString())).flat(),\n );\n const _signers = [..._signerStrs.values()].map((i) => signerKey[i]).filter((i) => i !== undefined);\n\n if (\n computeBudgetConfig &&\n checkV0TxSize({\n instructions: [...computeBudgetData.instructions, ...instructionQueue],\n payer: this.feePayer,\n lookupTableAddressAccount,\n recentBlockhash: blockHash,\n })\n ) {\n const messageV0 = new TransactionMessage({\n payerKey: this.feePayer,\n recentBlockhash: blockHash,\n instructions: [...computeBudgetData.instructions, ...instructionQueue],\n }).compileToV0Message(Object.values(lookupTableAddressAccount));\n allTransactions.push(new VersionedTransaction(messageV0));\n } else {\n const messageV0 = new TransactionMessage({\n payerKey: this.feePayer,\n recentBlockhash: blockHash,\n instructions: [...instructionQueue],\n }).compileToV0Message(Object.values(lookupTableAddressAccount));\n allTransactions.push(new VersionedTransaction(messageV0));\n }\n allSigners.push(_signers);\n }\n\n if (this.owner?.signer) {\n allSigners.forEach((signers) => {\n if (!signers.some((s) => s.publicKey.equals(this.owner!.publicKey))) signers.push(this.owner!.signer!);\n });\n }\n\n return {\n builder: this,\n transactions: allTransactions,\n buildProps: props,\n signers: allSigners,\n instructionTypes: this.instructionTypes,\n execute: async (executeParams?: MultiTxExecuteParam) => {\n const { sequentially, onTxUpdate, recentBlockHash: propBlockHash, skipPreflight = true } = executeParams || {};\n allTransactions.map(async (tx, idx) => {\n if (allSigners[idx].length) tx.sign(allSigners[idx]);\n if (propBlockHash) tx.message.recentBlockhash = propBlockHash;\n });\n printSimulate(allTransactions);\n if (this.owner?.isKeyPair) {\n if (sequentially) {\n const txIds: string[] = [];\n for (const tx of allTransactions) {\n const txId = await this.connection.sendTransaction(tx, { skipPreflight });\n await confirmTransaction(this.connection, txId);\n txIds.push(txId);\n }\n\n return { txIds, signedTxs: allTransactions };\n }\n\n return {\n txIds: await Promise.all(\n allTransactions.map(async (tx) => {\n return await this.connection.sendTransaction(tx, { skipPreflight });\n }),\n ),\n signedTxs: allTransactions,\n };\n }\n if (this.signAllTransactions) {\n const signedTxs = await this.signAllTransactions(allTransactions);\n if (sequentially) {\n let i = 0;\n const processedTxs: TxUpdateParams[] = [];\n const checkSendTx = async (): Promise<void> => {\n if (!signedTxs[i]) return;\n const txId = await this.connection.sendTransaction(signedTxs[i], { skipPreflight });\n processedTxs.push({ txId, status: \"sent\", signedTx: signedTxs[i] });\n onTxUpdate?.([...processedTxs]);\n i++;\n this.connection.onSignature(\n txId,\n (signatureResult) => {\n const targetTxIdx = processedTxs.findIndex((tx) => tx.txId === txId);\n if (targetTxIdx > -1) processedTxs[targetTxIdx].status = signatureResult.err ? \"error\" : \"success\";\n onTxUpdate?.([...processedTxs]);\n if (!signatureResult.err) checkSendTx();\n },\n \"processed\",\n );\n this.connection.getSignatureStatus(txId);\n };\n checkSendTx();\n return {\n txIds: [],\n signedTxs,\n };\n } else {\n const txIds: string[] = [];\n for (let i = 0; i < signedTxs.length; i += 1) {\n const txId = await this.connection.sendTransaction(signedTxs[i], { skipPreflight });\n txIds.push(txId);\n }\n return { txIds, signedTxs };\n }\n }\n throw new Error(\"please provide owner in keypair format or signAllTransactions function\");\n },\n extInfo: extInfo || {},\n };\n }\n}\n","import { Connection, PublicKey, AddressLookupTableAccount } from \"@solana/web3.js\";\nimport { getMultipleAccountsInfo } from \"../accountInfo\";\n\nexport interface CacheLTA {\n [key: string]: AddressLookupTableAccount;\n}\n\nexport async function getMultipleLookupTableInfo({\n connection,\n address,\n}: {\n connection: Connection;\n address: PublicKey[];\n}): Promise<CacheLTA> {\n const dataInfos = await getMultipleAccountsInfo(\n connection,\n [...new Set<string>(address.map((i) => i.toString()))].map((i) => new PublicKey(i)),\n );\n\n const outDict: CacheLTA = {};\n for (let i = 0; i < address.length; i++) {\n const info = dataInfos[i];\n const key = address[i];\n if (!info) continue;\n const lookupAccount = new AddressLookupTableAccount({\n key,\n state: AddressLookupTableAccount.deserialize(info.data),\n });\n outDict[key.toString()] = lookupAccount;\n LOOKUP_TABLE_CACHE[key.toString()] = lookupAccount;\n }\n\n return outDict;\n}\n\nexport const LOOKUP_TABLE_CACHE: CacheLTA = {\n \"2immgwYNHBbyVQKVGCEkgWpi53bLwWNRMB5G2nbgYV17\": new AddressLookupTableAccount({\n key: new PublicKey(\"2immgwYNHBbyVQKVGCEkgWpi53bLwWNRMB5G2nbgYV17\"),\n state: AddressLookupTableAccount.deserialize(\n Buffer.from(\n \"AQAAAP//////////d49+DAAAAAAAAQZMWvw7GUNJdaccNBVnb57OKakxL2BHLYvhRwVILRsgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMGRm/lIRcy/+ytunLDm+e8jOW7xfcSayxDmzpAAAAABt324ddloZPZy+FGzut5rBy0he1fWzeROoz1hX7/AKkG3fbh7nWP3hhCXbzkbM3athr8TYO5DSf+vfko2KGL/AVKU1D4XciC1hSlVnJ4iilt3x6rq9CmBniISTL07vagBqfVFxksXFEhjMlMPUrxf1ja7gibof1E49vZigAAAAAGp9UXGMd0yShWY5hpHV62i164o5tLbVxzVVshAAAAAIyXJY9OJInxuz0QKRSODYMLWhOZ2v8QhASOe9jb6fhZC3BlsePRfEU4nVJ/awTDzVi4bHMaoP21SbbRvAP4KUbIScv+6Yw2LHF/6K0ZjUPibbSWXCirYPGuuVl7zT789IUPLW4CpHr4JNCatp3ELXDLKMv6JJ+37le50lbBJ2LvDQdRqCgtphMF/imcN7mY5YRx2xE1A3MQ+L4QRaYK9u4GRfZP3LsAd00a+IkCpA22UNQMKdq5BFbJuwuOLqc8zxCTDlqxBG8J0HcxtfogQHDK06ukzfaXiNDKAob1MqBHS9lJxDYCwz8gd5DtFqNSTKG5l1zxIaKpDP/sffi2is1H9aKveyXSu5StXElYRl9SD5As0DHE4N0GLnf84/siiKXVyp4Ez121kLcUui/jLLFZEz/BwZK3Ilf9B9OcsEAeDMKAy2vjGSxQODgBz0QwGA+eP4ZjIjrIAQaXENv31QfLlOdXSRCkaybRniDHF4C8YcwhcvsqrOVuTP4B2Na+9wLdtrB31uz2rtlFI5kahdsnp/d1SrASDInYCtTYtdoke4kX+hoKWcEWM4Tle8pTUkUVv4BxS6fje/EzKBE4Qu9N9LMnrw/JNO0hqMVB4rk/2ou4AB1loQ7FZoPwut2o4KZB+0p9xnbrQKw038qjpHar+PyDwvxBRcu5hpHw3dguezeWv+IwvgW5icu8EGkhGa9AkFPPJT7VMSFb8xowveU=\",\n \"base64\",\n ),\n ),\n }),\n};\n","import { AccountInfo, Commitment, Connection, PublicKey } from \"@solana/web3.js\";\nimport { ReturnTypeFetchMultipleMintInfos } from \"../raydium/type\";\nimport { WSOLMint, chunkArray, solToWSol } from \"./\";\nimport { createLogger } from \"./logger\";\nimport { MINT_SIZE, TOKEN_PROGRAM_ID, getTransferFeeConfig, unpackMint } from \"@solana/spl-token\";\n\ninterface MultipleAccountsJsonRpcResponse {\n jsonrpc: string;\n id: string;\n error?: {\n code: number;\n message: string;\n };\n result: {\n context: { slot: number };\n value: { data: Array<string>; executable: boolean; lamports: number; owner: string; rentEpoch: number }[];\n };\n}\n\nexport interface GetMultipleAccountsInfoConfig {\n batchRequest?: boolean;\n commitment?: Commitment;\n chunkCount?: number;\n}\n\nconst logger = createLogger(\"Raydium_accountInfo_util\");\n\nexport async function getMultipleAccountsInfo(\n connection: Connection,\n publicKeys: PublicKey[],\n config?: GetMultipleAccountsInfoConfig,\n): Promise<(AccountInfo<Buffer> | null)[]> {\n const {\n batchRequest,\n commitment = \"confirmed\",\n chunkCount = 100,\n } = {\n batchRequest: false,\n ...config,\n };\n\n const chunkedKeys = chunkArray(publicKeys, chunkCount);\n let results: (AccountInfo<Buffer> | null)[][] = new Array(chunkedKeys.length).fill([]);\n\n if (batchRequest) {\n const batch = chunkedKeys.map((keys) => {\n const args = connection._buildArgs([keys.map((key) => key.toBase58())], commitment, \"base64\");\n return {\n methodName: \"getMultipleAccounts\",\n args,\n };\n });\n\n const _batch = chunkArray(batch, 10);\n\n const unsafeResponse: MultipleAccountsJsonRpcResponse[] = await (\n await Promise.all(_batch.map(async (i) => await (connection as any)._rpcBatchRequest(i)))\n ).flat();\n results = unsafeResponse.map((unsafeRes: MultipleAccountsJsonRpcResponse) => {\n if (unsafeRes.error)\n logger.logWithError(`failed to get info for multiple accounts, RPC_ERROR, ${unsafeRes.error.message}`);\n\n return unsafeRes.result.value.map((accountInfo) => {\n if (accountInfo) {\n const { data, executable, lamports, owner, rentEpoch } = accountInfo;\n\n if (data.length !== 2 && data[1] !== \"base64\") logger.logWithError(`info must be base64 encoded, RPC_ERROR`);\n\n return {\n data: Buffer.from(data[0], \"base64\"),\n executable,\n lamports,\n owner: new PublicKey(owner),\n rentEpoch,\n };\n }\n return null;\n });\n });\n } else {\n try {\n results = (await Promise.all(\n chunkedKeys.map((keys) => connection.getMultipleAccountsInfo(keys, commitment)),\n )) as (AccountInfo<Buffer> | null)[][];\n } catch (error) {\n if (error instanceof Error) {\n logger.logWithError(`failed to get info for multiple accounts, RPC_ERROR, ${error.message}`);\n }\n }\n }\n\n return results.flat();\n}\n\nexport async function getMultipleAccountsInfoWithCustomFlags<T extends { pubkey: PublicKey }>(\n connection: Connection,\n publicKeysWithCustomFlag: T[],\n config?: GetMultipleAccountsInfoConfig,\n): Promise<({ accountInfo: AccountInfo<Buffer> | null } & T)[]> {\n const multipleAccountsInfo = await getMultipleAccountsInfo(\n connection,\n publicKeysWithCustomFlag.map((o) => o.pubkey),\n config,\n );\n\n return publicKeysWithCustomFlag.map((o, idx) => ({ ...o, accountInfo: multipleAccountsInfo[idx] }));\n}\n\nexport enum AccountType {\n Uninitialized,\n Mint,\n Account,\n}\nexport const ACCOUNT_TYPE_SIZE = 1;\n\nexport async function fetchMultipleMintInfos({\n connection,\n mints,\n config,\n}: {\n connection: Connection;\n mints: PublicKey[];\n config?: { batchRequest?: boolean };\n}): Promise<ReturnTypeFetchMultipleMintInfos> {\n if (mints.length === 0) return {};\n const mintInfos = await getMultipleAccountsInfoWithCustomFlags(\n connection,\n mints.map((i) => ({ pubkey: solToWSol(i) })),\n config,\n );\n\n const mintK: ReturnTypeFetchMultipleMintInfos = {};\n for (const i of mintInfos) {\n if (!i.accountInfo || i.accountInfo.data.length < MINT_SIZE) {\n console.log(\"invalid mint account\", i.pubkey.toBase58());\n continue;\n }\n const t = unpackMint(i.pubkey, i.accountInfo, i.accountInfo?.owner);\n mintK[i.pubkey.toString()] = {\n ...t,\n programId: i.accountInfo?.owner || TOKEN_PROGRAM_ID,\n feeConfig: getTransferFeeConfig(t) ?? undefined,\n };\n }\n mintK[PublicKey.default.toBase58()] = mintK[WSOLMint.toBase58()];\n\n return mintK;\n}\n","import BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { CurrencyAmount, TokenAmount } from \"../module/amount\";\nimport { Currency } from \"../module/currency\";\nimport { Fraction } from \"../module/fraction\";\nimport { Percent } from \"../module/percent\";\nimport { Price } from \"../module/price\";\nimport { Token } from \"../module/token\";\nimport { SplToken, TokenJson } from \"../raydium/token/type\";\nimport { ReplaceType } from \"../raydium/type\";\nimport { parseBigNumberish } from \"./constant\";\nimport { mul } from \"./fractionUtil\";\nimport { notInnerObject } from \"./utility\";\n\nexport const BN_ZERO = new BN(0);\nexport const BN_ONE = new BN(1);\nexport const BN_TWO = new BN(2);\nexport const BN_THREE = new BN(3);\nexport const BN_FIVE = new BN(5);\nexport const BN_TEN = new BN(10);\nexport const BN_100 = new BN(100);\nexport const BN_1000 = new BN(1000);\nexport const BN_10000 = new BN(10000);\nexport type BigNumberish = BN | string | number | bigint;\nexport type Numberish = number | string | bigint | Fraction | BN;\n\n\nexport function tenExponential(shift: BigNumberish): BN {\n return BN_TEN.pow(parseBigNumberish(shift));\n}\n\n/**\n *\n * @example\n * getIntInfo(0.34) => { numerator: '34', denominator: '100'}\n * getIntInfo('0.34') //=> { numerator: '34', denominator: '100'}\n */\nexport function parseNumberInfo(n: Numberish | undefined): {\n denominator: string;\n numerator: string;\n sign?: string;\n int?: str