Skip to main content

SDK API reference

The Messaging SDK APIs follow the lifecycle of a secure communication system: create groups, manage membership, send messages, and maintain encryption state.

All methods are accessed through the client.messaging namespace after setup.

For permission management (grant, revoke, check membership), use client.groups. See the Sui Groups API Reference.

Key types

GroupRef

Most methods accept a GroupRef to identify a group. Either form works:

type GroupRef =
| { uuid: string } // derives both IDs
| { groupId: string; encryptionHistoryId: string }; // explicit IDs

DecryptedMessage

Returned by getMessage, getMessages, and subscribe:

interface DecryptedMessage {
messageId: string;
groupId: string;
order: number;
text: string; // empty string for deleted or attachment-only messages
senderAddress: string;
createdAt: number; // unix timestamp (seconds)
updatedAt: number;
isEdited: boolean;
isDeleted: boolean;
syncStatus?: SyncStatus; // Walrus sync state (when relayer archives)
attachments: AttachmentHandle[]; // lazy-download handles
senderVerified: boolean; // per-message signature verified
}

AttachmentHandle

Resolved attachment with lazy download:

interface AttachmentHandle {
fileName: string;
mimeType: string;
fileSize: number;
extras?: Record<string, unknown>;
wire: Attachment; // raw wire format (for edits)
data(): Promise<Uint8Array>; // download + decrypt on demand
}

GetMessagesResult

interface GetMessagesResult {
messages: DecryptedMessage[];
hasNext: boolean;
}

EditAttachments

interface EditAttachments {
current: Attachment[]; // current attachments on the message
remove?: string[]; // storageIds to remove
new?: AttachmentFile[]; // new files to upload
}

Messaging methods

These methods handle E2EE messaging through the relayer transport. Encryption and decryption are automatic. See Encryption for the underlying encryption model.

sendMessage(options)

Encrypt and send a message to a group.

ParameterTypeRequiredDescription
signerSignerYesSigns the message and authenticates with the relayer
groupRefGroupRefYesTarget group
textstringNo*Message text
filesAttachmentFile[]No*Files to attach (requires attachments config)
sealApproveContextTApproveContextOnly with custom SealPolicyContext for custom Seal policies

*At least one of text or files must be provided.

Returns: { messageId: string }

const { messageId } = await client.messaging.sendMessage({
signer: keypair,
groupRef: { uuid: 'my-group' },
text: 'Hello!',
});

getMessage(options)

Fetch and decrypt a single message by ID.

ParameterTypeRequiredDescription
signerSignerYesAuthenticates with the relayer
groupRefGroupRefYesTarget group
messageIdstringYesMessage ID

Returns: DecryptedMessage

const msg = await client.messaging.getMessage({
signer: keypair,
groupRef: { uuid: 'my-group' },
messageId: 'abc123',
});

getMessages(options)

Fetch and decrypt a paginated list of messages.

ParameterTypeRequiredDescription
signerSignerYesAuthenticates with the relayer
groupRefGroupRefYesTarget group
afterOrdernumberNoFetch messages after this order (exclusive)
beforeOrdernumberNoFetch messages before this order (exclusive)
limitnumberNoMax messages to return

Returns: GetMessagesResult

Messages that fail decryption (for example, key not available) are silently skipped.

const { messages, hasNext } = await client.messaging.getMessages({
signer: keypair,
groupRef: { uuid: 'my-group' },
limit: 50,
});

editMessage(options)

Re-encrypt and update an existing message. Only the original sender can edit.

ParameterTypeRequiredDescription
signerSignerYesMust be the original sender
groupRefGroupRefYesTarget group
messageIdstringYesMessage to edit
textstringYesNew message text
attachmentsEditAttachmentsNoAttachment changes (omit to leave unchanged)

Returns: void

await client.messaging.editMessage({
signer: keypair,
groupRef: { uuid: 'my-group' },
messageId: 'abc123',
text: 'Updated text',
attachments: {
current: originalMsg.attachments.map(a => a.wire),
remove: ['old-storage-id'],
new: [{ fileName: 'new.txt', mimeType: 'text/plain', data: bytes }],
},
});

deleteMessage(options)

Soft-delete a message. Only the original sender can delete.

