AURA

Confidential

Encrypted guardrails, FHE proposals, and the policy decryption flow.

The confidential domain stores spending guardrails as FHE ciphertexts and evaluates policy over the encrypted values through the Ika Encrypt network. Builders live under instructions::confidential::*.

Requires the Ika Encrypt network

Every instruction except disable / close takes ciphertext accounts and the Encrypt CPI accounts. Derive the AURA-side authority with derive_encrypt_cpi_authority_pda and the event authority with derive_encrypt_event_authority_pda(&encrypt_program_id). These flows are exercised by the Rust smoke tests in smoke/aura-devnet/.

Examples assume:

use aura_sdk::{anchor_accounts as accounts, types::*, AuraClient};
use solana_sdk::signature::{Keypair, Signer};

let client = AuraClient::devnet();
let now = chrono::Utc::now().timestamp();
// `treasury` is the treasury PDA; `guardrails` is its confidential-guardrails PDA.

init_confidential_guardrails

Creates the encrypted guardrails account for an epoch (positional epoch_id). Accounts: owner (s, w), treasury, guardrails (w), the three limit ciphertexts, system_program.

let sig = client.init_confidential_guardrails(
    &owner,
    accounts::InitConfidentialGuardrails {
        owner: owner.pubkey(),
        treasury,
        guardrails,
        daily_limit_ciphertext,
        per_tx_limit_ciphertext,
        spent_today_ciphertext,
        system_program: solana_sdk::system_program::ID,
    },
    1, // epoch_id
    now,
)?;

configure_confidential_guardrails

Sets the encrypted daily/per-tx limits. The send-helper takes the three ciphertext pubkeys positionally. Accounts: owner (s), treasury (w), the ciphertexts (w).

let sig = client.configure_confidential_guardrails(
    &owner,
    treasury,
    daily_limit_ciphertext,
    per_tx_limit_ciphertext,
    spent_today_ciphertext,
    now,
)?;

update_confidential_guardrails

Updates limit ciphertexts. ManageConfidentialGuardrails carries the full set of optional limit/spend ciphertexts — set only the ones you're changing and None for the rest. Accounts: owner (s, w), treasury (w), guardrails (w).

let sig = client.update_confidential_guardrails(
    &owner,
    accounts::ManageConfidentialGuardrails {
        owner: owner.pubkey(),
        treasury,
        guardrails,
        daily_limit_ciphertext: Some(daily_limit_ciphertext),
        per_tx_limit_ciphertext: None,
        velocity_limit_ciphertext: None,
        hourly_limit_ciphertext: None,
        weekly_limit_ciphertext: None,
        spent_today_ciphertext: None,
        weekly_spent_ciphertext: None,
        hourly_spent_ciphertext: None,
        velocity_window_ciphertext: None,
    },
    now,
)?;

rotate_confidential_guardrails

Rotates to a new encryption epoch (positional new_epoch_id; same optional ciphertext set as update). Accounts: owner (s, w), treasury (w), guardrails (w).

let sig = client.rotate_confidential_guardrails(&owner, manage_accounts, 2 /* new_epoch_id */, now)?;

reset_confidential_counters

Resets the encrypted spend counters (same optional ciphertext set). Accounts: owner (s, w), treasury (w), guardrails (w).

let sig = client.reset_confidential_counters(&owner, manage_accounts, now)?;

disable_confidential_guardrails

Disables confidential guardrails while keeping the account. No Encrypt CPI. Accounts: owner (s, w), treasury (w), guardrails (w).

let sig = client.disable_confidential_guardrails(
    &owner,
    accounts::DisableConfidentialGuardrails { owner: owner.pubkey(), treasury, guardrails },
    now,
)?;

close_confidential_guardrails

Closes the guardrails account and reclaims rent. No arguments, no Encrypt CPI. Accounts: owner (s, w), treasury, guardrails (w).

let sig = client.close_confidential_guardrails(
    &owner,
    accounts::CloseConfidentialGuardrails { owner: owner.pubkey(), treasury, guardrails },
)?;

propose_confidential_transaction

Proposes a spend evaluated against encrypted limits via the Encrypt CPI, producing an encrypted policy-output ciphertext. extra_signers carries any additional ciphertext-account signers. Accounts: ai_authority (s), treasury (w), the limit/amount/output ciphertexts, the Encrypt CPI accounts, and optional sidecars.

let sig = client.propose_confidential_transaction(
    &ai,
    accounts::ProposeConfidentialTransaction {
        ai_authority: ai.pubkey(),
        treasury,
        daily_limit_ciphertext,
        per_tx_limit_ciphertext,
        spent_today_ciphertext,
        amount_ciphertext,
        policy_output_ciphertext,
        encrypt_program,
        config,
        deposit,
        caller_program,
        cpi_authority,
        network_encryption_key,
        event_authority,
        external_liveness: None,
        weekly_limit_ciphertext: None,
        weekly_spent_ciphertext: None,
        confidential_guardrails: None,
        system_program: solana_sdk::system_program::ID,
    },
    ProposeConfidentialTransactionArgs {
        amount_usd: 100,
        target_chain: 2,
        tx_type: 0,
        protocol_id: None,
        current_timestamp: now,
        expected_output_usd: None,
        actual_output_usd: None,
        quote_age_secs: None,
        counterparty_risk_score: None,
        recipient_or_contract: "0x000000000000000000000000000000000000dead".to_string(),
    },
    &[], // extra ciphertext signers
)?;

request_policy_decryption

Requests decryption of an encrypted policy result (positional now + current_epoch_id; extra_signers for the request account). Accounts: operator (s), treasury (w), request_account (w), ciphertext, the Encrypt CPI accounts, confidential_guardrails?, system_program.

let sig = client.request_policy_decryption(
    &operator,
    accounts::RequestPolicyDecryption {
        operator: operator.pubkey(),
        treasury,
        request_account,
        ciphertext,
        encrypt_program,
        config,
        deposit,
        caller_program,
        cpi_authority,
        network_encryption_key,
        event_authority,
        confidential_guardrails: None,
        system_program: solana_sdk::system_program::ID,
    },
    now,
    1, // current_epoch_id
    &[&request_account_keypair],
)?;

confirm_policy_decryption

Confirms a completed decryption once the network returns the plaintext (positional args; the send-helper passes confidential_guardrails: None). Accounts: operator (s), treasury (w), request_account.

let sig = client.confirm_policy_decryption(
    &operator,
    treasury,
    request_account,
    now,
    1, // current_epoch_id
)?;

On this page