LearnCard Documentation
GithubStatusSupportLaunch App
  • 🚀Introduction
    • What is LearnCard?
    • Use Cases & Possibilities
    • Ecosystem Architecture
  • ⚡Quick Start
    • Setup & Prerequisites
    • Your First Integration
  • 📚Tutorials
    • Create a Credential
    • Create a Boost
    • Create a ConsentFlow
    • Create a Connected Website
    • Send xAPI Statements
    • Listen to Webhooks
  • ✅How-To Guides
    • Verify My Issuer
    • Connect Systems
      • Connect a Website
      • Connect a Game
    • Implement Flows
      • Claim Data after Guardian Consent
      • Connect via CHAPI
        • ⭐CHAPI Wallet Setup Guide
        • ↔️Translating to CHAPI documentation
        • 🖥️Demo Application
        • 🔰Using LearnCard to Interact with a CHAPI Wallet
        • 📝Cheat Sheets
          • Issuers
          • Wallets
    • Deploy Infrastructure
      • Remote Key Management
      • Generate API Tokens
      • Signing Authority
      • Connect to Independent Network
      • Build a Plugin
  • 🛠️SDKs & API Reference
    • LearnCard Wallet SDK
      • Authentication
      • Usage Examples
      • SDK Reference
      • Plugin API Reference
      • Integration Strategies
      • Deployment
      • Troubleshooting
      • Changelog
    • LearnCloud Network API
      • Authentication
      • Usage Examples
      • Architecture
      • Notifications & Webhooks
      • Profiles
      • Profile Managers
      • Credentials
      • Boosts
      • Presentations
      • Storage
      • Contracts
      • DID Metadata
      • Claim Hooks
      • Auth Grants
      • Utilities
      • Models
      • OpenAPI
    • LearnCloud Storage API
      • Authentication
      • Usage Examples
      • Architecture
      • Storage
      • Index
      • User
      • Custom Storage
      • Utilities
      • Models
      • xAPI Reference
    • Plugins
      • Crypto
      • DIDKit
      • DID Key
      • Dynamic Loader
      • VC
        • Expiration Sub-Plugin
      • VC-Templates
      • VC-API
      • Ceramic
      • IDX
      • VPQR
      • Ethereum
      • CHAPI
      • LearnCard Network
      • LearnCloud
      • LearnCard
      • Simple Signing
      • Claimable Boosts
    • LearnCard CLI
  • 🧠Core Concepts
    • Identities & Keys
      • Decentralized Identifiers (DIDs)
      • Seed Phrases
      • Network Profiles
      • Signing Authorities
      • Trust Registries
    • Credentials & Data
      • Verifiable Credentials (VCs)
      • Credential Lifecycle
      • Schemas, Types, & Categories
      • Building Verifiable Credentials
      • Boost Credentials
      • Getting Started with Boosts
      • Credential URIs
      • xAPI Data
      • General Best Practices & Troubleshooting
    • Consent & Permissions
      • ConsentFlow Overview
      • Consent Contracts
      • User Consent & Terms
      • Consent Transactions
      • Auto-Boosts
      • Writing Consented Data
      • Accessing Consented Data
      • GameFlow Overview
    • Network & Interactions
      • Network Vision & Principles
      • Key Network Procedures
      • Core Interaction Workflows
    • Architecture & Principles
      • Control Planes
      • Plugin System
      • Auth Grants and API Tokens
  • 🔗Development
    • Contributing
Powered by GitBook
On this page
  • Install
  • Uploading to Ceramic
  • Uploading to Ceramic with Encryption
  • Reading from Ceramic
  • Getting the Ceramic Client
  • Advanced Encryption Settings

Was this helpful?

  1. SDKs & API Reference
  2. Plugins

Ceramic

PreviousVC-APINextIDX

Last updated 23 days ago

Was this helpful?

The Ceramic Plugin adds support for storing and retrieving credentials on . It exposes the ability to publish and read from Ceramic, as well as providing access to a Ceramic client object with a did attached to it.

This plugin implements the Read and Store Planes.

Install

pnpm i @learncard/ceramic-plugin

Uploading to Ceramic

To upload a credential to Ceramic, you may use the Store Plane:

const uri = await learnCard.store.Ceramic.upload(vc);

Uploading to Ceramic with Encryption

