The on-chain Soulbound Token (SBT) registry for Stellar Wrap. This contract stores non-transferable wrap records linked to user addresses, containing data hashes and persona archetypes.
This repository contains the Soroban smart contract that serves as the on-chain anchor for Stellar Wrap. For the full application (frontend, backend, etc.), see the main Stellar Wrap repository.
Stellar Wrap is a "Spotify Wrapped"-style experience built specifically for the Stellar community.
Block explorers are great for data, but terrible for stories. Stellar Wrap takes your raw, complex on-chain history—transactions, smart contract deployments, NFT buys—and transforms it into a beautiful, personalized visual story that anyone can understand and share.
By simply connecting your wallet, you get a dynamic snapshot of your month on Stellar, highlighting your achievements and assigning you a unique on-chain persona based on your activity.
It's more than just stats; it's a tool for builders to prove their contributions and for users to flex their participation in the Stellar ecosystem.
In Web3, your on-chain history is your resume, your identity, and your reputation. But right now, that reputation is hidden behind confusing transaction hashes.
Stellar Wrap solves the visibility gap:
- For Builders & Developers: It's hard to showcase the immense value of deploying open-source Soroban contracts. Stellar Wrap makes their code contributions visible and shareable to non-technical users.
- For the Community: We lack easy, viral loops to share excitement about what's happening on Stellar. This tool gives everyone a reason to post about their on-chain life on social media.
- For Users: It turns isolated transactions into a sense of progress and belonging within the ecosystem.
This smart contract provides the on-chain registry for Stellar Wrap records:
- Initialize: The contract is initialized once with an admin address that has permission to mint wrap records.
- Mint Wrap: The admin (backend service) calls
mint_wrap()to create a soulbound record for a user, storing:
- Timestamp of when the wrap was generated
- SHA256 hash of the full off-chain JSON data (ensuring integrity)
- Archetype/persona assigned to the user (e.g., "soroban_architect", "defi_patron", "diamond_hand")
- Query: Anyone can call
get_wrap()to retrieve a user's wrap record, enabling verification and display of on-chain personas. - Soulbound: Records are non-transferable (SBT), permanently linked to the user's Stellar address.
We look beyond simple payments to capture the full spectrum of Stellar's vibrant ecosystem:
- 🧙♂️ Soroban Builder Stats: Contracts deployed and unique user interactions. (Critical for developer reputation!).
- 🤝 dApp Interactions: Which ecosystem projects did you support the most?
- 🎨 NFT Activity: New mints collected and top creators supported.
- 💸 Network Volume: A summary of your general transaction activity.
- 🏆 Your Monthly Persona: A gamified badge that reflects your unique contribution style.
This project is designed to support the growth of the Stellar network by:
- Incentivizing Building: Publicly celebrating developers who ship code creates positive reinforcement. A "Soroban Architect" badge is a social flex that encourages more building.
- Driving Viral Activity: Every shared Stellar Wrap card is organic marketing for the blockchain, showing the world that Stellar is active and being used.
- Increasing Retention: Giving users a personalized summary fosters a sense of ownership and encourages them to come back next month to beat their stats.
The diagram below shows how on-chain and off-chain components interact in the Stellar Wrap system:
sequenceDiagram
participant Backend as Backend Service
participant Admin as Admin Key
participant User as User Wallet
participant Contract as Soroban Contract
participant Frontend as Frontend App
Note over Backend: 1. Generate wrap data
Backend->>Backend: Analyze user's on-chain activity
Backend->>Backend: Compute data_hash (SHA256 of JSON)
Backend->>Backend: Assign archetype persona
Note over Backend,Admin: 2. Sign with admin key
Backend->>Admin: Sign(contract_id + user + period + archetype + data_hash)
Admin-->>Backend: Ed25519 signature
Note over Backend,User: 3. Deliver to user
Backend-->>User: signature + period + archetype + data_hash
Note over User,Contract: 4. User claims on-chain
User->>Contract: mint_wrap(user, period, archetype, data_hash, signature)
Contract->>Contract: Verify user auth (require_auth)
Contract->>Contract: Verify admin signature (ed25519_verify)
Contract->>Contract: Check no duplicate (Wrap key)
Contract->>Contract: Store WrapRecord (persistent)
Contract->>Contract: Update balance & latest period
Contract-->>User: Event: (mint, user, period) → archetype
Note over Frontend,Contract: 5. Frontend reads data
Frontend->>Contract: get_wrap(user, period)
Contract-->>Frontend: WrapRecord {timestamp, data_hash, archetype, period}
Frontend->>Contract: balance_of(user)
Contract-->>Frontend: wrap count
Frontend->>Frontend: Display persona & stats
- Language: Rust
- Smart Contract Framework: Soroban SDK v20.0.0
- Build Tool: Cargo
- Target: WebAssembly (WASM) for Soroban runtime
- Testing: Soroban SDK testutils
- ✅ Admin-controlled initialization
- ✅ Soulbound token (SBT) minting with authorization checks
- ✅ Wrap record storage (timestamp, data hash, archetype)
- ✅ Public query interface for retrieving wrap records
- ✅ Event emission for minting actions
- ✅ Prevention of duplicate wraps per user
initialize(e: Env, admin: Address)- Initialize contract with admin (callable once)mint_wrap(e: Env, to: Address, data_hash: BytesN<32>, archetype: Symbol)- Mint a wrap record (admin only)get_wrap(e: Env, user: Address) -> Option<WrapRecord>- Retrieve a user's wrap record
WrapRecord: Containstimestamp,data_hash, andarchetypeDataKey::Admin: Stores the admin addressDataKey::Wrap(Address): Maps user addresses to their wrap records