Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Solidus Network

Solidus SDK

License

TypeScript packages for building on the Solidus Network — a blockchain protocol for decentralized identity and verifiable credentials.

Published packages

Published to npm under the @solidus-network scope. Versions in the badges are live from the registry — this page does not restate them, because a number typed into prose goes stale the day after you type it.

Core

Package npm Description
@solidus-network/sdk npm Main SDK — DID resolution + rotation, credential issuance/verification, SD-JWT VC (incl. KB-JWT, status list, nested-path disclosure), on-chain queries
@solidus-network/auth npm DID-based authentication primitives — Ed25519 challenge, W3C VP verification
@solidus-network/types npm Shared TypeScript types — DIDs, Verifiable Credentials (Data Model 2.0), auth challenges
@solidus-network/bbs npm BBS+ selective-disclosure primitives — draft-irtf-cfrg-bbs-signatures, BLS12-381 SHA-256, byte-compatible with the on-chain implementation

Agent identity

Portable identity for AI agents. Built on the core above; you do not need these to issue or verify human credentials. Source lives in the Solidus monorepo, not this repo.

Package npm Description
@solidus-network/agent-identity npm did:solidus DIDs, BBS+ selective-disclosure credentials, and ERC-8004 passport anchoring for AI agents
@solidus-network/agent-identity-verify npm Hot-path verifier — offline BBS+ proof verification plus a cached, fail-closed OAuth Status List revocation check
@solidus-network/agent-identity-react npm React components — the Verified-by-Solidus badge, agent passport card, mandate-approval prompt

ID capture

Browser-side document capture, used by Solidus Verify. Source lives in the monorepo, not this repo.

Package npm Description
@solidus-network/capture npm Embeddable web ID-capture SDK — guided camera capture with quality gating and on-device MRZ/barcode extraction
@solidus-network/id-extract npm Client-side (WASM) extraction — barcode read, MRZ OCR, checksum reconstruction, confidence gate. Framework-free

Wallet, agent runtime and tooling

Source lives in the monorepo, not this repo.

Package npm Description
@solidus-network/wallet npm Wallet SDK — did:solidus keypair derivation, injectable credential store, BBS+ selective-disclosure presentation, scoped payment-mandate stamping
@solidus-network/mcp npm MCP server — run-time agent tools: resolve did:solidus, verify credentials, check/create scoped spend mandates, authorize payments against them
@solidus-network/auth-otp npm Provider-agnostic OTP (SMS/email) login core — injected clock, rng, store, sender and identity resolver; the caller owns session issuance and delivery
@solidus-network/cli npm CLI — wire did:solidus, verify and agent identity into your app in one command

Install

npm install \
  @solidus-network/sdk \
  @solidus-network/auth \
  @solidus-network/types \
  @solidus-network/bbs

Quick start

import { createSdk } from '@solidus-network/sdk'

// Config is flat — there is no `chain` wrapper.
const solidus = createSdk({
  mode: 'testnet',
  rpcUrl: 'https://rpc.solidus.network',
  signerPrivateKey: process.env.SOLIDUS_SIGNER_KEY,
})

// Resolve a DID. Returns null when the DID is unknown or deactivated.
const didDocument = await solidus.did.resolve('did:solidus:testnet:abc123')

// Spec-conformant W3C DID Resolution — distinguishes "not found" from
// "deactivated" instead of folding both into null. Chain mode only, so it is
// optional on the SDK surface and `undefined` in stub mode. Guard it.
if (solidus.did.resolveWithMetadata) {
  const { didDocument, didDocumentMetadata } =
    await solidus.did.resolveWithMetadata('did:solidus:testnet:abc123')
}

// Issue a W3C VC 2.0 credential (as an authorised issuer)
const vc = await solidus.credentials.issue({
  subjectDid: 'did:solidus:testnet:xyz789',
  issuerDid: 'did:solidus:testnet:issuer1',
  issuerPrivateKey: process.env.SOLIDUS_ISSUER_KEY!,
  type: ['VerifiableCredential', 'KYCVerified'],
  claims: { country: 'US', tier: 'standard' },
  expiresInDays: 365,
})

