To make your first wallet, import and call initLearnCard with a unique string that is 64 characters or less:
Good to know: If you do not pass in a string that is 64 characters long. It will be prefixed with zeroes until it is 64 characters. This means that '1' and '001' are identical keys in the eyes of initLearnCard.
Warning: Key input should be a hexadecimal string. If you pass a string that is not valid hex, an error will be thrown!
First, make an unsigned Verifiable Credential. You can do this yourself if you already have that set up for your app, or, if you just need to test out working with this library, you can use the newCredential method to easily create a test VC.
constunsignedVc=learnCard.invoke.newCredential();
To sign (or "issue") that VC, simply call issueCredential
After a credential is signed, the credential may be transferred via an exchange mechanism, where a receiving party can verify it! To verify a signed Verifiable Credential, you can use verifyCredential
constresult=awaitlearnCard.invoke.verifyCredential(signedVc);console.log(result);// { checks: ['proof', 'expiration'], warnings: [], errors: [] }// OR, for a more human readable output:constresult=awaitlearnCard.invoke.verifyCredential(signedVc, {},true);// [// { status: "Success", check: "proof", message: "Valid" },// {// status: "Success",// check: "expiration",// message: "Valid • Does Not Expire"// }// ]
signedVc.expirationDate ='2022-06-10T18:26:57.687Z';constresult=awaitlearnCard.invoke.verifyCredential(signedVc);console.log(result);// {// checks: ['proof'],// warnings: [],// errors: [// 'signature error: Verification equation was not satisfied',// 'expiration error: Credential is expired'// ]// }// OR, for a more human readable output:constresult=awaitlearnCard.invoke.verifyCredential(signedVc, {},true);console.log(result); // [// { // status: "Failed",// check: "signature",// details: "signature error: Verification equation was not satisfied"// },// {// status: "Failed",// check: "expiration",// details: "Invalid • Expired 10 JUN 2022"// },// { status: "Success", check: "proof", message: "Valid" }// ]
Issue/Verify Presentations
Similar to Verifiable Credentials, LearnCard has methods for verifying and issuing Verifiable Presentations:
constunsignedVp=awaitlearnCard.invoke.getTestVp();//Package signed Verifiable Credential into the presentationunsignedVp.verifiableCredential = signedVc;constvp=awaitlearnCard.invoke.issuePresentation(unsignedVp);constresult=awaitlearnCard.invoke.verifyPresentation(vp);console.log(result);// {// checks: ['proof'],// warnings: [],// errors: [],// }
constunsignedVp=awaitlearnCard.invoke.getTestVp();constvp=awaitlearnCard.invoke.issuePresentation(unsignedVp);vp.holder ='did:key:nope';constresult=awaitlearnCard.invoke.verifyPresentation(vp);console.log(result);// {// checks: [],// warnings: [],// errors: ['Unable to filter proofs: Unable to resolve: invalidDid'],// }
Verifiable Presentations enable trusted sharing of one or more claims in a single, verifiable package. Claims may be bundled from one or multiple issuers, and they may consist of the original Verifiable Credential, or a derived "zero-knowledge proof."
As a general principle, you should use Verifiable Presentations when presenting Verifiable Credentials to a verifying party because it proves the relationship between the user or entity presenting the credential, and the credential itself.
Storing/Retrieving Credentials
Credentials can be converted back and forth to URIs, which can be stored per holder using Control Planes. URIs simplify complex processes, such as indexing and caching, over credentials stored in many different locations, such as in IPFS, device storage, or a Decentralized Web Node.
Issuer
constholderDid='did:key:z6MknqnHBn4Rx64gH4Dy1qjmaHjxFjaNG1WioKvQuXKhEKL5'constuvc=learnCard.invoke.newCredential({ subject: holderDid });constvc=awaitlearnCard.invoke.issueCredential(uvc);consturi=awaitlearnCard.store.Ceramic.upload(vc);// *** Send URI to Holder ***
Holder
// *** Receive URI from Issuer ***constcredential=awaitlearnCard.read.get(uri);constresult=awaitlearnCard.invoke.verifyCredential(credential);if (result.errors.length==0) {awaitlearnCard.index.IDX.add({ uri, id:'test' });}// Later, when the Holder would like to see the credential againconstrecords=awaitlearnCard.index.all.get();constrecord=records.find(({ id }) => id ==='test');conststoredCredential=awaitlearnCard.read.get(record.uri);// _.isEqual(credential, storedCredential) = true
The above example uses Ceramic storage, but there are many ways to store and retrieve a credential! Check out theStore control plane for more info and options.