buildW3cCredentialwithHashes function
Builds a credential conform to W3C-Standard, which includes all hashes a
plaintext-credential credential
contains.
issuerInformation
is a valid json Object (dart string or map) containing additional Information about the issuer, e.g its homepage or name.
revocationRegistryAddress
is a valid Ethereum-Address of a SmartContract capable of showing the revocation Status of the credential.
Implementation
String buildW3cCredentialwithHashes(dynamic credential, String? issuerDid,
{dynamic type,
dynamic context,
dynamic issuerInformation,
DateTime? validUntil,
String? revocationRegistryAddress}) {
var plaintextMap = credentialToMap(credential);
var hashCred =
_collectHashes(credential, id: plaintextMap['id'], firstLevel: true);
List<String> credTypes = [];
credTypes.add('VerifiableCredential');
if (type != null) {
if (type is String) {
if (type != 'VerifiableCredential') credTypes.add(type);
} else if (type is List<String>) {
type.remove('VerifiableCredential');
credTypes.addAll(type);
} else {
throw Exception('type has unknown datatype');
}
}
List<dynamic> credContext = [];
credContext.add('https://www.w3.org/2018/credentials/v1');
if (context != null) {
if (context is String) {
if (context != 'https://www.w3.org/2018/credentials/v1') {
credContext.add(context);
}
} else if (context is List<String>) {
if (context.contains('https://www.w3.org/2018/credentials/v1')) {
context.remove('https://www.w3.org/2018/credentials/v1');
}
credContext += context;
} else if (context is Map) {
credContext.add(context);
} else if (context is List) {
credContext += context;
} else {
throw Exception('context has unknown datatype');
}
}
// adding context of Plaintext-credential
var plaintextCredMap = credentialToMap(credential);
if (plaintextCredMap.containsKey('@context')) {
var context = plaintextCredMap['@context'];
if (context is List) {
for (var element in context) {
if (!credContext.contains(element)) {
credContext.add(element);
}
}
} else if (context is String) {
if (!credContext.contains(context)) credContext.add(context);
} else {
throw Exception('@context has unsupported type');
}
}
var issuerInfo = {};
if (issuerInformation != null) {
issuerInfo = credentialToMap(issuerInformation);
issuerInfo['id'] = issuerDid;
}
var w3cCred = {
'@context': credContext,
'type': credTypes,
'credentialSubject': jsonDecode(hashCred),
'issuer': issuerInfo.isEmpty ? issuerDid : issuerInfo,
'issuanceDate': DateTime.now().toUtc().toIso8601String()
};
if (validUntil != null) {
w3cCred['expirationDate'] = validUntil.toIso8601String();
}
if (revocationRegistryAddress != null) {
var credStatus = {
'id': revocationRegistryAddress,
'type': 'EthereumRevocationList'
};
w3cCred['credentialStatus'] = credStatus;
}
return jsonEncode(w3cCred);
}