Arcium
Frontend SDK

A Technical Codex for Secure
Multi-Party Computation Integration

I. Overview

The Solana blockchain operates as a transparent public ledger where every transaction is visible to all. While this transparency fosters trust, it presents significant challenges for applications requiring privacy in their computations.

The Arcium Frontend SDK bridges this gap. It provides the necessary client-side logic to interface with the Multi-Party Execution Environment (MXE). By employing this SDK, developers can encrypt data client-side before submission, ensuring that sensitive inputs remain confidential throughout the entire computational lifecycle.

PDA Derivation
X25519 Encryption
Transaction Builders
React Hooks
Result Polling
Typed Errors

II. Transaction Architecture

A confidential transaction in the Arcium network flows through three distinct layers, each serving a critical role in the preservation of data privacy.

1
Client Side

Data originates here. The SDK employs RescueCipher and X25519 protocols to encrypt raw values into ciphertexts before they depart the browser.

2
Public Network

The Solana blockchain serves as the transport layer. It propagates the encrypted payload without exposing the underlying data to observers.

3
Execution Layer

The encrypted payload reaches the Arcium Cluster. Nodes collaboratively decrypt and compute using MPC, revealing only the final result.

III. Installation

To commence integration, install the SDK alongside its peer dependencies. The package requires Node.js version 20.18 or higher.

Terminal
npm install arcium-frontend-sdk \
    @coral-xyz/anchor \
    @solana/web3.js \
    @arcium-hq/client

For applications utilizing React, install the additional peer dependencies to access the hooks module:

Terminal (React)
npm install @solana/wallet-adapter-react react
React hooks are optional and exported from arcium-frontend-sdk/react

IV. Core Concepts: PDAs

To anchor computation to the Solana blockchain, the SDK derives specific Program Derived Addresses (PDAs). Understanding these accounts is crucial for debugging and successful integration.

Account Purpose
MXE Account Represents the Cluster Identity. Stores the public encryption key used by clients to encrypt their inputs.
Comp. Definition Contains the WASM bytecode defining the computation logic to be executed by the MXE cluster.
Computation A unique address holding the state of a specific computational request instance.
Cluster Identifies the specific Arcium cluster handling the computation.
Mempool Queue for pending computations awaiting execution.
Executing Pool Tracks computations currently being processed by the cluster.
Derive All Accounts
import { deriveCoreAccounts } from 'arcium-frontend-sdk';

const accounts = deriveCoreAccounts({
  programId,
  clusterOffset: 768109697,
  computationOffset,
  compDefOffset: 'my_computation',
});

// accounts.mxeAccount
// accounts.compDefAccount
// accounts.computationAccount
// accounts.clusterAccount
// accounts.mempoolAccount
// accounts.executingPool

V. Encryption

Encryption forms the cornerstone of the SDK. All sensitive values must be encrypted client-side before transmission to the blockchain. The SDK employs X25519 key exchange and RescueCipher for this purpose.

Fig. 1: Visual representation of client-side encryption masking.

Fetching the MXE Public Key

Before encryption, obtain the MXE public key from the chain. The SDK provides retry logic to handle network instability:

Fetch MXE Key
import { getMXEPublicKeyWithRetry } from 'arcium-frontend-sdk';

const mxePublicKey = await getMXEPublicKeyWithRetry(
  provider,
  programId,
  {
    maxRetries: 10,
    retryDelayMs: 500,
    onRetry: (attempt, err) => {
      console.log(`Attempt ${attempt} failed: ${err.message}`);
    },
  }
);

Encrypting Values

With the MXE key in hand, encrypt your sensitive values using prepareEncryptionPayload:

Encrypt Values
import { 
  prepareEncryptionPayload,
  randomComputationOffset 
} from 'arcium-frontend-sdk';

// Generate unique computation offset
const computationOffset = randomComputationOffset();

// Encrypt values (numbers or bigints)
const encrypted = prepareEncryptionPayload({
  values: [100n, 50n, 25n],
  mxePublicKey,
});

// encrypted.ciphertexts    - Encrypted values
// encrypted.encryptionPubkey - Your ephemeral public key
// encrypted.nonce          - Encryption nonce
// encrypted.nonceBytes     - Raw nonce bytes

VI. Account Management

Beyond PDA derivation, the SDK provides utilities for managing computation definition accounts and checking their initialization status.