ParameterTypeRequiredDescription
signerSignerYesMust be the original sender
groupRefGroupRefYesTarget group
messageIdstringYesMessage to delete

Returns: void

subscribe(options)

Subscribe to real-time messages for a group. Returns an AsyncIterable that yields decrypted messages as they arrive.

ParameterTypeRequiredDescription
signerSignerYesAuthenticates with the relayer
groupRefGroupRefYesTarget group
afterOrdernumberNoResume from this order (exclusive)
signalAbortSignalNoCancel the subscription

Returns: AsyncIterable<DecryptedMessage>

Messages that fail decryption are silently skipped.

const controller = new AbortController();

for await (const msg of client.messaging.subscribe({
signer: keypair,
groupRef: { uuid: 'my-group' },
signal: controller.signal,
})) {
console.log(msg.text, msg.senderVerified);
}

disconnect()

Disconnect the underlying transport. Active subscriptions complete.

client.messaging.disconnect();

recoverMessages(options)

Recover messages from an alternative storage backend (for example, Walrus). Requires a RecoveryTransport to be configured at client creation. See Archive and Recovery.

Unlike other messaging methods, this does not require a signer because recovery is read-only.

ParameterTypeRequiredDescription
groupRefGroupRefYesTarget group
afterOrdernumberNoFetch messages after this order (exclusive)
beforeOrdernumberNoFetch messages before this order (exclusive)
limitnumberNoMax messages to return

Returns: GetMessagesResult

Messages that fail decryption are silently dropped.

const { messages, hasNext } = await client.messaging.recoverMessages({
groupRef: { uuid: 'my-group' },
limit: 50,
});

Group management methods

Onchain transactions for group lifecycle. Each method signs and executes a transaction.

createAndShareGroup(options)

Create a new messaging group and share both objects (PermissionedGroup and EncryptionHistory). The transaction sender becomes the creator with all permissions.

ParameterTypeRequiredDescription
signerSignerYesTransaction sender (becomes group creator)
namestringYesHuman-readable group name
uuidstringNoUUID for deterministic addressing (generated if omitted)
initialMembersstring[]NoAddresses to grant MessagingReader on creation

Returns: { digest: string; effects: TransactionEffects }

await client.messaging.createAndShareGroup({
signer: keypair,
name: 'My Group',
initialMembers: ['0xAlice...', '0xBob...'],
});

rotateEncryptionKey(options)

Rotate the DEK for a group. Generates a new Seal-encrypted DEK for the next key version. Requires EncryptionKeyRotator permission. See Encryption for key versioning details.

ParameterTypeRequiredDescription
signerSignerYesMust have EncryptionKeyRotator permission
groupRefGroupRefYesTarget group (through uuid or explicit IDs)

Returns: { digest: string; effects: TransactionEffects }

removeMembersAndRotateKey(options)

Atomically remove members and rotate the encryption key in a single PTB. This is the recommended way to remove members. See Security.

ParameterTypeRequiredDescription
signerSignerYesMust have permission to remove members and rotate keys
groupRefGroupRefYesTarget group
membersstring[]YesAddresses to remove

Returns: { digest: string; effects: TransactionEffects }

await client.messaging.removeMembersAndRotateKey({
signer: keypair,
groupRef: { uuid: 'my-group' },
members: ['0xAlice...'],
});

leave(options)

Remove the transaction sender from a group.

ParameterTypeRequiredDescription
signerSignerYesThe member leaving
groupIdstringYesPermissionedGroup object ID

Returns: { digest: string; effects: TransactionEffects }

leave() does not rotate the encryption key. See Security for implications.

archiveGroup(options)

Permanently archive a group. Pauses the group and burns the UnpauseCap, making it impossible to unpause. Requires PermissionsAdmin permission.

ParameterTypeRequiredDescription
signerSignerYesMust have PermissionsAdmin permission
groupIdstringYesPermissionedGroup object ID

Returns: { digest: string; effects: TransactionEffects }

Metadata methods

Onchain key-value metadata for groups. All require MetadataAdmin permission.

setGroupName(options)

ParameterTypeRequiredDescription
signerSignerYesMust have MetadataAdmin permission
groupIdstringYesPermissionedGroup object ID
namestringYesNew group name

