UNPKG

@layerzerolabs/lz-sui-sdk-v2

Version:

106 lines (92 loc) 3.54 kB
import { SuiClient, SuiObjectResponse } from '@mysten/sui/client' import { MAX_BATCH_SIZE, MoveCall } from '../types' /** * Represents a move call with its associated object details */ export interface MoveCallWithObjectDetails { moveCall: MoveCall objectDetails: Map<string, SuiObjectResponse> } /** * MoveCallObjectFetcher fetches object details for move calls once * and provides them to validators to avoid multiple API calls */ export class MoveCallObjectFetcher { private client: SuiClient private batchSize: number constructor(client: SuiClient, batchSize: number = MAX_BATCH_SIZE) { this.client = client this.batchSize = batchSize } /** * Fetches object details for all objects referenced in move calls * @param moveCalls - Array of move calls to fetch object details for * @param options - Options for what object data to fetch * @returns Array of move calls with their associated object details */ async fetchObjectDetails( moveCalls: MoveCall[], options: { showOwner?: boolean showType?: boolean showContent?: boolean showBcs?: boolean showDisplay?: boolean showStorageRebate?: boolean } = {} ): Promise<MoveCallWithObjectDetails[]> { // Extract all unique object IDs from move calls const objectIdSet = new Set<string>() for (const moveCall of moveCalls) { for (const arg of moveCall.arguments) { if ('Object' in arg) { objectIdSet.add(arg.Object) } } } const objectIds = Array.from(objectIdSet) if (objectIds.length === 0) { // No objects to fetch, return move calls with empty object details return moveCalls.map((moveCall) => ({ moveCall, objectDetails: new Map<string, SuiObjectResponse>(), })) } // Validate batch size if (this.batchSize > MAX_BATCH_SIZE || this.batchSize < 1) { throw new Error(`batchSize must be between 1 and ${MAX_BATCH_SIZE}`) } // Fetch all objects in batches const objectDetailsMap = new Map<string, SuiObjectResponse>() for (let i = 0; i < objectIds.length; i += this.batchSize) { const batch = objectIds.slice(i, i + this.batchSize) const objects = await this.client.multiGetObjects({ ids: batch, options, }) // Map object responses to their IDs objects.forEach((object, index) => { const objectId = batch[index] objectDetailsMap.set(objectId, object) }) } // Create move calls with object details return moveCalls.map((moveCall) => { // Get object details for this specific move call const moveCallObjectDetails = new Map<string, SuiObjectResponse>() for (const arg of moveCall.arguments) { if ('Object' in arg) { const objectId = arg.Object const objectDetail = objectDetailsMap.get(objectId) if (objectDetail) { moveCallObjectDetails.set(objectId, objectDetail) } } } return { moveCall, objectDetails: moveCallObjectDetails, } }) } }