Check Account Existence

Query CompDef Status
import { getCompDefAccountInfo } from 'arcium-frontend-sdk';

const info = await getCompDefAccountInfo(
  provider,
  programId,
  'my_computation'
);

if (!info.exists) {
  console.log('CompDef not initialized');
  console.log('Address:', info.address.toBase58());
}

Initialize CompDef

If the computation definition does not exist, initialize it:

Initialize If Needed
import { initCompDefIfNeeded } from 'arcium-frontend-sdk';

const result = await initCompDefIfNeeded({
  program,      // Anchor Program instance
  provider,     // Anchor Provider
  compDefName: 'my_computation',
  // methodName: 'initMyComputationCompDef' // optional
});

if (!result.exists) {
  console.log('Initialized:', result.tx);
}

Signer PDA

Get Signer PDA
import { getSignerPDA } from 'arcium-frontend-sdk';

const signerPDA = getSignerPDA(programId);
// Used for program-signed operations

VII. Transaction Building

The SDK offers two approaches to building transactions: a high-level builder that handles all complexity, and low-level primitives for custom implementations.

High-Level: Execute Encrypted Call

The simplest method - handles MXE key fetching, encryption, PDA derivation, and transaction submission:

One-Shot Execution
import { executeEncryptedCall } from 'arcium-frontend-sdk';

const result = await executeEncryptedCall({
  provider,
  programId,
  compDefOffset: 'my_computation',
  discriminator: Buffer.from([1,2,3,4,5,6,7,8]),
  values: [42n, 100n],
  computeBudget: {
    cuPriceMicro: 1000,
    cuLimit: 1_400_000,
  },
});

console.log('Signature:', result.signature);
console.log('Offset:', result.computationOffset.toString());

Low-Level: Manual Construction

For fine-grained control, build instructions manually:

Manual Transaction
import {
  encodeEncryptedCall,
  buildInstruction,
  buildTransaction,
} from 'arcium-frontend-sdk';

// Encode instruction data
const data = encodeEncryptedCall({
  discriminator,
  computationOffset,
  encryptionPubkey: encrypted.encryptionPubkey,
  nonce: encrypted.nonce,
  ciphertexts: encrypted.ciphertexts,
});

// Build instruction
const { ix } = buildInstruction({
  programId,
  accounts: accountMetas,
  data,
});

// Build transaction with compute budget
const tx = await buildTransaction(ix, {
  cuPriceMicro: 1000,
  cuLimit: 1_400_000,
});

VIII. React Hooks

For React applications, the SDK provides hooks that integrate seamlessly with @solana/wallet-adapter-react. Import from the /react subpath.

Provider Hook
import { useArciumProvider } from 'arcium-frontend-sdk/react';

function MyComponent() {
  const { provider, isReady, publicKey } = useArciumProvider();
  
  if (!isReady) {
    return <ConnectWalletButton />;
  }
  
  // provider is an AnchorProvider
}
Encryption Hook
import { useEncryption } from 'arcium-frontend-sdk/react';

function EncryptForm({ programId }) {
  const { encrypt, generateOffset, isReady, error } = useEncryption(programId);
  
  const handleSubmit = () => {
    if (!isReady) return;
    
    const offset = generateOffset();
    const encrypted = encrypt([42n, 100n]);
    
    // Use encrypted data...
  };
}
MXE Key Hook
import { useMXEPublicKey } from 'arcium-frontend-sdk/react';

function Component({ programId }) {
  const { mxePublicKey, isLoading, error, refetch } = useMXEPublicKey(programId);
  
  if (isLoading) return <Spinner />;
  if (error) return <Error message={error.message} />;
  
  // mxePublicKey is cached and ready
}
Network Detection Hook
import { useNetwork } from 'arcium-frontend-sdk/react';

function NetworkInfo() {
  const { network, clusterAccount, endpoint } = useNetwork();
  
  return (
    <div>
      Network: {network}
      Cluster: {clusterAccount?.toBase58()}
    </div>
  );
}
Result Polling Hook
import { useComputationResult } from 'arcium-frontend-sdk/react';

function ResultDisplay({ computationOffset, clusterOffset }) {
  const { result, isPolling, error, startPolling } = useComputationResult(
    computationOffset,
    clusterOffset,
    true // autoStart
  );
  
  if (isPolling) return <Spinner />;
  if (result) return <ResultView data={result} />;
}

