package arbitrum 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 Arbitrum-specific behavior using the shared EVM logic. type Driver struct { logger mlogger.Logger } func New(logger mlogger.Logger) *Driver { return &Driver{logger: logger.Named("arbitrum")} } func (d *Driver) Name() string { return "arbitrum" } 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)