Returns: { digest: string; effects: TransactionEffects }

insertGroupData(options)

Insert a key-value pair into the group's onchain metadata map.

ParameterTypeRequiredDescription
signerSignerYesMust have MetadataAdmin permission
groupIdstringYesPermissionedGroup object ID
keystringYesMetadata key
valuestringYesMetadata value

Returns: { digest: string; effects: TransactionEffects }

removeGroupData(options)

Remove a key-value pair from the group's metadata map.

ParameterTypeRequiredDescription
signerSignerYesMust have MetadataAdmin permission
groupIdstringYesPermissionedGroup object ID
keystringYesMetadata key to remove

Returns: { digest: string; effects: TransactionEffects }

SuiNS methods

Manage SuiNS reverse lookup for human-readable group names. Require SuiNsAdmin permission.

setSuinsReverseLookup(options)

ParameterTypeRequiredDescription
signerSignerYesMust have SuiNsAdmin permission
groupIdstringYesPermissionedGroup object ID
domainNamestringYesSuiNS domain name

Returns: { digest: string; effects: TransactionEffects }

unsetSuinsReverseLookup(options)

ParameterTypeRequiredDescription
signerSignerYesMust have SuiNsAdmin permission
groupIdstringYesPermissionedGroup object ID

Returns: { digest: string; effects: TransactionEffects }

Verification

verifyMessageSender(params)

Verify that a message was signed by the claimed sender. Reconstructs the canonical message, rebuilds the serialized signature, and verifies against the public key.

ParameterTypeDescription
groupIdstringGroup ID
encryptedTextUint8ArrayCiphertext
nonceUint8ArrayAES-GCM nonce
keyVersionbigintKey version
senderAddressstringClaimed sender
signaturestringHex-encoded 64-byte raw signature
publicKeystringHex-encoded public key with scheme flag prefix

Returns: boolean

The SDK automatically verifies sender signatures during decryption and populates DecryptedMessage.senderVerified. Use this method only if you need to re-verify manually.

View methods (client.messaging.view)

Read-only queries that fetch onchain state through RPC. No gas required.

encryptedKey(options)

Fetch the encrypted DEK for a specific key version.

ParameterTypeDescription
encryptionHistoryId or uuidstringEncryptionHistory reference
versionbigint | numberKey version (0-indexed)

Returns: Uint8Array

currentEncryptedKey(options)

Fetch the encrypted DEK for the latest key version. Always makes at least two RPC calls (one for current size, one for the entry).

ParameterTypeDescription
encryptionHistoryId or uuidstringEncryptionHistory reference

Returns: Uint8Array

getCurrentKeyVersion(options)

Return the current (latest) key version number.

ParameterTypeDescription
encryptionHistoryId or uuidstringEncryptionHistory reference

Returns: bigint

groupsMetadata(options)

Return multiple groups' onchain metadata (name, uuid, creator, data map). Results are cached; pass refresh: true to bypass.

ParameterTypeDescription
groupIdsstring[]PermissionedGroup object IDs
refreshbooleanBypass cache (optional)

Returns: Record<string, ParsedMetadata> where each key is a group ID and value is { name: string; uuid: string; creator: string; data: Map<string, string> }

Derive methods (client.messaging.derive)

Pure, synchronous address derivation. No network calls.

groupId({ uuid })

Derive the PermissionedGroup<Messaging> object ID from a UUID.

Returns: string

encryptionHistoryId({ uuid })

Derive the EncryptionHistory object ID from a UUID.

Returns: string

resolveGroupRef(ref)

Resolve a GroupRef to explicit { groupId, encryptionHistoryId }. When a UUID is provided, both IDs are derived. When explicit IDs are provided, they pass through.

Returns: { groupId: string; encryptionHistoryId: string }

groupLeaverId()

Derive the GroupLeaver singleton object ID. Used internally by leave().

Returns: string

groupManagerId()

Derive the GroupManager singleton object ID. Used internally by metadata and SuiNS methods.

Returns: string

systemObjectAddresses()

Return the addresses of system-level actor objects (GroupLeaver, GroupManager) that are automatically added to every group. Useful for filtering system entries from member lists in UI:

