A collection of Rust-based Soroban smart contracts deployed on the Stellar blockchain, powering the KindFi platform's authentication, NFT issuance, academy system, and reputation management.
This repository contains multiple smart contract systems:
- Auth Contracts - WebAuthn-based authentication and smart account management
- NFT Contracts - Token issuance for KindFi platform and academy graduation certificates
- Academy Contracts - Educational module tracking, badge management, and verification
- Reputation Contract - User reputation and tier management system
All contracts are built using:
- Rust with Soroban SDK
- OpenZeppelin Stellar Contracts for access control and standards
- Stellar/Soroban blockchain
- Deploys new account contracts deterministically
- Uses WASM hash for contract instance deployment
- Ensures only authorized entities can initiate deployments
- Emits events upon successful contract deployments
- Handles multi-signature authentication and permission management
- Manages dynamic set of signers with authentication thresholds
- Supports account and factory management through stored contexts
- Implements flexible authorization rules for external contract calls
- Verifies Ed25519 cryptographic signatures
- Emits events for signer additions and removals
- Represents individual user accounts
- Verifies Secp256r1 cryptographic signatures (WebAuthn compatible)
- Provides account recovery, device management, and security updates
- Multi-device authentication model with public keys tied to devices
- Supports recovery mechanisms through designated recovery address
- Emits events for device additions, removals, and security updates
How It Works:
- Account Factory deploys a new Account Contract when a user registers
- Auth Controller manages authentication flows, including key validation and session authorization
- Account Contract holds user credentials for secure, decentralized identity management
- Standard NFT contract for KindFi platform tokens
- Minting with custom metadata
- Role-based access control (minter, burner, metadata_manager)
- Metadata management and updates
- Burn functionality
- Implements OpenZeppelin NonFungibleToken standard
- Soulbound NFTs - Non-transferable graduation certificates
- Issues NFTs to users who complete all required academy modules
- Cross-contract integration with ProgressTracker and BadgeTracker
- On-chain metadata storage (timestamp, version, badges)
- Secure authentication via
require_auth - Single NFT per user enforcement
Features:
- Verifies module completion via ProgressTracker
- Fetches earned badges from BadgeTracker
- Stores graduation metadata persistently on-chain
- Prevents transfer to maintain credential integrity
- Manages user badges earned during academy program
- Tracks badge assignments and completions
- Provides badge retrieval functions for other contracts
- Tracks user progress through educational modules
- Verifies module completion status
- Provides completion verification for graduation NFT minting
- Verifies user certification status
- Validates completion of academy requirements
- Provides certification verification services
- Manages user reputation scores and tiers
- Calculates reputation based on user activity
- Tracks streaks and achievements
- Admin-controlled tier thresholds
- NFT contract integration for reputation-based rewards
Features:
- Score updates with admin authorization
- Tier calculation from reputation scores
- Streak tracking
- Admin role management
- Mock implementation for testing Academy Graduation NFT
- Simulates badge tracking without external dependencies
- Uses temporary storage for flexibility
- Mock implementation for testing Academy Graduation NFT
- Simulates progress tracking without external dependencies
- Uses temporary storage for flexibility
-
Install Rust (stable toolchain):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh rustup target add wasm32-unknown-unknown
-
Install Stellar CLI:
cargo install stellar-cli
Note: The Stellar CLI installation will ensure you have a compatible Rust version. The SDK version (22.0.6) will determine the minimum Rust version required.
-
Setup Stellar Account:
# Create account identity stellar keys generate <account_name> --network testnet # Or use existing stellar keys add <account_name> --secret-key <secret_key>
-
Fund Your Account:
- Testnet: Visit Stellar Laboratory and use Friendbot
- Futurenet: Use the faucet at Friendbot Futurenet
- Mainnet: Fund via exchange or Stellar account
-
Clone and navigate to contracts directory:
cd apps/contract -
Build all contracts:
cargo build --target wasm32-unknown-unknown --release
-
Run tests:
cargo test
Deploy all auth contracts (Factory, Controller, Account) using the deployment script:
# Testnet (default)
./scripts/deploy-auth.sh --testnet
# Futurenet
./scripts/deploy-auth.sh --futurenet
# Mainnet
./scripts/deploy-auth.sh --mainnet
# Specify source account
./scripts/deploy-auth.sh --testnet --source <account_name>The script will:
- Build all auth contracts
- Deploy Account Contract WASM
- Deploy Auth Controller and initialize with admin key
- Deploy Account Factory and register with controller
- Save deployment info to
auth-deployment-info-<network>.txt
Deployment Output:
- Contract addresses (Factory, Controller, Account)
- WASM hashes
- Transaction hashes
- Network configuration
Deploy the KindFi NFT contract using the deployment script:
# Testnet (default)
./scripts/deploy-nft.sh --testnet
# Futurenet
./scripts/deploy-nft.sh --futurenet
# Mainnet (with confirmation prompt)
./scripts/deploy-nft.sh --mainnet
# With custom options
./scripts/deploy-nft.sh --testnet --source alice --name "My NFT" --symbol "MNFT"Options:
--testnet|--futurenet|--mainnet: Target network--source NAME: Stellar account identity to use--admin ADDRESS: Admin address for the contract--name NAME: NFT collection name (default: "KindFi Kinder NFT")--symbol SYMBOL: NFT collection symbol (default: "KINDER")--base-uri URI: Base URI for token metadata
The script will:
- Build the NFT contract
- Upload WASM to network
- Deploy contract instance with initialization
- Save deployment info to
nft-deployment-info-<network>.txt
Post-Deployment Setup:
# Grant minter role
stellar contract invoke --network testnet --source alice --id <NFT_CONTRACT_ID> \
-- grant_role --account <MINTER_ADDRESS> --role 'minter' --caller <ADMIN_ADDRESS>
# Grant metadata_manager role to Reputation contract
stellar contract invoke --network testnet --source alice --id <NFT_CONTRACT_ID> \
-- grant_role --account <REPUTATION_CONTRACT_ID> --role 'metadata_manager' --caller <ADMIN_ADDRESS>Deploy the KindFi Reputation contract:
# Testnet (default)
./scripts/deploy-reputation.sh --testnet
# With NFT contract integration
./scripts/deploy-reputation.sh --testnet --nft-contract <NFT_CONTRACT_ID>
# Futurenet
./scripts/deploy-reputation.sh --futurenet
# Mainnet (with confirmation prompt)
./scripts/deploy-reputation.sh --mainnetOptions:
--testnet|--futurenet|--mainnet: Target network--source NAME: Stellar account identity to use--admin ADDRESS: Admin address for the contract--nft-contract ID: NFT contract ID for integration (optional)
The script will:
- Build the Reputation contract
- Upload WASM to network
- Deploy contract instance with initialization
- Save deployment info to
reputation-deployment-info-<network>.txt
Post-Deployment Setup:
# Grant recorder role (can record reputation events)
stellar contract invoke --network testnet --source alice --id <REPUTATION_CONTRACT_ID> \
-- grant_role --account <RECORDER_ADDRESS> --role 'recorder' --caller <ADMIN_ADDRESS>
# Grant config role (can update thresholds)
stellar contract invoke --network testnet --source alice --id <REPUTATION_CONTRACT_ID> \
-- grant_role --account <CONFIG_ADDRESS> --role 'config' --caller <ADMIN_ADDRESS>
# Set NFT contract (if not set during deployment)
stellar contract invoke --network testnet --source alice --id <REPUTATION_CONTRACT_ID> \
-- set_nft_contract --caller <ADMIN_ADDRESS> --nft_address <NFT_CONTRACT_ID>For a complete deployment with NFT integration:
# 1. Deploy NFT contract
./scripts/deploy-nft.sh --testnet --source alice
# Note the NFT_CONTRACT_ID from output
# 2. Deploy Reputation contract with NFT integration
./scripts/deploy-reputation.sh --testnet --source alice --nft-contract <NFT_CONTRACT_ID>
# Note the REPUTATION_CONTRACT_ID from output
# 3. Grant metadata_manager role to Reputation contract on NFT contract
stellar contract invoke --network testnet --source alice --id <NFT_CONTRACT_ID> \
-- grant_role --account <REPUTATION_CONTRACT_ID> --role 'metadata_manager' --caller <ADMIN_ADDRESS>
# 4. Grant recorder role on Reputation contract
stellar contract invoke --network testnet --source alice --id <REPUTATION_CONTRACT_ID> \
-- grant_role --account <RECORDER_ADDRESS> --role 'recorder' --caller <ADMIN_ADDRESS>Now when users level up, their NFT metadata will automatically update with the new level attribute.
For deploying individual contracts:
# Build specific contract
cd contracts/<contract-name>
stellar contract build
# Upload WASM
stellar contract upload \
--network testnet \
--source <account_name> \
--wasm target/wasm32-unknown-unknown/release/<contract>.wasm
# Deploy contract
stellar contract deploy \
--network testnet \
--source <account_name> \
--wasm-hash <wasm_hash>cargo testcd contracts/<contract-name>
cargo testcargo test -- --nocaptureMost contracts include comprehensive test suites covering:
- Success cases
- Failure cases
- Edge cases
- Authentication requirements
- Cross-contract interactions
stellar contract inspect \
--network testnet \
--id <contract_id>stellar contract storage \
--network testnet \
--id <contract_id>stellar contract invoke \
--network testnet \
--id <contract_id> \
--source <account_name> \
-- <function_name> <args>- Testnet:
--network testnet- Stellar testnet for development - Futurenet:
--network futurenet- Stellar futurenet for testing new features - Mainnet:
--network public- Stellar mainnet for production
Create a .env file from the example:
cp .env.example .envKey variables:
# Network Configuration
NETWORK="testnet"
NETWORK_PASSPHRASE="Test SDF Network ; September 2015"
RPC_URL="https://soroban-testnet.stellar.org"
HORIZON_URL="https://horizon-testnet.stellar.org"
# Auth Contracts (from auth deployment)
AUTH_CONTROLLER_CONTRACT_ID=""
ACCOUNT_FACTORY_CONTRACT_ID=""
ACCOUNT_CONTRACT_ID=""
# NFT Contract (from NFT deployment)
NFT_CONTRACT_ID=""
NFT_WASM_HASH=""
NFT_ADMIN_ADDRESS=""
# Reputation Contract (from reputation deployment)
REPUTATION_CONTRACT_ID=""
REPUTATION_WASM_HASH=""
REPUTATION_ADMIN_ADDRESS=""
# Account identity
SOURCE_ACCOUNT="bran"See .env.example for all available configuration options.
- Make changes to contract source code
- Build contract:
cargo build --target wasm32-unknown-unknown --release
- Run tests:
cargo test - Upload new WASM to network
- Deploy new instance or upgrade existing
- Initialize contract if needed
- Test deployment with contract invocations
All contracts use OpenZeppelin Stellar Contracts:
stellar-access-control- Role-based access controlstellar-non-fungible- NFT standard implementationstellar-ownable- Ownership managementstellar-pausable- Pause functionalitystellar-upgradeable- Upgrade patterns
⚠️ Always test on testnet first before mainnet deployment- 🔐 Keep secret keys secure - never commit to version control
- ✅ Verify contract ID after deployment
- 👀 Check all transactions before signing
- 🧪 Run comprehensive tests before deployment
- 📋 Review contract code for security best practices
- Stellar Soroban Documentation
- Stellar Developers
- OpenZeppelin Stellar Contracts
- Rust Book
- Soroban CLI Reference
- "Invalid account": Ensure your account is funded with XLM
- "Invalid sequence number": Wait a moment and retry the transaction
- "Contract already exists": Use a new WASM hash or deploy to a different network
- Build errors: Ensure Rust toolchain is up to date:
rustup update - WASM upload fails: Check network connectivity and account balance
-
"Unauthorized" when minting: Ensure the caller has the
minterrolestellar contract invoke --network testnet --id <NFT_CONTRACT_ID> \ -- has_role --account <CALLER_ADDRESS> --role 'minter'
-
"Unauthorized" when updating metadata: Ensure the caller has
metadata_managerrolestellar contract invoke --network testnet --id <NFT_CONTRACT_ID> \ -- has_role --account <CALLER_ADDRESS> --role 'metadata_manager'
-
Token not found: Verify token exists using
total_supplyand check token ID is valid
-
"Unauthorized" when recording events: Ensure the caller has the
recorderrolestellar contract invoke --network testnet --id <REPUTATION_CONTRACT_ID> \ -- has_role --account <CALLER_ADDRESS> --role 'recorder'
-
NFT not updating on level up:
- Verify NFT contract is set:
stellar contract invoke ... -- get_admin - Verify Reputation contract has
metadata_managerrole on NFT contract - Verify user's NFT token ID is registered with
register_user_nft
- Verify NFT contract is set:
-
"PointsOverflow" error: User points would exceed u32 max. This is rare but check current points first.
-
NFT metadata not updating automatically:
- Step 1: Verify NFT contract address is set in Reputation contract
- Step 2: Verify Reputation contract has
metadata_managerrole on NFT contract - Step 3: Verify user has an NFT token ID registered via
register_user_nft - Step 4: Verify the NFT token actually exists
-
Role grants failing: Ensure you're using the correct admin address and it has proper authorization
- Testnet: Use for development. Free XLM from Friendbot.
- Futurenet: Use for testing new Stellar features. May have instability.
- Mainnet: Production only. Real XLM required. Always test on testnet first.
# Check contract admin
stellar contract invoke --network testnet --id <CONTRACT_ID> -- get_admin
# Check if address has a specific role
stellar contract invoke --network testnet --id <CONTRACT_ID> \
-- has_role --account <ADDRESS> --role '<ROLE_NAME>'
# Get role member count
stellar contract invoke --network testnet --id <CONTRACT_ID> \
-- get_role_member_count --role '<ROLE_NAME>'
# Inspect contract
stellar contract inspect --network testnet --id <CONTRACT_ID>See the main repository LICENSE file.