Skip to main content

Registered Key Account

KeyClient manages a wallet's on-chain public encryption key account. Registering a key makes it possible for others to encrypt messages to you by looking up your key on-chain, without needing to know your public key out-of-band.

Use the same terms as the rest of the docs:

  • Crypto identity: private/public encryption key material held by the client.
  • Reader: public encryption target included in an encrypted body.
  • Registered Key account: on-chain account that declares a wallet's public encryption key.
  • Wallet-derived Ed25519-to-X25519: no on-chain key account; derived from the Solana wallet/keypair.

How it connects to encryption​

When someone wants to encrypt a message for you, they:

  1. Call client.loadKey(yourAddress) to fetch your key account
  2. Access keyClient.Reader to get a PacketReaderInput
  3. Pass that reader to client.crypto.encrypt({ readers: [reader] })

Without a registered key, they'd need your public key through some other channel.

Key types​

PacketKeyTypeAlgorithmNotes
Ed25519WalletDerivedX25519SOLANA_ED25519_X25519Default. Derived from the Solana wallet's Ed25519 key.
X25519X25519Standalone X25519 key pair.
Secp256k1—Reserved; not yet supported in the crypto layer.

Creating a key​

Browser wallet easy mode​

After setting up a crypto identity with useWalletPasswordCrypto, register the derived key in one call:

await client.useWalletPasswordCrypto({ password, signMessage });
const { client: keyClient } = await client.createKeyFromCrypto();

This always stays in sync — whatever key client.crypto uses gets registered.

Manual​

const { client: keyClient } = await client.createKey({
key: myX25519PublicKeyBytes,
keyType: PacketKeyType.X25519,
});

If key is omitted, the program stores the owner's wallet public key with Ed25519WalletDerivedX25519.

CreateUserKeyParams​

FieldTypeRequiredDescription
keyUint8ArrayNoPublic encryption key bytes
keyTypePacketKeyTypeRequired when key is providedKey algorithm
ownerPublicKeyNoDefaults to the connected wallet

Returns Promise<TxReceiptWithClient<KeyClient>>


Loading​

// Your own key
const keyClient = await client.loadKey();

// Another wallet's key
const keyClient = await client.loadKey(recipientPublicKey);

Get the reader entry for encryption:

const reader = keyClient.Reader; // PacketReaderInput
const encrypted = await client.crypto.encryptToContent({
plaintext: "Hello!",
readers: [reader],
});

Or check existence first:

const keyHandle = client.key(owner);
if (await keyHandle.exists()) {
await keyHandle.load();
}

Editing (key rotation)​

Update the registered key after rotating your crypto identity:

// Easy mode: sync from current crypto identity
await keyClient.editFromCrypto();

// Manual
await keyClient.edit({
key: newPublicKeyBytes,
keyType: PacketKeyType.X25519,
});

Returns Promise<TxReceiptWithClient<KeyClient>>


Getters​

GetterTypeDescription
LoadedbooleanWhether the account has been fetched
KeyUserDecryptionKeyRaw key data (throws if not loaded)
ReaderPacketReaderInputReady-to-use reader entry for encryption

UserDecryptionKey type​

type UserDecryptionKey = {
address: PublicKey;
owner: PublicKey;
keyType: PacketKeyTypeInput;
key: Uint8Array;
};

PacketKeyType enum​

enum PacketKeyType {
X25519 = "x25519",
Secp256k1 = "secp256k1",
Ed25519WalletDerivedX25519 = "ed25519WalletDerivedX25519",
Other = "other",
}