UNPKG

@layerzerolabs/lz-sui-sdk-v2

Version:

103 lines (88 loc) 3.6 kB
import { ObjectOwner } from '@mysten/sui/client' import { MoveCallWithObjectDetails } from './move-call-object-fetcher' import { IPTBValidator } from './ptb-validator' /** * NonSenderObjectValidator ensures objects are not owned by the transaction sender * * In Sui, this validator checks that objects are: * - Shared: globally accessible, mutations require consensus * - Immutable: can't change after creation * - Owned by another address (not the sender) * * This prevents the sender from using their own owned objects in the transaction */ export class NonSenderObjectValidator implements IPTBValidator { private sender: string constructor(sender: string) { this.sender = sender } /** * Validates that objects are not owned by the sender * @param moveCallsWithDetails - Array of move calls with object details * @throws Error if any object is owned by the sender */ validate(moveCallsWithDetails: MoveCallWithObjectDetails[]): void { for (const { objectDetails } of moveCallsWithDetails) { for (const [objectId, objectResponse] of objectDetails) { const owner = objectResponse.data?.owner if (owner == null) { throw new Error(`Object ${objectId} has no owner`) } // Validate that object is not owned by the sender if (!this.isValidOwnership(owner)) { const ownerType = this.getOwnershipType(owner) throw new Error( `Object ${objectId} is owned by the sender (${this.sender}). ` + `Only Shared, Immutable, or objects owned by other addresses are allowed. ` + `Current ownership: ${ownerType}` ) } } } } /** * Checks if the ownership is valid (not owned by sender) * @param owner - The object owner to check * @returns true if ownership is valid (Shared, Immutable, or owned by another address) */ private isValidOwnership(owner: ObjectOwner): boolean { // Shared objects are valid if (typeof owner === 'object' && 'Shared' in owner) { return true } // Immutable objects are valid if (owner === 'Immutable') { return true } // Objects owned by another address are valid if (typeof owner === 'object' && 'AddressOwner' in owner && owner.AddressOwner !== this.sender) { return true } // Objects owned by another object are valid if (typeof owner === 'object' && 'ObjectOwner' in owner) { return true } // If owned by sender, it's invalid return false } /** * Gets a human-readable description of the ownership type * @param owner - The object owner * @returns String description of ownership type */ private getOwnershipType(owner: ObjectOwner): string { if (typeof owner === 'object' && 'Shared' in owner) { return `Shared (initial_shared_version: ${owner.Shared.initial_shared_version})` } if (owner === 'Immutable') { return 'Immutable' } if (typeof owner === 'object' && 'AddressOwner' in owner) { return `AddressOwner: ${owner.AddressOwner}` } if (typeof owner === 'object' && 'ObjectOwner' in owner) { return `ObjectOwner: ${owner.ObjectOwner}` } return 'Unknown ownership type' } }