Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Enable quantum-resistant encryption and secret management for blockchain apps with post-quantum ML-KEM-768 key encapsulation and multi-chain support.
Enable quantum-resistant encryption and secret management for blockchain apps with post-quantum ML-KEM-768 key encapsulation and multi-chain support.
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
Skill for AI Agents | Enable quantum-resistant encryption in blockchain applications using the CIFER SDK.
CIFER (Cryptographic Infrastructure for Encrypted Records) SDK provides quantum-resistant encryption for blockchain applications. This skill enables AI agents to implement secure data encryption, secret management, and on-chain commitments using post-quantum cryptography.
Quantum-Resistant Encryption: ML-KEM-768 (NIST standardized) key encapsulation Multi-Chain Support: Automatic chain discovery and configuration Wallet Agnostic: Works with MetaMask, WalletConnect, Coinbase, Thirdweb, and custom signers File Encryption: Async job system for large file encryption/decryption On-Chain Commitments: Store encrypted data references on-chain with log-based retrieval Transaction Intents: Non-custodial pattern - you control transaction execution
Use the CIFER SDK when you need to: Encrypt sensitive data with quantum-resistant algorithms Store encrypted records on blockchain Manage encryption keys with owner/delegate authorization Encrypt files larger than 16KB using the job system Build applications requiring post-quantum security
npm install cifer-sdk # or yarn add cifer-sdk # or pnpm add cifer-sdk Requirements: Node.js 18.0+, TypeScript 5.0+ (recommended)
import { createCiferSdk, Eip1193SignerAdapter, blackbox } from 'cifer-sdk'; // 1. Initialize SDK with auto-discovery const sdk = await createCiferSdk({ blackboxUrl: 'https://blackbox.cifer.network', }); // 2. Connect wallet (browser) const signer = new Eip1193SignerAdapter(window.ethereum); // 3. Encrypt data const encrypted = await blackbox.payload.encryptPayload({ chainId: 752025, secretId: 123n, plaintext: 'My secret message', signer, readClient: sdk.readClient, blackboxUrl: sdk.blackboxUrl, }); // 4. Decrypt data const decrypted = await blackbox.payload.decryptPayload({ chainId: 752025, secretId: 123n, encryptedMessage: encrypted.encryptedMessage, cifer: encrypted.cifer, signer, readClient: sdk.readClient, blackboxUrl: sdk.blackboxUrl, }); console.log(decrypted.decryptedMessage); // 'My secret message'
A secret is the core primitive in CIFER. Each secret represents an ML-KEM-768 key pair: PropertyDescriptionownerAddress that can transfer, set delegate, and decryptdelegateAddress that can decrypt only (zero address if none)isSyncingtrue while key generation is in progressclusterIdWhich enclave cluster holds the private key shardssecretType1 = ML-KEM-768 (standard)publicKeyCidIPFS CID of public key (empty if syncing) Lifecycle: Creation β Syncing (~30-60s) β Ready
RoleCapabilitiesOwnerEncrypt, decrypt, transfer, set delegateDelegateDecrypt only
CIFER uses hybrid encryption: ML-KEM-768: Post-quantum key encapsulation (1088-byte ciphertext) AES-256-GCM: Symmetric encryption for actual data Output format: cifer: 1104 bytes (ML-KEM ciphertext + tag) encryptedMessage: Variable length (max 16KB)
The SDK returns transaction intents instead of executing transactions: interface TxIntent { chainId: number; to: Address; data: Hex; value?: bigint; } Execute with any wallet library (ethers, wagmi, viem).
With Discovery (Recommended) const sdk = await createCiferSdk({ blackboxUrl: 'https://blackbox.cifer.network', }); sdk.getSupportedChainIds(); // [752025, 11155111, ...] sdk.getControllerAddress(752025); // '0x...' sdk.getRpcUrl(752025); // 'https://...' With Overrides const sdk = await createCiferSdk({ blackboxUrl: 'https://blackbox.cifer.network', chainOverrides: { 752025: { rpcUrl: 'https://my-private-rpc.example.com', secretsControllerAddress: '0x...', }, }, }); Synchronous (No Discovery) import { createCiferSdkSync, RpcReadClient } from 'cifer-sdk'; const readClient = new RpcReadClient({ rpcUrlByChainId: { 752025: 'https://mainnet.ternoa.network', }, }); const sdk = createCiferSdkSync({ blackboxUrl: 'https://blackbox.cifer.network', readClient, chainOverrides: { 752025: { rpcUrl: 'https://mainnet.ternoa.network', secretsControllerAddress: '0x...', }, }, });
All wallets must implement the SignerAdapter interface: interface SignerAdapter { getAddress(): Promise<string>; signMessage(message: string): Promise<string>; sendTransaction?(txRequest: TxIntent): Promise<TxExecutionResult>; } MetaMask import { Eip1193SignerAdapter } from 'cifer-sdk'; await window.ethereum.request({ method: 'eth_requestAccounts' }); const signer = new Eip1193SignerAdapter(window.ethereum); WalletConnect v2 import { EthereumProvider } from '@walletconnect/ethereum-provider'; const provider = await EthereumProvider.init({ projectId: 'YOUR_WALLETCONNECT_PROJECT_ID', chains: [752025], showQrModal: true, }); await provider.connect(); const signer = new Eip1193SignerAdapter(provider); Private Key (Server-Side) import { Wallet } from 'ethers'; const wallet = new Wallet(process.env.PRIVATE_KEY); const signer = { async getAddress() { return wallet.address; }, async signMessage(message) { return wallet.signMessage(message); }, }; wagmi (React) import { useAccount, useConnectorClient } from 'wagmi'; function useCiferSigner() { const { address, isConnected } = useAccount(); const { data: connectorClient } = useConnectorClient(); const getSigner = async () => { if (!isConnected || !connectorClient) { throw new Error('Wallet not connected'); } const provider = await connectorClient.transport; return new Eip1193SignerAdapter(provider); }; return { getSigner, address, isConnected }; }
Interact with the SecretsController contract for secret management. Read Operations // Get secret creation fee const fee = await keyManagement.getSecretCreationFee({ chainId: 752025, controllerAddress: sdk.getControllerAddress(752025), readClient: sdk.readClient, }); // Get secret state const state = await keyManagement.getSecret(params, 123n); // Returns: { owner, delegate, isSyncing, clusterId, secretType, publicKeyCid } // Check if secret is ready const ready = await keyManagement.isSecretReady(params, 123n); // Check authorization const canDecrypt = await keyManagement.isAuthorized(params, 123n, '0x...'); // Get secrets by wallet const secrets = await keyManagement.getSecretsByWallet(params, '0xUser...'); // Returns: { owned: bigint[], delegated: bigint[] } Transaction Builders // Create a new secret const fee = await keyManagement.getSecretCreationFee(params); const txIntent = keyManagement.buildCreateSecretTx({ chainId: 752025, controllerAddress: sdk.getControllerAddress(752025), fee, }); // Set delegate const txIntent = keyManagement.buildSetDelegateTx({ chainId: 752025, controllerAddress: sdk.getControllerAddress(752025), secretId: 123n, newDelegate: '0xDelegate...', }); // Remove delegate const txIntent = keyManagement.buildRemoveDelegationTx({ ... }); // Transfer ownership (irreversible!) const txIntent = keyManagement.buildTransferSecretTx({ chainId: 752025, controllerAddress: sdk.getControllerAddress(752025), secretId: 123n, newOwner: '0xNewOwner...', }); Event Parsing const receipt = await provider.waitForTransaction(hash); const secretId = keyManagement.extractSecretIdFromReceipt(receipt.logs);
Encrypt and decrypt short messages (< 16KB). Encrypt const encrypted = await blackbox.payload.encryptPayload({ chainId: 752025, secretId: 123n, plaintext: 'My secret message', signer, readClient: sdk.readClient, blackboxUrl: sdk.blackboxUrl, outputFormat: 'hex', // or 'base64' }); // Returns: { cifer: string, encryptedMessage: string } Decrypt const decrypted = await blackbox.payload.decryptPayload({ chainId: 752025, secretId: 123n, encryptedMessage: encrypted.encryptedMessage, cifer: encrypted.cifer, signer, // Must be owner or delegate readClient: sdk.readClient, blackboxUrl: sdk.blackboxUrl, inputFormat: 'hex', }); // Returns: { decryptedMessage: string }
Encrypt and decrypt large files using async jobs. // Start encryption job const job = await blackbox.files.encryptFile({ chainId: 752025, secretId: 123n, file: myFile, signer, readClient: sdk.readClient, blackboxUrl: sdk.blackboxUrl, }); // Returns: { jobId: string, message: string } // Start decryption job const job = await blackbox.files.decryptFile({ ... }); // Decrypt from existing encrypt job const job = await blackbox.files.decryptExistingFile({ chainId: 752025, secretId: 123n, encryptJobId: previousJobId, signer, readClient: sdk.readClient, blackboxUrl: sdk.blackboxUrl, });
Manage async file jobs. // Get job status const status = await blackbox.jobs.getStatus(jobId, sdk.blackboxUrl); // Returns: { id, type, status, progress, secretId, chainId, ... } // Poll until complete const finalStatus = await blackbox.jobs.pollUntilComplete( jobId, sdk.blackboxUrl, { intervalMs: 2000, maxAttempts: 120, onProgress: (job) => console.log(`Progress: ${job.progress}%`), } ); // Download result (encrypt jobs: no auth, decrypt jobs: auth required) const blob = await blackbox.jobs.download(jobId, { blackboxUrl: sdk.blackboxUrl, // For decrypt jobs, also provide: chainId: 752025, secretId: 123n, signer, readClient: sdk.readClient, }); // List jobs for wallet const result = await blackbox.jobs.list({ chainId: 752025, signer, readClient: sdk.readClient, blackboxUrl: sdk.blackboxUrl, }); // Get data consumption stats const stats = await blackbox.jobs.dataConsumption({ ... });
Store and retrieve encrypted data on-chain. // Check if commitment exists const exists = await commitments.ciferDataExists(params, dataId); // Get metadata const metadata = await commitments.getCIFERMetadata(params, dataId); // Returns: { secretId, storedAtBlock, ciferHash, encryptedMessageHash } // Fetch encrypted data from logs const data = await commitments.fetchCommitmentFromLogs({ chainId: 752025, contractAddress: '0x...', dataId: dataKey, storedAtBlock: metadata.storedAtBlock, readClient: sdk.readClient, }); // Returns: { cifer, encryptedMessage, ciferHash, encryptedMessageHash } // Verify integrity const result = commitments.verifyCommitmentIntegrity(data, metadata); // Build store transaction const txIntent = commitments.buildStoreCommitmentTx({ chainId: 752025, contractAddress: '0xYourContract...', storeFunction: { type: 'function', name: 'store', inputs: [ { name: 'key', type: 'bytes32' }, { name: 'encryptedMessage', type: 'bytes' }, { name: 'cifer', type: 'bytes' }, ], }, args: { key: dataKey, secretId: 123n, encryptedMessage: encrypted.encryptedMessage, cifer: encrypted.cifer, }, }); Constants: CIFER_ENVELOPE_BYTES = 1104 (fixed cifer size) MAX_PAYLOAD_BYTES = 16384 (16KB max payload)
High-level orchestrated operations. Flow Context const ctx = { signer: SignerAdapter, readClient: ReadClient, blackboxUrl: string, chainId: number, controllerAddress?: Address, txExecutor?: (intent: TxIntent) => Promise<TxExecutionResult>, pollingStrategy?: { intervalMs: number, maxAttempts: number }, logger?: (message: string) => void, abortSignal?: AbortSignal, }; Create Secret and Wait const result = await flows.createSecretAndWaitReady({ ...ctx, controllerAddress: sdk.getControllerAddress(752025), txExecutor: async (intent) => { const hash = await wallet.sendTransaction(intent); return { hash, waitReceipt: () => provider.waitForTransaction(hash) }; }, }); if (result.success) { console.log('Secret ID:', result.data.secretId); console.log('Public Key CID:', result.data.state.publicKeyCid); } Encrypt and Prepare Commit const result = await flows.encryptThenPrepareCommitTx(ctx, { secretId: 123n, plaintext: 'My secret data', key: dataKey, commitmentContract: '0x...', }); if (result.success) { await wallet.sendTransaction(result.data.txIntent); } Retrieve and Decrypt from Logs const result = await flows.retrieveFromLogsThenDecrypt(ctx, { secretId: 123n, dataId: dataKey, commitmentContract: '0x...', }); if (result.success) { console.log('Decrypted:', result.data.decryptedMessage); } File Flows // Encrypt file flow const result = await flows.encryptFileJobFlow(ctx, { secretId: 123n, file: myFile, }); // Returns: { jobId, job, encryptedFile: Blob } // Decrypt file flow const result = await flows.decryptFileJobFlow(ctx, { secretId: 123n, file: ciferFile, }); // Returns: { jobId, job, decryptedFile: Blob }
All SDK errors extend CiferError with typed subclasses: CiferError βββ ConfigError β βββ DiscoveryError β βββ ChainNotSupportedError βββ AuthError β βββ SignatureError β βββ BlockStaleError β βββ SignerMismatchError βββ BlackboxError β βββ EncryptionError β βββ DecryptionError β βββ JobError β βββ SecretNotReadyError βββ KeyManagementError β βββ SecretNotFoundError β βββ NotAuthorizedError βββ CommitmentsError β βββ CommitmentNotFoundError β βββ IntegrityError β βββ InvalidCiferSizeError β βββ PayloadTooLargeError βββ FlowError βββ FlowAbortedError βββ FlowTimeoutError
import { isCiferError, isBlockStaleError, isSecretNotReadyError, } from 'cifer-sdk';
try { await blackbox.payload.encryptPayload({ ... }); } catch (error) { if (isBlockStaleError(error)) { console.log('RPC returning stale blocks'); } else if (error instanceof SecretNotReadyError) { console.log('Wait for secret to sync'); } else if (error instanceof SecretNotFoundError) { console.log('Secret not found:', error.secretId); } else if (isCiferError(error)) { console.log('CIFER error:', error.code, error.message); } else { throw error; } }
ErrorCauseSolution"Block number is too old"RPC issuesSDK auto-retries 3x; check RPC reliability"Secret is syncing"Key generation in progressWait 30-60s; use isSecretReady()"Signature verification failed"Wrong signing methodUse EIP-191 personal_sign"Not authorized"Not owner/delegateCheck with isAuthorized()
import { createCiferSdk, Eip1193SignerAdapter, blackbox } from 'cifer-sdk'; async function encryptDecryptExample() { const sdk = await createCiferSdk({ blackboxUrl: 'https://blackbox.cifer.network', }); const signer = new Eip1193SignerAdapter(window.ethereum); const chainId = 752025; const secretId = 123n; // Encrypt const encrypted = await blackbox.payload.encryptPayload({ chainId, secretId, plaintext: 'Hello, CIFER!', signer, readClient: sdk.readClient, blackboxUrl: sdk.blackboxUrl, }); // Decrypt const decrypted = await blackbox.payload.decryptPayload({ chainId, secretId, encryptedMessage: encrypted.encryptedMessage, cifer: encrypted.cifer, signer, readClient: sdk.readClient, blackboxUrl: sdk.blackboxUrl, }); console.log('Decrypted:', decrypted.decryptedMessage); }
import { createCiferSdk, RpcReadClient, blackbox } from 'cifer-sdk'; import { Wallet } from 'ethers'; async function serverSideExample() { const readClient = new RpcReadClient({ rpcUrlByChainId: { 752025: 'https://mainnet.ternoa.network', }, }); const sdk = await createCiferSdk({ blackboxUrl: 'https://blackbox.cifer.network', readClient, }); const wallet = new Wallet(process.env.PRIVATE_KEY); const signer = { async getAddress() { return wallet.address; }, async signMessage(message) { return wallet.signMessage(message); }, }; const encrypted = await blackbox.payload.encryptPayload({ chainId: 752025, secretId: 123n, plaintext: 'Server-side encryption', signer, readClient: sdk.readClient, blackboxUrl: sdk.blackboxUrl, }); console.log('Encrypted on server:', encrypted); }
import { createCiferSdk, Eip1193SignerAdapter, blackbox } from 'cifer-sdk'; async function fileEncryptionExample() { const sdk = await createCiferSdk({ blackboxUrl: 'https://blackbox.cifer.network', }); const signer = new Eip1193SignerAdapter(window.ethereum); const file = document.getElementById('fileInput').files[0]; // Start job const job = await blackbox.files.encryptFile({ chainId: 752025, secretId: 123n, file, signer, readClient: sdk.readClient, blackboxUrl: sdk.blackboxUrl, }); // Poll with progress const finalStatus = await blackbox.jobs.pollUntilComplete( job.jobId, sdk.blackboxUrl, { onProgress: (status) => console.log(`Progress: ${status.progress}%`), } ); if (finalStatus.status === 'completed') { const encryptedBlob = await blackbox.jobs.download(job.jobId, { blackboxUrl: sdk.blackboxUrl, }); // Download file const url = URL.createObjectURL(encryptedBlob); const a = document.createElement('a'); a.href = url; a.download = 'encrypted.cifer'; a.click(); } }
type Address = `0x${string}`; type Bytes32 = `0x${string}`; type Hex = `0x${string}`; type ChainId = number; type SecretId = bigint; type OutputFormat = 'hex' | 'base64'; type JobStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'expired'; type JobType = 'encrypt' | 'decrypt'; interface SecretState { owner: Address; delegate: Address; isSyncing: boolean; clusterId: number; secretType: number; publicKeyCid: string; } interface JobInfo { id: string; type: JobType; status: JobStatus; progress: number; secretId: number; chainId: ChainId; createdAt: number; completedAt?: number; error?: string; resultFileName?: string; ttl: number; originalSize?: number; } interface FlowResult<T> { success: boolean; plan: FlowPlan; data?: T; error?: Error; receipts?: TransactionReceipt[]; }
npm: https://www.npmjs.com/package/cifer-sdk GitHub: https://github.com/cifer-security/cifer-sdk Blackbox API: https://blackbox.cifer.network Supported Chain: Ternoa (752025) This skill enables AI agents to implement quantum-resistant encryption in blockchain applications using the CIFER SDK.
Agent frameworks, memory systems, reasoning layers, and model-native orchestration.
Largest current source with strong distribution and engagement signals.