import { isValidSuiAddress } from '@mysten/sui/utils' import { RpcModule } from '../modules/rpcModule' import type { BaseSdkOptions, InitCetusSDKOptions, SuiAddressType, SuiResource } from '../type/sui' import { CachedContent, cacheTime24h, getFutureTime } from '../utils/cachedContent' import { CommonErrorCode, handleMessageError } from '../errors/errors' import { patchFixSuiObjectId } from '../utils/contracts' export abstract class SdkWrapper { readonly _cache: Record = {} readonly _fullClient: RpcModule private _senderAddress: SuiAddressType = '' /** * Provide sdk options */ protected _sdkOptions: T constructor(options: T) { this._fullClient = new RpcModule({ url: options.full_rpc_url }) patchFixSuiObjectId(options) this._sdkOptions = options } /** * Getter for the sdkOptions property. * @returns {SdkOptions} The sdkOptions property value. */ get sdkOptions(): T { return this._sdkOptions } get FullClient(): RpcModule { return this._fullClient } /** * Static factory method to initialize the SDK * @param options SDK initialization options * @param clmmSDK Optional CLMM SDK instance * @returns An instance of the SDK */ static createSDK(options: InitCetusSDKOptions, clmmSDK?: any): any { throw new Error('createSDK must be implemented in derived class') } /** * Create a custom SDK instance with the given options * @param options The options for the SDK * @returns An instance of the SDK */ static createCustomSDK(options: T, clmmSDK?: any): any { throw new Error('createCustomSDK must be implemented in derived class') } /** * Getter for the sender address property. * @param {boolean} validate - Whether to validate the sender address. Default is true. * @returns The sender address value. */ getSenderAddress(validate = true) { if (validate && !isValidSuiAddress(this._senderAddress)) { handleMessageError( CommonErrorCode.InvalidSenderAddress, 'Invalid sender address: sdk requires a valid sender address. Please set it using sdk.setSenderAddress("0x...")' ) } return this._senderAddress } /** * Setter for the sender address property. * @param {string} value - The new sender address value. */ setSenderAddress(value: string) { this._senderAddress = value } /** * Updates the cache for the given key. * * @param key The key of the cache entry to update. * @param data The data to store in the cache. * @param time The time in minutes after which the cache entry should expire. */ updateCache(key: string, data: SuiResource, time = cacheTime24h): void { let cacheData = this._cache[key] if (cacheData) { cacheData.overdueTime = getFutureTime(time) cacheData.value = data } else { cacheData = new CachedContent(data, getFutureTime(time)) } this._cache[key] = cacheData } /** * Gets the cache entry for the given key. * * @param key The key of the cache entry to get. * @param forceRefresh Whether to force a refresh of the cache entry. * @returns The cache entry for the given key, or undefined if the cache entry does not exist or is expired. */ getCache(key: string, forceRefresh = false): T | undefined { const cacheData = this._cache[key] const isValid = cacheData?.isValid() if (!forceRefresh && isValid) { return cacheData.value as T } if (!isValid) { delete this._cache[key] } return undefined } }