adapters

package
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 19, 2026 License: AGPL-3.0 Imports: 17 Imported by: 0

Documentation

Overview

Package adapters provides core off-ramp interfaces and types for USSD integrations with off-ramp providers.

Package adapters provides core implementation for USSD integration with yellowcard off-ramp provider.

Package adapters provides core implementation for USSD integration for stellar treasury transfers.

Package adapters implements USSD integration for user and account services.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ExchangeRate

type ExchangeRate struct {
	FromCurrency string
	ToCurrency   string
	Rate         float64
	BuyRate      float64
	RateID       string
	Locale       string
	UpdatedAt    time.Time
}

ExchangeRate contains current exchange rate info.

type InsufficientBalanceError

type InsufficientBalanceError struct {
	Available float64
	Requested float64
}

InsufficientBalanceError is returned when the YellowCard account balance is too low for a fiat disbursement.

func (*InsufficientBalanceError) Error

func (e *InsufficientBalanceError) Error() string

Error returns a human-readable description of the insufficient balance condition.

type MobileMoneyNetwork

type MobileMoneyNetwork struct {
	ID     string
	Name   string
	Code   string
	Status string
}

MobileMoneyNetwork represents a MoMo operator.

type NetworkInactiveError

type NetworkInactiveError struct {
	NetworkCode string
	NetworkName string
	Country     string
	Status      string
}

NetworkInactiveError is returned when a network is not currently active.

func (*NetworkInactiveError) Error

func (e *NetworkInactiveError) Error() string

Error returns a human-readable description of the inactive network.

type NetworkNotFoundError

type NetworkNotFoundError struct {
	NetworkCode string
	NetworkName string
	Country     string
}

NetworkNotFoundError is returned when a network is not found in YellowCard.

func (*NetworkNotFoundError) Error

func (e *NetworkNotFoundError) Error() string

Error returns a human-readable description of the missing network.

type NoOpOffRampService

type NoOpOffRampService struct{}

NoOpOffRampService is a placeholder implementation that returns mock data.

func (*NoOpOffRampService) GetAvailableBalance

func (s *NoOpOffRampService) GetAvailableBalance(ctx context.Context) (float64, error)

GetAvailableBalance returns a mock balance.

func (*NoOpOffRampService) GetExchangeRate

func (s *NoOpOffRampService) GetExchangeRate(ctx context.Context, currency string) (*ExchangeRate, error)

GetExchangeRate returns a mock rate.

func (*NoOpOffRampService) GetMobileMoneyNetworks

func (s *NoOpOffRampService) GetMobileMoneyNetworks(ctx context.Context, countryCode string) ([]MobileMoneyNetwork, error)

GetMobileMoneyNetworks returns an empty list.

func (*NoOpOffRampService) GetOffRampStatus

func (s *NoOpOffRampService) GetOffRampStatus(ctx context.Context, requestID string) (*OffRampStatus, error)

GetOffRampStatus returns a mock status.

func (*NoOpOffRampService) GetSupportedProviders

func (s *NoOpOffRampService) GetSupportedProviders(ctx context.Context, countryCode string) ([]OffRampProvider, error)

GetSupportedProviders returns an empty list.

func (*NoOpOffRampService) InitiateOffRamp

func (s *NoOpOffRampService) InitiateOffRamp(ctx context.Context, req OffRampRequest) (*OffRampResult, error)

InitiateOffRamp returns a mock off-ramp result.

type OffRampProvider

type OffRampProvider struct {
	ID                      string
	Name                    string
	SupportedMethods        []string
	MinAmount               float64
	MaxAmount               float64
	Currency                string
	Status                  string
	FeeUSD                  float64
	FeeLocal                float64
	EstimatedSettlementTime int
}

OffRampProvider represents an available off-ramp provider.

type OffRampRequest

type OffRampRequest struct {
	LoanID           string
	UserID           string
	RecipientName    string
	AmountUSD        float64
	AmountStroops    int64 // Amount in stroops (USDC * 10^7) for direct settlement crypto transfer
	DestinationPhone string
	CountryCode      string
	IdempotencyKey   string
	NetworkCode      string
	NetworkName      string
	SettlementMethod string // "direct" (default) or "fiat"
}

