Migration Guide
Did you upgrade and something broke? Here's how to fix it!
We try not to needlessly add breaking changes, but sometimes it can happen! To find out how to migrate between versions, follow this guide.
“Love doesn't just sit there, like a stone, it has to be made, like bread; remade all the time, made new.” - Ursula Le Guin, the Lathe of Heaven
8.0 -> 9.0
BREAKING CHANGE: @learncard/core package split
Breaking Changes
initLearnCard
is no longer exported by@learncard/core
, as it is now the responsibility of@learncard/init
The didkit wasm binary is no longer exported by
@learncard/core
, as it is now the responsibility of@learncard/init
@learncard/network-plugin
and@learncard/did-web-plugin
no longer export their own version ofinitLearnCard
, and are instead now proper instantiation targets from@learncard/init
Migration Steps
For the most part, you can just rename @learncard/core
to @learncard/init
, and everything should just work, with the exceptions listed above! In the rare case that doesn't immediately work, you may need to import something directly from the plugin itself, such as the case with the didkit wasm binary.
Notes
With this change, @learncard/core
becomes version 9.0, however it also becomes much less public facing compared to the newly released @learncard/init
(version 1.0). This documentation will continue to use the @learncard/core
versioning.
7.0 -> 8.0
BREAKING CHANGE: Control Planes Overhaul
Breaking Changes
Universal Wallets are now returned directly by
initLearnCard
, rather than a wrapped object.This means you can now call
addPlugin
directly on the return value ofinitLearnCard
:
Universal Wallets now implement Control Planes as well as just methods - These are top-level objects with standardized functions that allow plugins/consumers access to a unified interface for common operations. When it makes sense, a specific plugin implementing a plane can also be chosen, such as choosing where to store a credential when uploading. - There are currently five planes, with more planned for the future:
Read, which implements
get
get
simply resolves a URI to a VC
Store, which implements
upload
and (optionally)uploadMany
upload
stores a VC and returns a URI that can be resolveduploadMany
stores an array of VCs, returning an array of URIs that can be resolved
Index, which implements
get
,add
,update
, andremove
get
returns a list of the holder's credential objects (currently namedIDXCredential
s)These objects contain (at a minimum) an
id
and auri
that can be resolved to a VC
add
adds a credential to the holder's listupdate
updates an object in the holder's listremove
removes an object from the holder's list
Cache, which implements
getIndex
,setIndex
,flushIndex
,getVc
,setVc
, andflushVc
getIndex
returns the hodler's credential list as it exists in the cachesetIndex
sets the holder's credential list in the cacheflushIndex
emptys the holder's credential list cachegetVc
returns a VC for a URI if it exists in the cachesetVc
sets a VC for a URI in the cacheflushVc
emptys all VCs from the cache
ID, which implements
did
andkeypair
did
is identical to the previouswallet.did
method, returning a did for a given methodkeypair
is identical to the previouswallet.keypair
method, returning a JWK for a given cryptographic algorithm
Plugins implement planes via the second generic parameter to the
Plugin
typeFor example, a plugin implementing the Read and Store planes would be typed like this:
Plugin<'Test', 'read' | 'store'>
Plugins may continue to expose methods the same way they have, instead using the third generic parameter instead of the second:
For example, a plugin implementing the
getSubjectDid
method would be typed like this:Plugin<'Test', any, { getSubjectDid: (did?: string) => string }>
Plugins may depend on wallets that implement planes/methods in the same way
For example, a wallet implementing the id plane and the
getSubjectDid
method may be typed like this:Wallet<any, 'id', { getSubjectDid: (did?: string) => string }>
The
pluginMethods
key has been renamed tomethods
when creating a plugin, andinvoke
when calling them from a walletThe old
LearnCard
type has been removedThe
Wallet
type has been renamed toLearnCard
generateWallet
has been renamed togenerateLearnCard
This function should now be considered private. If you'd like to construct a fully custom LearnCard, please use
initLearnCard({ custom: true })
instead
The
did
method now has had its type loosened to juststring
The
verifyCredential
method now returns aVerificationCheck
directly, unless you explicitly ask for the prettified version via a flagI.e.
wallet.verifyCredential(vc)
is nowc(vc, {}, true)
The
name
field is now required for plugins, and they may optionally specify adisplayName
anddescription
walletFromKey
has been renamed tolearnCardFromSeed
walletFromApiUrl
has been renamed tolearnCardFromApiUrl
emptyWallet
has been renamed toemptyLearnCard
Migration Steps
Migration Steps
For the most part, you can simply rename calls and everything will just work
wallet.did
is nowwallet.id.did
wallet.keypair
is nowwallet.id.keypair
wallet.newCredential
is nowwallet.invoke.newCredential
wallet.newPresentation
is nowwallet.invoke.newPresentation
wallet.verifyCredential
is nowwallet.invoke.verifyCredential
As per above, if you'd like to retain the same output format, you will need to pass true as the third argument
I.e.
wallet.verifyCredential(vc)
is nowwallet.invoke.verifyCredential(vc, {}, true)
wallet.issueCredential
is nowwallet.invoke.issueCredential
wallet.issuePresentation
is nowwallet.invoke.issuePresentation
wallet.verifyPresentation
is nowwallet.invoke.verifyPresentation
wallet.getCredential
is a bit more complex, as it was actually wrapping two operations:Getting a credential with a given id
Resolving that credential
This can now be replaced with the following code:
If this proves to be too cumbersome, we may add back in the getCredential
method as helper in invoke
wallet.getCredentials
has the same issue aswallet.getCredential
, it can be replaced with the following code:
wallet.getCredentialsList
is nowwallet.index.all.get
wallet.publishCredential
is nowwallet.store.Ceramic.upload
wallet.addCredential
is nowwallet.index.IDX.add
wallet.removeCredential
is nowwallet.index.IDX.remove
wallet.resolveDid
is nowwallet.invoke.resolveDid
wallet.readFromCeramic
is nowwallet.invoke.readContentFromCeramic
wallet.resolveCredential
is nowwallet.read.get
wallet.getTestVc
is nowwallet.invoke.getTestVc
wallet.getTestVp
is nowwallet.invoke.getTestVp
wallet.getEthereumAddress
is nowwallet.invoke.getEthereumAddress
wallet.getBalance
is nowwallet.invoke.getBalance
wallet.getBalanceForAddress
is nowwallet.invoke.getBalanceForAddress
wallet.transferTokens
is nowwallet.invoke.transferTokens
wallet.getCurrentNetwork
is nowwallet.invoke.getCurrentNetwork
wallet.changeNetwork
is nowwallet.invoke.changeNetwork
wallet.addInfuraProjectId
is nowwallet.invoke.addInfuraProjectId
wallet.vpFromQrCode
is nowwallet.invoke.vpFromQrCode
wallet.vpToQrCode
is nowwallet.invoke.vpToQrCode
wallet.installChapiHandler
is nowwallet.invoke.installChapiHandler
wallet.activateChapiHandler
is nowwallet.invoke.activateChapiHandler
wallet.receiveChapiEvent
is nowwallet.invoke.receiveChapiEvent
wallet.storePresentationViaChapi
is nowwallet.invoke.storePresentationViaChapi
wallet.storeCredentialViaChapiDidAuth
is nowwallet.invoke.storeCredentialViaChapiDidAuth
Because the LearnCard
and Wallet
types have changed, if you were using either, you will need to update your code:
Notes
We are moving away from the term "wallet", preferring instead to use the term LearnCard in its place. You may notice that in updated documentation and examples, variables named wallet
have been replaced with the name learnCard
.
Last updated