private async Task <(IssuerCreateCredentialResult, RevocationRegistryRecord)> IssueCredentialSafeAsync( IAgentContext agentContext, DefinitionRecord definitionRecord, CredentialRecord credentialRecord) { BlobStorageReader tailsReader = null; RevocationRegistryRecord revocationRecord = null; if (definitionRecord.SupportsRevocation) { revocationRecord = await RecordService.GetAsync <RevocationRegistryRecord>(agentContext.Wallet, definitionRecord.CurrentRevocationRegistryId); tailsReader = await TailsService.OpenTailsAsync(revocationRecord.TailsFile); } try { return(await AnonCreds.IssuerCreateCredentialAsync( agentContext.Wallet, credentialRecord.OfferJson, credentialRecord.RequestJson, CredentialUtils.FormatCredentialValues(credentialRecord.CredentialAttributesValues), definitionRecord.CurrentRevocationRegistryId, tailsReader), revocationRecord); } catch (RevocationRegistryFullException) { if (!definitionRecord.RevocationAutoScale) { throw; } } var registryIndex = definitionRecord.CurrentRevocationRegistryId.Split(':').LastOrDefault()?.Split('-').FirstOrDefault(); string registryTag; if (int.TryParse(registryIndex, out var currentIndex)) { registryTag = $"{currentIndex + 1}-{definitionRecord.MaxCredentialCount}"; } else { registryTag = $"1-{definitionRecord.MaxCredentialCount}"; } var(_, nextRevocationRecord) = await SchemaService.CreateRevocationRegistryAsync(agentContext, registryTag, definitionRecord); definitionRecord.CurrentRevocationRegistryId = nextRevocationRecord.Id; await RecordService.UpdateAsync(agentContext.Wallet, definitionRecord); tailsReader = await TailsService.OpenTailsAsync(nextRevocationRecord.TailsFile); return(await AnonCreds.IssuerCreateCredentialAsync( agentContext.Wallet, credentialRecord.OfferJson, credentialRecord.RequestJson, CredentialUtils.FormatCredentialValues(credentialRecord.CredentialAttributesValues), nextRevocationRecord.Id, tailsReader), nextRevocationRecord); }
/// <inheritdoc /> public async Task <(IssuerCreateAndStoreRevocRegResult, RevocationRegistryRecord)> CreateRevocationRegistryAsync( IAgentContext context, string tag, DefinitionRecord definitionRecord) { var tailsHandle = await TailsService.CreateTailsAsync(); var revocationRegistryDefinitionJson = new { issuance_type = "ISSUANCE_BY_DEFAULT", max_cred_num = definitionRecord.MaxCredentialCount }.ToJson(); var revocationRegistry = await AnonCreds.IssuerCreateAndStoreRevocRegAsync( wallet : context.Wallet, issuerDid : definitionRecord.IssuerDid, type : null, tag : tag, credDefId : definitionRecord.Id, configJson : revocationRegistryDefinitionJson, tailsWriter : tailsHandle); var revocationRecord = new RevocationRegistryRecord { Id = revocationRegistry.RevRegId, CredentialDefinitionId = definitionRecord.Id }; // Update tails location URI var revocationDefinition = JObject.Parse(revocationRegistry.RevRegDefJson); var tailsfile = Path.GetFileName(revocationDefinition["value"]["tailsLocation"].ToObject <string>()); var tailsLocation = Url.Combine( AgentOptions.EndpointUri, AgentOptions.RevocationRegistryUriPath, tailsfile); revocationDefinition["value"]["tailsLocation"] = tailsLocation; revocationRecord.TailsFile = tailsfile; revocationRecord.TailsLocation = tailsLocation; //paymentInfo = await paymentService.GetTransactionCostAsync(context, TransactionTypes.REVOC_REG_DEF); await LedgerService.RegisterRevocationRegistryDefinitionAsync( context : context, submitterDid : definitionRecord.IssuerDid, data : revocationDefinition.ToString(), paymentInfo : null); await RecordService.AddAsync(context.Wallet, revocationRecord); await LedgerService.SendRevocationRegistryEntryAsync( context : context, issuerDid : definitionRecord.IssuerDid, revocationRegistryDefinitionId : revocationRegistry.RevRegId, revocationDefinitionType : "CL_ACCUM", value : revocationRegistry.RevRegEntryJson, paymentInfo : null); return(revocationRegistry, revocationRecord); }
/// <inheritdoc /> public virtual async Task <string> CreateCredentialDefinitionAsync(Pool pool, Wallet wallet, string schemaId, string issuerDid, string tag, bool supportsRevocation, int maxCredentialCount, Uri tailsBaseUri) { var definitionRecord = new DefinitionRecord(); var schema = await LedgerService.LookupSchemaAsync(pool, schemaId); var credentialDefinition = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(wallet, issuerDid, schema.ObjectJson, tag, null, new { support_revocation = supportsRevocation }.ToJson()); await LedgerService.RegisterCredentialDefinitionAsync(wallet, pool, issuerDid, credentialDefinition.CredDefJson); definitionRecord.SupportsRevocation = supportsRevocation; definitionRecord.Id = credentialDefinition.CredDefId; definitionRecord.SchemaId = schemaId; if (supportsRevocation) { definitionRecord.MaxCredentialCount = maxCredentialCount; var tailsHandle = await TailsService.CreateTailsAsync(); var revRegDefConfig = new { issuance_type = "ISSUANCE_ON_DEMAND", max_cred_num = maxCredentialCount }.ToJson(); var revocationRegistry = await AnonCreds.IssuerCreateAndStoreRevocRegAsync(wallet, issuerDid, null, "Tag2", credentialDefinition.CredDefId, revRegDefConfig, tailsHandle); // Update tails location URI var revocationDefinition = JObject.Parse(revocationRegistry.RevRegDefJson); var tailsfile = Path.GetFileName(revocationDefinition["value"]["tailsLocation"].ToObject <string>()); revocationDefinition["value"]["tailsLocation"] = new Uri(tailsBaseUri, tailsfile).ToString(); await LedgerService.RegisterRevocationRegistryDefinitionAsync(wallet, pool, issuerDid, revocationDefinition.ToString()); await LedgerService.SendRevocationRegistryEntryAsync(wallet, pool, issuerDid, revocationRegistry.RevRegId, "CL_ACCUM", revocationRegistry.RevRegEntryJson); var revocationRecord = new RevocationRegistryRecord { Id = revocationRegistry.RevRegId, TailsFile = tailsfile, CredentialDefinitionId = credentialDefinition.CredDefId }; await RecordService.AddAsync(wallet, revocationRecord); } await RecordService.AddAsync(wallet, definitionRecord); return(credentialDefinition.CredDefId); }
/// <inheritdoc /> public virtual async Task <string> CreateCredentialDefinitionAsync(IAgentContext context, string schemaId, string issuerDid, string tag, bool supportsRevocation, int maxCredentialCount, Uri tailsBaseUri) { var definitionRecord = new DefinitionRecord(); var schema = await LedgerService.LookupSchemaAsync(await context.Pool, schemaId); var credentialDefinition = await AnonCreds.IssuerCreateAndStoreCredentialDefAsync(context.Wallet, issuerDid, schema.ObjectJson, tag, null, new { support_revocation = supportsRevocation }.ToJson()); var paymentInfo = await paymentService.GetTransactionCostAsync(context, TransactionTypes.CRED_DEF); await LedgerService.RegisterCredentialDefinitionAsync(context : context, submitterDid : issuerDid, data : credentialDefinition.CredDefJson, paymentInfo : paymentInfo); if (paymentInfo != null) { await RecordService.UpdateAsync(context.Wallet, paymentInfo.PaymentAddress); } definitionRecord.SupportsRevocation = supportsRevocation; definitionRecord.Id = credentialDefinition.CredDefId; definitionRecord.SchemaId = schemaId; if (supportsRevocation) { definitionRecord.MaxCredentialCount = maxCredentialCount; var tailsHandle = await TailsService.CreateTailsAsync(); var revRegDefConfig = new { issuance_type = "ISSUANCE_ON_DEMAND", max_cred_num = maxCredentialCount }.ToJson(); var revocationRegistry = await AnonCreds.IssuerCreateAndStoreRevocRegAsync(context.Wallet, issuerDid, null, "Tag2", credentialDefinition.CredDefId, revRegDefConfig, tailsHandle); // Update tails location URI var revocationDefinition = JObject.Parse(revocationRegistry.RevRegDefJson); var tailsfile = Path.GetFileName(revocationDefinition["value"]["tailsLocation"].ToObject <string>()); revocationDefinition["value"]["tailsLocation"] = new Uri(tailsBaseUri, tailsfile).ToString(); paymentInfo = await paymentService.GetTransactionCostAsync(context, TransactionTypes.REVOC_REG_DEF); await LedgerService.RegisterRevocationRegistryDefinitionAsync(context : context, submitterDid : issuerDid, data : revocationDefinition.ToString(), paymentInfo : paymentInfo); if (paymentInfo != null) { await RecordService.UpdateAsync(context.Wallet, paymentInfo.PaymentAddress); } paymentInfo = await paymentService.GetTransactionCostAsync(context, TransactionTypes.REVOC_REG_ENTRY); await LedgerService.SendRevocationRegistryEntryAsync(context : context, issuerDid : issuerDid, revocationRegistryDefinitionId : revocationRegistry.RevRegId, revocationDefinitionType : "CL_ACCUM", value : revocationRegistry.RevRegEntryJson, paymentInfo : paymentInfo); if (paymentInfo != null) { await RecordService.UpdateAsync(context.Wallet, paymentInfo.PaymentAddress); } var revocationRecord = new RevocationRegistryRecord { Id = revocationRegistry.RevRegId, TailsFile = tailsfile, CredentialDefinitionId = credentialDefinition.CredDefId }; await RecordService.AddAsync(context.Wallet, revocationRecord); } await RecordService.AddAsync(context.Wallet, definitionRecord); return(credentialDefinition.CredDefId); }