To upload a credential to Ceramic using encryption, you may use the Store Plane:

// Encrypted, only the controller(s) can decrypt
const uri = await learnCard.store.Ceramic.uploadEncrypted(vc);

Ceramic's uploadEncrypted method encrypts VCs as JWEs with the controller's DID and other specified recipients (). JOSE encryption is implemented with ECDH-ES+XC20PKW on the x25519curve with a key length of 256. This is handled by the library from the .

Note: Additional metadata is not, by default, encrypted.

Reading from Ceramic

To read a credential from Ceramic, you may use the Read Plane:

const vc = await learnCard.read.get(uri);

Getting the Ceramic Client

To get access to the Ceramic Client, use the getCeramicClient method:

const ceramic = learnCard.invoke.getCeramicClient();

Advanced Encryption Settings

As indicated above, when using learnCard.store.Ceramic.uploadEncrypted(vc), uploaded VCs are encrypted using default settings.

Upload & Get Encrypted Credential:

const user = await initLearnCard({ seed: '123', debug: console.log })
const malicious = await initLearnCard({ seed: '666', debug: console.log });

const uvc = user.invoke.getTestVc();   
const vc = await  user.invoke.issueCredential(uvc);
const streamId = await user.store.Ceramic.uploadEncrypted(vc);

// Should properly retrieve credential!  ✅
await user.read.get(streamId);

// Should error -  Could not decrypt credential - DID not authorized. ❌
await malicious.read.get(streamId);

Upload & Get Shared Encrypted Credential:

In addition to encrypting VCs for the controller, you can pass additional params of the following shape, to learnCard.store.Ceramic.uploadEncrypted(vc, params):

// params in uploadEncrypted(vc, params):
type EncryptionParams = {
    recipients: string[]; // DIDs who can also decrypt the credential, in addition to the controller
};
const user = await initLearnCard({ seed: '123', debug: console.log })
const malicious = await initLearnCard({ seed: '666', debug: console.log });
const friend = await initLearnCard({ seed: '808', debug: console.log });

const sharedStreamId = await user.store.Ceramic.uploadEncrypted(vc, { recipients: [friend.id.did()] });

// Should properly retrieve credential!  ✅
await user.read.get(sharedStreamId);
// Should properly retrieve credential!  ✅
await friend.read.get(sharedStreamId);

// Should error -  Could not decrypt credential - DID not authorized. ❌
await malicious.read.get(sharedStreamId);

Upload & Get One-Way Encrypted Credential:

To manually set encryption settings, you should directly use learnCard.invoke.publishContentToCeramic(vc, encryption) and pass in your encryption params:

Ceramic's specific encryption param is of the following shape:

export type CeramicEncryptionParams = {
    encrypt: boolean; // Enables / disables JWE encryption
    controllersCanDecrypt?: boolean; // Adds the controller DIDs to the recipients list
    recipients?: string[] | undefined; // Specifies which DIDs can decrypt the credential
    options?: CreateJWEOptions | undefined; // Additional options, https://did.js.org/docs/api/modules/dids#createjweoptions
};
const user = await initLearnCard({ seed: '123', debug: console.log })
const malicious = await initLearnCard({ seed: '666', debug: console.log });
const friend = await initLearnCard({ seed: '808', debug: console.log });

const unidirectionalStreamId = await user.invoke.publishContentToCeramic(vc, { encrypt: true, controllersCanDecrypt: false, recipients: [friend.id.did()] });

// Should properly retrieve credential!  ✅
await friend.read.get(unidirectionalStreamId);

// Should error -  Could not decrypt credential - DID not authorized. ❌
await user.read.get(unidirectionalStreamId);
// Should error -  Could not decrypt credential - DID not authorized. ❌
await malicious.read.get(unidirectionalStreamId);

You can also use publishContentToCeramic to upload VPs! Try:

learnCard.invoke.publishContentToCeramic(vp, encryption)

Ceramic's getmethod will decrypt any JWE encrypted credentials (see ) when reading, using the learnCard's DID (learnCard.id.did()). If the learnCard's DID is not a recipient of the JWE, reading the credential will fail.

You can play with the following examples in the:

🛠️
LearnCard CLI
Ceramic
did-jwt
Decentralized Identity Foundation
see below for advanced encryption options
uploadEncrypted