Example #1
0
        /// <inheritdoc />
        public async Task <(CredentialIssueMessage, CredentialRecord)> CreateCredentialAsync(IAgentContext agentContext,
                                                                                             string credentialId, IEnumerable <CredentialPreviewAttribute> values)
        {
            var credentialRecord = await GetAsync(agentContext, credentialId);

            if (credentialRecord.State != CredentialState.Requested)
            {
                throw new AriesFrameworkException(ErrorCode.RecordInInvalidState,
                                                  $"Credential state was invalid. Expected '{CredentialState.Requested}', found '{credentialRecord.State}'");
            }
            if (values != null && values.Any())
            {
                credentialRecord.CredentialAttributesValues = values;
            }

            var definitionRecord =
                await SchemaService.GetCredentialDefinitionAsync(agentContext.Wallet,
                                                                 credentialRecord.CredentialDefinitionId);

            if (credentialRecord.ConnectionId != null)
            {
                var connection = await ConnectionService.GetAsync(agentContext, credentialRecord.ConnectionId);

                if (connection.State != ConnectionState.Connected)
                {
                    throw new AriesFrameworkException(ErrorCode.RecordInInvalidState,
                                                      $"Connection state was invalid. Expected '{ConnectionState.Connected}', found '{connection.State}'");
                }
            }

            var(issuedCredential, revocationRecord) = await IssueCredentialSafeAsync(agentContext, definitionRecord,
                                                                                     credentialRecord);

            if (definitionRecord.SupportsRevocation)
            {
                var provisioning = await ProvisioningService.GetProvisioningAsync(agentContext.Wallet);

                var paymentInfo =
                    await PaymentService.GetTransactionCostAsync(agentContext, TransactionTypes.REVOC_REG_ENTRY);

                if (issuedCredential.RevocRegDeltaJson != null)
                {
                    await LedgerService.SendRevocationRegistryEntryAsync(
                        context : agentContext,
                        issuerDid : provisioning.IssuerDid,
                        revocationRegistryDefinitionId : revocationRecord.Id,
                        revocationDefinitionType : "CL_ACCUM",
                        value : issuedCredential.RevocRegDeltaJson,
                        paymentInfo : paymentInfo);
                }

                // Store data relevant for credential revocation
                credentialRecord.CredentialRevocationId = issuedCredential.RevocId;
                credentialRecord.RevocationRegistryId   = revocationRecord.Id;

                if (paymentInfo != null)
                {
                    await RecordService.UpdateAsync(agentContext.Wallet, paymentInfo.PaymentAddress);
                }
            }

            await credentialRecord.TriggerAsync(CredentialTrigger.Issue);

            await RecordService.UpdateAsync(agentContext.Wallet, credentialRecord);

            var threadId = credentialRecord.GetTag(TagConstants.LastThreadId);

            var credentialMsg = new CredentialIssueMessage(agentContext.UseMessageTypesHttps)
            {
                Credentials = new[]
                {
                    new Attachment
                    {
                        Id       = "libindy-cred-0",
                        MimeType = CredentialMimeTypes.ApplicationJsonMimeType,
                        Data     = new AttachmentContent
                        {
                            Base64 = issuedCredential.CredentialJson
                                     .GetUTF8Bytes()
                                     .ToBase64String()
                        }
                    }
                }
            };

            credentialMsg.ThreadFrom(threadId);
            return(credentialMsg, credentialRecord);
        }
Example #2
0
        /// <inheritdoc />
        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 AriesFrameworkException(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);

            if (credential.ConnectionId != null)
            {
                var connection = await ConnectionService.GetAsync(agentContext, credential.ConnectionId);

                if (connection.State != ConnectionState.Connected)
                {
                    throw new AriesFrameworkException(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 provisioning = await ProvisioningService.GetProvisioningAsync(agentContext.Wallet);

                var paymentInfo = await PaymentService.GetTransactionCostAsync(agentContext, TransactionTypes.REVOC_REG_ENTRY);

                await LedgerService.SendRevocationRegistryEntryAsync(
                    context : agentContext,
                    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);
        }