IX. Error Handling

The SDK provides typed error classes for precise error handling. Each error includes a code, message, and optional cause for detailed debugging.

Error Class Description
ArciumSDKError Base class for all SDK errors
MXEKeyFetchError Failed to fetch MXE public key after retries
EncryptionError Encryption operation failed
TransactionBuildError Failed to build or send transaction
ComputationTimeoutError Result polling timed out
ValidationError Input validation failed
Error Handling Pattern
import {
  isArciumError,
  MXEKeyFetchError,
  ComputationTimeoutError,
} from 'arcium-frontend-sdk';

try {
  await executeEncryptedCall(config);
} catch (error) {
  if (error instanceof MXEKeyFetchError) {
    console.log('Fetch failed after', error.attempts, 'attempts');
    console.log('Program:', error.programId);
  } else if (error instanceof ComputationTimeoutError) {
    console.log('Timed out:', error.timeoutMs, 'ms');
    console.log('Offset:', error.computationOffset);
  } else if (isArciumError(error)) {
    console.log('Code:', error.code);
    console.log('Details:', error.toDetailedString());
  }
}

X. Configuration

Configure the SDK through environment variables and runtime settings. The SDK automatically detects network type from the RPC endpoint.

Environment Variables

.env
# Required: Cluster offset for PDA derivation
ARCIUM_CLUSTER_OFFSET=768109697

# Optional: RPC endpoint (defaults to devnet)
NEXT_PUBLIC_RPC_URL=https://api.devnet.solana.com

# Your program ID
NEXT_PUBLIC_MXE_PROGRAM_ID=YourProgramId

Network Detection

Auto-Detect Network
import { 
  detectNetwork,
  getClusterAccountForNetwork 
} from 'arcium-frontend-sdk';

// Detect from endpoint
const network = detectNetwork('https://api.devnet.solana.com');
// Returns: 'devnet' | 'testnet' | 'mainnet-beta' | 'localnet'

// Get cluster account
const clusterAccount = getClusterAccountForNetwork(provider);

Debug Mode

Enable debug logging to trace SDK operations:

Enable Debug
import { configureSDK } from 'arcium-frontend-sdk';

configureSDK({
  debug: true,
  logger: (message, data) => {
    console.log(`[Arcium] ${message}`, data);
  },
});

Result Polling

Poll for Results
import { 
  pollComputationResult,
  subscribeToComputationResult 
} from 'arcium-frontend-sdk';

// One-time poll
const result = await pollComputationResult(
  provider,
  computationOffset,
  clusterOffset,
  { maxAttempts: 30, intervalMs: 2000 }
);

// Or subscribe
const sub = subscribeToComputationResult(provider, {
  computationOffset,
  clusterOffset,
  onResult: (data) => console.log('Result:', data),
  onError: (err) => console.error(err),
});

// Later: sub.unsubscribe();

XI. LLM Integration Guide

The SDK includes a comprehensive LLM Integration Guide (LLM_GUIDE.md) designed specifically for developers using Large Language Models as programming assistants. This document serves as a structured knowledge base that LLMs can reference when helping you integrate encrypted Solana computations into your applications.

What is LLM_GUIDE.md?

The LLM_GUIDE.md is a detailed technical reference document located in the SDK's root directory. It contains structured documentation covering all aspects of the Arcium Frontend SDK, from installation and configuration to advanced usage patterns and troubleshooting.

Why Use It with LLMs?

Modern LLM assistants excel at understanding context from documentation. By providing access to LLM_GUIDE.md, you enable them to:

How to Use It

Simply include the LLM_GUIDE.md file in your conversation with an LLM assistant:

What's Included

The guide covers all aspects of the SDK in a format optimized for LLM consumption:

Guide Structure
• Installation and setup
• Environment configuration
• Core concepts (PDAs, encryption flow)
• High-level and low-level APIs
• Step-by-step transaction building
• Encryption details and algorithms
• Account management
• React integration hooks
• Error handling patterns
• Validation utilities
• Complete working examples
• API reference tables
• Troubleshooting guide

The guide is written with LLM consumption in mind: it uses clear structure, includes type definitions, provides both high-level and low-level approaches, and contains practical examples that can be directly adapted to your use case.

Tip: When working with LLMs, always reference the version of the SDK you're using (currently v0.2.0) to ensure the generated code matches the available API.