Skip to main content

Encrypt & Decrypt

All encryption and decryption goes through client.crypto, which returns a PacketEncryptionClient. Set an identity first — see Crypto Overview.


client.crypto.encrypt(params)

Encrypts a plaintext string and returns a PacketEncryptedBody object.

const body = await client.crypto.encrypt({
plaintext: "Hello!",
readers: [
client.crypto.reader({
ownerWallet: recipientAddress,
keyAlg: AsymmetricEncryptionAlgorithm.SOLANA_ED25519_X25519,
publicKey: recipientPublicKeyBytes,
}),
],
});

By default, the active identity is also added as a reader (includeSelf: true), so you can decrypt your own messages.

PacketEncryptParams

FieldTypeDefaultDescription
plaintextstringThe message to encrypt
readersPacketReaderInput[][]Additional recipients
includeSelfbooleantrueAuto-include the active identity as a reader
encoding"base64" | "utf8""base64"Encoding for ciphertext serialization
contentEncSymmetricEncryptionAlgorithmsuite defaultBody encryption algorithm
keyKdfKeyDerivationAlgorithmsuite defaultKey derivation function override
keyEncSymmetricEncryptionAlgorithmsuite defaultKey wrapping algorithm override
maxInlineBytesnumberThrow if encrypted body exceeds this size

Returns Promise<PacketEncryptedBody>


client.crypto.encryptToContent(params)

Encrypts and serializes to a content string ready to be stored as a message's content field.

const content = await client.crypto.encryptToContent({
plaintext: "Hello!",
});

await thread.sendMessage({ messageType: MessageType.Text, content });

Returns Promise<string>


client.crypto.encryptToJson(params)

Same as encryptToContent but returns a plain JSON string instead of the SDK's content encoding.

Returns Promise<string>


client.crypto.decrypt(params)

Decrypts a PacketEncryptedBody using the active identity (or an explicit one).

const plaintext = await client.crypto.decrypt({ body });

PacketDecryptParams

FieldTypeDescription
bodyPacketEncryptedBody | stringThe encrypted body or its JSON/content string
identityPacketCryptoIdentityInputOptional override; uses the active identity if omitted

Returns Promise<string> — the original plaintext.

Throws if no reader entry for the identity is found in the body.


client.crypto.maybeDecrypt(content, identity?)

Tries to decrypt content. If the content is not encrypted, it returns the original string unchanged.

const result = await client.crypto.maybeDecrypt(messageContent);

if (result.encrypted) {
console.log(result.plaintext); // decrypted
} else {
console.log(result.plaintext); // plain text, returned as-is
}

Returns Promise<PacketMaybeDecryptResult>

type PacketMaybeDecryptResult =
| { encrypted: true; plaintext: string; body: PacketEncryptedBody }
| { encrypted: false; plaintext: string };

Reader helpers

client.crypto.selfReader()

Returns a PacketReaderInput for the active identity. Pass this to another user's reader list to let yourself decrypt that message.

const readers = [
client.crypto.selfReader(),
client.crypto.reader({ ownerWallet: recipient, keyAlg, publicKey }),
];

Returns PacketReaderInput


client.crypto.reader(input)

Builds a reader entry for another user's public key.

const entry = client.crypto.reader({
ownerWallet: recipientAddress,
keyAlg: AsymmetricEncryptionAlgorithm.SOLANA_ED25519_X25519,
publicKey: recipientPublicKeyBytes,
});

Returns PacketReaderInput


client.crypto.hasReader(body, identity?)

Returns true if the body contains a reader entry for the given identity (defaults to the active one).

const canDecrypt = client.crypto.hasReader(body);

Returns boolean


Body serialization helpers

These convert between PacketEncryptedBody objects and their serialized string forms.

MethodInOutDescription
toJson(body)PacketEncryptedBodystringSerialize to JSON
fromJson(json)stringPacketEncryptedBodyParse from JSON
toContent(body)PacketEncryptedBodystringSerialize to content encoding
fromContent(content)stringPacketEncryptedBodyParse from content encoding
tryFromContent(content)stringPacketEncryptedBody | nullParse from content, returns null if not encrypted
isEncryptedContent(content)stringbooleanCheck if string is encrypted content
isBody(value)unknownboolean (type guard)Check if value is a PacketEncryptedBody

Key algorithm notes

X25519

  • publicKey — X25519 public key (32 bytes)
  • privateKey — X25519 private key (32 bytes)
  • Key derivation: HKDF-SHA256
  • Key wrapping: AES-256-GCM

SOLANA_ED25519_X25519

  • publicKey — Solana Ed25519 wallet public key (32 bytes)
  • privateKey — Ed25519 seed or TweetNaCl secretKey (32 or 64 bytes)
  • Key derivation: NaCl Box Before (Curve25519 DH)
  • Key wrapping: XSalsa20-Poly1305

Use SOLANA_ED25519_X25519 when the reader is identified by their Solana wallet address.