snapper-sdk
Version:
An SDK for building applications on top of Snapper.
1 lines • 354 kB
Source Map (JSON)
{"version":3,"sources":["../../../src/raydium/token/token.ts","../../../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 { PublicKey } from \"@solana/web3.js\";\nimport { MintLayout, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\n\nimport { ApiV3Token, JupTokenType } from \"@/api/type\";\nimport ModuleBase, { ModuleBaseProps } from \"../moduleBase\";\nimport { LoadParams } from \"../type\";\n\nimport { SOL_INFO } from \"./constant\";\nimport { TokenInfo } from \"./type\";\n\nexport default class TokenModule extends ModuleBase {\n private _tokenList: TokenInfo[] = [];\n private _tokenMap: Map<string, TokenInfo> = new Map();\n private _blackTokenMap: Map<string, TokenInfo> = new Map();\n private _mintGroup: { official: Set<string>; jup: Set<string>; extra: Set<string> } = {\n official: new Set(),\n jup: new Set(),\n extra: new Set(),\n };\n private _whiteMap: Set<string> = new Set();\n private _extraTokenList: TokenInfo[] = [];\n\n constructor(params: ModuleBaseProps) {\n super(params);\n }\n\n public async load(params?: LoadParams & { type?: JupTokenType }): Promise<void> {\n this.checkDisabled();\n const { forceUpdate = false, type = JupTokenType.Strict } = params || {};\n const snapper = await this.scope.fetchSnapperTokenList();\n const { mintList, blacklist, whiteList } = await this.scope.fetchV3TokenList(forceUpdate);\n const jup = await this.scope.fetchJupTokenList(forceUpdate);\n\n // console.log('mintList', mintList);\n // console.log('jup', jup);\n // console.log('snapper', snapper);\n // reset all data\n this._tokenList = [];\n this._tokenMap = new Map();\n this._blackTokenMap = new Map();\n this._mintGroup = { official: new Set(), jup: new Set(), extra: new Set() };\n this._whiteMap = new Set(whiteList);\n\n this._tokenMap.set(SOL_INFO.address, SOL_INFO);\n this._mintGroup.official.add(SOL_INFO.address);\n blacklist.forEach((token) => {\n this._blackTokenMap.set(token.address, { ...token, priority: -1 });\n });\n\n snapper.forEach((token) => {\n if (this._blackTokenMap.has(token.address) || this._tokenMap.has(token.address)) return;\n this._tokenMap.set(token.address, {\n ...token,\n type: \"jupiter\",\n priority: 1,\n programId:\n token.programId ??\n (token.tags.includes(\"token-2022\") ? TOKEN_2022_PROGRAM_ID.toBase58() : TOKEN_PROGRAM_ID.toBase58()),\n tags: token.freezeAuthority ? [...(token.tags || []), \"hasFreeze\"] : token.tags,\n });\n this._mintGroup.jup.add(token.address);\n });\n\n mintList.forEach((token) => {\n if (this._blackTokenMap.has(token.address)) return;\n this._tokenMap.set(token.address, {\n ...token,\n type: \"raydium\",\n priority: 2,\n programId:\n token.programId ??\n (token.tags.includes(\"token-2022\") ? TOKEN_2022_PROGRAM_ID.toBase58() : TOKEN_PROGRAM_ID.toBase58()),\n });\n this._mintGroup.official.add(token.address);\n });\n\n jup.forEach((token) => {\n if (this._blackTokenMap.has(token.address) || this._tokenMap.has(token.address)) return;\n this._tokenMap.set(token.address, {\n ...token,\n type: \"jupiter\",\n priority: 1,\n programId:\n token.programId ??\n (token.tags.includes(\"token-2022\") ? TOKEN_2022_PROGRAM_ID.toBase58() : TOKEN_PROGRAM_ID.toBase58()),\n tags: token.freezeAuthority ? [...(token.tags || []), \"hasFreeze\"] : token.tags,\n });\n this._mintGroup.jup.add(token.address);\n });\n\n this._extraTokenList.forEach((token) => {\n if (this._blackTokenMap.has(token.address) || this._tokenMap.has(token.address)) return;\n this._tokenMap.set(token.address, {\n ...token,\n type: \"extra\",\n priority: 1,\n programId:\n token.programId || token.tags.includes(\"token-2022\")\n ? TOKEN_2022_PROGRAM_ID.toBase58()\n : TOKEN_PROGRAM_ID.toBase58(),\n });\n this._mintGroup.extra.add(token.address);\n });\n\n this._tokenList = Array.from(this._tokenMap).map((data) => data[1]);\n }\n\n get tokenList(): TokenInfo[] {\n return this._tokenList;\n }\n get tokenMap(): Map<string, TokenInfo> {\n return this._tokenMap;\n }\n get blackTokenMap(): Map<string, TokenInfo> {\n return this._blackTokenMap;\n }\n get mintGroup(): { official: Set<string>; jup: Set<string> } {\n return this._mintGroup;\n }\n get whiteListMap(): Set<string> {\n return this._whiteMap;\n }\n\n /** === util functions === */\n\n public async getTokenInfo(mint: string | PublicKey): Promise<ApiV3Token> {\n if (!mint) throw new Error(\"please input mint\");\n const mintStr = mint.toString();\n const info = this._tokenMap.get(mintStr);\n if (info) return info;\n if (mintStr.toLocaleUpperCase() === \"SOL\") return SOL_INFO;\n\n const apiTokenInfo = (await this.scope.api.getTokenInfo([mintStr]))[0];\n if (apiTokenInfo) {\n this._mintGroup.extra.add(mintStr);\n this._tokenMap.set(mintStr, { ...apiTokenInfo, priority: 2 });\n return apiTokenInfo;\n }\n\n const onlineInfo = await this.scope.connection.getAccountInfo(new PublicKey(mintStr));\n if (!onlineInfo) throw new Error(`mint address not found: ${mintStr}`);\n const data = MintLayout.decode(onlineInfo.data);\n const mintSymbol = mintStr.toString().substring(0, 6);\n const fullInfo = {\n chainId: 101,\n address: mintStr,\n programId: onlineInfo.owner.toBase58(),\n logoURI: \"\",\n symbol: mintSymbol,\n name: mintSymbol,\n decimals: data.decimals,\n tags: [],\n extensions: {},\n priority: 0,\n type: \"unknown\",\n };\n this._mintGroup.extra.add(mintStr);\n this._tokenMap.set(mintStr, fullInfo);\n return fullInfo;\n }\n}\n","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