80 lines
2.7 KiB
Go
80 lines
2.7 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync/atomic"
|
|
|
|
"github.com/genex/translate-service/internal/domain/entity"
|
|
"github.com/genex/translate-service/internal/domain/repository"
|
|
)
|
|
|
|
// TranslateService is the application service that orchestrates address mapping
|
|
// operations. It depends on the domain repository interface, not a concrete
|
|
// implementation — following the Dependency Inversion Principle.
|
|
type TranslateService struct {
|
|
repo repository.AddressMappingRepository
|
|
idCounter atomic.Int64
|
|
}
|
|
|
|
// NewTranslateService creates a new TranslateService with the injected repository.
|
|
func NewTranslateService(repo repository.AddressMappingRepository) *TranslateService {
|
|
return &TranslateService{
|
|
repo: repo,
|
|
}
|
|
}
|
|
|
|
// CreateMapping validates inputs via the domain entity factory, persists the
|
|
// mapping through the repository, and returns the created entity.
|
|
func (s *TranslateService) CreateMapping(ctx context.Context, userID, internalAddr, chainAddr, chainType string) (*entity.AddressMapping, error) {
|
|
id := fmt.Sprintf("map-%d", s.idCounter.Add(1))
|
|
|
|
mapping, err := entity.NewAddressMapping(id, userID, internalAddr, chainAddr, chainType)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("domain validation failed: %w", err)
|
|
}
|
|
|
|
if err := s.repo.Save(ctx, mapping); err != nil {
|
|
return nil, fmt.Errorf("failed to save mapping: %w", err)
|
|
}
|
|
|
|
return mapping, nil
|
|
}
|
|
|
|
// InternalToChain resolves an internal platform address to the corresponding
|
|
// on-chain mapping.
|
|
func (s *TranslateService) InternalToChain(ctx context.Context, internalAddr string) (*entity.AddressMapping, error) {
|
|
mapping, err := s.repo.FindByInternalAddress(ctx, internalAddr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("repository lookup failed: %w", err)
|
|
}
|
|
return mapping, nil
|
|
}
|
|
|
|
// ChainToInternal resolves an on-chain address (with chain type) to the
|
|
// corresponding internal platform mapping.
|
|
func (s *TranslateService) ChainToInternal(ctx context.Context, chain, chainAddr string) (*entity.AddressMapping, error) {
|
|
mapping, err := s.repo.FindByChainAddress(ctx, chain, chainAddr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("repository lookup failed: %w", err)
|
|
}
|
|
return mapping, nil
|
|
}
|
|
|
|
// GetByUserID returns all address mappings belonging to the specified user.
|
|
func (s *TranslateService) GetByUserID(ctx context.Context, userID string) ([]*entity.AddressMapping, error) {
|
|
mappings, err := s.repo.FindByUserID(ctx, userID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("repository lookup failed: %w", err)
|
|
}
|
|
return mappings, nil
|
|
}
|
|
|
|
// DeleteMapping removes an address mapping by its ID.
|
|
func (s *TranslateService) DeleteMapping(ctx context.Context, id string) error {
|
|
if err := s.repo.Delete(ctx, id); err != nil {
|
|
return fmt.Errorf("failed to delete mapping: %w", err)
|
|
}
|
|
return nil
|
|
}
|