For the complete documentation index, see llms.txt. This page is also available as Markdown.

LearnCard CLI

npx @learncard/cli is two things: a set of commands for setting up and operating an issuer (below), and an interactive REPL for exploring the SDK (further down).

Commands

Every command reads its identity from the .env in the current folder — one folder is one profile on one network. --network staging (or a tRPC URL) targets a non-production network; --json prints a single JSON result on stdout; -y accepts defaults.

Command
Does

send <recipient>

Sends a badge to an email or phone (via the Universal Inbox, with a claim link) or to a profile ID or DID (delivered directly). Signs through your registered signing authority when one exists; --no-template signs locally. --as <profileId> sends as a profile you manage.

org apply <file>

Makes the network match an org spec. Idempotent. --dry-run reads only; --secrets-out <path> is where new service-account tokens go.

doctor

Network preflight: identity, signing service, token scopes, signing authority (test-sign + verify), did:web, credential refresh, and optional webhook POST (--webhook-url). Trusted Registry is a skipped manual check. Does not provision resources. --strict fails on warnings.

whoami

This folder's profile, DID, signing authority, manager DID, and every profile --as can target.

promote --from <net> --to <net> --org <file>

Applies the spec on a second network in .learncard/<network>/. Only the seed and profile ID carry over; tokens land in <target>/secrets.env; runs doctor. --dry-run writes nothing.

status [activityId]

Recent sends, or the claim history of one.

inbox list

Sent inbox credentials. --status PENDING|ISSUED|EXPIRED, --since 7d, --as <profileId>.

refresh history <refreshId>

Versions published for a managed credential.

clr validate <file>

Zod-validates a CLR 2.0 credential and lints it as --profile provisional or official. --dry-run-sign signs and verifies without delivering.

setup-signing, token, webhook, verify, revoke, open, init, export, restore

Single-purpose helpers; --help on each.

LEARNCARD_AS=<profileId> is the environment fallback for --as on every command that accepts it.

A newly generated send --as script reads MANAGED_DID, saved in .env, and stays bound to that managed issuer and network. It rejects a missing or changed DID. Existing scripts are left untouched with a warning that they may use a different issuer.

Org spec

The file org apply and promote read. YAML or JSON. Only issuer is required. Worked examples: packages/learn-card-cli/examples; guide: Bootstrap an Issuer Organization.

Field
Type
Notes

issuer.profileId

string

3–40 chars: lowercase letters, digits, hyphens. Must match the folder's PROFILE_ID if one exists.

issuer.displayName

string

Updated in place if it differs.

issuer.branding

object

See branding below.

issuer.signingAuthority.type

learncard-hosted | self-hosted

Hosted: LearnCard creates and registers the key. Self-hosted: also needs endpoint (https) and did. A registered self-hosted signer whose DID differs from did is reported as drift.

issuer.signingAuthority.name

string

≤15 chars, lowercase/digits/hyphens.

profileManager.displayName

string

Creates a profile manager owned by the issuer. Its DID is saved to .env as ORG_PROFILE_MANAGER_DID. Updated in place if it differs.

profileManager.managed[]

{ profileId, displayName, branding? }

Profiles with no seed of their own; act as them with --as. displayName is updated in place if it differs. With a learncard-hosted signer, each also gets its own hosted signing authority registered (so API tokens can sign as it).

serviceAccounts[]

{ name, scopes[], expiresAt? }

One auth grant + API token each. Tokens go to --secrets-out as NAME=… (upper-cased, -→_; normalized keys must be unique). Missing token keys are re-issued. Scope/expiry drift errors with a revoke command before replacement; dry-run reports drifted.

webhooks[].url

https URL

Not registered on the network (webhooks are per issuance). The first is saved as WEBHOOK_URL in .env for doctor and your code.

branding (on issuer and on each managed[] entry) — every field optional; only listed fields are compared, display is merged not replaced:

Field
Type
Notes

image, heroImage

https URL

Local paths are rejected with a hint; host the file and use its URL.

shortBio

string ≤280

bio, websiteLink

string / URL

type

organization | service | person

display.*Color

#RRGGBB

backgroundColor, fontColor, accentColor, accentFontColor, idBackgroundColor

display.*Image, display.fade*, display.repeat*

https URL / boolean

backgroundImage, idBackgroundImage and their fade/repeat toggles

Files the CLI keeps

File
Holds

.env

SECURE_SEED, PROFILE_ID, NETWORK_URL, plus per-network facts org apply records (SIGNING_AUTHORITY_*, ORG_PROFILE_MANAGER_DID, WEBHOOK_URL, TEMPLATE_URI). Mode 0600, gitignored.

secrets.env (or --secrets-out)

Service-account tokens for your backend. Mode 0600, gitignored. org apply --secrets-out reads existing keys to determine whether a token needs re-issuing.

.learncard/<network>/

Created by promote: a sibling project folder for the other network.

Interactive REPL

LearnCard CLI is also an easy to use node REPL that instantiates a Learn Card wallet for you and gives you all the tools you need to easily play around with the Learn Card SDK!

Usage

Holder Continuity Export

The CLI also provides REPL helpers from @learncard/holder-continuity for holder-controlled continuity exports. These helpers create a standard ZIP with a readable manifest and encrypted payload files for keys, credentials, presentations, consent records, and status-list snapshots.

getLearnCardBundlePassword() prompts without echoing the password into the REPL, which avoids saving it in REPL history. You can still pass a password string directly for local scripts.

restoreLearnCardFromBundle(...) decrypts the exported seed and returns a wallet with the original DID. It does not upload bundle payloads or recreate index records; use importLearnCardBundle(...) when copying credentials into another wallet.

If you omit the first argument, the CLI exports the default learnCard wallet it created at startup:

Lower-level helpers are also available in the REPL:

For the data model and portability caveats, see Holder Continuity and the @learncard/holder-continuity package BUNDLE_SPEC.md.

Getting Started

Run npx @learncard/cli to boot up the CLI - you should see this screen in your terminal!

From within the CLI, you should be able to start playing around with a basic LearnCard. When the CLI boots up, it creates a default LearnCard called learnCard that you can interact with.

Basic Usage

View your wallet's DID

One of the easiest ways to interact with your LearnCard is to get its DID:

If your LearnCard is initialized to support more DID methods, such as did:web, you could retrieve the corresponding DID through this function.

Basic Verifiable Credential Issuance & Verification Flow

Once the CLI has booted up, you can start issuing credentials. Try a basic Verifiable Credential issuance and verification flow, for example:

Basic Verifiable Presentation Issuance & Verification Flow

Now, take the signedVerifiableCredential you created in the VC issuance flow above, and try wrapping it into a Verifiable Presentation, and verifying it.

Initialize more LearnCards

At any point, you can initialize additional LearnCards in the CLI, which can be helpful for testing cross-wallet flows:

Check out the docs on initializing LearnCards for more ways to create a LearnCard.

And beyond!

There is a ton of functionality exposed through the CLI. Explore the Usage Examples in LearnCard Wallet SDK:

Methods

Last updated

Was this helpful?