Skip to content

Commit

Permalink
Replace LTO credential plugin with credential manager.
Browse files Browse the repository at this point in the history
Seems like this is the way intended by Veramo, but the implementation is incomplete.
`agent.credentialStatusGenerate()` needs to be called separately.
  • Loading branch information
jasny committed Jul 26, 2023
1 parent fa2a764 commit a4d8da9
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 77 deletions.
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from './lto-did-provider';
export * from './lto-credential-plugin';
export * from './lto-credential-status-manager';
export * from './convert';
Original file line number Diff line number Diff line change
@@ -1,32 +1,25 @@
import {
IAgentPlugin,
IAgentPluginSchema,
ICreateVerifiableCredentialArgs,
ICredentialPlugin,
IssuerAgentContext,
VerifiableCredential,
IVerifyCredentialArgs,
IVerifyResult,
VerifierAgentContext,
ICredentialStatusManager,
CredentialPayload,
CredentialStatusGenerateArgs,
CredentialStatusUpdateArgs,
CredentialStatusReference,
CredentialPayload,
IAgentContext,
CredentialStatusUpdateArgs,
ICredentialStatusManager,
IDIDManager,
IKey,
IIdentifier,
IssuerType,
IAgentContext,
IAgentPlugin,
IKey,
IKeyManager,
IssuerType,
TAgent,
VerifiableCredential,
} from '@veramo/core';
import canonicalize from 'canonicalize';
import { sha256 } from '@noble/hashes/sha256';
import { base58 } from '@scure/base';
import { LtoConnection, LtoOptions } from './lto-connection';
import { Statement } from '@ltonetwork/lto';
import { ofKey } from './convert';
import { TAgent } from '@veramo/core/src/types/IAgent';

interface LtoCredentialStatusGenerateArgs extends CredentialStatusGenerateArgs {
type: 'LtoStatusRegistry2023';
Expand Down Expand Up @@ -55,37 +48,26 @@ enum StatusStatementType {
acknowledge = 0x15,
}

export class LtoCredentialPlugin implements IAgentPlugin {
readonly _createVerifiableCredential: ICredentialPlugin['createVerifiableCredential'];
readonly _verifyCredential: ICredentialPlugin['verifyCredential'];
readonly methods: ICredentialPlugin & ICredentialStatusManager;
readonly schema?: IAgentPluginSchema;
export class LtoCredentialStatusManager implements IAgentPlugin {
readonly methods: ICredentialStatusManager;
readonly schema = {
components: {
schemas: undefined,
methods: undefined,
},
};

readonly lto: LtoConnection;
readonly addCredentialStatus: boolean;
readonly issueStatement: boolean;

constructor(
plugin: { methods: ICredentialPlugin; schema?: IAgentPluginSchema },
options: LtoOptions & { addCredentialStatus?: boolean; issueStatement?: boolean },
) {
const { methods, schema } = plugin;

constructor(options: LtoOptions & { issueStatement?: boolean }) {
this.methods = {
...methods,
createVerifiableCredential: this.createVerifiableCredential.bind(this),
verifyCredential: this.verifyCredential.bind(this),
credentialStatusGenerate: this.credentialStatusGenerate.bind(this),
credentialStatusUpdate: this.credentialStatusUpdate.bind(this),
credentialStatusTypes: this.credentialStatusTypes.bind(this),
};
this._createVerifiableCredential = methods.createVerifiableCredential;
this._verifyCredential = methods.verifyCredential;

this.schema = schema;

this.lto = new LtoConnection(options);
this.addCredentialStatus = options.addCredentialStatus ?? false;
this.issueStatement = options.issueStatement ?? true;
}

Expand Down Expand Up @@ -123,52 +105,13 @@ export class LtoCredentialPlugin implements IAgentPlugin {
return sha256(canonicalize(rest) as string);
}

async createVerifiableCredential(
args: ICreateVerifiableCredentialArgs,
context: IssuerAgentContext,
): Promise<VerifiableCredential> {
if (this.addCredentialStatus) {
args.credential.credentialStatus = await this.credentialStatusGenerate(
{ type: 'LtoStatusRegistry2023', ...args },
context,
);
}

return this._createVerifiableCredential(args, context);
}

async verifyCredential(args: IVerifyCredentialArgs, context: VerifierAgentContext): Promise<IVerifyResult> {
const result = await this._verifyCredential(args, context);

const { credential } = args;

if (
result.verified &&
typeof credential !== 'string' &&
credential.credentialStatus?.type === 'LtoStatusRegistry2023'
) {
const id = this.credentialStatusId(credential);

if (credential.credentialStatus.id !== base58.encode(id)) {
result.verified = false;
result.error = {
errorCode: 'invalid_credential_status_id',
message:
'invalid_credential_status_id: ' +
'Credential status id is not a base58 encoded sha256 hash of the credential',
};
}
}

return result;
}

async credentialStatusGenerate(
args: LtoCredentialStatusGenerateArgs,
context?: ManagerAgentContext,
): Promise<CredentialStatusReference> {
const { type, credential } = args;
if (type !== 'LtoStatusRegistry2023') throw new Error('Unsupported credential status type');
if (!credential) throw new Error('No credential supplied');

const id = this.credentialStatusId(credential);

Expand Down

0 comments on commit a4d8da9

Please sign in to comment.