Example #1
0
        private async Task <bool> SignTransactionAsync(
            TezosTransaction tx,
            CancellationToken cancellationToken = default)
        {
            var walletAddress = await _account
                                .GetAddressAsync(
                address : tx.From,
                cancellationToken : cancellationToken)
                                .ConfigureAwait(false);

            return(await _account.Wallet
                   .SignAsync(
                       tx : tx,
                       address : walletAddress,
                       cancellationToken : cancellationToken)
                   .ConfigureAwait(false));
        }
        public override async Task PayAsync(
            Swap swap,
            CancellationToken cancellationToken = default)
        {
            if (!await CheckPayRelevanceAsync(swap, cancellationToken))
            {
                return;
            }

            var lockTimeInSeconds = swap.IsInitiator
                ? DefaultInitiatorLockTimeInSeconds
                : DefaultAcceptorLockTimeInSeconds;

            var paymentTx = await CreatePaymentTxAsync(swap, lockTimeInSeconds, cancellationToken)
                            .ConfigureAwait(false);

            if (paymentTx == null)
            {
                Log.Error("Can't create payment transaction");
                return;
            }

            try
            {
                try
                {
                    await _account.AddressLocker
                    .LockAsync(paymentTx.From, cancellationToken)
                    .ConfigureAwait(false);

                    var address = await _account
                                  .GetAddressAsync(paymentTx.From, cancellationToken)
                                  .ConfigureAwait(false);

                    using var securePublicKey = _account.Wallet
                                                .GetPublicKey(XtzConfig, address.KeyIndex, address.KeyType);

                    // fill operation
                    var(fillResult, isRunSuccess, hasReveal) = await paymentTx
                                                               .FillOperationsAsync(
                        securePublicKey : securePublicKey,
                        tezosConfig : XtzConfig,
                        headOffset : TezosConfig.HeadOffset,
                        cancellationToken : cancellationToken)
                                                               .ConfigureAwait(false);

                    var signResult = await SignTransactionAsync(paymentTx, cancellationToken)
                                     .ConfigureAwait(false);

                    if (!signResult)
                    {
                        Log.Error("Transaction signing error");
                        return;
                    }

                    swap.PaymentTx   = paymentTx;
                    swap.StateFlags |= SwapStateFlags.IsPaymentSigned;

                    await UpdateSwapAsync(swap, SwapStateFlags.IsPaymentSigned, cancellationToken)
                    .ConfigureAwait(false);

                    await BroadcastTxAsync(swap, paymentTx, cancellationToken)
                    .ConfigureAwait(false);
                }
                catch
                {
                    throw;
                }
                finally
                {
                    _account.AddressLocker.Unlock(paymentTx.From);
                }

                swap.PaymentTx   = paymentTx;
                swap.StateFlags |= SwapStateFlags.IsPaymentBroadcast;

                await UpdateSwapAsync(swap, SwapStateFlags.IsPaymentBroadcast, cancellationToken)
                .ConfigureAwait(false);

                // check initiate payment tx confirmation
                var isInitiated =
                    await WaitPaymentConfirmationAsync(paymentTx.Id, InitiationTimeout, cancellationToken)
                    .ConfigureAwait(false);

                if (!isInitiated)
                {
                    Log.Error("Initiation payment tx not confirmed after timeout {@timeout}",
                              InitiationTimeout.Minutes);
                    return;
                }

                swap.StateFlags |= SwapStateFlags.IsPaymentConfirmed;
                await UpdateSwapAsync(swap, SwapStateFlags.IsPaymentConfirmed, cancellationToken)
                .ConfigureAwait(false);
            }
            catch (Exception e)
            {
                Log.Error(e, "Swap payment error for swap {@swapId}", swap.Id);
                return;
            }
        }