/// <inheritdoc /> public async Task MakePaymentAsync(IAgentContext agentContext, PaymentRecord paymentRecord, PaymentAddressRecord addressFromRecord = null) { if (paymentRecord.Amount == 0) { throw new AriesFrameworkException(ErrorCode.InvalidRecordData, "Cannot make a payment with 0 amount"); } await paymentRecord.TriggerAsync(PaymentTrigger.ProcessPayment); if (paymentRecord.Address == null) { throw new AriesFrameworkException(ErrorCode.InvalidRecordData, "Payment record is missing an address"); } var provisioning = await provisioningService.GetProvisioningAsync(agentContext.Wallet); if (addressFromRecord == null) { addressFromRecord = await GetDefaultPaymentAddressAsync(agentContext); } await RefreshBalanceAsync(agentContext, addressFromRecord); if (addressFromRecord.Balance < paymentRecord.Amount) { throw new AriesFrameworkException(ErrorCode.PaymentInsufficientFunds, "Address doesn't have enough funds to make this payment"); } var txnFee = await GetTransactionFeeAsync(agentContext, TransactionTypes.XFER_PUBLIC); var paymentResult = await IndyPayments.BuildPaymentRequestAsync( wallet : agentContext.Wallet, submitterDid : null, inputsJson : addressFromRecord.Sources.Select(x => x.Source).ToJson(), outputsJson : new[] { new IndyPaymentOutputSource { Amount = paymentRecord.Amount, Recipient = paymentRecord.Address }, new IndyPaymentOutputSource { Recipient = addressFromRecord.Address, Amount = addressFromRecord.Balance - paymentRecord.Amount - txnFee } }.ToJson(), extra : null); var response = await IndyLedger.SignAndSubmitRequestAsync(await agentContext.Pool, agentContext.Wallet, provisioning.Endpoint.Did, paymentResult.Result); var paymentResponse = await IndyPayments.ParsePaymentResponseAsync(TokenConfiguration.MethodName, response); var paymentOutputs = paymentResponse.ToObject <IList <IndyPaymentOutputSource> >(); var paymentOutput = paymentOutputs.SingleOrDefault(x => x.Recipient == paymentRecord.Address); paymentRecord.ReceiptId = paymentOutput.Receipt; addressFromRecord.Sources = paymentOutputs .Where(x => x.Recipient == addressFromRecord.Address) .Select(x => new IndyPaymentInputSource { Amount = x.Amount, PaymentAddress = x.Recipient, Source = x.Receipt }) .ToList(); await recordService.UpdateAsync(agentContext.Wallet, paymentRecord); await recordService.UpdateAsync(agentContext.Wallet, addressFromRecord); }