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

The Ceramic Plugin adds support for storing and retrieving credentials on Ceramic. 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 (see below for advanced encryption options). JOSE encryption is implemented with ECDH-ES+XC20PKW on the x25519curve with a key length of 256. This is handled by the did-jwt library from the Decentralized Identity Foundation.

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

Ceramic's getmethod will decrypt any JWE encrypted credentials (see uploadEncrypted) 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.

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
};

You can play with the following examples in the LearnCard CLI:

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)

PreviousVC-APINextIDX

Last updated 1 month ago

Was this helpful?

🛠️