public async Task <ActionStatus> IssueAttributes(long accountId, IssuanceDetails issuanceDetails) { ActionStatus actionStatus = new ActionStatus { IntegrationType = Key, IntegrationAction = nameof(IssueAttributes), ActionSucceeded = true }; await _semaphoreSlim.WaitAsync(); try { var privateKey = _dataAccessService.GetAccountKeyValue(accountId, "RskSecretKey"); if (string.IsNullOrEmpty(privateKey)) { actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = $"Account {accountId} has no integration with {Key}"; } else { var account = new Account(privateKey); actionStatus.IntegrationAddress = account.Address; var web3 = new Web3(account, _integrationConfiguration.RpcUri); var o10IdentityService = new O10IdentityService(web3, _integrationConfiguration.ContractAddress); var issuers = await o10IdentityService.GetAllIssuersQueryAsync().ConfigureAwait(false); if (!issuers.ReturnValue1.Any(issuers => issuers.Address.Equals(account.Address, StringComparison.InvariantCultureIgnoreCase))) { actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = $"Account with Id {accountId} not registered as an Identity Provider"; } else { List <AttributeRecord> attributeRecords = new List <AttributeRecord> { new AttributeRecord { AttributeName = issuanceDetails.RootAttribute.AttributeName, AssetCommitment = issuanceDetails.RootAttribute.AssetCommitment, BindingCommitment = issuanceDetails.RootAttribute.OriginatingCommitment } }; foreach (var attr in issuanceDetails.AssociatedAttributes) { attributeRecords.Add(new AttributeRecord { AttributeName = attr.AttributeName, AssetCommitment = attr.AssetCommitment, BindingCommitment = attr.BindingToRootCommitment, AttributeId = new BigInteger(0), Version = new BigInteger(0) }); } var balance = await web3.Eth.GetBalance.SendRequestAsync(account.Address).ConfigureAwait(false); var functionIssueAttributesHandler = web3.Eth.GetContractTransactionHandler <IssueAttributesFunction>(); IssueAttributesFunction func = new IssueAttributesFunction { AttributeRecords = attributeRecords }; var esimatedGas = await functionIssueAttributesHandler.EstimateGasAsync(_integrationConfiguration.ContractAddress, func).ConfigureAwait(false); func.Gas = new BigInteger(esimatedGas.ToLong() * 100); if (balance < func.Gas) { actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = "Not enough funds"; } else { var receipt = await o10IdentityService.IssueAttributesRequestAndWaitForReceiptAsync(func.AttributeRecords).ConfigureAwait(false); if (receipt.Failed()) { actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = $"Transaction with hash {receipt.TransactionHash} failed"; } } } } } catch (Exception ex) { _logger.Error($"{nameof(IssueAttributes)} failed for the acccount {accountId}", ex); actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = ex.Message; } finally { _semaphoreSlim.Release(); } return(actionStatus); }
public async Task <ActionStatus> Register(long accountId) { ActionStatus actionStatus = new ActionStatus { IntegrationType = Key, IntegrationAction = "Register", ActionSucceeded = true }; await _semaphoreSlim.WaitAsync(); var privateKey = _dataAccessService.GetAccountKeyValue(accountId, "RskSecretKey"); if (string.IsNullOrEmpty(privateKey)) { var ecKey = Nethereum.Signer.EthECKey.GenerateKey(); privateKey = ecKey.GetPrivateKeyAsBytes().ToHex(); _dataAccessService.SetAccountKeyValues(accountId, new Dictionary <string, string> { { "RskSecretKey", privateKey } }); } var account = new Account(privateKey); actionStatus.IntegrationAddress = account.Address; var web3 = new Web3(account, _integrationConfiguration.RpcUri); var balance = await web3.Eth.GetBalance.SendRequestAsync(account.Address).ConfigureAwait(false); var o10IdentityService = new O10IdentityService(web3, _integrationConfiguration.ContractAddress); try { var issuers = await o10IdentityService.GetAllIssuersQueryAsync().ConfigureAwait(false); if (!issuers.ReturnValue1.Any(issuers => issuers.Address.Equals(account.Address, StringComparison.InvariantCultureIgnoreCase))) { var registerFunctionTransactionHandler = web3.Eth.GetContractTransactionHandler <RegisterFunction>(); RegisterFunction registerFunction = new RegisterFunction { AliasName = _accountsService.GetById(accountId).AccountInfo }; var esimatedGas = await registerFunctionTransactionHandler.EstimateGasAsync(_integrationConfiguration.ContractAddress, registerFunction).ConfigureAwait(false); registerFunction.Gas = new BigInteger(esimatedGas.ToLong() * 1.1); if (balance.Value >= registerFunction.Gas) { var rcpt = await o10IdentityService.RegisterRequestAndWaitForReceiptAsync(registerFunction).ConfigureAwait(false); if (rcpt.Failed()) { actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = $"Transaction with hash {rcpt.TransactionHash} failed"; } } else { actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = "Not enough funds"; } } } catch (Exception ex) { _logger.Error("Failure during communication with RSK network", ex); actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = ex.Message; } finally { _semaphoreSlim.Release(); } return(actionStatus); }
public async Task <ActionStatus> StoreScheme(long accountId, Client.Common.Entities.AttributeDefinition[] attributeDefinitions) { ActionStatus actionStatus = new ActionStatus { IntegrationType = Key, IntegrationAction = nameof(StoreScheme), ActionSucceeded = true }; await _semaphoreSlim.WaitAsync(); try { var privateKey = _dataAccessService.GetAccountKeyValue(accountId, "RskSecretKey"); if (string.IsNullOrEmpty(privateKey)) { actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = $"Account {accountId} has no integration with {Key}"; } else { var account = new Account(privateKey); actionStatus.IntegrationAddress = account.Address; var web3 = new Web3(account, _integrationConfiguration.RpcUri); var o10IdentityService = new O10IdentityService(web3, _integrationConfiguration.ContractAddress); var issuers = await o10IdentityService.GetAllIssuersQueryAsync().ConfigureAwait(false); if (!issuers.ReturnValue1.Any(issuers => issuers.Address.Equals(account.Address, StringComparison.InvariantCultureIgnoreCase))) { actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = $"Account with Id {accountId} not registered as an Identity Provider"; } else { GetSchemeOutputDTO scheme = null; try { scheme = await o10IdentityService.GetSchemeQueryAsync(account.Address).ConfigureAwait(false); } catch (Exception) { scheme = null; } List <AttributeDefinition> definitions = attributeDefinitions.Select(a => new AttributeDefinition { AttributeName = a.AttributeName, AttributeScheme = a.SchemeName, Alias = a.Alias, IsRoot = a.IsRoot }).ToList(); if (scheme?.ReturnValue2.All(a => definitions.Any(d => a.AttributeName == d.AttributeName && a.AttributeScheme == d.AttributeScheme && a.Alias == d.Alias && a.IsRoot == d.IsRoot)) ?? false) { actionStatus.ActionSucceeded = true; } else { var balance = await web3.Eth.GetBalance.SendRequestAsync(account.Address).ConfigureAwait(false); var functionTransactionHandler = web3.Eth.GetContractTransactionHandler <SetSchemeFunction>(); SetSchemeFunction func = new SetSchemeFunction { Definitions = definitions }; var esimatedGas = await functionTransactionHandler.EstimateGasAsync(_integrationConfiguration.ContractAddress, func).ConfigureAwait(false); func.Gas = new BigInteger(esimatedGas.ToLong() * 10); if (balance < func.Gas) { actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = "Not enough funds"; } else { var receipt = await o10IdentityService.SetSchemeRequestAndWaitForReceiptAsync(func).ConfigureAwait(false); if (receipt.Failed()) { actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = $"Transaction with hash {receipt.TransactionHash} failed"; } } } } } } catch (Exception ex) { _logger.Error($"{nameof(StoreScheme)} failed for the acccount {accountId}", ex); actionStatus.ActionSucceeded = false; actionStatus.ErrorMsg = ex.Message; } finally { _semaphoreSlim.Release(); } return(actionStatus); }