@layerzerolabs/lz-sui-sdk-v2
Version:
1,278 lines (1,213 loc) • 95.9 kB
text/typescript
import { bcs } from '@mysten/sui/bcs'
import { SuiClient } from '@mysten/sui/client'
import { Transaction, TransactionArgument, TransactionResult } from '@mysten/sui/transactions'
import { MessagingFeeBcs, TimeoutBcs } from '../bcs'
import { ModuleManager } from '../module-manager'
import {
CallTypeName,
DEFAULT_SIMULATION_TIMES,
LzTypeName,
MessageLibType,
MessagingFee,
MoveCall,
ObjectOptions,
Timeout,
} from '../types'
import {
asAddress,
asArgWithTx,
asBytes,
asBytes32,
asObject,
asString,
asU16,
asU32,
asU64,
executeSimulate,
simulateTransaction,
} from '../utils'
import { PackageAllowlistValidator } from '../utils/package-allowlist-validator'
import { IPTBValidator } from '../utils/ptb-validator'
import { ShareObjectValidator } from '../utils/share-object-validator'
import { callId, getTypeName } from '../utils/type-name'
import { validateWithDetails } from '../utils/validate-with-details'
const MODULE_NAME = 'endpoint_v2'
export const EndpointErrorCode = {
// MessageLibManager related errors (with MessageLibManager_ prefix)
MessageLibManager_EAlreadyRegistered: 1,
MessageLibManager_EDefaultReceiveLibUnavailable: 2,
MessageLibManager_EDefaultSendLibUnavailable: 3,
MessageLibManager_EInvalidAddress: 4,
MessageLibManager_EInvalidBounds: 5,
MessageLibManager_EInvalidExpiry: 6,
MessageLibManager_EInvalidReceiveLib: 7,
MessageLibManager_EOnlyNonDefaultLib: 8,
MessageLibManager_EOnlyReceiveLib: 9,
MessageLibManager_EOnlyRegisteredLib: 10,
MessageLibManager_EOnlySendLib: 11,
MessageLibManager_ESameValue: 12,
MessagingChannel_EAlreadyInitialized: 1,
MessagingChannel_EInsufficientNativeFee: 2,
MessagingChannel_EInsufficientZroFee: 3,
MessagingChannel_EInvalidNonce: 4,
MessagingChannel_EInvalidOApp: 5,
MessagingChannel_EInvalidPayloadHash: 6,
MessagingChannel_ENotSending: 7,
MessagingChannel_EPathNotVerifiable: 8,
MessagingChannel_EPayloadHashNotFound: 9,
MessagingChannel_ESendReentrancy: 10,
MessagingChannel_EUninitializedChannel: 11,
// MessagingComposer related errors (with MessagingComposer_ prefix)
MessagingComposer_EComposeExists: 1,
MessagingComposer_EComposeMessageMismatch: 2,
MessagingComposer_EComposeNotFound: 3,
MessagingComposer_EComposerNotRegistered: 4,
MessagingComposer_EComposerRegistered: 5,
// OAppRegistry related errors (with OAppRegistry_ prefix)
OAppRegistry_EOAppNotRegistered: 1,
OAppRegistry_EOAppRegistered: 2,
// Endpoint related errors (with Endpoint_ prefix)
Endpoint_EAlreadyInitialized: 1,
Endpoint_EInvalidEid: 2,
Endpoint_ENotInitialized: 3,
Endpoint_ERefundAddressNotFound: 4,
Endpoint_EUnauthorizedOApp: 5,
Endpoint_EUnauthorizedSendLibrary: 6,
} as const
export class Endpoint {
public packageId: string
public readonly client: SuiClient
private readonly objects: ObjectOptions
constructor(
packageId: string,
client: SuiClient,
objects: ObjectOptions,
private readonly moduleManager: ModuleManager
) {
this.packageId = packageId
this.client = client
this.objects = objects
}
// === Set Functions ===
/**
* Initialize the endpoint with an Endpoint ID (EID)
* @param tx - The transaction to add the move call to
* @param eid - The endpoint ID to initialize or transaction argument
*/
initEidMoveCall(tx: Transaction, eid: number | TransactionArgument): void {
tx.moveCall({
target: this.#target('init_eid'),
arguments: [tx.object(this.objects.endpointV2), tx.object(this.objects.endpointAdminCap), asU32(tx, eid)],
})
}
// ===== OApp Messaging Functions =====
/**
* Register an OApp with the endpoint
* @param tx - The transaction to add the move call to
* @param oappCap - The OApp capability object ID or transaction argument
* @param oappInfo - OApp information including lz_receive execution information
* @returns Transaction result containing the messaging channel address
*/
registerOAppMoveCall(
tx: Transaction,
oappCap: string | TransactionArgument,
oappInfo: Uint8Array | TransactionArgument
): TransactionResult {
return tx.moveCall({
target: this.#target('register_oapp'),
arguments: [tx.object(this.objects.endpointV2), asObject(tx, oappCap), asBytes(tx, oappInfo)],
})
}
/**
* Set a delegate for an OApp
* @param tx - The transaction to add the move call to
* @param oappCap - The OApp capability object ID or transaction argument
* @param newDelegate - The new delegate address or transaction argument
*/
setDelegateMoveCall(
tx: Transaction,
oappCap: string | TransactionArgument,
newDelegate: string | TransactionArgument
): void {
tx.moveCall({
target: this.#target('set_delegate'),
arguments: [tx.object(this.objects.endpointV2), asObject(tx, oappCap), asAddress(tx, newDelegate)],
})
}
/**
* Set OApp information for an OApp
* @param tx - The transaction to add the move call to
* @param callerCap - The caller capability object ID or transaction argument
* @param oapp - The OApp address or transaction argument
* @param oappInfo - The OApp information including lz_receive execution information as bytes or transaction argument
*/
setOappInfoMoveCall(
tx: Transaction,
callerCap: string | TransactionArgument,
oapp: string | TransactionArgument,
oappInfo: Uint8Array | TransactionArgument
): void {
tx.moveCall({
target: this.#target('set_oapp_info'),
arguments: [
tx.object(this.objects.endpointV2),
asObject(tx, callerCap),
asAddress(tx, oapp),
asBytes(tx, oappInfo),
],
})
}
/**
* Initialize a messaging channel between local and remote OApps
* @param tx - The transaction to add the move call to
* @param callerCap - The caller capability object ID or transaction argument
* @param messagingChannel - The messaging channel object ID or transaction argument
* @param remoteEid - The remote endpoint ID or transaction argument
* @param remoteOapp - The remote OApp address as bytes or transaction argument
*/
initChannelMoveCall(
tx: Transaction,
callerCap: string | TransactionArgument,
messagingChannel: string | TransactionArgument,
remoteEid: number | TransactionArgument,
remoteOapp: Uint8Array | TransactionArgument
): void {
tx.moveCall({
target: this.#target('init_channel'),
arguments: [
tx.object(this.objects.endpointV2),
asObject(tx, callerCap),
asObject(tx, messagingChannel),
asU32(tx, remoteEid),
asBytes32(tx, remoteOapp, this.moduleManager.getUtils()),
],
})
}
/**
* Quote the messaging fee for sending a message
* @param tx - The transaction to add the move call to
* @param messagingChannel - The messaging channel object ID or transaction argument
* @param call - The call transaction result
* @returns Transaction result containing the quote
*/
quoteMoveCall(
tx: Transaction,
messagingChannel: string | TransactionArgument,
call: TransactionArgument
): TransactionResult {
return tx.moveCall({
target: this.#target('quote'),
arguments: [tx.object(this.objects.endpointV2), asObject(tx, messagingChannel), call],
})
}
/**
* Confirm quote operation with message library
* @param tx - The transaction to add the move call to
* @param endpointCall - The endpoint call transaction result or transaction argument
* @param messageLibCall - The message library call transaction result or transaction argument
*/
confirmQuoteMoveCall(
tx: Transaction,
endpointCall: TransactionArgument,
messageLibCall: TransactionArgument
): void {
tx.moveCall({
target: this.#target('confirm_quote'),
arguments: [tx.object(this.objects.endpointV2), endpointCall, messageLibCall],
})
}
/**
* Send a message through the messaging channel
* @param tx - The transaction to add the move call to
* @param messagingChannel - The messaging channel object ID or transaction argument
* @param call - The call transaction result
* @returns Transaction result containing the send operation
*/
sendMoveCall(
tx: Transaction,
messagingChannel: string | TransactionArgument,
call: TransactionArgument
): TransactionResult {
return tx.moveCall({
target: this.#target('send'),
arguments: [tx.object(this.objects.endpointV2), asObject(tx, messagingChannel), call],
})
}
/**
* Confirm send operation with send library
* @param tx - The transaction to add the move call to
* @param sendLibrary - The send library object ID or transaction argument
* @param messagingChannel - The messaging channel object ID or transaction argument
* @param endpointCall - The endpoint call transaction result
* @param sendLibraryCall - The send library call transaction result
* @returns Transaction result containing the confirmed send operation
*/
confirmSendMoveCall(
tx: Transaction,
sendLibrary: string | TransactionArgument,
messagingChannel: string | TransactionArgument,
endpointCall: TransactionArgument,
sendLibraryCall: TransactionArgument
): TransactionResult {
return tx.moveCall({
target: this.#target('confirm_send'),
arguments: [
tx.object(this.objects.endpointV2),
asObject(tx, sendLibrary),
asObject(tx, messagingChannel),
endpointCall,
sendLibraryCall,
],
})
}
/**
* Refund fees from a send operation
* @param tx - The transaction to add the move call to
* @param sendCall - The send call transaction result or transaction argument
* @returns Transaction result containing the refund operation
*/
refundMoveCall(tx: Transaction, sendCall: TransactionArgument): void {
tx.moveCall({
target: this.#target('refund'),
arguments: [tx.object(this.objects.endpointV2), sendCall],
})
}
/**
* Verify a message from another chain
* @param tx - The transaction to add the move call to
* @param receiveLibrary - The receive library object ID or transaction argument
* @param messagingChannel - The messaging channel object ID or transaction argument
* @param srcEid - The source endpoint ID or transaction argument
* @param sender - The sender address as bytes or transaction argument
* @param nonce - The message nonce or transaction argument
* @param payloadHash - The payload hash as bytes or transaction argument
*/
verifyMoveCall(
tx: Transaction,
receiveLibrary: string | TransactionArgument,
messagingChannel: string | TransactionArgument,
srcEid: number | TransactionArgument,
sender: Uint8Array | TransactionArgument,
nonce: bigint | number | string | TransactionArgument,
payloadHash: Uint8Array | TransactionArgument
): void {
tx.moveCall({
target: this.#target('verify'),
arguments: [
tx.object(this.objects.endpointV2),
asObject(tx, receiveLibrary),
asObject(tx, messagingChannel),
asU32(tx, srcEid),
asBytes32(tx, sender, this.moduleManager.getUtils()),
asU64(tx, nonce),
asBytes32(tx, payloadHash, this.moduleManager.getUtils()),
tx.object.clock(),
],
})
}
/**
* Clear a verified message by executing it
* @param tx - The transaction to add the move call to
* @param caller - The caller object ID or transaction argument
* @param messagingChannel - The messaging channel object ID or transaction argument
* @param srcEid - Source endpoint ID or transaction argument
* @param sender - Sender address as bytes or transaction argument
* @param nonce - Message nonce or transaction argument
* @param guid - Globally unique identifier as bytes or transaction argument
* @param message - Message payload as bytes or transaction argument
*/
clearMoveCall(
tx: Transaction,
caller: string | TransactionArgument,
messagingChannel: string | TransactionArgument,
srcEid: number | TransactionArgument,
sender: Uint8Array | TransactionArgument,
nonce: bigint | number | string | TransactionArgument,
guid: Uint8Array | TransactionArgument,
message: Uint8Array | TransactionArgument
): void {
tx.moveCall({
target: this.#target('clear'),
arguments: [
tx.object(this.objects.endpointV2),
asObject(tx, caller),
asObject(tx, messagingChannel),
asU32(tx, srcEid),
asBytes32(tx, sender, this.moduleManager.getUtils()),
asU64(tx, nonce),
asBytes32(tx, guid, this.moduleManager.getUtils()),
asBytes(tx, message),
],
})
}
/**
* Skip a message (mark as processed without execution)
* @param tx - The transaction to add the move call to
* @param caller - The caller object ID or transaction argument
* @param messagingChannel - The messaging channel object ID or transaction argument
* @param srcEid - Source endpoint ID or transaction argument
* @param sender - Sender address as bytes or transaction argument
* @param nonce - Message nonce or transaction argument
*/
skipMoveCall(
tx: Transaction,
caller: string | TransactionArgument,
messagingChannel: string | TransactionArgument,
srcEid: number | TransactionArgument,
sender: Uint8Array | TransactionArgument,
nonce: bigint | number | string | TransactionArgument
): void {
tx.moveCall({
target: this.#target('skip'),
arguments: [
tx.object(this.objects.endpointV2),
asObject(tx, caller),
asObject(tx, messagingChannel),
asU32(tx, srcEid),
asBytes32(tx, sender, this.moduleManager.getUtils()),
asU64(tx, nonce),
],
})
}
/**
* Nilify a message (clear without execution)
* @param tx - The transaction to add the move call to
* @param caller - The caller object ID or transaction argument
* @param messagingChannel - The messaging channel object ID or transaction argument
* @param srcEid - Source endpoint ID or transaction argument
* @param sender - Sender address as bytes or transaction argument
* @param nonce - Message nonce or transaction argument
* @param payloadHash - Message payload hash as bytes or transaction argument
*/
nilifyMoveCall(
tx: Transaction,
caller: string | TransactionArgument,
messagingChannel: string | TransactionArgument,
srcEid: number | TransactionArgument,
sender: Uint8Array | TransactionArgument,
nonce: bigint | number | string | TransactionArgument,
payloadHash: Uint8Array | TransactionArgument
): void {
tx.moveCall({
target: this.#target('nilify'),
arguments: [
tx.object(this.objects.endpointV2),
asObject(tx, caller),
asObject(tx, messagingChannel),
asU32(tx, srcEid),
asBytes32(tx, sender, this.moduleManager.getUtils()),
asU64(tx, nonce),
asBytes32(tx, payloadHash, this.moduleManager.getUtils()),
],
})
}
/**
* Burn a message (permanently remove)
* @param tx - The transaction to add the move call to
* @param caller - The caller object ID or transaction argument
* @param messagingChannel - The messaging channel object ID or transaction argument
* @param srcEid - Source endpoint ID or transaction argument
* @param sender - Sender address as bytes or transaction argument
* @param nonce - Message nonce or transaction argument
* @param payloadHash - Message payload hash as bytes or transaction argument
*/
burnMoveCall(
tx: Transaction,
caller: string | TransactionArgument,
messagingChannel: string | TransactionArgument,
srcEid: number | TransactionArgument,
sender: Uint8Array | TransactionArgument,
nonce: bigint | number | string | TransactionArgument,
payloadHash: Uint8Array | TransactionArgument
): void {
tx.moveCall({
target: this.#target('burn'),
arguments: [
tx.object(this.objects.endpointV2),
asObject(tx, caller),
asObject(tx, messagingChannel),
asU32(tx, srcEid),
asBytes32(tx, sender, this.moduleManager.getUtils()),
asU64(tx, nonce),
asBytes32(tx, payloadHash, this.moduleManager.getUtils()),
],
})
}
/**
* Execute a LayerZero receive operation
* @param tx - The transaction to add the move call to
* @param executorCallCap - The executor call capability
* @param messagingChannel - The messaging channel object ID or transaction argument
* @param srcEid - The source endpoint ID or transaction argument
* @param sender - The sender address as bytes or transaction argument
* @param nonce - The message nonce or transaction argument
* @param guid - The globally unique identifier as bytes or transaction argument
* @param message - The message payload as bytes or transaction argument
* @param extraData - Additional data as bytes or transaction argument (optional)
* @param value - The native token value to transfer or transaction argument
* @returns Transaction result containing the receive operation
*/
lzReceiveMoveCall(
tx: Transaction,
executorCallCap: TransactionArgument,
messagingChannel: string | TransactionArgument,
srcEid: number | TransactionArgument,
sender: Uint8Array | TransactionArgument,
nonce: bigint | number | string | TransactionArgument,
guid: Uint8Array | TransactionArgument,
message: Uint8Array | TransactionArgument,
extraData: Uint8Array | TransactionArgument = new Uint8Array(),
value: bigint | number | string | TransactionArgument
): TransactionResult {
return tx.moveCall({
target: this.#target('lz_receive'),
arguments: [
tx.object(this.objects.endpointV2),
executorCallCap,
asObject(tx, messagingChannel),
asU32(tx, srcEid),
asBytes32(tx, sender, this.moduleManager.getUtils()),
asU64(tx, nonce),
asBytes32(tx, guid, this.moduleManager.getUtils()),
asBytes(tx, message),
asBytes(tx, extraData),
asArgWithTx(tx, value, (tx, val) => this.moduleManager.getUtils().createOptionSuiMoveCall(tx, val)),
],
})
}
/**
* Send alert for failed LayerZero receive operation
* @param tx - The transaction to add the move call to
* @param executor - The executor object ID or transaction argument
* @param srcEid - Source endpoint ID or transaction argument
* @param sender - Sender address as bytes or transaction argument
* @param nonce - Message nonce or transaction argument
* @param receiver - Receiver address or transaction argument
* @param guid - Globally unique identifier as bytes or transaction argument
* @param gas - Gas amount for execution or transaction argument
* @param value - Native token value or transaction argument
* @param message - Message payload as bytes or transaction argument
* @param extraData - Additional execution data as bytes or transaction argument
* @param reason - Failure reason or transaction argument
*/
lzReceiveAlertMoveCall(
tx: Transaction,
executor: string | TransactionArgument,
srcEid: number | TransactionArgument,
sender: Uint8Array | TransactionArgument,
nonce: bigint | number | string | TransactionArgument,
receiver: string | TransactionArgument,
guid: Uint8Array | TransactionArgument,
gas: bigint | number | string | TransactionArgument,
value: bigint | number | string | TransactionArgument,
message: Uint8Array | TransactionArgument,
extraData: Uint8Array | TransactionArgument,
reason: string | TransactionArgument
): void {
tx.moveCall({
target: this.#target('lz_receive_alert'),
arguments: [
asObject(tx, executor),
asU32(tx, srcEid),
asBytes32(tx, sender, this.moduleManager.getUtils()),
asU64(tx, nonce),
asAddress(tx, receiver),
asBytes32(tx, guid, this.moduleManager.getUtils()),
asU64(tx, gas),
asU64(tx, value),
asBytes(tx, message),
asBytes(tx, extraData),
asString(tx, reason),
],
})
}
/**
* Register a composer with the endpoint
* @param tx - The transaction to add the move call to
* @param composerCap - The composer capability object ID or transaction argument
* @param composerInfo - Composer information including lz_compose execution information as bytes
* @returns Transaction result containing the compose queue address
*/
registerComposerMoveCall(
tx: Transaction,
composerCap: string | TransactionArgument,
composerInfo: Uint8Array | TransactionArgument
): TransactionResult {
return tx.moveCall({
target: this.#target('register_composer'),
arguments: [tx.object(this.objects.endpointV2), asObject(tx, composerCap), asBytes(tx, composerInfo)],
})
}
/**
* Set composer information for a composer
* @param tx - The transaction to add the move call to
* @param composerCap - The composer capability object ID or transaction argument
* @param composerInfo - Composer information including lz_compose execution information as bytes or transaction argument
*/
setComposerInfoMoveCall(
tx: Transaction,
composerCap: string | TransactionArgument,
composerInfo: Uint8Array | TransactionArgument
): void {
tx.moveCall({
target: this.#target('set_composer_info'),
arguments: [tx.object(this.objects.endpointV2), asObject(tx, composerCap), asBytes(tx, composerInfo)],
})
}
/**
* Send compose message to queue
* @param tx - The transaction to add the move call to
* @param from - The sender object ID or transaction argument
* @param composeQueue - The compose queue object ID or transaction argument
* @param guid - Globally unique identifier as bytes or transaction argument
* @param index - Compose message index or transaction argument
* @param message - Message payload as bytes or transaction argument
*/
sendComposeMoveCall(
tx: Transaction,
from: string | TransactionArgument,
composeQueue: string | TransactionArgument,
guid: Uint8Array | TransactionArgument,
index: number | TransactionArgument,
message: Uint8Array | TransactionArgument
): void {
tx.moveCall({
target: this.#target('send_compose'),
arguments: [
asObject(tx, from),
asObject(tx, composeQueue),
asBytes32(tx, guid, this.moduleManager.getUtils()),
asU16(tx, index),
asBytes(tx, message),
],
})
}
/**
* Execute LayerZero compose operation
* @param tx - The transaction to add the move call to
* @param executorCallCap - The executor call capability
* @param composeQueue - The compose queue object ID or transaction argument
* @param from - Source address or transaction argument
* @param guid - Globally unique identifier as bytes or transaction argument
* @param index - Compose message index or transaction argument
* @param message - Message payload as bytes or transaction argument
* @param extraData - Additional execution data as bytes or transaction argument (optional)
* @param value - Native token value to transfer or transaction argument
* @returns Transaction result containing the compose operation
*/
lzComposeMoveCall(
tx: Transaction,
executorCallCap: TransactionArgument,
composeQueue: string | TransactionArgument,
from: string | TransactionArgument,
guid: Uint8Array | TransactionArgument,
index: number | TransactionArgument,
message: Uint8Array | TransactionArgument,
extraData: Uint8Array | TransactionArgument = new Uint8Array(),
value: bigint | number | string | TransactionArgument
): TransactionResult {
return tx.moveCall({
target: this.#target('lz_compose'),
arguments: [
tx.object(this.objects.endpointV2),
executorCallCap,
asObject(tx, composeQueue),
asAddress(tx, from),
asBytes32(tx, guid, this.moduleManager.getUtils()),
asU16(tx, index),
asBytes(tx, message),
asBytes(tx, extraData),
asArgWithTx(tx, value, (tx, val) => this.moduleManager.getUtils().createOptionSuiMoveCall(tx, val)),
],
})
}
/**
* Send alert for failed LayerZero compose operation
* @param tx - The transaction to add the move call to
* @param executor - The executor object ID or transaction argument
* @param from - Source address or transaction argument
* @param to - Destination address or transaction argument
* @param guid - Globally unique identifier as bytes or transaction argument
* @param index - Compose message index or transaction argument
* @param gas - Gas amount for execution or transaction argument
* @param value - Native token value or transaction argument
* @param message - Message payload as bytes or transaction argument
* @param extraData - Additional execution data as bytes or transaction argument
* @param reason - Failure reason or transaction argument
*/
lzComposeAlertMoveCall(
tx: Transaction,
executor: string | TransactionArgument,
from: string | TransactionArgument,
to: string | TransactionArgument,
guid: Uint8Array | TransactionArgument,
index: number | TransactionArgument,
gas: bigint | number | string | TransactionArgument,
value: bigint | number | string | TransactionArgument,
message: Uint8Array | TransactionArgument,
extraData: Uint8Array | TransactionArgument,
reason: string | TransactionArgument
): void {
tx.moveCall({
target: this.#target('lz_compose_alert'),
arguments: [
asObject(tx, executor),
asAddress(tx, from),
asAddress(tx, to),
asBytes32(tx, guid, this.moduleManager.getUtils()),
asU16(tx, index),
asU64(tx, gas),
asU64(tx, value),
asBytes(tx, message),
asBytes(tx, extraData),
asString(tx, reason),
],
})
}
// ===== OApp Library Configuration Functions =====
/**
* Set the send library for an OApp to a specific destination
* @param tx - The transaction to add the move call to
* @param caller - The caller capability object ID or transaction argument
* @param sender - The sender OApp address or transaction argument
* @param dstEid - The destination endpoint ID or transaction argument
* @param newLib - The new send library address or transaction argument
*/
setSendLibraryMoveCall(
tx: Transaction,
caller: string | TransactionArgument,
sender: string | TransactionArgument,
dstEid: number | TransactionArgument,
newLib: string | TransactionArgument
): void {
tx.moveCall({
target: this.#target('set_send_library'),
arguments: [
tx.object(this.objects.endpointV2),
asObject(tx, caller),
asAddress(tx, sender),
asU32(tx, dstEid),
asAddress(tx, newLib),
],
})
}
/**
* Set the receive library for an OApp from a specific source
* @param tx - The transaction to add the move call to
* @param caller - The caller capability object ID or transaction argument
* @param receiver - The receiver OApp address or transaction argument
* @param srcEid - The source endpoint ID or transaction argument
* @param newLib - The new receive library address or transaction argument
* @param gracePeriod - The grace period in seconds or transaction argument
*/
setReceiveLibraryMoveCall(
tx: Transaction,
caller: string | TransactionArgument,
receiver: string | TransactionArgument,
srcEid: number | TransactionArgument,
newLib: string | TransactionArgument,
gracePeriod: number | string | bigint | TransactionArgument
): void {
tx.moveCall({
target: this.#target('set_receive_library'),
arguments: [
tx.object(this.objects.endpointV2),
asObject(tx, caller),
asAddress(tx, receiver),
asU32(tx, srcEid),
asAddress(tx, newLib),
asU64(tx, gracePeriod),
tx.object.clock(),
],
})
}
/**
* Set timeout for receive library transition
* @param tx - The transaction to add the move call to
* @param caller - The caller capability object ID or transaction argument
* @param receiver - The receiver OApp address or transaction argument
* @param srcEid - Source endpoint ID or transaction argument
* @param lib - The library address or transaction argument
* @param expiry - Timeout expiry timestamp or transaction argument
*/
setReceiveLibraryTimeoutMoveCall(
tx: Transaction,
caller: string | TransactionArgument,
receiver: string | TransactionArgument,
srcEid: number | TransactionArgument,
lib: string | TransactionArgument,
expiry: number | string | bigint | TransactionArgument
): void {
tx.moveCall({
target: this.#target('set_receive_library_timeout'),
arguments: [
tx.object(this.objects.endpointV2),
asObject(tx, caller),
asAddress(tx, receiver),
asU32(tx, srcEid),
asAddress(tx, lib),
asU64(tx, expiry),
tx.object.clock(),
],
})
}
/**
* Set configuration for an OApp's message library
* @param tx - The transaction to add the move call to
* @param caller - The caller object ID or transaction argument
* @param oapp - The OApp address or transaction argument
* @param lib - The message library address or transaction argument
* @param eid - Endpoint ID or transaction argument
* @param config_type - Configuration type identifier or transaction argument
* @param config - Configuration data as bytes or transaction argument
* @returns Transaction result containing the configuration operation
*/
setConfigMoveCall(
tx: Transaction,
caller: string | TransactionArgument,
oapp: string | TransactionArgument,
lib: string | TransactionArgument,
eid: number | TransactionArgument,
config_type: number | TransactionArgument,
config: Uint8Array | TransactionArgument
): TransactionResult {
return tx.moveCall({
target: this.#target('set_config'),
arguments: [
tx.object(this.objects.endpointV2),
asObject(tx, caller),
asAddress(tx, oapp),
asAddress(tx, lib),
asU32(tx, eid),
asU32(tx, config_type),
asBytes(tx, config),
],
})
}
/**
* Register a message library with the endpoint (admin only)
* @param tx - The transaction to add the move call to
* @param messageLibCap - The message library capability address or transaction argument
* @param messageLibType - The type of message library (Send, Receive, or SendAndReceive)
*/
registerLibraryMoveCall(
tx: Transaction,
messageLibCap: string | TransactionArgument,
messageLibType: MessageLibType
): void {
const libType = this.messageLibTypeMoveCall(tx, messageLibType)
tx.moveCall({
target: this.#target('register_library'),
arguments: [
tx.object(this.objects.endpointV2),
tx.object(this.objects.endpointAdminCap),
asAddress(tx, messageLibCap),
libType,
],
})
}
/**
* Set default send library for a destination EID (admin only)
* @param tx - The transaction to add the move call to
* @param dstEid - Destination endpoint ID
* @param newLib - The new default send library address
*/
setDefaultSendLibraryMoveCall(
tx: Transaction,
dstEid: number | TransactionArgument,
newLib: string | TransactionArgument
): void {
tx.moveCall({
target: this.#target('set_default_send_library'),
arguments: [
tx.object(this.objects.endpointV2),
tx.object(this.objects.endpointAdminCap),
asU32(tx, dstEid),
asAddress(tx, newLib),
],
})
}
/**
* Set default receive library for a source EID (admin only)
* @param tx - The transaction to add the move call to
* @param srcEid - Source endpoint ID
* @param newLib - The new default receive library address
* @param gracePeriod - Grace period in seconds for library transition
*/
setDefaultReceiveLibraryMoveCall(
tx: Transaction,
srcEid: number | TransactionArgument,
newLib: string | TransactionArgument,
gracePeriod: number | string | bigint | TransactionArgument
): void {
tx.moveCall({
target: this.#target('set_default_receive_library'),
arguments: [
tx.object(this.objects.endpointV2),
tx.object(this.objects.endpointAdminCap),
asU32(tx, srcEid),
asAddress(tx, newLib),
asU64(tx, gracePeriod),
tx.object.clock(),
],
})
}
/**
* Set timeout for default receive library transition (admin only)
* @param tx - The transaction to add the move call to
* @param srcEid - Source endpoint ID
* @param lib - The library address
* @param expiry - Timeout expiry timestamp
*/
setDefaultReceiveLibraryTimeoutMoveCall(
tx: Transaction,
srcEid: number | TransactionArgument,
lib: string | TransactionArgument,
expiry: number | string | bigint | TransactionArgument
): void {
tx.moveCall({
target: this.#target('set_default_receive_library_timeout'),
arguments: [
tx.object(this.objects.endpointV2),
tx.object(this.objects.endpointAdminCap),
asU32(tx, srcEid),
asAddress(tx, lib),
asU64(tx, expiry),
tx.object.clock(),
],
})
}
/**
* Create message library type move call
* @param tx - The transaction to add the move call to
* @param messageLibType - The message library type enum value
* @returns Transaction result containing the library type
*/
messageLibTypeMoveCall(tx: Transaction, messageLibType: MessageLibType): TransactionResult {
switch (messageLibType) {
case MessageLibType.Send:
return tx.moveCall({
target: this.#target('send', 'message_lib_type'),
arguments: [],
})
case MessageLibType.Receive:
return tx.moveCall({
target: this.#target('receive', 'message_lib_type'),
arguments: [],
})
case MessageLibType.SendAndReceive:
return tx.moveCall({
target: this.#target('send_and_receive', 'message_lib_type'),
arguments: [],
})
default:
throw new Error(`Invalid message lib type: ${JSON.stringify(messageLibType)}`)
}
}
// === View Functions ===
// Basic endpoint info
/**
* Get the Endpoint ID (EID) of the current chain
* @param tx - The transaction to add the move call to
* @returns Transaction result containing the EID
*/
eidMoveCall(tx: Transaction): TransactionResult {
return tx.moveCall({
target: this.#target('eid'),
arguments: [tx.object(this.objects.endpointV2)],
})
}
/**
* Get the Endpoint ID (EID) of the current chain
* @returns The endpoint ID, or 0 if not initialized
*/
async eid(): Promise<number> {
return executeSimulate(
this.client,
(tx) => {
this.eidMoveCall(tx)
},
(result) => bcs.U32.parse(result[0].value)
)
}
/**
* Check if an OApp is registered with the endpoint
* @param tx - The transaction to add the move call to
* @param oapp - The OApp address to check or transaction argument
* @returns Transaction result containing the registration status
*/
isOappRegisteredMoveCall(tx: Transaction, oapp: string | TransactionArgument): TransactionResult {
return tx.moveCall({
target: this.#target('is_oapp_registered'),
arguments: [tx.object(this.objects.endpointV2), asAddress(tx, oapp)],
})
}
/**
* Check if an OApp is registered with the endpoint
* @param oapp - The OApp address to check
* @returns True if the OApp is registered, false otherwise
*/
async isOappRegistered(oapp: string): Promise<boolean> {
return executeSimulate(
this.client,
(tx) => this.isOappRegisteredMoveCall(tx, oapp),
(result) => bcs.Bool.parse(result[0].value)
)
}
/**
* Get messaging channel for an OApp
* @param tx - The transaction to add the move call to
* @param oapp - The OApp address or transaction argument
* @returns Transaction result containing the messaging channel address
*/
getMessagingChannelMoveCall(tx: Transaction, oapp: string | TransactionArgument): TransactionResult {
return tx.moveCall({
target: this.#target('get_messaging_channel'),
arguments: [tx.object(this.objects.endpointV2), asAddress(tx, oapp)],
})
}
/**
* Get the messaging channel for an OApp
* @param oapp - The OApp address
* @returns The messaging channel address
*/
async getMessagingChannel(oapp: string): Promise<string> {
return executeSimulate(
this.client,
(tx) => {
this.getMessagingChannelMoveCall(tx, oapp)
},
(result) => bcs.Address.parse(result[0].value)
)
}
/**
* Get OApp information for an OApp
* @param tx - The transaction to add the move call to
* @param oapp - The OApp address or transaction argument
* @returns Transaction result containing the OApp information including lz_receive execution information
*/
getOappInfoMoveCall(tx: Transaction, oapp: string | TransactionArgument): TransactionResult {
return tx.moveCall({
target: this.#target('get_oapp_info'),
arguments: [tx.object(this.objects.endpointV2), asAddress(tx, oapp)],
})
}
/**
* Get OApp information for an OApp
* @param oapp - The OApp address
* @returns Promise<Uint8Array> - The OApp information including lz_receive execution information as bytes
*/
async getOappInfo(oapp: string): Promise<Uint8Array> {
return executeSimulate(
this.client,
(tx) => {
return this.getOappInfoMoveCall(tx, oapp)
},
(result) => {
const parsed = bcs.vector(bcs.u8()).parse(result[0].value)
return new Uint8Array(parsed)
}
)
}
/**
* Get delegate address for an OApp
* @param tx - The transaction to add the move call to
* @param oapp - The OApp address or transaction argument
* @returns Transaction result containing the delegate address
*/
getDelegateMoveCall(tx: Transaction, oapp: string | TransactionArgument): TransactionResult {
return tx.moveCall({
target: this.#target('get_delegate'),
arguments: [tx.object(this.objects.endpointV2), asAddress(tx, oapp)],
})
}
/**
* Get delegate address for an OApp
* @param oapp - The OApp address
* @returns Promise<string> - The delegate address
*/
async getDelegate(oapp: string): Promise<string> {
return executeSimulate(
this.client,
(tx) => {
this.getDelegateMoveCall(tx, oapp)
},
(result) => bcs.Address.parse(result[0].value)
)
}
/**
* Check if a composer is registered with the endpoint
* @param tx - The transaction to add the move call to
* @param composer - The composer address or transaction argument
* @returns Transaction result containing the registration status
*/
isComposerRegisteredMoveCall(tx: Transaction, composer: string | TransactionArgument): TransactionResult {
return tx.moveCall({
target: this.#target('is_composer_registered'),
arguments: [tx.object(this.objects.endpointV2), asAddress(tx, composer)],
})
}
/**
* Check if a composer is registered with the endpoint
* @param composer - The composer address
* @returns Promise<boolean> - True if the composer is registered
*/
async isComposerRegistered(composer: string): Promise<boolean> {
return executeSimulate(
this.client,
(tx) => {
this.isComposerRegisteredMoveCall(tx, composer)
},
(result) => bcs.Bool.parse(result[0].value)
)
}
/**
* Get compose queue address for a composer
* @param tx - The transaction to add the move call to
* @param composer - The composer address or transaction argument
* @returns Transaction result containing the compose queue address
*/
getComposeQueueMoveCall(tx: Transaction, composer: string | TransactionArgument): TransactionResult {
return tx.moveCall({
target: this.#target('get_compose_queue'),
arguments: [tx.object(this.objects.endpointV2), asAddress(tx, composer)],
})
}
/**
* Get compose queue address for a composer
* @param composer - The composer address
* @returns Promise<string> - The compose queue address
*/
async getComposeQueue(composer: string): Promise<string> {
return executeSimulate(
this.client,
(tx) => {
this.getComposeQueueMoveCall(tx, composer)
},
(result) => bcs.Address.parse(result[0].value)
)
}
/**
* Get composer information for a registered composer
* @param tx - The transaction to add the move call to
* @param composer - The composer address or transaction argument
* @returns Transaction result containing the composer information
*/
getComposerInfoMoveCall(tx: Transaction, composer: string | TransactionArgument): TransactionResult {
return tx.moveCall({
target: this.#target('get_composer_info'),
arguments: [tx.object(this.objects.endpointV2), asAddress(tx, composer)],
})
}
/**
* Get composer information for a registered composer
* @param composer - The composer address
* @returns Promise<Uint8Array> - The composer information as bytes
*/
async getComposerInfo(composer: string): Promise<Uint8Array> {
return executeSimulate(
this.client,
(tx) => {
this.getComposerInfoMoveCall(tx, composer)
},
(result) => {
const parsed = bcs.vector(bcs.u8()).parse(result[0].value)
return new Uint8Array(parsed)
}
)
}
// Compose Queue View Functions
/**
* Get composer address from compose queue
* @param tx - The transaction to add the move call to
* @param composeQueue - The compose queue object ID or transaction argument
* @returns Transaction result containing the composer address
*/
getComposerMoveCall(tx: Transaction, composeQueue: string | TransactionArgument): TransactionResult {
return tx.moveCall({
target: this.#target('get_composer'),
arguments: [asObject(tx, composeQueue)],
})
}
/**
* Get composer address from compose queue
* @param composeQueue - The compose queue object ID
* @returns Promise<string> - The composer address
*/
async getComposer(composeQueue: string): Promise<string> {
return executeSimulate(
this.client,
(tx) => this.getComposerMoveCall(tx, composeQueue),
(result) => bcs.Address.parse(result[0].value)
)
}
/**
* Check if compose message hash exists
* @param tx - The transaction to add the move call to
* @param composeQueue - The compose queue object ID
* @param from - Sender address
* @param guid - Globally unique identifier as bytes
* @param index - Compose message index
* @returns Transaction result containing the message hash existence status
*/
hasComposeMessageHashMoveCall(
tx: Transaction,
composeQueue: string | TransactionArgument,
from: string | TransactionArgument,
guid: Uint8Array | TransactionArgument,
index: number | TransactionArgument
): TransactionResult {
return tx.moveCall({
target: this.#target('has_compose_message_hash'),
arguments: [
asObject(tx, composeQueue),
asAddress(tx, from),
asBytes32(tx, guid, this.moduleManager.getUtils()),
asU16(tx, index),
],
})
}
/**
* Check if compose message hash exists
* @param composeQueue - The compose queue object ID
* @param from - Sender address
* @param guid - Globally unique identifier as bytes
* @param index - Compose message index
* @returns Promise<boolean> - True if message hash exists
*/
async hasComposeMessageHash(composeQueue: string, from: string, guid: Uint8Array, index: number): Promise<boolean> {
return executeSimulate(
this.client,
(tx) => this.hasComposeMessageHashMoveCall(tx, composeQueue, from, guid, index),
(result) => bcs.Bool.parse(result[0].value)
)
}
/**
* Get compose message hash
* @param tx - The transaction to add the move call to
* @param composeQueue - The compose queue object ID
* @param from - Sender address
* @param guid - Globally unique identifier as bytes
* @param index - Compose message index
* @returns Transaction result containing the message hash
*/
getComposeMessageHashMoveCall(
tx: Transaction,
composeQueue: string | TransactionArgument,
from: string | TransactionArgument,
guid: Uint8Array | TransactionArgument,
index: number | TransactionArgument
): TransactionResult {
return tx.moveCall({
target: this.#target('get_compose_message_hash'),
arguments: [
asObject(tx, composeQueue),
asAddress(tx, from),
asBytes32(tx, guid, this.moduleManager.getUtils()),
asU16(tx, index),
],
})
}
/**
* Get compose message hash
* @param composeQue