Escape the surveillance. Own your conversations.
Live deployment: dmessage.vercel.app Launch announcement: X/Twitter Promo video:
dMessage is a decentralized, end-to-end encrypted messaging platform built on the Stellar blockchain — created so you can talk without being listened to, mined, traded, or fed into someone's AI training pipeline.
Big tech companies treat your private conversations as their free data mine. Every message, every contact, every metadata point is scraped, analyzed, and used to train models you'll never control and profits you'll never see. dMessage exists to break that cycle.
Your data is not their product. Your words are not their training set.
Messages are encrypted on your device using X25519 ECDH key exchange + AES-GCM-256 — the same standards militaries and security professionals trust. The encrypted blobs live on IPFS, not on a corporate server. Only cryptographic hashes and metadata touch the Stellar Soroban blockchain, which no single entity controls. No servers to subpoena. No database to breach. No CEO to decide your data is worth more than your privacy.
A world where:
- Your identity is your wallet — not a login tied to your real name, phone number, or email
- Your messages are private by default — end-to-end encrypted before they leave your device
- Your data stays yours — no one can resell, train on, or monetize your conversations
- Your communication is uncensorable — no intermediary can decide who you're allowed to talk to
- Stellar Wallet Identity: Login with Freighter, Albedo, or any Stellar wallet via Wallet Kit
- End-to-End Encryption: X25519 ECDH key exchange + AES-GCM-256 symmetric encryption (Web Crypto API)
- Decentralized Storage: IPFS for encrypted message content, Soroban for metadata/hashes
- Real-time Threads: Live message updates via React Query + Soroban contract queries
- Media Support: Text and image sharing with IPFS pinning
- Wallet Integration: Native Stellar transaction signing for contract interactions
- Low Gas Costs: Optimized Soroban storage patterns using persistent storage
- Gasless / Fee Sponsorship: A sponsor/relayer can pay a user's fee via Stellar fee-bump, so new users transact without holding XLM (on-chain sponsorship accounting via
*_sponsoredfunctions) - Open Source: Fully auditable smart contracts and frontend code
- Dark Theme: Modern UI with Tailwind CSS v4, custom OKLCH color system
- 3D Landing Page: Interactive hero scene with Three.js and Framer Motion
| Layer | Technology |
|---|---|
| Blockchain | Stellar Soroban (Rust smart contracts) |
| Frontend | Next.js 16, React 19, TypeScript 5 |
| Styling | Tailwind CSS v4, OKLCH color system |
| 3D Graphics | Three.js, React Three Fiber, Drei |
| Animation | Framer Motion 12 |
| State/Data | TanStack React Query 5 |
| Wallet | Stellar Wallet Kit 2 |
| Crypto | Web Crypto API (ECDH P-256, AES-GCM-256) |
| Storage | IPFS (pinning service + gateway) |
| CI/CD | GitHub Actions (Soroban deploy + Vercel) |
┌─────────────────────┐ ┌──────────────────────┐
│ Next.js Frontend │ │ IPFS (Content) │
│ (React 19) │────▶│ Encrypted blobs │
│ │ └──────────────────────┘
│ - Wallet Provider │
│ - E2EE Crypto │ ┌──────────────────────┐
│ - React Query │────▶│ Stellar Soroban │
│ - Tailwind CSS │ │ (Metadata/Hashes) │
└─────────────────────┘ │ │
│ - UserRegistry │
│ - SocialGraph │
│ - MessageContract │
└──────────────────────┘
| Contract | Description |
|---|---|
| UserRegistry | Stores user profiles: usernames, ECDH public keys, IPFS metadata links |
| SocialGraph | Creates deterministic conversation references, maintains per-user conversation lists |
| MessageContract | Inbox-per-recipient message storage with paginated retrieval and read receipts |
Every state-changing function has a *_sponsored variant for gasless / fee-sponsored
use (see Advanced Features).
register_user(caller, username, encryption_pubkey, metadata_ipfs)— Register or update your profileregister_user_sponsored(sponsor, caller, …)— Gasless register;sponsorpays the fee (fee-bump) and is recorded on-chainget_user(addr)— Get a user's profile by their Stellar addressget_sponsored_count(sponsor)— How many actions a sponsor has paid for
ensure_conversation(caller, user_a, user_b)— Create or get a deterministic conversation between two usersensure_conversation_sponsored(sponsor, caller, user_a, user_b)— Gasless variant;sponsorpays via fee-bumpget_user_conversations(user_addr)— Get all conversation references for a userget_sponsored_count(sponsor)— How many actions a sponsor has paid for
send_message(sender, recipient, content)— Store a message in the recipient's inboxsend_message_sponsored(sponsor, sender, recipient, content)— Gasless send;sponsorpays via fee-bumpget_messages(user, page, page_size)— Paginated inbox retrievalmark_as_read(caller, index)— Mark a message as readmark_as_read_sponsored(sponsor, caller, index)— Gasless mark-as-read;sponsorpays via fee-bumpmy_message_count(user)— Get the total message count for a userget_sponsored_count(sponsor)— How many actions a sponsor has paid for
The current contracts (see contracts/gasless/) let a
sponsor/relayer pay a user's transaction fee, so a brand-new user with no
XLM can register, send messages, and mark them read — a fully gasless
experience.
How fee-bump works on Stellar. A fee-bump is a transaction-envelope feature, not contract logic. One transaction is wrapped inside another:
┌─────────────────────────────────────────────┐
│ FeeBumpTransaction (OUTER) │
│ • feeSource = SPONSOR account │ ← pays the XLM fee
│ • signatures = [ sponsor's signature ] │
│ ┌─────────────────────────────────────────┐ │
│ │ Transaction (INNER) │ │
│ │ • source = USER account │ │ ← the real action
│ │ • operation = InvokeHostFunction(...) │ │ (calls the contract)
│ │ • Soroban auth signed by USER │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
- The user signs the Soroban auth entries of the inner transaction (this is what
satisfies
caller.require_auth()/sender.require_auth()in the contract). - A sponsor account wraps it in a
FeeBumpTransaction(fee source = sponsor), signs the outer envelope, and submits it. - The network charges the sponsor; the user spends nothing.
Security. The user's signature covers the inner transaction, and the sponsor cannot alter it — any change invalidates the user's signature and the Soroban auth entries. The sponsor controls whether the action is paid for, never what the action does.
On-chain accountability (what the contracts add). Fee-bump alone leaves no
contract-level record of who sponsored whom. Each state-changing function gains a
*_sponsored variant that:
- requires
sponsor.require_auth()(the sponsor cryptographically consents, so the tally cannot be forged) and the user's ownrequire_auth(); - increments a per-sponsor counter readable via
get_sponsored_count(sponsor); - emits a
Sponsoredevent with(sponsor, user)topics.
This enables relayer analytics, rate-limiting, and abuse prevention (e.g. "this sponsor has funded N actions this month — stop relaying"). The original, self-paid functions are kept intact and still work — including transparently under a fee-bump.
This release redeployed all three contracts as gasless / fee-sponsored
versions (addresses in the Current — Gasless
table) and repointed the frontend, .env.example, and deployment.json to them.
The previous non-gasless contracts are deprecated — kept on-chain and in the
repo (contracts/user_registry, contracts/social_graph, contracts/messages)
for history and verification, but no longer used by the app. See the
Deprecated Contracts
table for their addresses and WASM hashes.
These contracts add Fee Sponsorship: a sponsor/relayer account can pay a user's
transaction fee via a Stellar fee-bump transaction, so users transact without holding
XLM. Each state-changing function has a *_sponsored variant that records on-chain
sponsorship (get_sponsored_count, Sponsored event). Source lives in
contracts/gasless/.
Security-hardened build. These are the audited versions (see
contracts/gasless/SECURITY_AUDIT.md): indexed inbox storage (no unbounded-growth DoS), participant-only conversation creation, persistent-entry TTL bumping, 32-byte pubkey validation, global username uniqueness, and message/field size caps. The earlier (pre-audit) gasless build is listed under Deprecated.
| Contract | Address | WASM Hash (SHA256) |
|---|---|---|
| UserRegistry (gasless) | CDHJHY3LQWJM3PPKGFA6QRDUK2JQU5DQEBFKL42I3UEZNNM6IRFF76DJ |
053d3a283dc2fdd605f53420e1f169adc0036b8edbcab16ef38139637ccc5627 |
| SocialGraph (gasless) | CC3SRPHPKC4WIEJUSQY5KKUSHCBO2Y77VDXIDRKX6XVZLHKTIOQEPULK |
435836ec67d6ae80557ff606ee80f6178fbd30a3cc6fc79956b46c486d56ad6a |
| MessageContract (gasless) | CAGETMAVXLCMB7NLZFF6TPHVAXJAQY4DQ2CTJWPQP5TL32PLQT7IVBEO |
9133e011abaa8537d6f271378b3920f884976c94adcf4445f1b6f051cb5af26a |
Explorer: UserRegistry · SocialGraph · Messages
The gasless contracts were deployed by account GDTPJE3COWLAYGDQ4GOGZF64CLHME6HJ5AVDO2ZC44HZXCHJZUXCEPAM.
The previous non-gasless contracts remain on-chain and in the repo for history and verification, but the frontend no longer points to them.
| Contract | Address | WASM Hash (SHA256) | Status |
|---|---|---|---|
| UserRegistry (audited, strict 32-byte pubkey) | CCJO373LK257MCNEEQ24NWLL34RN34HBASNN3ASP7SBZKCA4YSUAKOF2 |
dbd3df271dd71f33ef8984266fca44251e5db103b018c63b453f4c6b55d88988 |
deprecated |
| UserRegistry (gasless v1, pre-audit) | CD3SG54U3XKT4SOK2T25HZRF244Q5KWSXCKTNCIQH44ZPBB2OZ4F6YZG |
1565c6a47be7c5a04496764d56348e98e0f9f243046e42442a788cd13460cf4c |
deprecated |
| SocialGraph (gasless v1, pre-audit) | CCEOAERFEEVPFRVKMIXYBWQGS5H5N7ZYNY2JJ37TG4AI4V2W5XGFGB2Q |
2eebe3418e6e78b2c471d88e6136d77cf2a4f957c7221b4e15b2575b0a6a5724 |
deprecated |
| MessageContract (gasless v1, pre-audit) | CDK2AI4JMCD6I53TCYKL5WISQADKE6VHQKHRWK7NTFJ2TQOSM2RIIYY3 |
64194f4ea00d6970a4819d1977c700163f2d9df75f242ad139e7e49e15baa995 |
deprecated |
| UserRegistry (non-gasless) | CAFHDYYSSR7A5MRMTNY457HDDBBWYJZAQNZ22NT7TOMMBRSNC2OOBYHA |
000a21be277fa53e1e91b5cbea85b20d8638dfac07396c157b2894b6f3742964 |
deprecated |
| SocialGraph (non-gasless) | CCI7DBNILBDTLR2KF24I7647H5JGUSMEJDHXS6D7H6GPSQ3WEBJMUPM7 |
2f1eaee677be5dbd9124a715efb47c432c496681f0145f9e27d3c3153a48401c |
deprecated |
| MessageContract (v2) | CATLF3WXUG3GMD2J4XIOIYVE3ND7PBFYYXHPS4632ZXEPJPNGYNAEZK7 |
98221de14f435ac68060c3e7494da96819563467ed46ce78ce8d1e618e1bb51d |
deprecated |
| MessageContract (v1) | CAXNXU2GV45Y7TXDLDJNOVQQ74P4LSX2D5PWRAN52GH3GPVLR423E3TK |
8a17841a2e9ad82147154ff43d57d0a9f82bddea4880922208803d546b10bf6e |
deprecated |
Explorer (deprecated): UserRegistry gasless v1 · SocialGraph gasless v1 · Messages gasless v1 · UserRegistry · SocialGraph · Messages v2 · Messages v1
The deprecated contracts were deployed by GDTPJE3COWLAYGDQ4GOGZF64CLHME6HJ5AVDO2ZC44HZXCHJZUXCEPAM (v1) and GDHP5PPKFRCC23E6MSNDKC7UCHYNTV74DJI7UYR7EDR4YMSGCL3KTZQH (v2).
Anyone can verify the current (gasless) contracts by rebuilding from source:
# 1. Clone the repo at the deployment commit (audited gasless build, branch level6)
git checkout 4b40a6d
# 2. Build each gasless contract (wasm32v1-none)
cd contracts/gasless/user_registry_gasless && stellar contract build && cd -
cd contracts/gasless/social_graph_gasless && stellar contract build && cd -
cd contracts/gasless/messages_gasless && stellar contract build && cd -
# 3. Compare SHA256 hashes
sha256sum contracts/gasless/target/wasm32v1-none/release/*.wasm
# The output should match the gasless WASM hashes in the table aboveThe deprecated (non-gasless) contracts can still be verified by building
contracts/user_registry, contracts/social_graph, and contracts/messages.
The deployment manifest with full metadata (current + deprecated) is at
deployment.json.
The gasless / fee-sponsored contracts are deployed on Stellar Mainnet:
| Contract | Address | WASM Hash (SHA256) |
|---|---|---|
| UserRegistry (gasless) | CBXX465FRKWQMWPPX3YDEBHPHC2K2L55VWLCPZCRRZB77ZVDABFC33YY |
053d3a283dc2fdd605f53420e1f169adc0036b8edbcab16ef38139637ccc5627 |
| SocialGraph (gasless) | CBUC7OBYGSMRIHPARU4B77M4LSRPY5X7LSGOGYO3HZXH5RFAPP752CY5 |
435836ec67d6ae80557ff606ee80f6178fbd30a3cc6fc79956b46c486d56ad6a |
| MessageContract (gasless) | CB4YOOUV3MLKN6AMRFETCYAD2HRHFUI45IUUCE3KXAJTZZJYBMOG76WX |
6f94bcd729179502f0461b1095162d447377fc098571b793dbbca75dfcf1b462 |
Deployed by GCJJ7WCTRWLR7YLOWZH6VGCYKZ62HG2N7US7AUQPT762GDN7HFA4Y7Q5.
Explorer: UserRegistry · SocialGraph · Messages
- Node.js 20+
- Rust 1.75+ (with
wasm32-unknown-unknowntarget) - Stellar Freighter browser extension (for wallet connection)
# Clone and install
git clone https://github.com/rylsherdamz-rgb/dMessage.git
cd dMessage
# Install frontend dependencies
cd frontend && npm install && cd ..
# Build smart contracts (current / gasless)
cd contracts/gasless/user_registry_gasless && stellar contract build && cd -
cd contracts/gasless/social_graph_gasless && stellar contract build && cd -
cd contracts/gasless/messages_gasless && stellar contract build && cd -Copy .env.example to .env.local and fill in your values:
cp frontend/.env.example frontend/.env.localRequired variables:
NEXT_PUBLIC_SOROBAN_RPC— Soroban RPC endpoint (defaults to Stellar Testnet)NEXT_PUBLIC_CONTRACT_USER_REGISTRY— Deployed UserRegistry contract IDNEXT_PUBLIC_CONTRACT_SOCIAL_GRAPH— Deployed SocialGraph contract IDNEXT_PUBLIC_CONTRACT_MESSAGES— Deployed MessageContract contract IDNEXT_PUBLIC_IPFS_PIN_API— IPFS pinning service API endpoint
cd frontend && npm run devOpen http://localhost:3000 in your browser.
Users registered and interacting via the deployed Soroban contracts on testnet:
Real users registered and interacting via the deployed Soroban contracts on Stellar Mainnet:
| Contract | Screenshot |
|---|---|
| UserRegistry | ![]() |
| SocialGraph | ![]() |
| MessageContract | ![]() |
dMessage was user-tested with 20 participants who provided feedback via Google Form. The raw responses and a summary of requested changes are linked below.
| Resource | Link |
|---|---|
| Feedback Form (testnet) | Google Form |
| Response Spreadsheet (testnet) | Google Sheets |
| Feedback Form (mainnet) | Google Form |
| Response Spreadsheet (mainnet) | Google Sheets |
Top requested improvements (ordered by frequency):
- QR code integration — scanner for wallet addresses, shareable QR per profile/chat
- Onboarding improvements — guided tour, better first-run experience, feature highlights
- Search — filter conversations and contacts
- Dark mode — theme toggle for night-time use
- Read receipts — delivery indicators and read status on messages
- Notification customization — per-contact sounds, more variety
- Group chats — multi-party encrypted conversations
- Emoji picker — inline emoji selection while typing
- File sharing — send images and files beyond text
- Disappearing messages — auto-delete after viewing
Full details available in the response spreadsheet.
- User Feedback Folder:
user_feedback/(Excel export)
Demo video:
Watch on Google Drive (backup)
We collected structured feedback from real testers (see user_feedback/) and shipped a round of changes based on the most-requested items. The table below maps recurring feedback to what was actually changed in the codebase.
| # | What users asked for | What we changed | Status |
|---|---|---|---|
| 1 | Dark mode toggle for late-night use | Added a Light/Dark theme toggle in Settings → Appearance; replaced hardcoded text-white styles with the themeable --text CSS variable across the dashboard, settings, and conversation sidebar so text stays readable in both modes |
✅ Shipped |
| 2 | QR codes for sharing wallet addresses | Added a new QrCode component (frontend/src/components/ui/QrCode.tsx, backed by the qrcode package) and surfaced it in Settings → Account → Share your address |
✅ Shipped |
| 3 | Search / filter for conversations | Added a conversation filter in the sidebar with a ⌘K keyboard shortcut |
✅ Shipped |
| 4 | Read receipts / delivery indicators | Added ✓ (delivered) and ✓✓ (read) status indicators backed by the on-chain mark_as_read receipt |
✅ Shipped |
| 5 | Emoji picker in chat | Added an emoji picker to the message composer | ✅ Shipped |
| 6 | File sharing beyond text | Added image/file attachments uploaded to IPFS with only the CID sent on-chain (Messenger-style attachment chip UX) | ✅ Shipped |
| 7 | Keyboard shortcuts for power users | Added shortcuts (e.g. ⌘K to filter conversations) |
✅ Shipped |
| 8 | Better mobile experience | Improved mobile responsiveness across the dashboard and sidebar layouts | ✅ Shipped |
| 9 | Notification sound variety, group chats, disappearing messages | Tracked on the roadmap (see Future Scope) | 🔜 Planned |
| 10 | Clearer onboarding / empty states | Improved the dashboard welcome/empty state and added an in-README User Guide; richer interactive onboarding tracked for a future iteration | ◑ Partial |
- Added a full Technical Documentation section (cryptographic protocol, smart-contract architecture, frontend architecture, project structure)
- Added a User Guide (getting started, features, troubleshooting)
- Added Community & Contributions guidelines
- Added the launch announcement and embedded promo video links
- Pointed the promo video raw link at the
level5branch
View the dMessage pitch deck:
- Interactive: Gamma Presentation
- PDF:
ppt/dMessage.pdf
dMessage uses a hybrid E2EE scheme combining X25519 ECDH key exchange with AES-GCM-256 symmetric encryption:
- Key Generation: Each user generates an X25519 keypair stored in their browser's
localStorage(never leaked to the network). - Key Registration: The public key is published on-chain via the
UserRegistrycontract during registration. - Session Key Derivation: When Alice messages Bob, her client fetches Bob's public key from the contract and computes a shared secret via
ECDH(Alice_priv, Bob_pub). This shared secret is fed through HKDF to derive a 256-bit AES key. - Encryption: The plaintext message is encrypted with AES-GCM-256 using a random 12-byte IV. The IV + ciphertext form the encrypted payload.
- Storage: The encrypted payload is uploaded to IPFS as a JSON blob. Only the IPFS content hash (CID) is sent to the Soroban contract, keeping message content off-chain.
The system uses three Soroban contracts. The currently deployed versions are the
gasless / fee-sponsored copies in contracts/gasless/; the
original non-gasless sources remain for reference:
-
UserRegistry (
contracts/user_registry/src/lib.rs): Maps Stellar addresses to usernames, ECDH public keys, and IPFS metadata links. Implementsregister_userandget_userwith persistent bumpable storage. -
SocialGraph (
contracts/social_graph/src/lib.rs): Tracks user conversation lists.ensure_conversationcreates a sorted, deterministic conversation reference between two users.get_user_conversationsreturns paginated results. -
MessageContract (
contracts/messages/src/lib.rs): Per-recipient inbox model. Each message stores(sender, content_cid, timestamp, read)in aVecmapped to the recipient's address. Supports paginated reads, read receipts, and message counting.
The gasless variants (contracts/gasless/) keep these exact
functions and add *_sponsored entry points plus per-sponsor accounting (see
Advanced Features).
- Wallet Integration:
WalletProviderwraps the app, connecting via Stellar Wallet Kit. Supports Freighter, Albedo, and Wallet Connect. - Key Management:
keystore.tshandles X25519 key generation (via@noble/curves), storage, and retrieval. - Encryption Pipeline:
crypto.tsprovidesencryptMessageanddecryptMessageusing Web Crypto API. - Data Fetching: React Query manages contract state with configurable polling intervals for real-time updates.
- IPFS Layer:
ipfs.tsuploads encrypted payloads to Pinata and fetches them via public gateways.
dMessage/
├── contracts/ # Soroban smart contracts (Rust)
│ ├── user_registry/ # Profile & key management (deprecated, non-gasless)
│ ├── social_graph/ # Conversation indexing (deprecated, non-gasless)
│ ├── messages/ # Inbox message storage (deprecated, non-gasless)
│ └── gasless/ # Current fee-sponsored contracts (in use)
├── frontend/ # Next.js 16 application
│ └── src/
│ ├── app/ # Pages & routing
│ ├── components/ # React components
│ ├── hooks/ # React Query hooks
│ └── lib/ # Crypto, IPFS, Stellar utils
├── ppt/ # Pitch deck materials
├── user_feedback/ # Collected user feedback data
└── images/ # Screenshots & diagrams
-
Install Freighter: Download the Freighter browser extension and create a Stellar wallet. Switch the network to Testnet in Freighter settings.
-
Get Test XLM: Visit the Stellar Lab Friendbot and fund your wallet address with testnet lumens.
-
Connect: Go to dmessage.vercel.app and click Connect Wallet. Approve the connection in Freighter.
-
Create Your Profile:
- Choose a username (letters, numbers, underscores — not just digits)
- Your encryption keypair is generated automatically in your browser
- Sign the registration transaction via Freighter when prompted
-
Start a Conversation:
- Copy another user's Stellar address (you can find yours in Settings → Account → Address)
- Paste it into the search bar in the sidebar
- Click the conversation to open it
- Type your message and hit send
- Dark/Light Mode: Toggle in Settings → Appearance.
- QR Code: In Settings → Account, click the QR code to share your address.
- Read Receipts: Messages show ✓ (delivered) and ✓✓ (read) indicators.
- Encryption Keys: Manage your keypair in Settings → Encryption Keys. Rotate keys if needed, then re-register to publish the new public key.
- Network Status: Your connection to Stellar Testnet is shown in Settings → Account.
| Issue | Solution |
|---|---|
| Wallet won't connect | Ensure Freighter is on Testnet and funded |
| Messages not sending | Check your encryption keypair in Settings |
| Blank/white screen | Reload the page; clear browser cache if persistent |
| Transaction fails | Ensure you have enough test XLM (use the friendbot) |
- All smart contracts undergo third-party audit before mainnet deployment
- Client-side E2EE using standards-compliant Web Crypto API (ECDH + AES-GCM)
- Bug bounty program via Immunefi (post-launch)
- Regular dependency updates with Dependabot
- Formal verification of critical contract functions (in progress)
- Group Chats: Multi-party conversations with shared symmetric keys
- Verified Identities: Keybase-style identity proofs via Stellar assets
- Message Reactions: Emoji reactions stored as contract events
- Read Receipts: Optional delivery and read tracking flags
- Communities: Topic-based public channels with membership management
- Moderation Tools: User-controlled muting, blocking, and reporting
- Cross-chain Bridges: Connect to Ethereum/Solana via Stellar Asset Contracts
- DAO Governance: Token-weighted voting for protocol upgrades and parameters
- Accessibility: WCAG 2.1 AA compliance with full screen reader support
- Performance: IPFS Cluster pinning and CDN gateways for media delivery
- Mobile: React Native app with shared crypto/IPFS primitives
We welcome contributions of all kinds — code, design, documentation, testing, and feedback.
- Fork the repository on GitHub
- Create a feature branch:
git checkout -b feat/your-feature - Commit your changes:
git commit -am 'Add awesome feature' - Push to the branch:
git push origin feat/your-feature - Open a Pull Request with a clear description of your changes
See the Getting Started section above. After setup, run the test suite:
cd frontend && npm run buildSmart contract tests:
cd contracts/gasless && cargo test- Follow the existing code style (ESLint + Prettier configs are in
frontend/) - Smart contracts should use Soroban SDK patterns from the existing contracts
- All new features should include tests (Playwright for frontend, Rust tests for contracts)
- Write meaningful commit messages in the conventional format (
feat:,fix:,docs:)
- Bug reports: Open a GitHub Issue with steps to reproduce
- Security vulnerabilities: Email the maintainers directly (see security policy)
- Feature requests: Use the Discussions tab
- GitHub Discussions: Join the conversation
- Twitter/X: Launch announcement
- Discord: Join our server (coming soon)
MIT
Built with ☯️ on Stellar Soroban





















