Helpers Module
Device key management and signer helpers
Helpers Module
The helpers module provides comprehensive functionality for device key management and signer operations, simplifying working with email/phone signers and providing automatic device key resolution, validation, and caching.
Import
import {
// Storage Adapters (use createIndexedDBAdapter in browser for email/phone signers)
createIndexedDBAdapter,
createLocalStorageAdapter,
createFileSystemAdapter,
createMemoryAdapter,
getDefaultStorageAdapter,
// Validation
isValidEmail,
isValidPhone,
// Email Signer Helpers
createEmailSignerHelper,
getEmailSignerKeypair,
signWithEmailSigner,
getEmailSignerByEmail,
// Phone Signer Helpers
createPhoneSignerHelper,
getPhoneSignerKeypair,
signWithPhoneSigner,
getPhoneSignerByPhone,
// Passkey
createPasskeySigner,
signWithPasskeySigner,
// Generic / external
signWithSigner,
// Device Key Management
getDevicePublicKey,
generateDeviceKeyPair,
rotateDeviceKey,
clearDeviceKeyCache,
findDeviceKeyByPublicKey,
listAllDeviceKeys,
// Device Identity Management
addDeviceIdentityToSigner,
replaceDeviceIdentity,
addNewDeviceToSigner,
canAddDeviceToSigner,
// Validation & Resolution
getSignerDeviceKeys,
validateDeviceKey,
resolveDeviceKey,
getBestDeviceIdentity
} from 'cilantro-sdk/helpers';
import { createExternalWalletSigner } from 'cilantro-sdk/wallet';
In the browser, use createIndexedDBAdapter() for email/phone signers (recommended over localStorage). Create it once and pass the same instance to CilantroProvider and to helpers when creating signers. For external wallet signers, use createExternalWalletSigner from cilantro-sdk/wallet. Validate email/phone with isValidEmail and isValidPhone before creating signers.
Quick Example
import {
createEmailSignerHelper,
getEmailSignerKeypair,
createIndexedDBAdapter
} from 'cilantro-sdk/helpers';
// Create storage for device keys (browser: use IndexedDB)
const deviceKeyManager = createIndexedDBAdapter();
// Create email signer (device key generated automatically)
const result = await createEmailSignerHelper(walletId, {
email: 'user@example.com',
deviceKeyManager,
});
// result: { signerId, walletId, ... }
// Get keypair - SDK automatically:
// 1. Fetches signer from API
// 2. Extracts devicePublicKey and deviceId
// 3. Resolves device key from storage
// 4. Validates device key matches API
const keypair = await getEmailSignerKeypair(
walletId,
result.signerId,
{ deviceKeyManager }
);
Passkey: use createPasskeySigner, registerPasskey, authenticateWithPasskey, signWithPasskeySigner (browser only). External wallet signer: use createExternalWalletSigner(walletId, { address }) from cilantro-sdk/wallet.
Transaction helpers (non-custodial)
Option 1 — One step (recommended): use sendSOLWithSigner and sendSPLWithSigner from cilantro-sdk/helpers so device key resolution and signing are handled for you:
import { sendSOLWithSigner, sendSPLWithSigner } from 'cilantro-sdk/helpers';
import { createIndexedDBAdapter } from 'cilantro-sdk/helpers';
const storage = createIndexedDBAdapter();
const result = await sendSOLWithSigner(
walletId,
signerId,
'email', // or 'phone', 'passkey', 'external'
'7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU',
100000000,
{ emailSignerOptions: { deviceKeyManager: storage } }
);
Option 2 — Manual prepare / sign / submit: use prepareTransaction and submitTransaction from cilantro-sdk/wallet, and signTransactionWithEmailSigner from cilantro-sdk/helpers:
import { prepareTransaction, submitTransaction } from 'cilantro-sdk/wallet';
import { signTransactionWithEmailSigner } from 'cilantro-sdk/helpers';
const { data: { unsignedTransaction, blockhash } } = await prepareTransaction(walletId, {
type: 'send_sol',
signerPubkey: signerPublicKeyBase58,
sendSolParams: { recipient: recipientAddress, amount: amountLamports },
});
const signedTransaction = await signTransactionWithEmailSigner(
walletId,
signerId,
unsignedTransaction,
{ deviceKeyManager: storage }
);
const { data } = await submitTransaction(walletId, { signedTransaction });
Device Key Management
getDevicePublicKey(options)
Get or create device key with caching.
const deviceKey = await getDevicePublicKey({
deviceKeyManager: storage
});
generateDeviceKeyPair(options)
Generate new device key pair.
const keyPair = await generateDeviceKeyPair({
deviceKeyManager: storage
});
rotateDeviceKey(deviceId, options)
Rotate device keys.
await rotateDeviceKey('old-device-id', {
deviceKeyManager: storage
});
clearDeviceKeyCache()
Clear cache.
clearDeviceKeyCache();
findDeviceKeyByPublicKey(publicKey, options)
Find device key by public key.
const deviceKey = await findDeviceKeyByPublicKey(
'device-public-key',
{ deviceKeyManager: storage }
);
listAllDeviceKeys(options)
List all device keys with metadata.
const deviceKeys = await listAllDeviceKeys({
deviceKeyManager: storage
});
Email Signer Helpers
createEmailSignerHelper(walletId, options)
Create email signer with automatic device key generation.
emailstringrequiredEmail address for the signer
deviceKeyManagerDeviceKeyStoragerequiredStorage adapter for device keys
const signer = await createEmailSignerHelper('wallet-id', {
email: 'user@example.com',
deviceKeyManager: storage
});
getEmailSignerKeypair(walletId, signerId, options)
Get keypair with automatic device key resolution.
const keypair = await getEmailSignerKeypair(
'wallet-id',
'signer-id',
{
deviceKeyManager: storage
}
);
signWithEmailSigner(walletId, signerId, message, options)
Sign messages with email signer.
const signature = await signWithEmailSigner(
'wallet-id',
'signer-id',
message,
{ deviceKeyManager: storage }
);
getEmailSignerByEmail(walletId, email)
Find email signer by email address.
const signer = await getEmailSignerByEmail('wallet-id', 'user@example.com');
Phone Signer Helpers
createPhoneSignerHelper(walletId, options)
Create phone signer with automatic device key generation.
const signer = await createPhoneSignerHelper('wallet-id', {
phone: '+1234567890',
deviceKeyManager: storage
});
getPhoneSignerKeypair(walletId, signerId, options)
Get keypair with automatic device key resolution.
const keypair = await getPhoneSignerKeypair(
'wallet-id',
'signer-id',
{ deviceKeyManager: storage }
);
signWithPhoneSigner(walletId, signerId, message, options)
Sign messages with phone signer.
const signature = await signWithPhoneSigner(
'wallet-id',
'signer-id',
message,
{ deviceKeyManager: storage }
);
getPhoneSignerByPhone(walletId, phone)
Find phone signer by phone number. Validate phone with isValidPhone before creating a signer.
import { isValidPhone } from 'cilantro-sdk/helpers';
if (!isValidPhone(phone)) throw new Error('Invalid phone');
const signer = await createPhoneSignerHelper(walletId, { phone, deviceKeyManager });
Similarly use isValidEmail before createEmailSignerHelper.
Storage Adapters
createIndexedDBAdapter()
Browser IndexedDB adapter. Recommended for email/phone signers in the browser. Create once (e.g. in useMemo in React) and pass to CilantroProvider and to signer helpers.
const storage = createIndexedDBAdapter();
createLocalStorageAdapter()
Browser localStorage adapter.
const storage = createLocalStorageAdapter();
createFileSystemAdapter(options?)
Node.js filesystem adapter.
const storage = createFileSystemAdapter({
basePath: './device-keys'
});
createMemoryAdapter()
In-memory adapter (for testing).
const storage = createMemoryAdapter();
getDefaultStorageAdapter()
Get platform-appropriate adapter.
const storage = getDefaultStorageAdapter();
Device Identity Management
addDeviceIdentityToSigner(walletId, signerId, identity)
Add new device to existing signer.
await addDeviceIdentityToSigner(
'wallet-id',
'signer-id',
{
devicePublicKey: 'new-device-public-key',
deviceId: 'new-device-id'
}
);
replaceDeviceIdentity(walletId, signerId, oldDeviceId, newIdentity)
Replace existing device identity.
await replaceDeviceIdentity(
'wallet-id',
'signer-id',
'old-device-id',
{
devicePublicKey: 'new-device-public-key',
deviceId: 'new-device-id'
}
);
addNewDeviceToSigner(walletId, signerId, options)
Convenience function for adding new device.
await addNewDeviceToSigner('wallet-id', 'signer-id', {
deviceKeyManager: storage
});
canAddDeviceToSigner(walletId, signerId)
Check if device can be added.
const canAdd = await canAddDeviceToSigner('wallet-id', 'signer-id');
Validation & Resolution
getSignerDeviceKeys(walletId, signerId)
Get all device keys for a signer from API.
const deviceKeys = await getSignerDeviceKeys('wallet-id', 'signer-id');
validateDeviceKey(walletId, signerId, devicePublicKey, options)
Validate device key matches API.
const isValid = await validateDeviceKey(
'wallet-id',
'signer-id',
'device-public-key',
{ deviceKeyManager: storage }
);
resolveDeviceKey(walletId, signerId, options)
Automatically find matching device key.
const deviceKey = await resolveDeviceKey(
'wallet-id',
'signer-id',
{ deviceKeyManager: storage }
);
getBestDeviceIdentity(walletId, signerId, options)
Get most recently used device identity.
const deviceIdentity = await getBestDeviceIdentity(
'wallet-id',
'signer-id',
{ deviceKeyManager: storage }
);