OffRampRequest contains all data needed to initiate an off-ramp.

type OffRampResult

type OffRampResult struct {
	RequestID        string
	SequenceID       string
	Status           string
	AmountUSD        float64
	AmountLocal      float64
	LocalCurrency    string
	ExchangeRate     float64
	Fee              float64 // Total fee in USD
	FeeLocal         float64 // Total fee in local currency
	EstimatedTime    int
	CreatedAt        time.Time
	SettlementMethod string // "direct" or "fiat" — which mode was actually used
	StellarAddress   string // Stellar address (direct settlement only)
	StellarMemo      string // Stellar memo/walletTag (direct settlement only)
	StellarTxHash    string // USDC transfer tx hash (direct settlement only)
}

OffRampResult contains the result of initiating an off-ramp.

type OffRampService

type OffRampService interface {
	// InitiateOffRamp starts the off-ramp process after validating balance.
	InitiateOffRamp(ctx context.Context, req OffRampRequest) (*OffRampResult, error)

	// GetOffRampStatus checks the status of an off-ramp transaction.
	GetOffRampStatus(ctx context.Context, requestID string) (*OffRampStatus, error)

	// GetSupportedProviders returns available off-ramp providers for a region.
	GetSupportedProviders(ctx context.Context, countryCode string) ([]OffRampProvider, error)

	// GetExchangeRate returns the current exchange rate for a currency.
	GetExchangeRate(ctx context.Context, currency string) (*ExchangeRate, error)

	// GetMobileMoneyNetworks returns available MoMo networks for a country.
	GetMobileMoneyNetworks(ctx context.Context, countryCode string) ([]MobileMoneyNetwork, error)

	// GetAvailableBalance returns the available USD balance for disbursements.
	GetAvailableBalance(ctx context.Context) (float64, error)
}

OffRampService defines the interface for off-ramping funds from crypto to fiat.

type OffRampStatus

type OffRampStatus struct {
	RequestID     string
	SequenceID    string
	Status        string
	AmountLocal   float64
	LocalCurrency string
	CompletedAt   *time.Time
	FailureReason *string
}

OffRampStatus contains status information for an off-ramp.

type StellarSendUSDC

type StellarSendUSDC interface {
	// SendUSDC sends USDC from the treasury wallet to the destination specified in the request.
	SendUSDC(ctx context.Context, req types.SendUSDCRequest) (*types.SendUSDCResponse, error)
}

StellarSendUSDC is the subset of the Stellar service needed for treasury USDC transfers.

type StellarTreasuryTransfer

type StellarTreasuryTransfer struct {
	// contains filtered or unexported fields
}

StellarTreasuryTransfer adapts the Stellar service's SendUSDC method to the TreasuryTransfer interface used by the OffRamp adapter.

func NewStellarTreasuryTransfer

func NewStellarTreasuryTransfer(stellar StellarSendUSDC, logger *slog.Logger) *StellarTreasuryTransfer

NewStellarTreasuryTransfer creates a new TreasuryTransfer backed by the Stellar service.

func (*StellarTreasuryTransfer) SendUSDC

func (t *StellarTreasuryTransfer) SendUSDC(ctx context.Context, destination string, memo string, amount int64) (string, error)

SendUSDC sends USDC from the treasury wallet to a destination address with a memo.

type TreasuryTransfer

type TreasuryTransfer interface {
	// SendUSDC sends USDC from the treasury wallet to a destination Stellar address with a memo.
	// Returns the transaction hash on success.
	SendUSDC(ctx context.Context, destination string, memo string, amount int64) (txHash string, err error)
}

TreasuryTransfer defines the interface for sending USDC from treasury to an external address. This decouples the off-ramp adapter from the Stellar service for testability.

type UserServiceAdapter

type UserServiceAdapter struct {
	// contains filtered or unexported fields
}

UserServiceAdapter adapts the user and account services to implement the USSD UserService interface

func NewUserServiceAdapter

