UNPKG

@layerzerolabs/lz-sui-sdk-v2

Version:

246 lines (223 loc) 8.39 kB
import { bcs } from '@mysten/sui/bcs' import { SuiClient } from '@mysten/sui/client' import { Transaction, TransactionArgument, TransactionResult } from '@mysten/sui/transactions' import { asObject, executeSimulate } from '../utils' const DEFAULT_MODULE_NAME = 'call' export const CallErrorCode = { // Call related errors (matching call.move) Call_ECallNotActive: 1, Call_ECallNotCompleted: 2, Call_ECallNotCreating: 3, Call_ECallNotRoot: 4, Call_ECallNotWaiting: 5, Call_EInvalidChild: 6, Call_EInvalidNonce: 7, Call_EInvalidParent: 8, Call_EParameterNotMutable: 9, Call_EUnauthorized: 10, // CallCap related errors (matching call_cap.move) CallCap_EBadWitness: 1, // MultiCall related errors (matching dynamic-call/multi-call/multi_call.move) MultiCall_ENoMoreCalls: 1, MultiCall_EUnauthorized: 2, } as const export class Call { public packageId: string public readonly client: SuiClient constructor(packageId: string, client: SuiClient) { this.packageId = packageId this.client = client } // === Set function === /** * Create a new CallCap for a user (direct interaction) * Creates a user-based CallCap that uses its own UID as the identifier * @param tx - The transaction to add the move call to * @returns Transaction result containing the new individual CallCap */ newIndividualCapMoveCall(tx: Transaction): TransactionResult { return tx.moveCall({ target: this.#target('new_individual_cap', 'call_cap'), arguments: [], }) } /** * Create a void result for calls with no meaningful return value * @param tx - The transaction to add the move call to * @returns Transaction result containing a void result */ voidMoveCall(tx: Transaction): TransactionResult { return tx.moveCall({ target: this.#target('void'), arguments: [], }) } // === View function === /** * Get the result from a call * @param tx - The transaction to add the move call to * @param paramType - The parameter type for the call * @param resultType - The result type for the call * @param call - The call transaction result or transaction argument * @returns Transaction result containing the call result */ resultMoveCall( tx: Transaction, paramType: string, resultType: string, call: TransactionArgument ): TransactionResult { return tx.moveCall({ target: this.#target('result'), typeArguments: [paramType, resultType], arguments: [call], }) } /** * Get the recipient from a call * @param tx - The transaction to add the move call to * @param paramType - The parameter type for the call * @param resultType - The result type for the call * @param call - The call transaction result or transaction argument * @returns Transaction result containing the call recipient */ recipientMoveCall( tx: Transaction, paramType: string, resultType: string, call: TransactionArgument ): TransactionResult { return tx.moveCall({ target: this.#target('recipient'), typeArguments: [paramType, resultType], arguments: [call], }) } /** * Get the unique identifier for a CallCap * Returns the appropriate identifier based on the source type * @param tx - The transaction to add the move call to * @param callCap - The CallCap object ID or transaction argument * @returns Transaction result containing the CallCap identifier */ callCapIdMoveCall(tx: Transaction, callCap: string | TransactionArgument): TransactionResult { return tx.moveCall({ target: this.#target('id', 'call_cap'), arguments: [asObject(tx, callCap)], }) } /** * Get the unique identifier for a CallCap * Returns the appropriate identifier based on the source type * @param callCap - The CallCap object ID * @returns Promise resolving to the CallCap identifier as a string */ async getCallCapId(callCap: string): Promise<string> { return executeSimulate( this.client, (tx) => { this.callCapIdMoveCall(tx, callCap) }, (result) => bcs.Address.parse(result[0].value) ) } /** * Check if this is an Individual CallCap * @param tx - The transaction to add the move call to * @param callCap - The CallCap object ID or transaction argument * @returns Transaction result containing a boolean indicating if it's an Individual CallCap */ isIndividualCapMoveCall(tx: Transaction, callCap: string | TransactionArgument): TransactionResult { return tx.moveCall({ target: this.#target('is_individual', 'call_cap'), arguments: [asObject(tx, callCap)], }) } /** * Check if this is an Individual CallCap * @param callCap - The CallCap object ID * @returns Promise resolving to true if it's an Individual CallCap */ async isIndividualCap(callCap: string): Promise<boolean> { return executeSimulate( this.client, (tx) => { this.isIndividualCapMoveCall(tx, callCap) }, (result) => bcs.Bool.parse(result[0].value) ) } /** * Check if this is a Package CallCap * @param tx - The transaction to add the move call to * @param callCap - The CallCap object ID or transaction argument * @returns Transaction result containing a boolean indicating if it's a Package CallCap */ isPackageCapMoveCall(tx: Transaction, callCap: string | TransactionArgument): TransactionResult { return tx.moveCall({ target: this.#target('is_package', 'call_cap'), arguments: [asObject(tx, callCap)], }) } /** * Check if this is a Package CallCap * @param callCap - The CallCap object ID * @returns Promise resolving to true if it's a Package CallCap */ async isPackageCap(callCap: string): Promise<boolean> { return executeSimulate( this.client, (tx) => { this.isPackageCapMoveCall(tx, callCap) }, (result) => bcs.Bool.parse(result[0].value) ) } /** * Get the package address for a Package CallCap * Returns None if this is a User CallCap * @param tx - The transaction to add the move call to * @param callCap - The CallCap object ID or transaction argument * @returns Transaction result containing the package address option */ packageAddressMoveCall(tx: Transaction, callCap: string | TransactionArgument): TransactionResult { return tx.moveCall({ target: this.#target('package_address', 'call_cap'), arguments: [asObject(tx, callCap)], }) } /** * Get the package address for a Package CallCap * Returns null if this is an Individual CallCap * @param callCap - The CallCap object ID * @returns Promise resolving to the package address or null if Individual CallCap */ async getPackageAddress(callCap: string): Promise<string | null> { return executeSimulate( this.client, (tx) => { this.packageAddressMoveCall(tx, callCap) }, (result) => { try { // Try to parse as Option<address> const option = bcs.option(bcs.Address).parse(result[0].value) return option ?? null } catch { // If parsing fails, it might be None return null } } ) } /** * Generate the full target path for move calls * @param name - The function name to call * @param module_name - The module name (defaults to DEFAULT_MODULE_NAME) * @returns The full module path for the move call * @private */ #target(name: string, module_name = DEFAULT_MODULE_NAME): string { return `${this.packageId}::${module_name}::${name}` } }