private async Task <CredentialRecord> UpdateValuesAsync(string credentialId, CredentialIssueMessage credentialIssue, IAgentContext agentContext) { var credentialAttachment = credentialIssue.Credentials.FirstOrDefault(x => x.Id == "libindy-cred-0") ?? throw new ArgumentException("Credential attachment not found"); var credentialJson = credentialAttachment.Data.Base64.GetBytesFromBase64().GetUTF8String(); var jcred = JObject.Parse(credentialJson); var values = jcred["values"].ToObject <Dictionary <string, AttributeValue> >(); var credential = await _credentialService.GetAsync(agentContext, credentialId); credential.CredentialAttributesValues = values.Select(x => new CredentialPreviewAttribute { Name = x.Key, Value = x.Value.Raw, MimeType = CredentialMimeTypes.TextMimeType }).ToList(); await _recordService.UpdateAsync(agentContext.Wallet, credential); return(credential); }
public async Task <(CredentialIssueMessage, CredentialRecord)> CreateCredentialAsync(IAgentContext agentContext, string credentialId, IEnumerable <CredentialPreviewAttribute> values) { var credential = await GetAsync(agentContext, credentialId); if (credential.State != CredentialState.Requested) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Credential state was invalid. Expected '{CredentialState.Requested}', found '{credential.State}'"); } if (values != null && values.Any()) { credential.CredentialAttributesValues = values; } var definitionRecord = await SchemaService.GetCredentialDefinitionAsync(agentContext.Wallet, credential.CredentialDefinitionId); var connection = await ConnectionService.GetAsync(agentContext, credential.ConnectionId); var provisioning = await ProvisioningService.GetProvisioningAsync(agentContext.Wallet); if (connection.State != ConnectionState.Connected) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Connection state was invalid. Expected '{ConnectionState.Connected}', found '{connection.State}'"); } string revocationRegistryId = null; BlobStorageReader tailsReader = null; if (definitionRecord.SupportsRevocation) { var revocationRecordSearch = await RecordService.SearchAsync <RevocationRegistryRecord>( agentContext.Wallet, SearchQuery.Equal(nameof(RevocationRegistryRecord.CredentialDefinitionId), definitionRecord.Id), null, 5); var revocationRecord = revocationRecordSearch.Single(); // TODO: Credential definition can have multiple revocation registries revocationRegistryId = revocationRecord.Id; tailsReader = await TailsService.OpenTailsAsync(revocationRecord.TailsFile); } var issuedCredential = await AnonCreds.IssuerCreateCredentialAsync(agentContext.Wallet, credential.OfferJson, credential.RequestJson, CredentialUtils.FormatCredentialValues(credential.CredentialAttributesValues), revocationRegistryId, tailsReader); if (definitionRecord.SupportsRevocation) { var paymentInfo = await PaymentService.GetTransactionCostAsync(agentContext, TransactionTypes.REVOC_REG_ENTRY); await LedgerService.SendRevocationRegistryEntryAsync( wallet : agentContext.Wallet, pool : await agentContext.Pool, issuerDid : provisioning.IssuerDid, revocationRegistryDefinitionId : revocationRegistryId, revocationDefinitionType : "CL_ACCUM", value : issuedCredential.RevocRegDeltaJson, paymentInfo : paymentInfo); credential.CredentialRevocationId = issuedCredential.RevocId; if (paymentInfo != null) { await RecordService.UpdateAsync(agentContext.Wallet, paymentInfo.PaymentAddress); } } await credential.TriggerAsync(CredentialTrigger.Issue); await RecordService.UpdateAsync(agentContext.Wallet, credential); var threadId = credential.GetTag(TagConstants.LastThreadId); var credentialMsg = new CredentialIssueMessage { Credentials = new [] { new Attachment { Id = "libindy-cred-0", MimeType = CredentialMimeTypes.ApplicationJsonMimeType, Data = new AttachmentContent { Base64 = issuedCredential.CredentialJson .GetUTF8Bytes() .ToBase64String() } } } }; credentialMsg.ThreadFrom(threadId); return(credentialMsg, credential); }
public async Task <string> ProcessCredentialAsync(IAgentContext agentContext, CredentialIssueMessage credential, ConnectionRecord connection) { var credentialAttachment = credential.Credentials.FirstOrDefault(x => x.Id == "libindy-cred-0") ?? throw new ArgumentException("Credential attachment not found"); var credentialJson = credentialAttachment.Data.Base64.GetBytesFromBase64().GetUTF8String(); var credentialJobj = JObject.Parse(credentialJson); var definitionId = credentialJobj["cred_def_id"].ToObject <string>(); var revRegId = credentialJobj["rev_reg_id"]?.ToObject <string>(); var credentialRecord = await this.GetByThreadIdAsync(agentContext, credential.GetThreadId()); if (credentialRecord.State != CredentialState.Requested) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Credential state was invalid. Expected '{CredentialState.Requested}', found '{credentialRecord.State}'"); } var credentialDefinition = await LedgerService.LookupDefinitionAsync(await agentContext.Pool, definitionId); string revocationRegistryDefinitionJson = null; if (!string.IsNullOrEmpty(revRegId)) { // If credential supports revocation, lookup registry definition var revocationRegistry = await LedgerService.LookupRevocationRegistryDefinitionAsync(await agentContext.Pool, revRegId); revocationRegistryDefinitionJson = revocationRegistry.ObjectJson; } var credentialId = await AnonCreds.ProverStoreCredentialAsync( wallet : agentContext.Wallet, credId : null, credReqMetadataJson : credentialRecord.CredentialRequestMetadataJson, credJson : credentialJson, credDefJson : credentialDefinition.ObjectJson, revRegDefJson : revocationRegistryDefinitionJson); credentialRecord.CredentialId = credentialId; credentialRecord.CredentialAttributesValues = null; await credentialRecord.TriggerAsync(CredentialTrigger.Issue); await RecordService.UpdateAsync(agentContext.Wallet, credentialRecord); EventAggregator.Publish(new ServiceMessageProcessingEvent { RecordId = credentialRecord.Id, MessageType = credential.Type, ThreadId = credential.GetThreadId() }); return(credentialRecord.Id); }