66 lines
2.8 KiB
Go
66 lines
2.8 KiB
Go
package transfer
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/tech/sendico/gateway/chain/storage/model"
|
|
"github.com/tech/sendico/pkg/merrors"
|
|
chainv1 "github.com/tech/sendico/pkg/proto/gateway/chain/v1"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func resolveDestination(ctx context.Context, deps Deps, dest *chainv1.TransferDestination, source *model.ManagedWallet) (model.TransferDestination, error) {
|
|
if dest == nil {
|
|
return model.TransferDestination{}, merrors.InvalidArgument("destination is required")
|
|
}
|
|
managedRef := strings.TrimSpace(dest.GetManagedWalletRef())
|
|
external := strings.TrimSpace(dest.GetExternalAddress())
|
|
if managedRef != "" && external != "" {
|
|
deps.Logger.Warn("Both managed and external destination provided")
|
|
return model.TransferDestination{}, merrors.InvalidArgument("destination must be managed_wallet_ref or external_address")
|
|
}
|
|
if managedRef != "" {
|
|
wallet, err := deps.Storage.Wallets().Get(ctx, managedRef)
|
|
if err != nil {
|
|
deps.Logger.Warn("Destination wallet lookup failed", zap.Error(err), zap.String("managed_wallet_ref", managedRef))
|
|
return model.TransferDestination{}, err
|
|
}
|
|
if !strings.EqualFold(wallet.Network, source.Network) {
|
|
deps.Logger.Warn("Destination wallet network mismatch", zap.String("source_network", source.Network), zap.String("dest_network", wallet.Network))
|
|
return model.TransferDestination{}, merrors.InvalidArgument("destination wallet network mismatch")
|
|
}
|
|
if strings.TrimSpace(wallet.DepositAddress) == "" {
|
|
deps.Logger.Warn("Destination wallet missing deposit address", zap.String("managed_wallet_ref", managedRef))
|
|
return model.TransferDestination{}, merrors.InvalidArgument("destination wallet missing deposit address")
|
|
}
|
|
return model.TransferDestination{
|
|
ManagedWalletRef: wallet.WalletRef,
|
|
Memo: strings.TrimSpace(dest.GetMemo()),
|
|
}, nil
|
|
}
|
|
if external == "" {
|
|
deps.Logger.Warn("Destination external address missing")
|
|
return model.TransferDestination{}, merrors.InvalidArgument("destination is required")
|
|
}
|
|
if deps.Drivers == nil {
|
|
deps.Logger.Warn("Chain drivers missing", zap.String("network", source.Network))
|
|
return model.TransferDestination{}, merrors.Internal("chain drivers not configured")
|
|
}
|
|
chainDriver, err := deps.Drivers.Driver(source.Network)
|
|
if err != nil {
|
|
deps.Logger.Warn("Unsupported chain driver", zap.String("network", source.Network), zap.Error(err))
|
|
return model.TransferDestination{}, merrors.InvalidArgument("unsupported chain for wallet")
|
|
}
|
|
normalized, err := chainDriver.NormalizeAddress(external)
|
|
if err != nil {
|
|
deps.Logger.Warn("Invalid external address", zap.Error(err))
|
|
return model.TransferDestination{}, err
|
|
}
|
|
return model.TransferDestination{
|
|
ExternalAddress: normalized,
|
|
ExternalAddressOriginal: external,
|
|
Memo: strings.TrimSpace(dest.GetMemo()),
|
|
}, nil
|
|
}
|