/// <inheritdoc /> public virtual async Task <string> ProcessCredentialRequestAsync(IAgentContext agentContext, CredentialRequestMessage credentialRequest, ConnectionRecord connection) { Logger.LogInformation(LoggingEvents.StoreCredentialRequest, "Type {0},", credentialRequest.Type); // TODO Handle case when no thread is included //var credential = await this.GetByThreadIdAsync(agentContext, credentialRequest.GetThreadId()); var credential = await Policy.Handle <AriesFrameworkException>() .RetryAsync(3, async(ex, retry) => { await Task.Delay((int)Math.Pow(retry, 2) * 100); }) .ExecuteAsync(() => this.GetByThreadIdAsync(agentContext, credentialRequest.GetThreadId())); var credentialAttachment = credentialRequest.Requests.FirstOrDefault(x => x.Id == "libindy-cred-request-0") ?? throw new ArgumentException("Credential request attachment not found."); if (credential.State != CredentialState.Offered) { throw new AriesFrameworkException(ErrorCode.RecordInInvalidState, $"Credential state was invalid. Expected '{CredentialState.Offered}', found '{credential.State}'"); } credential.RequestJson = credentialAttachment.Data.Base64.GetBytesFromBase64().GetUTF8String(); credential.ConnectionId = connection?.Id; await credential.TriggerAsync(CredentialTrigger.Request); await RecordService.UpdateAsync(agentContext.Wallet, credential); EventAggregator.Publish(new ServiceMessageProcessingEvent { RecordId = credential.Id, MessageType = credentialRequest.Type, ThreadId = credentialRequest.GetThreadId() }); return(credential.Id); }
/// <inheritdoc /> public async Task <(CredentialRequestMessage, CredentialRecord)> CreateRequestAsync(IAgentContext agentContext, string credentialId) { var credential = await GetAsync(agentContext, credentialId); if (credential.State != CredentialState.Offered) { throw new AriesFrameworkException(ErrorCode.RecordInInvalidState, $"Credential state was invalid. Expected '{CredentialState.Offered}', found '{credential.State}'"); } string proverDid = null; if (credential.ConnectionId != null) { var connection = await ConnectionService.GetAsync(agentContext, credential.ConnectionId); proverDid = connection.MyDid; } else { var newDid = await Did.CreateAndStoreMyDidAsync(agentContext.Wallet, "{}"); proverDid = newDid.Did; } var definition = await LedgerService.LookupDefinitionAsync(agentContext, credential.CredentialDefinitionId); var provisioning = await ProvisioningService.GetProvisioningAsync(agentContext.Wallet); var request = await AnonCreds.ProverCreateCredentialReqAsync( wallet : agentContext.Wallet, proverDid : proverDid, credOfferJson : credential.OfferJson, credDefJson : definition.ObjectJson, masterSecretId : provisioning.MasterSecretId); // Update local credential record with new info credential.CredentialRequestMetadataJson = request.CredentialRequestMetadataJson; await credential.TriggerAsync(CredentialTrigger.Request); await RecordService.UpdateAsync(agentContext.Wallet, credential); var threadId = credential.GetTag(TagConstants.LastThreadId); var response = new CredentialRequestMessage(agentContext.UseMessageTypesHttps) { // The comment was required by Aca-py, even though it is declared optional in RFC-0036 // Was added for interoperability Comment = "", Requests = new[] { new Attachment { Id = "libindy-cred-request-0", MimeType = CredentialMimeTypes.ApplicationJsonMimeType, Data = new AttachmentContent { Base64 = request.CredentialRequestJson.GetUTF8Bytes().ToBase64String() } } } }; response.ThreadFrom(threadId); return(response, credential); }