SD-JWT VC (EUDI Wallet-aligned)

import { issueSdJwtVc, presentSdJwtVc, verifySdJwtVc } from '@solidus-network/sdk'

// Ed25519 keys are raw bytes — Uint8Array, not hex strings and not JWKs.
declare const issuerPrivateKey: Uint8Array, issuerPublicKey: Uint8Array
declare const holderPrivateKey: Uint8Array, holderPublicKey: Uint8Array

// Anything NOT listed in `disclosable` is always visible to the verifier, so
// list every claim the holder should be able to withhold.
const issued = await issueSdJwtVc({
  issuer: 'did:solidus:testnet:issuer1',
  vct: 'https://example.com/credentials/age',
  subject: { given_name: 'Ada', birth_date: '1990-01-01' },
  disclosable: ['given_name', 'birth_date'],
  issuerPrivateKey,
  holderPublicKey, // binds the credential to this holder, enabling the KB-JWT
})

// Holder reveals birth_date and withholds given_name. The Key-Binding JWT ties
// that disclosure to one verifier and one nonce, so it cannot be replayed.
const presentation = await presentSdJwtVc({
  compact: issued.compact,
  claimsToReveal: ['birth_date'],
  audience: 'https://verifier.example',
  nonce: 'abc',
  holderPrivateKey,
})

// The verifier supplies the issuer's public key itself — resolve it from the
// issuer DID (`solidus.did.resolve`) and apply your own trust policy.
const result = await verifySdJwtVc({
  compact: presentation.compact,
  issuerPublicKey,
  expectedAudience: 'https://verifier.example',
  expectedNonce: 'abc',
})

BBS+ selective disclosure

The API is class-based. Messages and headers are raw bytes; utf8() encodes them.

import { BbsSecretKey, utf8 } from '@solidus-network/bbs'

const messages = ['name=Ada', 'over18=true', 'birth_date=1990-01-01'].map(utf8)
const header = utf8('solidus-kyc-v1')

// Issuer signs the whole message set once
const sk = await BbsSecretKey.generate()
const pk = await sk.publicKey()
const signature = await sk.sign(header, messages)

// Holder discloses only "over18=true" (index 1) — the rest stay hidden.
// The presentation header binds the proof to one verifier challenge.
const presentationHeader = utf8('verifier-nonce')
const proof = await signature.createProof({
  pk,
  header,
  presentationHeader,
  messages,
  disclosedIndices: [1],
})

// The verifier never sees name or birth_date — only what was disclosed
const ok = await proof.verify({
  pk,
  header,
  presentationHeader,
  disclosedIndices: [1],
  disclosedMessages: [messages[1]],
})

DID-based authentication

import { createChallenge, verifyPresentation } from '@solidus-network/auth'
import type { VerifiablePresentation } from '@solidus-network/auth'

// Holder DID, then a time-to-live in seconds
const challenge = createChallenge('did:solidus:testnet:abc123', 300)

// The client signs challenge.nonce and returns a W3C Verifiable Presentation
declare const presentation: VerifiablePresentation

// Resolve the holder's Ed25519 public key from the VP's verificationMethod id
declare const getPublicKey: (verificationMethodId: string) => Promise<Uint8Array>

// Three positional arguments, in this order — not one options object
const result = await verifyPresentation(challenge, presentation, getPublicKey)

Modes

  • stub — local Postgres-backed mock for development; no chain interaction.
  • testnet — talks to the Solidus testnet via JSON-RPC at rpc.solidus.network.
  • mainnet — reserved for the post-audit launch.

Documentation

Network

License

Apache-2.0 — see LICENSE (each published package ships its own copy).

About

Solidus SDK — TypeScript packages for decentralized identity (@solidus/auth, @solidus/sdk, @solidus/jwt)

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages