Files
sendico/api/gateway/chain/internal/service/gateway/driver/ethereum/driver.go
2025-12-26 14:09:16 +01:00

174 lines
5.7 KiB
Go

package ethereum
import (
"context"
"github.com/ethereum/go-ethereum/core/types"
"github.com/tech/sendico/gateway/chain/internal/service/gateway/driver"
"github.com/tech/sendico/gateway/chain/internal/service/gateway/driver/evm"
"github.com/tech/sendico/gateway/chain/internal/service/gateway/shared"
"github.com/tech/sendico/gateway/chain/storage/model"
"github.com/tech/sendico/pkg/mlogger"
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
"go.uber.org/zap"
)
// Driver implements Ethereum-specific behavior using the shared EVM logic.
type Driver struct {
logger mlogger.Logger
}
func New(logger mlogger.Logger) *Driver {
return &Driver{logger: logger.Named("ethereum")}
}
func (d *Driver) Name() string {
return "ethereum"
}
func (d *Driver) FormatAddress(address string) (string, error) {
d.logger.Debug("Format address", zap.String("address", address))
normalized, err := evm.NormalizeAddress(address)
if err != nil {
d.logger.Warn("Format address failed", zap.String("address", address), zap.Error(err))
}
return normalized, err
}
func (d *Driver) NormalizeAddress(address string) (string, error) {
d.logger.Debug("Normalize address", zap.String("address", address))
normalized, err := evm.NormalizeAddress(address)
if err != nil {
d.logger.Warn("Normalize address failed", zap.String("address", address), zap.Error(err))
}
return normalized, err
}
func (d *Driver) Balance(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet) (*moneyv1.Money, error) {
d.logger.Debug("Balance request",
zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name),
)
driverDeps := deps
driverDeps.Logger = d.logger
result, err := evm.Balance(ctx, driverDeps, network, wallet, wallet.DepositAddress)
if err != nil {
d.logger.Warn("Balance failed",
zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name),
zap.Error(err),
)
} else if result != nil {
d.logger.Debug("Balance result",
zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name),
zap.String("amount", result.Amount),
zap.String("currency", result.Currency),
)
}
return result, err
}
func (d *Driver) NativeBalance(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet) (*moneyv1.Money, error) {
d.logger.Debug("Native balance request",
zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name),
)
driverDeps := deps
driverDeps.Logger = d.logger
result, err := evm.NativeBalance(ctx, driverDeps, network, wallet, wallet.DepositAddress)
if err != nil {
d.logger.Warn("Native balance failed",
zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name),
zap.Error(err),
)
} else if result != nil {
d.logger.Debug("Native balance result",
zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name),
zap.String("amount", result.Amount),
zap.String("currency", result.Currency),
)
}
return result, err
}
func (d *Driver) EstimateFee(ctx context.Context, deps driver.Deps, network shared.Network, wallet *model.ManagedWallet, destination string, amount *moneyv1.Money) (*moneyv1.Money, error) {
d.logger.Debug("Estimate fee request",
zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name),
zap.String("destination", destination),
)
driverDeps := deps
driverDeps.Logger = d.logger
result, err := evm.EstimateFee(ctx, driverDeps, network, wallet, wallet.DepositAddress, destination, amount)
if err != nil {
d.logger.Warn("Estimate fee failed",
zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name),
zap.Error(err),
)
} else if result != nil {
d.logger.Debug("Estimate fee result",
zap.String("wallet_ref", wallet.WalletRef),
zap.String("network", network.Name),
zap.String("amount", result.Amount),
zap.String("currency", result.Currency),
)
}
return result, err
}
func (d *Driver) SubmitTransfer(ctx context.Context, deps driver.Deps, network shared.Network, transfer *model.Transfer, source *model.ManagedWallet, destination string) (string, error) {
d.logger.Debug("Submit transfer request",
zap.String("transfer_ref", transfer.TransferRef),
zap.String("network", network.Name),
zap.String("destination", destination),
)
driverDeps := deps
driverDeps.Logger = d.logger
txHash, err := evm.SubmitTransfer(ctx, driverDeps, network, transfer, source, source.DepositAddress, destination)
if err != nil {
d.logger.Warn("Submit transfer failed",
zap.String("transfer_ref", transfer.TransferRef),
zap.String("network", network.Name),
zap.Error(err),
)
} else {
d.logger.Debug("Submit transfer result",
zap.String("transfer_ref", transfer.TransferRef),
zap.String("network", network.Name),
zap.String("tx_hash", txHash),
)
}
return txHash, err
}
func (d *Driver) AwaitConfirmation(ctx context.Context, deps driver.Deps, network shared.Network, txHash string) (*types.Receipt, error) {
d.logger.Debug("Await confirmation",
zap.String("tx_hash", txHash),
zap.String("network", network.Name),
)
driverDeps := deps
driverDeps.Logger = d.logger
receipt, err := evm.AwaitConfirmation(ctx, driverDeps, network, txHash)
if err != nil {
d.logger.Warn("Await confirmation failed",
zap.String("tx_hash", txHash),
zap.String("network", network.Name),
zap.Error(err),
)
} else if receipt != nil {
d.logger.Debug("Await confirmation result",
zap.String("tx_hash", txHash),
zap.String("network", network.Name),
zap.Uint64("block_number", receipt.BlockNumber.Uint64()),
zap.Uint64("status", receipt.Status),
)
}
return receipt, err
}
var _ driver.Driver = (*Driver)(nil)