NOVA SDK for Rust
A Rust SDK for interacting with NOVA secure file-sharing on NEAR blockchain. NOVA v2 hybridizes IPFS storage with Shade Agents and TEEs (via Phala) for verifiable privacy, using ephemeral nonce-based tokens for key access. Files are encrypted client-side and stored off-chain, with on-chain metadata ensuring auditable, group-based controls.
Features
- 🔐 AES-256-CBC Encryption - Client-side encryption for data privacy
- 🌐 IPFS Storage - Decentralized file storage via Pinata
- ⛓️ NEAR Blockchain - Immutable transaction records and access control
- 🛡️ TEE-Verified Keys - Off-chain keys stored encrypted in Shade Agents (Phala TEEs); no on-chain exposure
- 🔑 Ephemeral Token Auth - Ed25519-signed payloads with nonces/timestamps for replay-proof, time-bound key access
- 👥 Group Management - Fine-grained access control with event-driven key generation/rotation
- 🔄 Key Rotation - Automatic TEE-side rotation on revocation, with on-chain checksum verification
- 🚀 Composite Operations - End-to-end workflows: Encrypt → Upload → Authenticate → Retrieve
Installation
Add to your Cargo.toml:
[]
= "0.2.0"
= { = "1", = ["full"] }
Quick Start
use ;
use env;
async
Core Concepts
Groups
Groups manage shared access to encrypted files. Each group has:
- A unique identifier (
group_id) - An owner who manages membership
- A shared encryption key stored off-chain in Shade Agent/TEE (never stored publicly).
- A list of authorized members
Access Control (Ephemeral Tokens)
NOVA uses signed tokens for key access:
- Generate payload (group_id/user_id/nonce/timestamp/signing_pk_b58).
- Sign with ed25519 (from account keypair).
- Claim on-chain (claim_token): Verifies sig/membership/nonce (5min window), returns token.
- Present to Shade: TEE decrypts key, verifies checksum, responds transiently.
// Register new group (owner only)
sdk.register_group.await?;
// Add members
sdk.add_group_member.await?;
// Check authorization
let authorized = sdk.is_authorized.await?;
// Fetch key from TEE
let key_b64 = sdk.get_group_key.await?;
// Revoke member (automatically rotates key)
sdk.revoke_group_member.await?;
Encryption
All data is encrypted client-side using AES-256-CBC:
- 256-bit symmetric keys
- Random IV per encryption
- PKCS7 padding
- SHA256 hashing for integrity
Transaction Recording
Records file metadata (CID/hash) on-chain; now callable by any group member (v2 enhancement).
let trans_id = sdk.record_transaction.await?;
// Query group transactions
let txs = sdk.get_transactions_for_group.await?;
API Overview
Initialization
NovaSdk::new(rpc_url, contract_id, pinata_key, pinata_secret, shade_api_url)- Create SDK instancewith_signer(private_key, account_id)- Attach NEAR signer (ed25519 support for tokens)
Group Management
register_group(group_id)- Create new group (triggers TEE key gen via events).add_group_member(group_id, user_id)- Grant access to user.revoke_group_member(group_id, user_id)- Revoke access and auto-rotate key in TEE.is_authorized(group_id, user_id)- Check user authorization.
Key Management (TEE-Ephemeral)
store_group_key(group_id, user_id)- Fetches via token flow (signs payload → claim → Shade decrypt + checksum verify).get_group_key(group_id)- View on-chain TEE attestation (for manual verification).
File Operations
composite_upload(group_id, user_id, data: &[u8], filename)- Encrypt, upload to IPFS, record transaction (uses TEE key).composite_retrieve(group_id, cid)- Fetch from IPFS, decrypt (uses TEE key).record_transaction()- Log metadata (group-member callable).get_transactions_for_group()- Query transaction history
Utilities
get_balance(account_id)- Check NEAR account balancetransfer_tokens(to_account, amount_yocto)- Transfer NEAR tokens
Environment Setup
For testing and development, set these environment variables in a .env file:
# Required for integration tests
TEST_NEAR_ACCOUNT_ID=your-account.testnet
TEST_NEAR_PRIVATE_KEY=ed25519:your_private_key
PINATA_API_KEY=your_pinata_key
PINATA_SECRET_KEY=your_pinata_secret
SHADE_API_URL=https://your-shade.phala.network
Testing
# Run unit tests
# Run with integration tests (requires .env setup)
# Run specific test
Error Handling
The SDK uses a custom NovaError enum:
use NovaError;
match sdk.get_group_key.await
Security Considerations
⚠️ Important Security Notes:
- No On-Chain Keys - Keys encrypted in TEEs (Phala Shade); only checksums public—RPC scans reveal nothing decryptable.
- Ephemeral Tokens - Ed25519-signed (nonce/timestamp); 5min expiry, replay-proof (used_nonces map).
- TEE Verification - Shade workers attested (code hash); multi-instance sync via shared TEE_SECRET.
- Layered Auth - On-chain membership + token sig + TEE decrypt/checksum—defense against key theft.
- Private Keys - Never commit; use for signing only (ed25519 seed extraction secure).
- IPFS: Public CIDs; rely on encryption—avoid unencrypted uploads.
⚠️ General: Validate checksums in prod; monitor Shade attestations.
Examples
See the examples directory for complete working examples:
simple_upload.rs- Basic file uploadgroup_management.rs- Managing groups and memberskey_rotation.rs- Handling member revocation
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass (
cargo test) - Submit a pull request
License
This project is licensed under the MIT License - see LICENSE file for details.
Resources
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions