Decentralized Identity for a Trustless World.
Soroban Identity is a decentralized identity (DID) and credential management protocol built on Soroban — the smart contract platform of the Stellar network. It enables users to create, own, and manage verifiable on-chain identities linked to their wallets, while allowing applications to securely verify credentials without exposing sensitive data.
In the current Web3 ecosystem:
- Users lack persistent, verifiable identities
- Reputation is fragmented across platforms
- Compliance (KYC/AML) is difficult to implement in a decentralized way
- Sensitive user data is overexposed or centrally stored
Soroban Identity fixes this by providing a privacy-preserving identity layer that any dApp on Stellar can plug into.
Decentralized Identity (DID)
- Wallet-linked identity profiles using the
did:stellar:method - Unique on-chain identifiers, W3C DID-compatible
- Portable across multiple dApps
Verifiable Credentials
- KYC verification badges issued by trusted entities
- Proof of reputation, activity, or achievements
- Cryptographic attestations stored on-chain
Privacy-Preserving Verification
- Selective disclosure of identity data
- Permission-based access to credentials
- Zero-knowledge proof (ZKP) integration — future-ready
Reputation Layer
- On-chain activity scoring via trusted reporters
- Anti-sybil mechanisms with configurable thresholds
- Trust signals for marketplaces, DAOs, and DeFi
soroban-identity/
├── contracts/
│ ├── identity-registry/ # DID creation, update, deactivation, resolution
│ ├── credential-manager/ # Issue, verify, and revoke verifiable credentials
│ └── reputation/ # On-chain scoring and anti-sybil checks
├── frontend/ # React + TypeScript dApp (Vite)
├── sdk/ # TypeScript SDK for dApp integration
├── server/ # Operational API, expiry jobs, health, and metrics
├── scripts/
│ └── deploy.sh # Build + deploy all contracts to testnet
└── docs/
└── architecture.md # Protocol architecture deep-dive
The server/ package provides contract health checks, protected admin issuer management, credential expiry reporting and notifications, and Prometheus metrics. See docs/server-operations.md for configuration and scrape examples.
Manages W3C-aligned DID documents on-chain.
| Function | Description |
|---|---|
initialize(admin) |
One-time setup |
create_did(controller, metadata) |
Mint a new DID for a wallet |
update_did(controller, metadata) |
Update DID metadata |
deactivate_did(controller) |
Soft-delete a DID |
resolve_did(controller) |
Fetch a full DID document |
has_active_did(controller) |
Boolean active check |
Issues and verifies verifiable credentials.
| Function | Description |
|---|---|
initialize(admin) |
One-time setup |
add_issuer(issuer) |
Register a trusted issuer (admin only) |
remove_issuer(issuer) |
Remove an issuer (admin only) |
issue_credential(issuer, subject, type, claims, sig, expires) |
Issue a credential |
revoke_credential(issuer, id) |
Revoke a credential |
verify_credential(id) |
Check if a credential is valid and not expired |
get_credential(id) |
Fetch full credential data |
On-chain activity scoring and anti-sybil layer.
| Function | Description |
|---|---|
initialize(admin) |
One-time setup |
add_reporter(reporter) |
Register a trusted reporter (admin only) |
submit_score(reporter, subject, delta, reason) |
Submit a score delta |
get_reputation(subject) |
Get aggregated reputation record |
get_history(subject, reporter) |
Get score history from a reporter |
passes_sybil_check(subject, min_score, min_reporters) |
Anti-sybil gate |
did:stellar:<bech32-stellar-address>
Example:
did:stellar:GABC1234XYZ...
This is W3C DID-compatible and portable across any dApp that integrates the SDK.
Issuer Subject Verifier
│ │ │
│─── issue_credential ────▶│ │
│ │──── present cred id ───▶│
│ │ │─── verify_credential
│ │ │◀── true / false
The full API contract — SDK and contract operations — is defined in
docs/openapi.yaml as an OpenAPI 3.0 spec. Each operation
carries an x-soroban-contract extension naming the Soroban contract and
function it maps to.
Run the spec locally:
node scripts/serve-openapi.mjs # http://localhost:3030/openapi.yamlRegenerate the SDK's TypeScript types from the spec:
npx openapi-typescript docs/openapi.yaml -o sdk/src/openapi-types.tsInstall:
cd sdk && npm installUsage:
import {
IdentityClient,
CredentialClient,
ReputationClient,
TESTNET_CONFIG,
MAINNET_CONFIG,
} from "@soroban-identity/sdk";
// Testnet — spread and override the three contract IDs after deployment
const config = {
...TESTNET_CONFIG,
identityRegistryId: "YOUR_REGISTRY_CONTRACT_ID",
credentialManagerId: "YOUR_CREDENTIAL_CONTRACT_ID",
reputationId: "YOUR_REPUTATION_CONTRACT_ID",
};
// Mainnet — same pattern, different base config
// const config = {
// ...MAINNET_CONFIG,
// identityRegistryId: "YOUR_REGISTRY_CONTRACT_ID",
// credentialManagerId: "YOUR_CREDENTIAL_CONTRACT_ID",
// reputationId: "YOUR_REPUTATION_CONTRACT_ID",
// };
// Resolve a DID
const identity = new IdentityClient(config);
const doc = await identity.resolveDid("GABC...");
// Verify a credential
const credentials = new CredentialClient(config);
const valid = await credentials.verifyCredential(
"GABC...",
"credential-id-hex",
);
// Check reputation / anti-sybil
const reputation = new ReputationClient(config);
const passes = await reputation.passesSybilCheck(
"GABC...",
"GSUBJECT...",
50,
2,
);React + Vite dApp with Freighter wallet integration.
cd frontend
npm install
npm run devFeatures:
- Connect Freighter wallet
- Resolve any DID by Stellar address
- Create your own on-chain DID
- Verify credentials by ID
- Issue credentials (registered issuers)
- Rust +
wasm32-unknown-unknowntarget - Stellar CLI
- Node.js 18+
- Freighter Wallet browser extension
# 1. Install Rust wasm target
rustup target add wasm32-unknown-unknown
# 2. Build all contracts
cd contracts && cargo build --target wasm32-unknown-unknown --release
# 3. Deploy to testnet (set your secret key first)
export STELLAR_SECRET_KEY=S...
bash scripts/deploy.sh
# Contract IDs are saved to deployed.env in the repo root (git-ignored)
# 4. Install and run the frontend
cd frontend && npm install && npm run dev
# 5. Install and build the SDK
cd sdk && npm install && npm run buildThe frontend uses environment variables for configuration. Copy .env.example to .env and fill in the contract IDs after deployment:
cd frontend
cp .env.example .envEdit .env with your deployment values:
VITE_RPC_URL=https://soroban-testnet.stellar.org
VITE_NETWORK_PASSPHRASE=Test SDF Network ; September 2015
VITE_IDENTITY_REGISTRY_ID=YOUR_REGISTRY_CONTRACT_ID
VITE_CREDENTIAL_MANAGER_ID=YOUR_CREDENTIAL_CONTRACT_ID
VITE_REPUTATION_ID=YOUR_REPUTATION_CONTRACT_IDEnvironment Variables:
VITE_RPC_URL— Soroban RPC endpoint URL (default:https://soroban-testnet.stellar.org)VITE_NETWORK_PASSPHRASE— Network passphrase for transaction signingVITE_IDENTITY_REGISTRY_ID— Identity registry contract ID (required)VITE_CREDENTIAL_MANAGER_ID— Credential manager contract ID (required)VITE_REPUTATION_ID— Reputation contract ID (required)
Note: .env is git-ignored. Only commit .env.example to the repository.
The scripts/deploy.sh script supports configurable network and RPC endpoint via environment variables:
# Deploy to testnet (default)
export STELLAR_SECRET_KEY=S...
bash scripts/deploy.sh
# Deploy to mainnet
export STELLAR_SECRET_KEY=S...
export STELLAR_NETWORK=mainnet
export STELLAR_RPC_URL=https://soroban-mainnet.stellar.org
bash scripts/deploy.sh
# Deploy to custom network
export STELLAR_SECRET_KEY=S...
export STELLAR_NETWORK=custom
export STELLAR_RPC_URL=https://your-rpc-endpoint.com
bash scripts/deploy.shEnvironment Variables:
STELLAR_NETWORK— Network name (default:testnet). Can betestnet,mainnet, or a custom network name.STELLAR_RPC_URL— RPC endpoint URL (default:https://soroban-testnet.stellar.org).STELLAR_SECRET_KEY— Your Stellar secret key (required). Used to sign transactions and deploy contracts.
The deploy script includes automatic retry with exponential backoff for transient RPC failures (e.g., 503 errors or timeouts):
- Default max retries: 3 attempts
- Initial delay: 2 seconds
- Backoff: Delay doubles after each failed attempt (2s → 4s → 8s)
You can configure retry behavior via environment variables:
# Use default retry settings
export STELLAR_SECRET_KEY=S...
bash scripts/deploy.sh
# Increase max retries for unstable networks
export STELLAR_SECRET_KEY=S...
export MAX_RETRIES=5
bash scripts/deploy.sh
# Increase initial delay for slower networks
export STELLAR_SECRET_KEY=S...
export RETRY_DELAY=5
bash scripts/deploy.sh
# Custom retry configuration
export STELLAR_SECRET_KEY=S...
export MAX_RETRIES=4
export RETRY_DELAY=3
bash scripts/deploy.shRetry Environment Variables:
MAX_RETRIES— Maximum number of retry attempts (default:3)RETRY_DELAY— Initial delay in seconds before first retry (default:2)
- KYC verification for DeFi and financial applications on Stellar
- Reputation systems for marketplaces (e.g. Stellar Mart)
- DAO governance — voting eligibility based on verified identity
- Access control for exclusive communities or gated services
- Anti-sybil protection for airdrops and incentive programs
- DID registry contract
- Verifiable credential issuance & revocation
- Reputation scoring + anti-sybil
- TypeScript SDK
- React frontend with Freighter integration
- Full ZKP selective disclosure
- Cross-chain identity interoperability
- Mobile identity wallet
- Identity-based credit scoring
- Integration with Stellar subscription and payment systems
A Node.js server is available under /server to support:
- Real-time contract event streaming over SSE (
GET /events) - W3C DID resolution endpoint (
GET /1.0/identifiers/{did}) - Optional Redis DID document caching (
did:{address}TTL default60s)
Run locally:
cd server
cp .env.example .env
npm install
npm startOpenAPI spec: server/openapi.json
The server emits structured JSON logs including requestId, method, path, status, and duration.
- Send
X-Request-IDto propagate your own correlation ID - If omitted, the server generates a UUID automatically
In the SDK, you can pass a pluggable logger via SorobanIdentityConfig.logger to capture debug-level simulation and submission outcomes.
See docs/contract-events.md for emitted topic/payload formats by contract.
PRs are welcome. See CONTRIBUTING.md for branch naming, commit style, local setup, and the PR checklist.