func NewUserServiceAdapter(
	userService user.Service,
	accountService account.Service,
	stellarService stellar.Service,
	db *gorm.DB,
	walletCfg WalletConfig,
) (*UserServiceAdapter, error)

NewUserServiceAdapter creates a new user service adapter

func (*UserServiceAdapter) GetUserWithAccounts

func (a *UserServiceAdapter) GetUserWithAccounts(ctx context.Context, userIDOrPhone string) (any, []any, error)

GetUserWithAccounts retrieves a user and their accounts by ID or phone number

func (*UserServiceAdapter) RegisterUser

func (a *UserServiceAdapter) RegisterUser(ctx context.Context, req *ussd.RegisterUserRequest) (any, []any, error)

RegisterUser registers a new user and auto-creates a Stellar account

type WalletConfig

type WalletConfig struct {
	MasterKey          *bip32.Key
	TreasuryPrivateKey string
	TreasuryPublicKey  string
	USDCIssuer         string
	EnableMultiSig     bool
	LowThreshold       uint32
	MediumThreshold    uint32
	HighThreshold      uint32
}

WalletConfig contains configuration for HD wallet derivation and Stellar account creation

type YellowCardOffRampAdapter

type YellowCardOffRampAdapter struct {
	// contains filtered or unexported fields
}

YellowCardOffRampAdapter implements OffRampService using YellowCard with dual-mode settlement: direct (crypto-funded) and fiat (YC balance-funded).

func NewYellowCardOffRampAdapter

func NewYellowCardOffRampAdapter(cfg YellowCardOffRampConfig) *YellowCardOffRampAdapter

NewYellowCardOffRampAdapter creates a new YellowCard off-ramp adapter.

func (*YellowCardOffRampAdapter) GetAvailableBalance

func (a *YellowCardOffRampAdapter) GetAvailableBalance(ctx context.Context) (float64, error)

GetAvailableBalance returns the available USD balance for disbursements.

func (*YellowCardOffRampAdapter) GetExchangeRate

func (a *YellowCardOffRampAdapter) GetExchangeRate(ctx context.Context, currency string) (*ExchangeRate, error)

GetExchangeRate returns the current USD to local currency rate.

func (*YellowCardOffRampAdapter) GetMobileMoneyNetworks

func (a *YellowCardOffRampAdapter) GetMobileMoneyNetworks(ctx context.Context, countryCode string) ([]MobileMoneyNetwork, error)

GetMobileMoneyNetworks returns available MoMo operators for a country.

func (*YellowCardOffRampAdapter) GetOffRampStatus

func (a *YellowCardOffRampAdapter) GetOffRampStatus(ctx context.Context, requestID string) (*OffRampStatus, error)

GetOffRampStatus retrieves the status of a disbursement from YellowCard.

func (*YellowCardOffRampAdapter) GetSupportedProviders

func (a *YellowCardOffRampAdapter) GetSupportedProviders(ctx context.Context, countryCode string) ([]OffRampProvider, error)

GetSupportedProviders returns available MoMo channels for disbursement.

func (*YellowCardOffRampAdapter) InitiateOffRamp

func (a *YellowCardOffRampAdapter) InitiateOffRamp(ctx context.Context, req OffRampRequest) (*OffRampResult, error)

InitiateOffRamp is the dual-mode orchestrator for loan disbursement.

Settlement flow:

  • "direct" (default): Submit with directSettlement=true → send USDC to YC wallet → YC disburses fiat Failover F1: If YC API call fails → fallback to fiat Failover F2: If Stellar USDC transfer fails → fallback to fiat (USDC still in treasury)
  • "fiat": Check YC balance → submit with forceAccept only → YC disburses from pre-funded balance

type YellowCardOffRampConfig

type YellowCardOffRampConfig struct {
	Adapter      *yellowcard.YellowcardAdapter
	Treasury     TreasuryTransfer // Required for direct settlement mode
	BusinessID   string
	BusinessName string
	Logger       *slog.Logger
}

YellowCardOffRampConfig contains configuration for the YellowCard off-ramp adapter.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL