LearnCard Developer Docs
  • 🚀Get Started
    • 👋Welcome
    • ⭐Who are you?
      • Learners & Employees
      • Traditional Educator
      • Non-Traditional Educator
      • Assessment Provider
      • Employer
      • App Developer & EdTech
      • DAO & Communities
      • Content Creators
      • Research Institutions
      • NGOs & Governments
      • Plugfest Partner
        • Guide for Interop Issuers
          • 🤽Creating an Interop Issuer
        • Guide for Interop Wallets
    • Protocol Overview
      • The Internet of Education
      • The Learning Economy
      • Learner & Employee Privacy
      • 22nd Century Education
      • The Open Credential Network
      • PVCs
  • 🔰LearnCard SDK
    • What is LearnCard?
      • Why a Universal Wallet?
      • Architectural Patterns
      • Production Deployment Guide
      • Troubleshooting Guide
    • LearnCard Core
      • Quick Start
        • Create New Credentials
          • Creating Verifiable Credentials for LearnCard
          • Achievement Types and Categories
          • Custom Types
          • Understanding Boosts
          • Creating Boost Credentials
        • Sign & Send Credentials
        • Accept & Verify Credentials
        • Share & Present Credentials
      • Construction
        • Managing Seed Phrases
        • initLearnCard
        • DIDKit
        • learnCardFromSeed
        • emptyLearnCard
        • IDX Config
      • Control Planes
        • ID
        • Read
        • Store
        • Index
        • Cache
        • Context
      • Plugins
        • Adding Plugins
        • Official Plugins
          • Dynamic Loader
          • Crypto
          • DIDKit
          • DID Key
          • VC
            • Expiration Sub-Plugin
          • VC Resolution
          • VC-Templates
          • VC-API
          • Ceramic
          • IDX
          • VPQR
          • Ethereum
          • CHAPI
          • LearnCard Network
          • LearnCloud
          • LearnCard
          • Claimable Boosts
        • Writing Plugins
          • The Simplest Plugin
          • The Plugin Type
          • The LearnCard Type
          • Implementing Control Planes
          • Implementing Methods
          • The Implicit LearnCard
          • Depending on Plugins
          • Private Fields
          • Publishing a Plugin to NPM
      • URIs
      • CHAPI
        • ⭐CHAPI Wallet Setup Guide
        • ↔️Translating to CHAPI documentation
        • 🖥️Demo Application
        • 🔰Using LearnCard to Interact with a CHAPI Wallet
        • 📝Cheat Sheets
          • Issuers
          • Wallets
      • LearnCard UX
        • Quick Start
        • Components
          • Verifiable Credentials
            • VC Thumbnail
            • VC Thumbnail, Mini
          • LearnCards
            • LearnCard Front
            • LearnCard Back
        • API
      • LearnCard Bridge
      • API
      • Migration Guide
    • LearnCard Network
      • LearnCard Network API
        • Authentication
        • Auth Grants and API Tokens
        • Profile
        • Credentials
        • Boosts
        • Presentations
        • Storage
        • Signing Authorities
        • Notifications
        • API Docs
        • Launch Your Own Network
      • 🔌Connect Your Application
    • ConsentFlow
      • Setting Up ConsentFlow with an Independent Network
    • GameFlow
      • Sending xAPI Statements
        • xAPI URIs
      • Reading xAPI Statements
        • Advanced xAPI Statement Queries
      • Consentful "Claim Later" Flow
  • 🚀Applications
    • LearnCard
    • SuperSkills!
      • SuperSkills! SDK
        • Digital Wallets
        • Issuing into SuperSkills!
        • 🦸Creating a SuperSkills! Issuer
    • Metaversity
    • Admin Dashboard
  • 🔗Resources
    • Github
    • Community
    • 💅Custom Development
    • Contact Our Team
    • Learning Economy
  • 🤖LearnCard Services
    • LearnCard CLI
    • Discord Bot
    • Metamask Snap
  • 💸LearnBank SDK
    • Why LearnBank?
  • 📊LearnGraph SDK
    • Why LearnGraph?
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. LearnCard SDK
  2. LearnCard Core
  3. Plugins
  4. Official Plugins

Ceramic

PreviousVC-APINextIDX

Last updated 1 year 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 and Planes.

Install

pnpm i @learncard/ceramic-plugin

Uploading to Ceramic

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

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 :

// 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 :

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
Read
Store
Store Plane
Store Plane
did-jwt
Decentralized Identity Foundation
Read Plane
see below for advanced encryption options
uploadEncrypted