███████╗ ██╗ ██████╗ █████╗ ██████╗ ██████╗██╗██╗ ██╗███╗ ███╗ ██╔════╝ ██║ ██╔══██╗ ██╔══██╗██╔══██╗██╔════╝██║██║ ██║████╗ ████║ ███████╗ ██║ ██████╔╝ ███████║██████╔╝██║ ██║██║ ██║██╔████╔██║ ╚════██║ ██║ ██╔═══╝ ██╔══██║██╔══██╗██║ ██║██║ ██║██║╚██╔╝██║ ███████║ ██║ ██║ ██║ ██║██║ ██║╚██████╗██║╚██████╔╝██║ ╚═╝ ██║ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝
Privacy through MPC — no single node sees your data
Confidential DeFi on Solana using Arcium's Multi-Party Computation network
Encrypted transfers • Confidential swaps • Balance privacy • Jupiter integration
Solana Privacy Hackathon 2026 | Arcium Track Submission
- What is SIP Arcium?
- The Problem
- The Solution
- MPC Circuits
- Architecture
- Deployment
- Quick Start
- Integration
- Tech Stack
- Development
- Security
- Related Projects
- License
SIP Arcium brings confidential DeFi to Solana using Arcium's Multi-Party Computation (MPC) network. Your balance and transfer amounts stay encrypted throughout the entire computation — no single node ever sees your actual values.
Traditional DeFi → Public balances, public amounts, MEV attacks
SIP + Arcium → Encrypted computation, hidden amounts, MEV protection
Your financial data stays private. Even during computation.
Current Solana DeFi exposes everything on-chain:
| Data Point | Visibility | Risk |
|---|---|---|
| Token Balances | Public | Wealth profiling, targeted attacks |
| Transfer Amounts | Public | Front-running, sandwich attacks |
| Swap Details | Public | MEV extraction, copy trading |
| Transaction Graph | Permanent | Surveillance, address clustering |
Zero-knowledge proofs verify correctness, but the computation itself still happens somewhere. With ZK:
- Prover sees all values during proof generation
- Single point of trust (the prover)
- Complex circuits for arbitrary logic
MPC solves this — computation is distributed across multiple nodes, none of which see the plaintext.
SIP Arcium uses threshold MPC to perform DeFi operations on encrypted data:
┌─────────────────────────────────────────────────────────────────┐
│ 1. CLIENT (SIP Mobile / Web App) │
│ └── Encrypt inputs with x25519 keypair │
│ (balance, amount, slippage — all encrypted) │
├─────────────────────────────────────────────────────────────────┤
│ 2. ANCHOR PROGRAM (this repo) │
│ └── Queue encrypted computation to Arcium MXE │
│ (on-chain coordination, no plaintext access) │
├─────────────────────────────────────────────────────────────────┤
│ 3. ARCIUM MXE CLUSTER (off-chain MPC network) │
│ ├── Threshold decrypt (requires 2/3+ nodes) │
│ ├── Execute circuit (distributed computation) │
│ │ └── No single node sees complete plaintext │
│ ├── Encrypt result with requester's key │
│ └── Return via callback │
├─────────────────────────────────────────────────────────────────┤
│ 4. CALLBACK (back on-chain) │
│ └── Emit encrypted result │
│ (only requester can decrypt) │
└─────────────────────────────────────────────────────────────────┘
| Property | Description |
|---|---|
| Confidentiality | No single node sees plaintext values |
| Correctness | Threshold signatures verify computation |
| Availability | Tolerates minority node failures |
| Non-collusion | Requires 2/3+ nodes to collude to break privacy |
Three Arcis circuits for confidential DeFi operations:
Validate encrypted balance transfers without revealing amounts.
// Inputs (all encrypted)
struct PrivateTransferInput {
sender_balance: u64, // Current balance (encrypted)
amount: u64, // Transfer amount (encrypted)
min_balance: u64, // Minimum to maintain (encrypted)
}
// Outputs (encrypted with requester's key)
struct PrivateTransferOutput {
is_valid: bool, // Sufficient balance?
new_sender_balance: u64, // Balance after transfer
}Use case: Shielded SOL/token transfers in SIP Mobile
Threshold check without revealing actual balance.
// Prove balance >= minimum without revealing balance
check_balance(balance: u64, minimum: u64) -> boolUse case: Pre-validation, rent exemption checks, minimum balance requirements
Validate DEX swaps with encrypted slippage protection.
// Inputs (all encrypted)
struct ConfidentialSwapInput {
input_balance: u64, // Token balance
input_amount: u64, // Swap input
min_output: u64, // Slippage protection
actual_output: u64, // DEX quote result
}
// Outputs
struct ConfidentialSwapOutput {
is_valid: bool, // Sufficient balance?
new_input_balance: u64, // Balance after swap
slippage_ok: bool, // Within tolerance?
}Use case: Jupiter swaps with hidden amounts in SIP Mobile
sip-arcium-program/
├── programs/
│ └── sip_arcium_transfer/
│ └── src/
│ └── lib.rs # Anchor program
│ ├── init_*_comp_def() # Initialize computation definitions
│ ├── private_transfer() # Queue transfer computation
│ ├── check_balance() # Queue balance check
│ ├── validate_swap() # Queue swap validation
│ └── *_callback() # Handle MXE responses
├── encrypted-ixs/
│ └── src/
│ └── lib.rs # Arcis MPC circuits
│ ├── private_transfer() # Transfer validation circuit
│ ├── check_balance() # Balance threshold circuit
│ └── validate_swap() # Swap validation circuit
├── scripts/
│ └── init-comp-defs.ts # Deploy computation definitions
├── tests/
│ └── sip_arcium_transfer.ts # Integration tests
├── Anchor.toml # Anchor config
├── Arcium.toml # Arcium MXE config
└── Cargo.toml # Rust dependencies
User Input → Encrypt (x25519) → Anchor Program → MXE Queue
│
┌───────────┴───────────┐
▼ ▼
MXE Node 1 MXE Node 2
│ │
└───────────┬───────────┘
▼
Threshold MPC
(compute on shares)
│
▼
Encrypt Result
│
▼
Callback → Client Decrypt
| Field | Value |
|---|---|
| Program ID | S1P5q5497A6oRCUutUFb12LkNQynTNoEyRyUvotmcX9 |
| MXE Account | 5qy4Njk4jCJE4QgZ5dsg8uye3vzFypFTV7o7RRSQ8vr4 |
| Cluster Offset | 456 |
| Arcium Version | v0.6.3 (devnet) |
- Rust 1.75+
- Solana CLI 1.18+
- Anchor 0.30+
- Node.js 20+
# Clone the repository
git clone https://github.com/sip-protocol/sip-arcium-program.git
cd sip-arcium-program
# Install dependencies
yarn install
# Build program + circuits
anchor build
# Run tests
anchor test
# Deploy to devnet
anchor deploy --provider.cluster devnet
# Initialize computation definitions
npx ts-node scripts/init-comp-defs.ts# Start local validator with Arcium
arcium localnet
# Deploy locally
anchor deploy --provider.cluster localnet
# Test with local MXE
anchor test --provider.cluster localnetimport { ArciumAdapter } from '@/privacy-providers/arcium'
import { Connection, Keypair } from '@solana/web3.js'
// Initialize adapter
const adapter = new ArciumAdapter({
programId: 'S1P5q5497A6oRCUutUFb12LkNQynTNoEyRyUvotmcX9',
mxeAccount: '5qy4Njk4jCJE4QgZ5dsg8uye3vzFypFTV7o7RRSQ8vr4',
connection: new Connection('https://api.devnet.solana.com'),
})
// Validate a private transfer
const result = await adapter.validateTransfer({
senderBalance: 1000000000n, // 1 SOL in lamports
amount: 100000000n, // 0.1 SOL
minBalance: 890880n, // Rent exemption
encryptionKeypair, // x25519 keypair
})
if (result.isValid) {
// Proceed with transfer
console.log('New balance:', result.newSenderBalance)
}use anchor_lang::prelude::*;
use sip_arcium_transfer::cpi::accounts::PrivateTransfer;
use sip_arcium_transfer::cpi::private_transfer;
// Queue computation
private_transfer(
ctx.accounts.into(),
computation_offset,
encrypted_balance,
encrypted_amount,
encrypted_min_balance,
x25519_pubkey,
nonce,
)?;| Category | Technology | Purpose |
|---|---|---|
| Language | Rust 1.75 | Program + circuits |
| Framework | Anchor 0.30 | Solana program framework |
| MPC | Arcium SDK 0.6.5 | Confidential computation |
| Circuits | Arcis | MPC circuit DSL |
| Encryption | x25519 | Input/output encryption |
| Testing | Mocha + Chai | Integration tests |
| Deployment | Solana CLI | On-chain deployment |
# Build everything
anchor build
# Run tests
anchor test
# Deploy to devnet
anchor deploy --provider.cluster devnet
# Initialize computation definitions
npx ts-node scripts/init-comp-defs.ts
# Check program logs
solana logs S1P5q5497A6oRCUutUFb12LkNQynTNoEyRyUvotmcX9- Define the circuit in
encrypted-ixs/src/lib.rs:
pub struct MyInput { /* encrypted fields */ }
pub struct MyOutput { /* result fields */ }
#[instruction]
pub fn my_circuit(input: Enc<Shared, MyInput>) -> Enc<Shared, MyOutput> {
// MPC computation logic
}- Add Anchor instructions in
programs/sip_arcium_transfer/src/lib.rs:
pub fn my_circuit(ctx: Context<MyCircuit>, /* params */) -> Result<()> {
queue_computation(/* ... */)?;
Ok(())
}
#[arcium_callback(encrypted_ix = "my_circuit")]
pub fn my_circuit_callback(ctx: Context<MyCircuitCallback>, output: /* ... */) -> Result<()> {
// Handle result
Ok(())
}- Rebuild and test:
anchor build
anchor test| Component | Trust Assumption |
|---|---|
| Anchor Program | Open source, auditable |
| Arcium MXE | Honest majority (2/3+ nodes) |
| x25519 Encryption | Standard cryptographic security |
| Client | User controls their keys |
- ✅ Balance privacy — No one sees actual amounts
- ✅ MEV protection — Encrypted until execution
- ✅ Non-custodial — User holds encryption keys
- ✅ Verifiable — Threshold signatures prove correctness
⚠️ Devnet only — Not audited for mainnet⚠️ MXE trust — Requires honest majority assumption⚠️ Latency — MPC adds ~2-5 seconds vs direct transaction
If you discover a vulnerability:
- Email: security@sip-protocol.org
- Do NOT open public issues for security vulnerabilities
| Project | Description | Link |
|---|---|---|
| sip-protocol | Core SDK (6,600+ tests) | GitHub |
| sip-mobile | Mobile wallet (uses Arcium adapter) | GitHub |
| sip-app | Web application | GitHub |
| Arcium Docs | MPC framework documentation | arcium.com/docs |
MIT License — see LICENSE file for details.
Solana Privacy Hackathon 2026 — Arcium Track
Privacy through MPC — no single node sees your data
Showcase · Documentation · Report Bug
Part of the SIP Protocol ecosystem