From 991c5773a357c8e82449a1b60330d172fc04a981 Mon Sep 17 00:00:00 2001 From: vbasiuk Date: Mon, 13 Jan 2025 18:09:28 +0200 Subject: [PATCH 1/2] fix IsPaymentDone verification - verify signer address --- internal/core/services/payment.go | 80 +++++++++++++++---------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/internal/core/services/payment.go b/internal/core/services/payment.go index 5fc5fad6..767952b2 100644 --- a/internal/core/services/payment.go +++ b/internal/core/services/payment.go @@ -13,7 +13,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/signer/core/apitypes" "github.com/google/uuid" @@ -227,12 +226,6 @@ func (p *payment) VerifyPayment(ctx context.Context, issuerDID w3c.DID, nonce *b return ports.BlockchainPaymentStatusPending, fmt.Errorf("payment Option <%d> not found in payment configuration", paymentReqItem.PaymentOptionID) } - payOptConfItem, err := p.paymentOptionConfigItem(ctx, issuerDID, paymentReqItem) - if err != nil { - log.Error(ctx, "failed to get payment option config", "err", err) - return ports.BlockchainPaymentStatusPending, fmt.Errorf("failed to get payment option config: %w", err) - } - client, err := p.networkResolver.GetEthClientByChainID(core.ChainID(setting.ChainID)) if err != nil { log.Error(ctx, "failed to get ethereum client from resolvers", "err", err, "key", paymentReqItem.SigningKeyID) @@ -244,7 +237,12 @@ func (p *payment) VerifyPayment(ctx context.Context, issuerDID w3c.DID, nonce *b return ports.BlockchainPaymentStatusPending, err } - status, err := p.verifyPaymentOnBlockchain(ctx, client, instance, payOptConfItem.Recipient, nonce, txHash) + signerAddress, err := p.getSignerAddress(ctx, paymentReqItem.SigningKeyID) + if err != nil { + return ports.BlockchainPaymentStatusPending, err + } + + status, err := p.verifyPaymentOnBlockchain(ctx, client, instance, signerAddress, nonce, txHash) if err != nil { log.Error(ctx, "failed to verify payment on blockchain", "err", err, "txHash", txHash, "nonce", nonce) return ports.BlockchainPaymentStatusPending, err @@ -256,58 +254,58 @@ func (p *payment) verifyPaymentOnBlockchain( ctx context.Context, client *eth.Client, contract *eth.PaymentContract, - recipient common.Address, + signerAddress common.Address, nonce *big.Int, txID *string, ) (ports.BlockchainPaymentStatus, error) { txIdProvided := txID != nil && *txID != "" - var receipt *types.Receipt + if txIdProvided { - _, isPending, err := client.GetTransactionByID(ctx, *txID) - if err != nil { - if err.Error() == "not found" { - return ports.BlockchainPaymentStatusCancelled, nil - } - return ports.BlockchainPaymentStatusUnknown, err - } - if isPending { - return ports.BlockchainPaymentStatusPending, nil - } - receipt, err = client.GetTransactionReceiptByID(ctx, *txID) - if err != nil { - return ports.BlockchainPaymentStatusUnknown, err + status, err := handleTransaction(ctx, client, *txID) + if err != nil || status != ports.BlockchainPaymentStatusSuccess { + return status, err } } - if !txIdProvided || receipt.Status == 1 { - isPaid, err := contract.IsPaymentDone(&bind.CallOpts{Context: ctx}, recipient, nonce) - if err != nil { - return ports.BlockchainPaymentStatusPending, nil - } - if isPaid { - return ports.BlockchainPaymentStatusSuccess, nil - } + + isPaid, err := contract.IsPaymentDone(&bind.CallOpts{Context: ctx}, signerAddress, nonce) + if err != nil { return ports.BlockchainPaymentStatusPending, nil } + + if isPaid { + return ports.BlockchainPaymentStatusSuccess, nil + } + return ports.BlockchainPaymentStatusFailed, nil } -// paymentOptionConfigItem finds the payment option config item used to pay using the payment id stored in PaymentRequest database -func (p *payment) paymentOptionConfigItem(ctx context.Context, issuerDID w3c.DID, item *domain.PaymentRequestItem) (*domain.PaymentOptionConfigItem, error) { - paymentReq, err := p.paymentsStore.GetPaymentRequestByID(ctx, issuerDID, item.PaymentRequestID) +func handleTransaction( + ctx context.Context, + client *eth.Client, + txID string, +) (ports.BlockchainPaymentStatus, error) { + _, isPending, err := client.GetTransactionByID(ctx, txID) if err != nil { - return nil, fmt.Errorf("failed to get payment request: %w", err) + if err.Error() == "not found" { + return ports.BlockchainPaymentStatusCancelled, nil + } + return ports.BlockchainPaymentStatusUnknown, err + } + + if isPending { + return ports.BlockchainPaymentStatusPending, nil } - option, err := p.paymentsStore.GetPaymentOptionByID(ctx, &issuerDID, paymentReq.PaymentOptionID) + receipt, err := client.GetTransactionReceiptByID(ctx, txID) if err != nil { - return nil, fmt.Errorf("failed to get payment option: %w", err) + return ports.BlockchainPaymentStatusUnknown, err } - configItem := option.Config.GetByID(item.PaymentOptionID) - if configItem == nil { - return nil, fmt.Errorf("payment option config item for id <%d> not found", item.PaymentOptionID) + if receipt.Status == 1 { + return ports.BlockchainPaymentStatusSuccess, nil } - return configItem, nil + + return ports.BlockchainPaymentStatusFailed, nil } func (p *payment) paymentInfo(ctx context.Context, setting payments.ChainConfig, chainConfig *domain.PaymentOptionConfigItem, nonce *big.Int) (protocol.PaymentRequestInfoDataItem, error) { From cc3f54c9b3a9376512b71de80e7d0666e04d4f7b Mon Sep 17 00:00:00 2001 From: vbasiuk Date: Tue, 14 Jan 2025 10:43:54 +0200 Subject: [PATCH 2/2] rn handlePaymentTransaction --- internal/core/services/payment.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/core/services/payment.go b/internal/core/services/payment.go index 767952b2..6d0ffb72 100644 --- a/internal/core/services/payment.go +++ b/internal/core/services/payment.go @@ -261,7 +261,7 @@ func (p *payment) verifyPaymentOnBlockchain( txIdProvided := txID != nil && *txID != "" if txIdProvided { - status, err := handleTransaction(ctx, client, *txID) + status, err := handlePaymentTransaction(ctx, client, *txID) if err != nil || status != ports.BlockchainPaymentStatusSuccess { return status, err } @@ -279,7 +279,7 @@ func (p *payment) verifyPaymentOnBlockchain( return ports.BlockchainPaymentStatusFailed, nil } -func handleTransaction( +func handlePaymentTransaction( ctx context.Context, client *eth.Client, txID string,