Returns: Set<string>

const system = client.messaging.derive.systemObjectAddresses();
const humanMembers = allMembers.filter(m => !system.has(m.address));

Transaction builders (tx.*)

Return Transaction objects ready for signing. Same parameters as imperative methods (minus signer). Use these when you need to inspect or modify the transaction before signing (for example, with dapp-kit's signAndExecuteTransaction).

const tx = client.messaging.tx.createAndShareGroup({
name: 'My Group',
initialMembers: ['0xAlice...'],
});

const result = await keypair.signAndExecuteTransaction({ transaction: tx, client });

Available: createAndShareGroup, rotateEncryptionKey, removeMembersAndRotateKey, archiveGroup, leave, setGroupName, insertGroupData, removeGroupData, setSuinsReverseLookup, unsetSuinsReverseLookup.

Call builders (call.*)

Return transaction thunks for composing multiple operations into a single PTB through tx.add().

import { Transaction } from '@mysten/sui/transactions';

const tx = new Transaction();
tx.add(client.messaging.call.createAndShareGroup({ name: 'My Group' }));
tx.add(client.groups.call.grantPermission({ groupId, member, permissionType }));
await keypair.signAndExecuteTransaction({ transaction: tx, client });

Available: same as tx.*, plus createGroup (returns unshared objects for manual composition with shareGroup), and shareGroup (shares the objects returned by createGroup).

BCS parsing (bcs.*)

BCS type definitions for parsing onchain data and constructing event type strings for GraphQL queries.

Messaging types:

  • bcs.Messaging -- the Messaging witness type
  • bcs.MessagingNamespace -- the shared namespace object
  • bcs.EncryptionHistory -- encryption key history
  • bcs.EncryptionHistoryCreated, bcs.EncryptionKeyRotated -- encryption events
  • bcs.EncryptionHistoryTag, bcs.PermissionedGroupTag -- derivation key types
  • bcs.Metadata, bcs.MetadataKey -- group metadata
  • bcs.GroupManager, bcs.GroupLeaver -- system actor objects

Permission types:

  • bcs.MessagingSender, bcs.MessagingReader, bcs.MessagingEditor, bcs.MessagingDeleter
  • bcs.EncryptionKeyRotator, bcs.SuiNsAdmin, bcs.MetadataAdmin

Each BCS type exposes a .name property with the fully-qualified Move type name, useful for GraphQL event queries and permission checks.

Encryption (encryption.*)

Low-level encryption module. Most developers do not need this directly because sendMessage, getMessages, and subscribe handle encryption automatically. See Encryption for the full encryption model.

  • encrypt(options) -- encrypt data with a group's DEK
  • decrypt(options) -- decrypt data with a group's DEK
  • generateGroupDEK(uuid?) -- generate a new Seal-encrypted DEK for group creation
  • generateRotationDEK(options) -- generate a new Seal-encrypted DEK for key rotation
  • clearCache(groupId?) -- clear cached DEKs (all or per-group)

Transport (transport)

Direct access to the underlying RelayerTransport instance. Useful for low-level operations or debugging:

// Direct relayer access (bypasses encryption)
const raw = await client.messaging.transport.fetchMessages({ ... });

See Relayer for the RelayerTransport interface definition.

Permission types

The messaging package defines these permission types, accessible through messagingPermissionTypes(packageId):

PermissionPurpose
MessagingSenderSend messages
MessagingReaderDecrypt messages (controls DEK access through Seal)
MessagingEditorEdit own messages
MessagingDeleterDelete own messages
EncryptionKeyRotatorRotate the group's DEK
SuiNsAdminManage SuiNS reverse lookup
MetadataAdminManage group metadata

Use defaultMemberPermissionTypes(packageId) for the four core messaging permissions (Sender, Reader, Editor, Deleter), the baseline for regular group members.

Grant permissions through the groups extension:

import { messagingPermissionTypes } from '@mysten/sui-stack-messaging';

const perms = messagingPermissionTypes(MESSAGING_PACKAGE_ID);

await client.groups.grantPermission({
signer: keypair,
groupId: '0x...',
member: '0xAlice...',
permissionType: perms.EncryptionKeyRotator,
});