Skip to content

Latest commit

 

History

History
221 lines (169 loc) · 12 KB

File metadata and controls

221 lines (169 loc) · 12 KB

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
@solidus-network/x401 npm x401 Verifier and agent sides — HTTP proof requirements, signed OpenID4VP request objects, Result Artifact validation, verification tokens, and the Digital Credentials API carrier
@solidus-network/pay npm Non-custodial crypto and stablecoin checkout: invoices, payments, webhook verification and an embeddable checkout. Zero runtime dependencies. Testnet only today

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).