Getting Started
Integrate Solidus identity verification into your application in 5 minutes. By the end of this guide you will have created a DID, issued a verifiable credential, and verified it — all on the live testnet.
Prerequisites
- Node.js 18+
- A package manager (npm, yarn, or pnpm)
Install the SDK
npm install @solidus-network/sdk @solidus-network/auth @noble/ed25519@solidus-network/sdk provides DID operations, credential issuance, and chain queries. @solidus-network/auth handles authentication challenges and presentation verification. @noble/ed25519 generates the Ed25519 key pairs that Solidus uses for signing.
1. Generate a Key Pair
Every identity on Solidus starts with an Ed25519 key pair. The public key becomes the basis of your DID address; the private key signs transactions and credentials.
import * as ed25519 from '@noble/ed25519'
// Generate a new private key (32 random bytes)
const privateKey = ed25519.utils.randomPrivateKey()
const publicKey = await ed25519.getPublicKeyAsync(privateKey)
// Hex-encode for SDK configuration
const privateKeyHex = Buffer.from(privateKey).toString('hex')
const publicKeyHex = Buffer.from(publicKey).toString('hex')
console.log('Private key:', privateKeyHex)
console.log('Public key:', publicKeyHex)Keep your private key secret. Anyone with access to it controls the associated DID.
2. Create an SDK Instance
Connect to the Solidus testnet by creating an SDK instance with your key pair.
import { createSdk } from '@solidus-network/sdk'
const sdk = createSdk({
mode: 'testnet',
chain: {
rpcUrl: 'https://rpc.solidus.network',
signerPrivateKey: privateKeyHex,
network: 'testnet',
},
})The SDK instance is your entry point for all protocol operations — DIDs, credentials, and chain queries.
3. Create a DID
A Decentralized Identifier (DID) is your on-chain identity. Creating one submits a transaction to the Solidus testnet.
const did = await sdk.did.create({
publicKey: publicKeyHex,
keyType: 'Ed25519VerificationKey2020',
})
console.log('DID created:', did.id)
// Output: did:solidus:7Hk3mRtQZv...The returned DID follows the W3C DID standard with the format did:solidus:<address>, where the address is derived from a BLAKE3 hash of your public key.
4. Resolve a DID
You can look up any DID to retrieve its DID Document, which contains the public keys and verification methods associated with that identity.
const document = await sdk.did.resolve(did.id)
console.log('DID Document:', JSON.stringify(document, null, 2))The document includes verification methods, authentication keys, and assertion methods that other parties use to verify signatures from this DID.
5. Issue a Credential
Verifiable Credentials are cryptographic proofs of claims. Here we issue a simple email credential — in production, credentials like KYC levels are issued after real verification.
const credential = await sdk.credentials.issue({
type: ['VerifiableCredential', 'EmailCredential'],
issuer: did.id,
subject: did.id,
claims: {
email: '[email protected]',
verified: true,
},
expirationDate: '2027-12-31T23:59:59Z',
})
console.log('Credential issued:', credential.id)
console.log('Proof type:', credential.proof.type)The credential is signed with your private key and its hash is anchored on-chain, creating an immutable record that the credential was issued without storing any personal data on the blockchain.
6. Verify a Credential
Any party can verify a credential by checking its cryptographic signature, on-chain anchor, expiration, and revocation status.
const result = await sdk.credentials.verify(credential)
console.log('Valid:', result.valid)
console.log('Checks:', result.checks)
// Output: Valid: true
// Checks: ['signature', 'expiration', 'revocation', 'onChainAnchor']Verification is entirely trustless — the verifier does not need to contact the issuer. They only need the credential and access to the Solidus network.
7. Authentication Flow
@solidus-network/auth lets you authenticate users by asking them to prove ownership of their DID. The flow has three steps: create a challenge, sign a presentation, and verify the presentation.
import { createAuthClient, createAuthVerifier } from '@solidus-network/auth'
// --- Verifier side: create a challenge ---
const verifier = createAuthVerifier({
rpcUrl: 'https://rpc.solidus.network',
})
const challenge = await verifier.createChallenge({
domain: 'myapp.example.com',
requiredCredentials: ['EmailCredential'],
})
// --- User side: sign a presentation ---
const authClient = createAuthClient({
privateKey: privateKeyHex,
did: did.id,
})
const presentation = await authClient.signPresentation({
challenge: challenge.id,
credentials: [credential],
})
// --- Verifier side: verify the presentation ---
const verification = await verifier.verifyPresentation(presentation)
console.log('Authenticated:', verification.valid)
console.log('Subject DID:', verification.subject)
console.log('Credentials:', verification.credentials)The verifier never sees the user’s private key. They only receive a signed presentation that proves the user controls the DID and holds the required credentials.
Full Example
Here is the complete flow in a single script.
import * as ed25519 from '@noble/ed25519'
import { createSdk } from '@solidus-network/sdk'
import { createAuthClient, createAuthVerifier } from '@solidus-network/auth'
async function main() {
// Key generation
const privateKey = ed25519.utils.randomPrivateKey()
const publicKey = await ed25519.getPublicKeyAsync(privateKey)
const privateKeyHex = Buffer.from(privateKey).toString('hex')
const publicKeyHex = Buffer.from(publicKey).toString('hex')
// SDK setup
const sdk = createSdk({
mode: 'testnet',
chain: {
rpcUrl: 'https://rpc.solidus.network',
signerPrivateKey: privateKeyHex,
network: 'testnet',
},
})
// Create DID
const did = await sdk.did.create({
publicKey: publicKeyHex,
keyType: 'Ed25519VerificationKey2020',
})
console.log('DID:', did.id)
// Issue credential
const credential = await sdk.credentials.issue({
type: ['VerifiableCredential', 'EmailCredential'],
issuer: did.id,
subject: did.id,
claims: {
email: '[email protected]',
verified: true,
},
expirationDate: '2027-12-31T23:59:59Z',
})
console.log('Credential:', credential.id)
// Verify credential
const result = await sdk.credentials.verify(credential)
console.log('Valid:', result.valid)
// Authentication
const verifier = createAuthVerifier({
rpcUrl: 'https://rpc.solidus.network',
})
const challenge = await verifier.createChallenge({
domain: 'myapp.example.com',
requiredCredentials: ['EmailCredential'],
})
const authClient = createAuthClient({
privateKey: privateKeyHex,
did: did.id,
})
const presentation = await authClient.signPresentation({
challenge: challenge.id,
credentials: [credential],
})
const verification = await verifier.verifyPresentation(presentation)
console.log('Authenticated:', verification.valid)
}
main().catch(console.error)Next Steps
- How Solidus Works — understand the protocol design
- DIDs in depth — DID document structure, key derivation, lifecycle
- Verifiable Credentials — credential types, selective disclosure, revocation
- Network and Testnet — RPC methods, explorer, faucet