data

package
v0.0.0-...-9a6a6cd Latest Latest
Warning

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

Go to latest
Published: Jan 13, 2026 License: Apache-2.0 Imports: 41 Imported by: 0

Documentation

Index

Constants

View Source
const (
	APIKeyPrefix     = "SDP_"
	APIKeySaltSize   = 16
	APIKeySecretSize = 32
)
View Source
const (
	DefaultReceiverRegistrationMessageTemplate = "You have a payment waiting for you from the {{.OrganizationName}}. Click {{.RegistrationLink}} to register."
	DefaultOTPMessageTemplate                  = "{{.OTP}} is your {{.OrganizationName}} verification code."
)
View Source
const (
	// TestnetAlwaysValidOTP is used for testing purposes and will be considered a valid OTP for any testnet account.
	TestnetAlwaysValidOTP = "000000"
	// TestnetAlwaysInvalidOTP is used for testing purposes and will be considered an invalid OTP for any testnet account.
	TestnetAlwaysInvalidOTP = "999999"
)
View Source
const (
	FixtureAssetUSDC = "USDC"
)
View Source
const MaxAttemptsAllowed = 15
View Source
const MaxInstructionsPerDisbursement = 10000

Variables

View Source
var (
	ErrMaxInstructionsExceeded       = errors.New("maximum number of instructions exceeded")
	ErrReceiverVerificationMismatch  = errors.New("receiver verification mismatch")
	ErrReceiverWalletAddressMismatch = errors.New("receiver wallet address mismatch")
)
View Source
var (
	DefaultDisbursementSortField = SortFieldCreatedAt
	DefaultDisbursementSortOrder = SortOrderDESC
	AllowedDisbursementFilters   = []FilterKey{FilterKeyStatus, FilterKeyCreatedAtAfter, FilterKeyCreatedAtBefore}
	AllowedDisbursementSorts     = []SortField{SortFieldName, SortFieldCreatedAt}
)
View Source
var (
	ErrRecordNotFound          = errors.New("record not found")
	ErrRecordAlreadyExists     = errors.New("record already exists")
	ErrMismatchNumRowsAffected = errors.New("mismatch number of rows affected")
	ErrMissingInput            = errors.New("missing input")
)
View Source
var (
	ErrDuplicateEmail       = errors.New("email already in use")
	ErrDuplicatePhoneNumber = errors.New("phone number already in use")
)
View Source
var (
	DefaultReceiverSortField = SortFieldUpdatedAt
	DefaultReceiverSortOrder = SortOrderDESC
	AllowedReceiverFilters   = []FilterKey{FilterKeyStatus, FilterKeyCreatedAtAfter, FilterKeyCreatedAtBefore}
	AllowedReceiverSorts     = []SortField{SortFieldCreatedAt, SortFieldUpdatedAt}
)
View Source
var (
	ErrWalletNotRegistered                   = errors.New("receiver wallet not registered")
	ErrPaymentsInProgressForWallet           = errors.New("receiver wallet has payments in progress")
	ErrUnregisterUserManagedWallet           = errors.New("user managed wallet cannot be unregistered")
	ErrDuplicateWalletAddress                = errors.New("wallet address already in use")
	ErrMemosNotSupportedForContractAddresses = errors.New("memos are not supported for contract addresses")
)
View Source
var (
	RegistrationContactTypeEmail                 = RegistrationContactType{ReceiverContactTypeEmail, false}
	RegistrationContactTypePhone                 = RegistrationContactType{ReceiverContactTypeSMS, false}
	RegistrationContactTypeEmailAndWalletAddress = RegistrationContactType{ReceiverContactTypeEmail, true}
	RegistrationContactTypePhoneAndWalletAddress = RegistrationContactType{ReceiverContactTypeSMS, true}
)
View Source
var (
	ErrWalletNameAlreadyExists           = errors.New("a wallet with this name already exists")
	ErrWalletHomepageAlreadyExists       = errors.New("a wallet with this homepage already exists")
	ErrWalletDeepLinkSchemaAlreadyExists = errors.New("a wallet with this deep link schema already exists")
	ErrInvalidAssetID                    = errors.New("invalid asset ID")
	ErrWalletInUse                       = errors.New("wallet has pending registrations and cannot be deleted")
)

Functions

func AssetColumnNames

func AssetColumnNames(tableReference, resultAlias string, includeDates bool) string

func AssociateAssetWithWalletFixture

func AssociateAssetWithWalletFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, assetID, walletID string)

AssociateAssetWithWalletFixture associates an asset with a wallet

func BuildSetClause

func BuildSetClause(u interface{}) (string, []interface{})

BuildSetClause builds a SET clause for an UPDATE query based on the provided struct and its "db" tags. For instance, given the following struct:

type User struct {
    ID   int64  `db:"id"`
    Name string `db:"name"`
}

The function will return the following string and slice when called with an instance of `User{ID: 1, Name: "John"}`: "id = ?, name = ?", []interface{}{1, "John"}

func CleanupBridgeIntegration

func CleanupBridgeIntegration(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

func CompareVerificationValue

func CompareVerificationValue(hashedValue, verificationValue string) bool

func CreateInstructionsFixture

func CreateInstructionsFixture(t *testing.T, instructions []*DisbursementInstruction) []byte

func CreateMockImage

func CreateMockImage(t *testing.T, width, height int, size ImageSize) image.Image

CreateMockImage creates an RGBA image with the given proportion and size. The size is defined by how many different colors are drawn in the image, so the compression format (jpeg or png) will generate a larger file since the image will have more complexity. Note: Depending on the compression format the image size may vary.

Example creating a file:

img := CreateMockImage(t, 3840, 2160, ImageSizeLarge)
f, err := os.Create("image.png")
require.NoError(t, err)
err = jpeg.Encode(f, img, &jpeg.Options{Quality: jpeg.DefaultQuality}
require.NoError(t, err)

Example in memory image:

img := CreateMockImage(t, 1920, 1080, ImageSizeMedium)
buf := new(bytes.Buffer)
err = png.Encode(buf, img)
require.NoError(t, err)
fmt.Println(img.Bytes())

func CreateShortURLFixture

func CreateShortURLFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, shortCode, url string)

func DeleteAllAssetFixtures

func DeleteAllAssetFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

DeleteAllAssetFixtures deletes all assets in the database

func DeleteAllCircleRecipientsFixtures

func DeleteAllCircleRecipientsFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

func DeleteAllCircleTransferRequests

func DeleteAllCircleTransferRequests(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

func DeleteAllDisbursementFixtures

func DeleteAllDisbursementFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

func DeleteAllFixtures

func DeleteAllFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

func DeleteAllMessagesFixtures

func DeleteAllMessagesFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

func DeleteAllPaymentsFixtures

func DeleteAllPaymentsFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

func DeleteAllReceiverVerificationFixtures

func DeleteAllReceiverVerificationFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

func DeleteAllReceiverWalletsFixtures

func DeleteAllReceiverWalletsFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

func DeleteAllReceiversFixtures

func DeleteAllReceiversFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

func DeleteAllTransactionsFixtures

func DeleteAllTransactionsFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

func DeleteAllWalletFixtures

func DeleteAllWalletFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter)

DeleteAllWalletFixtures deletes all wallets in the database

func DisableDisbursementApproval

func DisableDisbursementApproval(t *testing.T, ctx context.Context, orgModel *OrganizationModel)

DisableDisbursementApproval disables disbursement workflow approval for the given organization.

func DisbursementColumnNames

func DisbursementColumnNames(tableReference, resultAlias string) string

func EnableDisbursementApproval

func EnableDisbursementApproval(t *testing.T, ctx context.Context, orgModel *OrganizationModel)

EnableDisbursementApproval enables disbursement workflow approval for the given organization.

func EnableOrDisableWalletFixtures

func EnableOrDisableWalletFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, enabled bool, walletIDs ...string)

func FromUserRoleArrayToStringArray

func FromUserRoleArrayToStringArray(roles []UserRole) []string

FromUserRoleArrayToStringArray converts an array of UserRole type to an array of string.

func HashVerificationValue

func HashVerificationValue(verificationValue string) (string, error)

func MakeWalletUserManaged

func MakeWalletUserManaged(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, walletID string)

func PaymentColumnNames

func PaymentColumnNames(tableReference, resultAlias string) string

func ReceiverColumnNames

func ReceiverColumnNames(tableReference, resultAlias string) string

func ReceiverWalletColumnNames

func ReceiverWalletColumnNames(tableReference, resultAlias string) string

func SetupDBCP

func SetupDBCP(t *testing.T) db.DBConnectionPool

func UpdateDisbursementInstructionsFixture

func UpdateDisbursementInstructionsFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, disbursementID, fileName string, instructions []*DisbursementInstruction)

func ValidateAllowedIPs

func ValidateAllowedIPs(ips []string) error

func ValidatePermissions

func ValidatePermissions(perms []APIKeyPermission) error

func ValidateRoleMutualExclusivity

func ValidateRoleMutualExclusivity(roles []UserRole) error

ValidateRoleMutualExclusivity checks if the provided roles contain mutually exclusive combinations. Currently, InitiatorUserRole and ApproverUserRole are mutually exclusive.

func WalletColumnNames

func WalletColumnNames(tableReference, resultAlias string, includeDates bool) string

WalletColumnNames returns a comma-separated string of wallet column names for SQL queries. It includes optional date fields based on the provided parameter.

Types

type APIKey

type APIKey struct {
	ID          string            `db:"id" json:"id"`
	Name        string            `db:"name" json:"name"`
	KeyHash     string            `db:"key_hash" json:"-"`
	Salt        string            `db:"salt" json:"-"`
	ExpiryDate  *time.Time        `db:"expiry_date" json:"expiry_date,omitempty"`
	Permissions APIKeyPermissions `db:"permissions" json:"permissions"`
	AllowedIPs  IPList            `db:"allowed_ips" json:"allowed_ips,omitempty"`
	CreatedAt   time.Time         `db:"created_at" json:"created_at"`
	CreatedBy   string            `db:"created_by" json:"created_by,omitempty"`
	UpdatedAt   time.Time         `db:"updated_at" json:"updated_at"`
	UpdatedBy   string            `db:"updated_by" json:"updated_by,omitempty"`
	LastUsedAt  *time.Time        `db:"last_used_at" json:"last_used_at,omitempty"`
	Key         string            `db:"-" json:"key,omitempty"`
}

func (*APIKey) HasPermission

func (a *APIKey) HasPermission(req APIKeyPermission) bool

func (*APIKey) IsAllowedIP

func (a *APIKey) IsAllowedIP(ipStr string) bool

IsAllowedIP checks if an IP falls within AllowedIPs (or none means open)

func (*APIKey) IsExpired

func (a *APIKey) IsExpired() bool

type APIKeyModel

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

func (*APIKeyModel) Delete

func (m *APIKeyModel) Delete(ctx context.Context, id string, createdBy string) error

func (*APIKeyModel) GetAll

func (m *APIKeyModel) GetAll(ctx context.Context, createdBy string) ([]*APIKey, error)

func (*APIKeyModel) GetByID

func (m *APIKeyModel) GetByID(ctx context.Context, id, createdBy string) (*APIKey, error)

func (*APIKeyModel) Insert

func (m *APIKeyModel) Insert(
	ctx context.Context,
	name string,
	permissions []APIKeyPermission,
	allowedIPs []string,
	expiry *time.Time,
	createdBy string,
) (*APIKey, error)

Insert creates, stores, and returns a new APIKey (including the raw key once).

func (*APIKeyModel) Update

func (m *APIKeyModel) Update(ctx context.Context, id, createdBy string, perms APIKeyPermissions, ips []string) (*APIKey, error)

func (*APIKeyModel) ValidateRawKeyAndUpdateLastUsed

func (m *APIKeyModel) ValidateRawKeyAndUpdateLastUsed(ctx context.Context, raw string) (*APIKey, error)

ValidateRawKeyAndUpdateLastUsed validates an API key and updates last_used_at in a single DB call

type APIKeyPermission

type APIKeyPermission string
const (
	// General
	ReadAll  APIKeyPermission = "read:all"
	WriteAll APIKeyPermission = "write:all"

	// Disbursements
	ReadDisbursements  APIKeyPermission = "read:disbursements"
	WriteDisbursements APIKeyPermission = "write:disbursements"

	// Receivers
	ReadReceivers  APIKeyPermission = "read:receivers"
	WriteReceivers APIKeyPermission = "write:receivers"

	// Payments
	ReadPayments  APIKeyPermission = "read:payments"
	WritePayments APIKeyPermission = "write:payments"

	// Organization
	ReadOrganization  APIKeyPermission = "read:organization"
	WriteOrganization APIKeyPermission = "write:organization"

	// Users
	ReadUsers  APIKeyPermission = "read:users"
	WriteUsers APIKeyPermission = "write:users"

	// Wallets
	ReadWallets  APIKeyPermission = "read:wallets"
	WriteWallets APIKeyPermission = "write:wallets"

	// Statistics
	ReadStatistics APIKeyPermission = "read:statistics"

	// Exports
	ReadExports APIKeyPermission = "read:exports"
)

type APIKeyPermissions

type APIKeyPermissions []APIKeyPermission

func (*APIKeyPermissions) Scan

func (p *APIKeyPermissions) Scan(src any) error

func (APIKeyPermissions) Value

func (p APIKeyPermissions) Value() (driver.Value, error)

type Amount

type Amount struct {
	AssetCode      string `json:"asset_code" db:"asset_code"`
	AssetIssuer    string `json:"asset_issuer" db:"asset_issuer"`
	ReceivedAmount string `json:"received_amount" db:"received_amount"`
}

type Asset

type Asset struct {
	ID        string     `json:"id" csv:"-" db:"id"`
	Code      string     `json:"code" db:"code"`
	Issuer    string     `json:"issuer" db:"issuer"`
	CreatedAt *time.Time `json:"created_at,omitempty" csv:"-" db:"created_at"`
	UpdatedAt *time.Time `json:"updated_at,omitempty" csv:"-" db:"updated_at"`
	DeletedAt *time.Time `json:"deleted_at" csv:"-" db:"deleted_at"`
}

func ClearAndCreateAssetFixtures

func ClearAndCreateAssetFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter) []Asset

ClearAndCreateAssetFixtures deletes all assets in the database then creates new assets for testing

func CreateAssetFixture

func CreateAssetFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, code, issuer string) *Asset

func CreateWalletAssets

func CreateWalletAssets(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, walletID string, assetsIDs []string) []Asset

func GetAssetFixture

func GetAssetFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, code string) *Asset

func GetWalletAssetsFixture

func GetWalletAssetsFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, walletID string) []Asset

func (Asset) Equals

func (a Asset) Equals(other Asset) bool

Equals returns true if the asset is the same as the other asset.

func (Asset) EqualsHorizonAsset

func (a Asset) EqualsHorizonAsset(horizonAsset base.Asset) bool

func (Asset) IsNative

func (a Asset) IsNative() bool

IsNative returns true if the asset is the native asset (XLM).

func (Asset) ToBasicAsset

func (a Asset) ToBasicAsset() txnbuild.Asset

type AssetModel

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

func (*AssetModel) ExistsByCodeOrID

func (a *AssetModel) ExistsByCodeOrID(ctx context.Context, codeOrID string) (bool, error)

ExistsByCodeOrID checks if an asset exists by either code or ID.

func (*AssetModel) Get

func (a *AssetModel) Get(ctx context.Context, id string) (*Asset, error)

func (*AssetModel) GetAll

func (a *AssetModel) GetAll(ctx context.Context) ([]Asset, error)

GetAll returns all assets in the database.

func (*AssetModel) GetAssetsPerReceiverWallet

func (a *AssetModel) GetAssetsPerReceiverWallet(ctx context.Context, receiverWallets ...*ReceiverWallet) ([]ReceiverWalletAsset, error)

GetAssetsPerReceiverWallet returns the assets associated with a READY payment for each receiver wallet provided.

func (*AssetModel) GetByCodeAndIssuer

func (a *AssetModel) GetByCodeAndIssuer(ctx context.Context, code, issuer string) (*Asset, error)

GetByCodeAndIssuer returns asset filtering by code and issuer.

func (*AssetModel) GetByWalletID

func (a *AssetModel) GetByWalletID(ctx context.Context, walletID string) ([]Asset, error)

GetByWalletID returns all assets associated with a wallet.

func (*AssetModel) GetOrCreate

func (a *AssetModel) GetOrCreate(ctx context.Context, code, issuer string) (*Asset, error)

func (*AssetModel) Insert

func (a *AssetModel) Insert(ctx context.Context, sqlExec db.SQLExecuter, code string, issuer string) (*Asset, error)

Insert is idempotent and returns a new asset if it doesn't exist or the existing one if it does, clearing the deleted_at field if it was marked as deleted.

func (*AssetModel) SoftDelete

func (a *AssetModel) SoftDelete(ctx context.Context, sqlExec db.SQLExecuter, id string) (*Asset, error)

type BridgeIntegration

type BridgeIntegration struct {
	Status                  BridgeIntegrationStatus `db:"status"`
	KYCLinkID               *string                 `db:"kyc_link_id"`
	CustomerID              *string                 `db:"customer_id"`
	OptedInBy               *string                 `db:"opted_in_by"`
	OptedInAt               *time.Time              `db:"opted_in_at"`
	VirtualAccountID        *string                 `db:"virtual_account_id"`
	VirtualAccountCreatedBy *string                 `db:"virtual_account_created_by"`
	VirtualAccountCreatedAt *time.Time              `db:"virtual_account_created_at"`
	ErrorMessage            *string                 `db:"error_message"`
	CreatedAt               time.Time               `db:"created_at"`
	UpdatedAt               time.Time               `db:"updated_at"`
}

BridgeIntegration represents a Bridge integration record with simplified status tracking.

type BridgeIntegrationInsert

type BridgeIntegrationInsert struct {
	KYCLinkID  *string
	CustomerID string
	OptedInBy  string
}

func (BridgeIntegrationInsert) Validate

func (bii BridgeIntegrationInsert) Validate() error

type BridgeIntegrationModel

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

BridgeIntegrationModel provides database operations for Bridge integration.

func (*BridgeIntegrationModel) Get

Get retrieves the Bridge integration record.

func (*BridgeIntegrationModel) Insert

Insert creates a new Bridge integration record.

func (*BridgeIntegrationModel) Update

Update updates the Bridge integration record.

type BridgeIntegrationStatus

type BridgeIntegrationStatus string

BridgeIntegrationStatus represents the integration status.

const (
	BridgeIntegrationStatusNotEnabled      BridgeIntegrationStatus = "NOT_ENABLED"
	BridgeIntegrationStatusNotOptedIn      BridgeIntegrationStatus = "NOT_OPTED_IN"
	BridgeIntegrationStatusOptedIn         BridgeIntegrationStatus = "OPTED_IN"
	BridgeIntegrationStatusReadyForDeposit BridgeIntegrationStatus = "READY_FOR_DEPOSIT"
	BridgeIntegrationStatusError           BridgeIntegrationStatus = "ERROR"
)

type BridgeIntegrationUpdate

type BridgeIntegrationUpdate struct {
	Status                  *BridgeIntegrationStatus `db:"status"`
	KYCLinkID               *string                  `db:"kyc_link_id"`
	CustomerID              *string                  `db:"customer_id"`
	OptedInBy               *string                  `db:"opted_in_by"`
	OptedInAt               *time.Time               `db:"opted_in_at"`
	VirtualAccountID        *string                  `db:"virtual_account_id"`
	VirtualAccountCreatedBy *string                  `db:"virtual_account_created_by"`
	VirtualAccountCreatedAt *time.Time               `db:"virtual_account_created_at"`
	ErrorMessage            *string                  `db:"error_message"`
}

BridgeIntegrationUpdate represents fields that can be updated.

type CircleRecipient

type CircleRecipient struct {
	ReceiverWalletID  string                `db:"receiver_wallet_id"`
	IdempotencyKey    string                `db:"idempotency_key"`
	CircleRecipientID string                `db:"circle_recipient_id"`
	StellarAddress    string                `db:"stellar_address"`
	StellarMemo       string                `db:"stellar_memo"`
	Status            CircleRecipientStatus `db:"status"`
	CreatedAt         time.Time             `db:"created_at"`
	UpdatedAt         time.Time             `db:"updated_at"`
	SyncAttempts      int                   `db:"sync_attempts"`
	LastSyncAttemptAt time.Time             `db:"last_sync_attempt_at"`
	ResponseBody      []byte                `db:"response_body"`
}

func CreateCircleRecipientFixture

func CreateCircleRecipientFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, insert CircleRecipient) *CircleRecipient

type CircleRecipientModel

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

func (CircleRecipientModel) GetByReceiverWalletID

func (m CircleRecipientModel) GetByReceiverWalletID(ctx context.Context, receiverWalletID string) (*CircleRecipient, error)

func (CircleRecipientModel) Insert

func (m CircleRecipientModel) Insert(ctx context.Context, receiverWalletID string) (*CircleRecipient, error)

func (CircleRecipientModel) ResetRecipientsForRetryIfNeeded

func (m CircleRecipientModel) ResetRecipientsForRetryIfNeeded(ctx context.Context, sqlExec db.SQLExecuter, paymentIDs ...string) ([]*CircleRecipient, error)

ResetRecipientsForRetryIfNeeded resets the status of the circle recipients for the given payment IDs to NULL if the status is not active.

func (CircleRecipientModel) Update

func (m CircleRecipientModel) Update(ctx context.Context, receiverWalletID string, update CircleRecipientUpdate) (*CircleRecipient, error)

type CircleRecipientStatus

type CircleRecipientStatus string
const (
	CircleRecipientStatusPending  CircleRecipientStatus = "pending"
	CircleRecipientStatusActive   CircleRecipientStatus = "active" // means success
	CircleRecipientStatusInactive CircleRecipientStatus = "inactive"
	CircleRecipientStatusDenied   CircleRecipientStatus = "denied"
	CircleRecipientStatusFailed   CircleRecipientStatus = "failed"
)

func CompletedCircleRecipientStatuses

func CompletedCircleRecipientStatuses() []CircleRecipientStatus

func ParseRecipientStatus

func ParseRecipientStatus(statusStr string) (CircleRecipientStatus, error)

func (CircleRecipientStatus) IsCompleted

func (s CircleRecipientStatus) IsCompleted() bool

func (*CircleRecipientStatus) Scan

func (s *CircleRecipientStatus) Scan(value interface{}) error

type CircleRecipientUpdate

type CircleRecipientUpdate struct {
	IdempotencyKey    string                `db:"idempotency_key"`
	CircleRecipientID string                `db:"circle_recipient_id"`
	StellarAddress    string                `db:"stellar_address"`
	StellarMemo       string                `db:"stellar_memo"`
	Status            CircleRecipientStatus `db:"status"`
	SyncAttempts      int                   `db:"sync_attempts"`
	LastSyncAttemptAt time.Time             `db:"last_sync_attempt_at"`
	ResponseBody      []byte                `db:"response_body"`
}

type CircleTransferRequest

type CircleTransferRequest struct {
	IdempotencyKey    string                `db:"idempotency_key"`
	PaymentID         string                `db:"payment_id"`
	CircleTransferID  *string               `db:"circle_transfer_id"`
	CirclePayoutID    *string               `db:"circle_payout_id"`
	Status            *CircleTransferStatus `db:"status"`
	ResponseBody      []byte                `db:"response_body"`
	SourceWalletID    *string               `db:"source_wallet_id"`
	CreatedAt         time.Time             `db:"created_at"`
	UpdatedAt         time.Time             `db:"updated_at"`
	CompletedAt       *time.Time            `db:"completed_at"`
	LastSyncAttemptAt *time.Time            `db:"last_sync_attempt_at"`
	SyncAttempts      int                   `db:"sync_attempts"`
}

func CreateCircleTransferRequestFixture

func CreateCircleTransferRequestFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, insert CircleTransferRequest) *CircleTransferRequest

type CircleTransferRequestModel

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

func (CircleTransferRequestModel) Get

func (CircleTransferRequestModel) GetAll

func (CircleTransferRequestModel) GetCurrentTransfersForPaymentIDs

func (m CircleTransferRequestModel) GetCurrentTransfersForPaymentIDs(ctx context.Context, sqlExec db.SQLExecuter, paymentIDs []string) (map[string]*CircleTransferRequest, error)

func (CircleTransferRequestModel) GetIncompleteByPaymentID

func (m CircleTransferRequestModel) GetIncompleteByPaymentID(ctx context.Context, sqlExec db.SQLExecuter, paymentID string) (*CircleTransferRequest, error)

func (CircleTransferRequestModel) GetOrInsert

func (m CircleTransferRequestModel) GetOrInsert(ctx context.Context, paymentID string) (*CircleTransferRequest, error)

func (CircleTransferRequestModel) GetPendingReconciliation

func (m CircleTransferRequestModel) GetPendingReconciliation(ctx context.Context, sqlExec db.SQLExecuter) ([]*CircleTransferRequest, error)

GetPendingReconciliation returns the pending Circle transfer requests that are in `pending` status and have not reached the maximum sync attempts.

func (CircleTransferRequestModel) Insert

func (CircleTransferRequestModel) Update

type CircleTransferRequestUpdate

type CircleTransferRequestUpdate struct {
	CircleTransferID  string               `db:"circle_transfer_id"`
	CirclePayoutID    string               `db:"circle_payout_id"`
	Status            CircleTransferStatus `db:"status"`
	ResponseBody      []byte               `db:"response_body"`
	SourceWalletID    string               `db:"source_wallet_id"`
	CompletedAt       *time.Time           `db:"completed_at"`
	LastSyncAttemptAt *time.Time           `db:"last_sync_attempt_at"`
	SyncAttempts      int                  `db:"sync_attempts"`
}

type CircleTransferStatus

type CircleTransferStatus string
const (
	CircleTransferStatusPending CircleTransferStatus = "pending"
	CircleTransferStatusSuccess CircleTransferStatus = "complete" // means success
	CircleTransferStatusFailed  CircleTransferStatus = "failed"
)

func CompletedCircleStatuses

func CompletedCircleStatuses() []CircleTransferStatus

func (CircleTransferStatus) IsCompleted

func (s CircleTransferStatus) IsCompleted() bool

type CodeGenerator

type CodeGenerator interface {
	Generate(length int) string
}

type ConfirmedByType

type ConfirmedByType string
const (
	ConfirmedByTypeReceiver ConfirmedByType = "RECEIVER"
	ConfirmedByTypeUser     ConfirmedByType = "USER"
)

type Disbursement

type Disbursement struct {
	ID                                  string                    `json:"id" db:"id"`
	Name                                string                    `json:"name" db:"name"`
	Wallet                              *Wallet                   `json:"wallet,omitempty" db:"wallet"`
	Asset                               *Asset                    `json:"asset,omitempty" db:"asset"`
	Status                              DisbursementStatus        `json:"status" db:"status"`
	VerificationField                   VerificationType          `json:"verification_field,omitempty" db:"verification_field"`
	StatusHistory                       DisbursementStatusHistory `json:"status_history,omitempty" csv:"-" db:"status_history"`
	ReceiverRegistrationMessageTemplate string                    `json:"receiver_registration_message_template" csv:"-" db:"receiver_registration_message_template"`
	FileName                            string                    `json:"file_name,omitempty" csv:"-" db:"file_name"`
	FileContent                         []byte                    `json:"-" csv:"-" db:"file_content"`
	CreatedAt                           *time.Time                `json:"created_at" db:"created_at"`
	UpdatedAt                           *time.Time                `json:"updated_at" db:"updated_at"`
	RegistrationContactType             RegistrationContactType   `json:"registration_contact_type,omitempty" db:"registration_contact_type"`
	*DisbursementStats
}

func CreateDisbursementFixture

func CreateDisbursementFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, model *DisbursementModel, d *Disbursement) *Disbursement

func CreateDraftDisbursementFixture

func CreateDraftDisbursementFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, model *DisbursementModel, insert Disbursement) *Disbursement

type DisbursementInstruction

type DisbursementInstruction struct {
	Phone             string `csv:"phone"`
	Email             string `csv:"email"`
	ID                string `csv:"id"`
	Amount            string `csv:"amount"`
	VerificationValue string `csv:"verification"`
	ExternalPaymentID string `csv:"paymentID"`
	WalletAddress     string `csv:"walletAddress"`
	WalletAddressMemo string `csv:"walletAddressMemo"`
}

func (*DisbursementInstruction) Contact

func (di *DisbursementInstruction) Contact() (string, error)

type DisbursementInstructionModel

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

func NewDisbursementInstructionModel

func NewDisbursementInstructionModel(dbConnectionPool db.DBConnectionPool) *DisbursementInstructionModel

NewDisbursementInstructionModel creates a new DisbursementInstructionModel.

func (DisbursementInstructionModel) ProcessAll

ProcessAll Processes all disbursement instructions and persists the data to the database.

|--- For each line in the instructions:
|    |--- Check if a receiver exists by their contact information (phone, email).
|    |    |--- If a receiver does not exist, create one.
|    |--- For each receiver:
|    |    |--- Check if the receiver verification exists.
|    |    |    |--- If the receiver verification does not exist, create one.
|    |    |    |--- If the receiver verification exists:
|    |    |    |    |--- Check if the verification value matches.
|    |    |    |    |    |--- If the verification value does not match and the verification is confirmed, return an error.
|    |    |    |    |    |--- If the verification value does not match and the verification is not confirmed, update the verification value.
|    |    |    |    |    |--- If the verification value matches, continue.
|    |    |--- [!ReceiverContactType.IncludesWalletAddress] Check if the receiver wallet exists.
|    |    |    |--- If the receiver wallet does not exist, create one.
|    |    |    |--- If the receiver wallet exists and it's not REGISTERED, retry the invitation SMS.
|    |    |--- [ReceiverContactType.IncludesWalletAddress] Register the supplied wallet address
|    |    |--- Delete all previously existing payments tied to this disbursement.
|    |    |--- Create all payments passed in the instructions.

type DisbursementInstructionsOpts

type DisbursementInstructionsOpts struct {
	UserID                  string
	Instructions            []*DisbursementInstruction
	Disbursement            *Disbursement
	DisbursementUpdate      *DisbursementUpdate
	MaxNumberOfInstructions int
}

type DisbursementModel

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

func (*DisbursementModel) CompleteDisbursements

func (d *DisbursementModel) CompleteDisbursements(ctx context.Context, sqlExec db.SQLExecuter, disbursementIDs []string) error

CompleteDisbursements sets disbursements statuses to complete after all payments are processed and successfully sent.

func (*DisbursementModel) CompleteIfNecessary

func (d *DisbursementModel) CompleteIfNecessary(ctx context.Context, sqlExec db.SQLExecuter) ([]string, error)

CompleteIfNecessary completes the disbursement if all payments are in the final state.

func (*DisbursementModel) Count

func (d *DisbursementModel) Count(ctx context.Context, sqlExec db.SQLExecuter, queryParams *QueryParams) (int, error)

Count returns the number of disbursements matching the given query parameters.

func (*DisbursementModel) Delete

func (d *DisbursementModel) Delete(ctx context.Context, sqlExec db.SQLExecuter, disbursementID string) error

Delete deletes a disbursement by ID

func (*DisbursementModel) Get

func (d *DisbursementModel) Get(ctx context.Context, sqlExec db.SQLExecuter, id string) (*Disbursement, error)

func (*DisbursementModel) GetAll

func (d *DisbursementModel) GetAll(ctx context.Context, sqlExec db.SQLExecuter, queryParams *QueryParams, queryType QueryType) ([]*Disbursement, error)

GetAll returns all disbursements matching the given query parameters.

func (*DisbursementModel) GetByName

func (d *DisbursementModel) GetByName(ctx context.Context, sqlExec db.SQLExecuter, name string) (*Disbursement, error)

func (*DisbursementModel) GetWithStatistics

func (d *DisbursementModel) GetWithStatistics(ctx context.Context, id string) (*Disbursement, error)

func (*DisbursementModel) Insert

func (d *DisbursementModel) Insert(ctx context.Context, sqlExec db.SQLExecuter, disbursement *Disbursement) (string, error)

func (*DisbursementModel) Update

func (*DisbursementModel) UpdateStatus

func (d *DisbursementModel) UpdateStatus(ctx context.Context, sqlExec db.SQLExecuter, userID string, disbursementID string, targetStatus DisbursementStatus) error

UpdateStatus updates the status of the given disbursement.

type DisbursementReceiver

type DisbursementReceiver struct {
	ID             string          `json:"id" db:"id"`
	Email          string          `json:"email,omitempty" db:"email"`
	PhoneNumber    string          `json:"phone_number" db:"phone_number"`
	ExternalID     string          `json:"external_id" db:"external_id"`
	ReceiverWallet *ReceiverWallet `json:"receiver_wallet" db:"receiver_wallet"`
	Payment        *Payment        `json:"payment" db:"payment"`
	CreatedAt      time.Time       `json:"created_at" db:"created_at"`
	UpdatedAt      time.Time       `json:"updated_at" db:"updated_at"`
}

type DisbursementReceiverModel

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

func (DisbursementReceiverModel) Count

func (m DisbursementReceiverModel) Count(ctx context.Context, sqlExec db.SQLExecuter, disbursementID string) (int, error)

func (DisbursementReceiverModel) GetAll

func (m DisbursementReceiverModel) GetAll(ctx context.Context, sqlExec db.SQLExecuter, queryParams *QueryParams, disbursementID string) ([]*DisbursementReceiver, error)

type DisbursementStats

type DisbursementStats struct {
	TotalPayments      int    `json:"total_payments" db:"total_payments"`
	SuccessfulPayments int    `json:"total_payments_sent" db:"total_payments_sent"`
	FailedPayments     int    `json:"total_payments_failed" db:"total_payments_failed"`
	CanceledPayments   int    `json:"total_payments_canceled" db:"total_payments_canceled"`
	RemainingPayments  int    `json:"total_payments_remaining" db:"total_payments_remaining"`
	AmountDisbursed    string `json:"amount_disbursed" db:"amount_disbursed"`
	TotalAmount        string `json:"total_amount" db:"total_amount"`
	AverageAmount      string `json:"average_amount" db:"average_amount"`
}

type DisbursementStatus

type DisbursementStatus string
const (
	DraftDisbursementStatus     DisbursementStatus = "DRAFT"
	ReadyDisbursementStatus     DisbursementStatus = "READY"
	StartedDisbursementStatus   DisbursementStatus = "STARTED"
	PausedDisbursementStatus    DisbursementStatus = "PAUSED"
	CompletedDisbursementStatus DisbursementStatus = "COMPLETED"
)

func DisbursementStatuses

func DisbursementStatuses() []DisbursementStatus

DisbursementStatuses returns a list of all possible disbursement statuses

func ToDisbursementStatus

func ToDisbursementStatus(s string) (DisbursementStatus, error)

ToDisbursementStatus converts a string to a DisbursementStatus

func (DisbursementStatus) SourceStatuses

func (status DisbursementStatus) SourceStatuses() []DisbursementStatus

SourceStatuses returns a list of states that the payment status can transition from given the target state

func (DisbursementStatus) State

func (status DisbursementStatus) State() State

func (DisbursementStatus) TransitionTo

func (status DisbursementStatus) TransitionTo(targetState DisbursementStatus) error

TransitionTo transitions the disbursement status to the target state

func (DisbursementStatus) Validate

func (status DisbursementStatus) Validate() error

Validate validates the disbursement status

type DisbursementStatusHistory

type DisbursementStatusHistory []DisbursementStatusHistoryEntry

func (*DisbursementStatusHistory) Scan

func (dsh *DisbursementStatusHistory) Scan(src interface{}) error

Scan implements the sql.Scanner interface.

func (DisbursementStatusHistory) Value

Value implements the driver.Valuer interface.

type DisbursementStatusHistoryEntry

type DisbursementStatusHistoryEntry struct {
	UserID    string             `json:"user_id"`
	Status    DisbursementStatus `json:"status"`
	Timestamp time.Time          `json:"timestamp"`
}

type DisbursementUpdate

type DisbursementUpdate struct {
	ID          string
	FileName    string
	FileContent []byte
}

func (*DisbursementUpdate) Validate

func (du *DisbursementUpdate) Validate() error

type Filter

type Filter struct {
	Key   FilterKey
	Value interface{}
}

func NewFilter

func NewFilter(key FilterKey, value interface{}) Filter

type FilterKey

type FilterKey string
const (
	FilterKeyID               FilterKey = "id"
	FilterKeyStatus           FilterKey = "status"
	FilterKeyReceiverID       FilterKey = "receiver_id"
	FilterKeyPaymentID        FilterKey = "payment_id"
	FilterKeyReceiverWalletID FilterKey = "receiver_wallet_id"
	FilterKeyCompletedAt      FilterKey = "completed_at"
	FilterKeyCreatedAtAfter   FilterKey = "created_at_after"
	FilterKeyCreatedAtBefore  FilterKey = "created_at_before"
	FilterKeySyncAttempts     FilterKey = "sync_attempts"
	FilterKeyPaymentType      FilterKey = "type"
)
const (
	FilterEnabledWallets  FilterKey = "enabled"
	FilterUserManaged     FilterKey = "user_managed"
	FilterSupportedAssets FilterKey = "supported_assets"
	FilterIncludeDeleted  FilterKey = "include_deleted"
)

func IsNull

func IsNull(filterKey FilterKey) FilterKey

IsNull returns `{filterKey} IS NULL`.

func LowerThan

func LowerThan(filterKey FilterKey) FilterKey

LowerThan returns `{filterKey} < ?`.

func (FilterKey) Equals

func (fk FilterKey) Equals() string

func (FilterKey) LowerThan

func (fk FilterKey) LowerThan() string

type IPList

type IPList []string

IPList represents a list of IPs/CIDRs

func (*IPList) Scan

func (ip *IPList) Scan(src any) error

func (IPList) Value

func (ip IPList) Value() (driver.Value, error)

type ImageSize

type ImageSize int
const (
	ImageSizeSmall ImageSize = iota
	ImageSizeMedium
	ImageSizeLarge
)

type LogoType

type LogoType string
const (
	PNGLogoType  LogoType = "png"
	JPEGLogoType LogoType = "jpeg"
)

func (LogoType) ToHTTPContentType

func (lt LogoType) ToHTTPContentType() string

type Message

type Message struct {
	ID               string                `db:"id"`
	Type             message.MessengerType `db:"type"`
	AssetID          *string               `db:"asset_id"`
	ReceiverID       string                `db:"receiver_id"`
	WalletID         string                `db:"wallet_id"`
	ReceiverWalletID *string               `db:"receiver_wallet_id"`
	TextEncrypted    string                `db:"text_encrypted"`
	TitleEncrypted   string                `db:"title_encrypted"`
	Status           MessageStatus         `db:"status"`
	StatusHistory    MessageStatusHistory  `db:"status_history"`
	CreatedAt        time.Time             `db:"created_at"`
	UpdatedAt        time.Time             `db:"updated_at"`
}

func CreateMessageFixture

func CreateMessageFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, m *Message) *Message

type MessageChannelPriority

type MessageChannelPriority []message.MessageChannel

func (*MessageChannelPriority) Scan

func (mcp *MessageChannelPriority) Scan(src interface{}) error

func (MessageChannelPriority) Value

func (mcp MessageChannelPriority) Value() (driver.Value, error)

type MessageInsert

type MessageInsert struct {
	Type             message.MessengerType
	AssetID          *string
	ReceiverID       string
	WalletID         string
	ReceiverWalletID *string
	TextEncrypted    string
	TitleEncrypted   string
	Status           MessageStatus
	StatusHistory    MessageStatusHistory
}

type MessageModel

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

func (*MessageModel) BulkInsert

func (m *MessageModel) BulkInsert(ctx context.Context, sqlExec db.SQLExecuter, newMsgs []*MessageInsert) error

func (*MessageModel) Insert

func (m *MessageModel) Insert(ctx context.Context, newMsg *MessageInsert) (*Message, error)

type MessageStatus

type MessageStatus string
var (
	PendingMessageStatus MessageStatus = "PENDING"
	SuccessMessageStatus MessageStatus = "SUCCESS"
	FailureMessageStatus MessageStatus = "FAILURE"
)

type MessageStatusHistory

type MessageStatusHistory []MessageStatusHistoryEntry

func (*MessageStatusHistory) Scan

func (msh *MessageStatusHistory) Scan(src interface{}) error

Scan implements the sql.Scanner interface.

func (MessageStatusHistory) Value

func (msh MessageStatusHistory) Value() (driver.Value, error)

Value implements the driver.Valuer interface.

type MessageStatusHistoryEntry

type MessageStatusHistoryEntry struct {
	StatusMessage *string       `json:"status_message"`
	Status        MessageStatus `json:"status"`
	Timestamp     time.Time     `json:"timestamp"`
}

type Models

type Models struct {
	Disbursements               *DisbursementModel
	Wallets                     *WalletModel
	Assets                      *AssetModel
	Organizations               *OrganizationModel
	Payment                     *PaymentModel
	Receiver                    *ReceiverModel
	DisbursementInstructions    *DisbursementInstructionModel
	ReceiverVerification        *ReceiverVerificationModel
	ReceiverRegistrationAttempt *ReceiverRegistrationAttemptModel
	ReceiverWallet              *ReceiverWalletModel
	DisbursementReceivers       *DisbursementReceiverModel
	Message                     *MessageModel
	CircleTransferRequests      *CircleTransferRequestModel
	CircleRecipient             *CircleRecipientModel
	BridgeIntegration           *BridgeIntegrationModel
	URLShortener                *URLShortenerModel
	APIKeys                     *APIKeyModel
	DBConnectionPool            db.DBConnectionPool
}

func NewModels

func NewModels(dbConnectionPool db.DBConnectionPool) (*Models, error)

func SetupModels

func SetupModels(t *testing.T) *Models

type Organization

type Organization struct {
	ID                string `json:"id" db:"id"`
	Name              string `json:"name" db:"name"`
	TimezoneUTCOffset string `json:"timezone_utc_offset" db:"timezone_utc_offset"`
	// ReceiverInvitationResendInterval is the time period that SDP will wait to resend the invitation to the receivers that aren't registered.
	// If it's nil means resending the invitation is deactivated.
	ReceiverInvitationResendIntervalDays *int64 `json:"receiver_invitation_resend_interval_days" db:"receiver_invitation_resend_interval_days"`
	// PaymentCancellationPeriodDays is the number of days for a ready payment to be automatically cancelled.
	PaymentCancellationPeriodDays       *int64 `json:"payment_cancellation_period_days" db:"payment_cancellation_period_days"`
	ReceiverRegistrationMessageTemplate string `json:"receiver_registration_message_template" db:"receiver_registration_message_template"`
	// OTPMessageTemplate is the message template to send the OTP code to the receivers validates their identity when registering their wallets.
	// The message may have the template values {{.OTP}} and {{.OrganizationName}}, it will be parsed and the values injected when executing the template.
	// When the {{.OTP}} is not found in the message, it's added at the beginning of the message.
	// Example:
	//	{{.OTP}} OTPMessageTemplate
	OTPMessageTemplate     string                 `json:"otp_message_template" db:"otp_message_template"`
	PrivacyPolicyLink      *string                `json:"privacy_policy_link" db:"privacy_policy_link"`
	IsApprovalRequired     bool                   `json:"is_approval_required" db:"is_approval_required"`
	IsLinkShortenerEnabled bool                   `json:"is_link_shortener_enabled" db:"is_link_shortener_enabled"`
	IsMemoTracingEnabled   bool                   `json:"is_memo_tracing_enabled" db:"is_memo_tracing_enabled"`
	MessageChannelPriority MessageChannelPriority `json:"message_channel_priority" db:"message_channel_priority"`
	MFADisabled            *bool                  `json:"mfa_disabled" db:"mfa_disabled"`
	CAPTCHADisabled        *bool                  `json:"captcha_disabled" db:"captcha_disabled"`
	CreatedAt              time.Time              `json:"created_at" db:"created_at"`
	UpdatedAt              time.Time              `json:"updated_at" db:"updated_at"`
}

type OrganizationModel

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

func (*OrganizationModel) Get

func (*OrganizationModel) Update

type OrganizationUpdate

type OrganizationUpdate struct {
	Name                                 string `json:",omitempty"`
	TimezoneUTCOffset                    string `json:",omitempty"`
	IsApprovalRequired                   *bool  `json:",omitempty"`
	IsLinkShortenerEnabled               *bool  `json:",omitempty"`
	IsMemoTracingEnabled                 *bool  `json:",omitempty"`
	ReceiverInvitationResendIntervalDays *int64 `json:",omitempty"`
	PaymentCancellationPeriodDays        *int64 `json:",omitempty"`

	// Using pointers to accept empty strings
	ReceiverRegistrationMessageTemplate *string `json:",omitempty"`
	OTPMessageTemplate                  *string `json:",omitempty"`
	PrivacyPolicyLink                   *string `json:",omitempty"`

	// MFA and CAPTCHA settings
	MFADisabled     *bool `json:",omitempty"`
	CAPTCHADisabled *bool `json:",omitempty"`
}

type Payment

type Payment struct {
	ID                   string `json:"id" db:"id"`
	Amount               string `json:"amount" db:"amount"`
	StellarTransactionID string `json:"stellar_transaction_id" db:"stellar_transaction_id"`
	// TODO: evaluate if we will keep or remove StellarOperationID
	StellarOperationID      string               `json:"stellar_operation_id" db:"stellar_operation_id"`
	Status                  PaymentStatus        `json:"status" db:"status"`
	StatusHistory           PaymentStatusHistory `json:"status_history,omitempty" db:"status_history"`
	Type                    PaymentType          `json:"type" db:"type"`
	Disbursement            *Disbursement        `json:"disbursement,omitempty" db:"disbursement"`
	Asset                   Asset                `json:"asset"`
	ReceiverWallet          *ReceiverWallet      `json:"receiver_wallet,omitempty" db:"receiver_wallet"`
	CreatedAt               time.Time            `json:"created_at" db:"created_at"`
	UpdatedAt               time.Time            `json:"updated_at" db:"updated_at"`
	ExternalPaymentID       string               `json:"external_payment_id,omitempty" db:"external_payment_id"`
	CircleTransferRequestID *string              `json:"circle_transfer_request_id,omitempty"`
}

func CreatePaymentFixture

func CreatePaymentFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, model *PaymentModel, p *Payment) *Payment

type PaymentInsert

type PaymentInsert struct {
	ReceiverID        string      `db:"receiver_id"`
	DisbursementID    *string     `db:"disbursement_id"`
	PaymentType       PaymentType `db:"type"`
	Amount            string      `db:"amount"`
	AssetID           string      `db:"asset_id"`
	ReceiverWalletID  string      `db:"receiver_wallet_id"`
	ExternalPaymentID *string     `db:"external_payment_id"`
}

func (*PaymentInsert) Validate

func (p *PaymentInsert) Validate() error

type PaymentModel

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

func (*PaymentModel) CancelPaymentsWithinPeriodDays

func (p *PaymentModel) CancelPaymentsWithinPeriodDays(ctx context.Context, sqlExec db.SQLExecuter, periodInDays int64) error

CancelPaymentsWithinPeriodDays cancels automatically payments that are in "READY" status after a certain time period in days.

func (*PaymentModel) Count

func (p *PaymentModel) Count(ctx context.Context, queryParams *QueryParams, sqlExec db.SQLExecuter) (int, error)

Count returns the number of payments matching the given query parameters.

func (*PaymentModel) CreateDirectPayment

func (p *PaymentModel) CreateDirectPayment(ctx context.Context, sqlExec db.SQLExecuter, insert PaymentInsert, userID string) (string, error)

func (*PaymentModel) DeleteAllDraftForDisbursement

func (p *PaymentModel) DeleteAllDraftForDisbursement(ctx context.Context, sqlExec db.SQLExecuter, disbursementID string) error

DeleteAllDraftForDisbursement deletes all payments for a given disbursement.

func (*PaymentModel) Get

func (p *PaymentModel) Get(ctx context.Context, id string, sqlExec db.SQLExecuter) (*Payment, error)

func (*PaymentModel) GetAll

func (p *PaymentModel) GetAll(ctx context.Context, queryParams *QueryParams, sqlExec db.SQLExecuter, queryType QueryType) ([]Payment, error)

GetAll returns all PAYMENTS matching the given query parameters.

func (*PaymentModel) GetAllReadyToPatchCompletionAnchorTransactions

func (p *PaymentModel) GetAllReadyToPatchCompletionAnchorTransactions(ctx context.Context, sqlExec db.SQLExecuter) ([]Payment, error)

func (*PaymentModel) GetBatchForUpdate

func (p *PaymentModel) GetBatchForUpdate(ctx context.Context, sqlExec db.SQLExecuter, batchSize int) ([]*Payment, error)

func (*PaymentModel) GetByIDs

func (p *PaymentModel) GetByIDs(ctx context.Context, sqlExec db.SQLExecuter, paymentIDs []string) ([]Payment, error)

GetByIDs returns a list of payments for the given IDs.

func (*PaymentModel) GetReadyByDisbursementID

func (p *PaymentModel) GetReadyByDisbursementID(ctx context.Context, sqlExec db.SQLExecuter, disbursementID string) ([]*Payment, error)

func (*PaymentModel) GetReadyByID

func (p *PaymentModel) GetReadyByID(ctx context.Context, sqlExec db.SQLExecuter, paymentIDs ...string) ([]*Payment, error)

func (*PaymentModel) GetReadyByReceiverWalletID

func (p *PaymentModel) GetReadyByReceiverWalletID(ctx context.Context, sqlExec db.SQLExecuter, receiverWalletID string) ([]*Payment, error)

func (*PaymentModel) InsertAll

func (p *PaymentModel) InsertAll(ctx context.Context, sqlExec db.SQLExecuter, inserts []PaymentInsert) error

InsertAll inserts a batch of payments into the database.

func (*PaymentModel) RetryFailedPayments

func (p *PaymentModel) RetryFailedPayments(ctx context.Context, sqlExec db.SQLExecuter, email string, paymentIDs ...string) error

func (*PaymentModel) Update

func (p *PaymentModel) Update(ctx context.Context, sqlExec db.SQLExecuter, payment *Payment, update *PaymentUpdate) error

Update updates a payment's fields with the given update.

func (*PaymentModel) UpdateStatus

func (p *PaymentModel) UpdateStatus(
	ctx context.Context,
	sqlExec db.SQLExecuter,
	paymentID string,
	status PaymentStatus,
	statusMsg *string,
	stellarTransactionHash string,
) error

UpdateStatus updates the status of a payment.

func (*PaymentModel) UpdateStatusByDisbursementID

func (p *PaymentModel) UpdateStatusByDisbursementID(ctx context.Context, sqlExec db.SQLExecuter, disbursementID string, targetStatus PaymentStatus) error

UpdateStatusByDisbursementID updates the status of all payments with a given status for a given disbursement.

func (*PaymentModel) UpdateStatuses

func (p *PaymentModel) UpdateStatuses(ctx context.Context, sqlExec db.SQLExecuter, payments []*Payment, toStatus PaymentStatus) (int64, error)

type PaymentStatus

type PaymentStatus string
const (
	// DraftPaymentStatus is a non-terminal state for payments that were registered in the database but their disbursement has not started yet. Payments in this state can be deleted or transitioned to READY.
	DraftPaymentStatus PaymentStatus = "DRAFT"
	// ReadyPaymentStatus is a non-terminal state for payments that are waiting for the receiver to register. As soon as the receiver registers, the state is transitioned to PENDING.
	ReadyPaymentStatus PaymentStatus = "READY"
	// PendingPaymentStatus is a non-terminal state for payments that were marked for submission to the Stellar network. They can or can not have been submitted yet.
	PendingPaymentStatus PaymentStatus = "PENDING"
	// PausedPaymentStatus is a non-terminal state for payments that were manually paused. Payments in this state can be resumed.
	PausedPaymentStatus PaymentStatus = "PAUSED"
	// SuccessPaymentStatus is a terminal state for payments that were successfully submitted to the Stellar network.
	SuccessPaymentStatus PaymentStatus = "SUCCESS"
	// FailedPaymentStatus is a terminal state for payments that failed when submitted to the Stellar network. Payments in this state can be retried.
	FailedPaymentStatus PaymentStatus = "FAILED"
	// CanceledPaymentStatus is a terminal state for payments that were either manually or automatically canceled.
	CanceledPaymentStatus PaymentStatus = "CANCELED"
)

func PaymentActiveStatuses

func PaymentActiveStatuses() []PaymentStatus

func PaymentCompletedStatuses

func PaymentCompletedStatuses() []PaymentStatus

PaymentCompletedStatuses returns a list of payment statuses that reached a terminal state.

func PaymentInProgressStatuses

func PaymentInProgressStatuses() []PaymentStatus

PaymentInProgressStatuses returns a list of payment statuses that are in progress and could block potential new payments from being initiated if the distribution balance is low.

func PaymentStatuses

func PaymentStatuses() []PaymentStatus

PaymentStatuses returns a list of all possible payment statuses

func ToPaymentStatus

func ToPaymentStatus(s string) (PaymentStatus, error)

ToPaymentStatus converts a string to a PaymentStatus

func (PaymentStatus) SourceStatuses

func (status PaymentStatus) SourceStatuses() []PaymentStatus

SourceStatuses returns a list of states that the payment status can transition from given the target state

func (PaymentStatus) State

func (status PaymentStatus) State() State

func (PaymentStatus) TransitionTo

func (status PaymentStatus) TransitionTo(targetState PaymentStatus) error

TransitionTo transitions the payment status to the target state

func (PaymentStatus) Validate

func (status PaymentStatus) Validate() error

Validate validates the payment status

type PaymentStatusHistory

type PaymentStatusHistory []PaymentStatusHistoryEntry

func (*PaymentStatusHistory) Scan

func (psh *PaymentStatusHistory) Scan(src interface{}) error

Scan implements the sql.Scanner interface.

func (PaymentStatusHistory) Value

func (psh PaymentStatusHistory) Value() (driver.Value, error)

Value implements the driver.Valuer interface.

type PaymentStatusHistoryEntry

type PaymentStatusHistoryEntry struct {
	Status        PaymentStatus `json:"status"`
	StatusMessage string        `json:"status_message"`
	Timestamp     time.Time     `json:"timestamp"`
}

type PaymentType

type PaymentType string
const (
	PaymentTypeDisbursement PaymentType = "DISBURSEMENT"
	PaymentTypeDirect       PaymentType = "DIRECT"
)

func (PaymentType) Validate

func (pt PaymentType) Validate() error

type PaymentUpdate

type PaymentUpdate struct {
	Status               PaymentStatus `db:"status"`
	StatusMessage        string
	StellarTransactionID string `db:"stellar_transaction_id"`
}

func (*PaymentUpdate) Validate

func (p *PaymentUpdate) Validate() error

type QueryBuilder

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

QueryBuilder is a helper struct for building SQL queries

func NewQueryBuilder

func NewQueryBuilder(query string) *QueryBuilder

NewQueryBuilder creates a new QueryBuilder

func (*QueryBuilder) AddCondition

func (qb *QueryBuilder) AddCondition(condition string, value ...interface{}) *QueryBuilder

AddCondition adds a AND condition to the query The condition should be a string with a placeholder for the value e.g. "name = ?", "id > ?"

func (*QueryBuilder) AddGroupBy

func (qb *QueryBuilder) AddGroupBy(fields string) *QueryBuilder

func (*QueryBuilder) AddOrCondition

func (qb *QueryBuilder) AddOrCondition(condition string, value ...any) *QueryBuilder

AddOrCondition adds an OR condition to the query.

func (*QueryBuilder) AddPagination

func (qb *QueryBuilder) AddPagination(page int, pageLimit int) *QueryBuilder

AddPagination adds a pagination clause to the query

func (*QueryBuilder) AddSorting

func (qb *QueryBuilder) AddSorting(sortField SortField, sortOrder SortOrder, prefix string) *QueryBuilder

AddSorting adds a sorting clause to the query prefix is the prefix to use for the sort field e.g. "d" for "d.created_at"

func (*QueryBuilder) Build

func (qb *QueryBuilder) Build() (string, []interface{})

Build assembles all statements in the correct order and returns the query and the parameters

func (*QueryBuilder) BuildAndRebind

func (qb *QueryBuilder) BuildAndRebind(sqlExec db.SQLExecuter) (string, []interface{})

type QueryParams

type QueryParams struct {
	Query               string
	Page                int
	PageLimit           int
	SortBy              SortField
	SortOrder           SortOrder
	Filters             map[FilterKey]interface{}
	ForUpdateSkipLocked bool
}

type QueryType

type QueryType string
const (
	QueryTypeSelectPaginated QueryType = "SELECT_PAGINATED"
	QueryTypeSelectAll       QueryType = "SELECT_ALL"
	QueryTypeSingle          QueryType = "SINGLE"
)

type RandomCodeGenerator

type RandomCodeGenerator struct{}

func (*RandomCodeGenerator) Generate

func (g *RandomCodeGenerator) Generate(length int) string

type ReceivedAmounts

type ReceivedAmounts []Amount

func (*ReceivedAmounts) Scan

func (ra *ReceivedAmounts) Scan(src interface{}) error

Scan implements the sql.Scanner interface.

type Receiver

type Receiver struct {
	ID          string     `json:"id" db:"id"`
	Email       string     `json:"email,omitempty" db:"email"`
	PhoneNumber string     `json:"phone_number,omitempty" db:"phone_number"`
	ExternalID  string     `json:"external_id,omitempty" db:"external_id"`
	CreatedAt   *time.Time `json:"created_at,omitempty" db:"created_at"`
	UpdatedAt   *time.Time `json:"updated_at,omitempty" db:"updated_at"`
	ReceiverStats
}

func CreateReceiverFixture

func CreateReceiverFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, r *Receiver) *Receiver

func InsertReceiverFixture

func InsertReceiverFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, r *ReceiverInsert) *Receiver

func (Receiver) ContactByType

func (r Receiver) ContactByType(contactType ReceiverContactType) string

type ReceiverContactType

type ReceiverContactType string
const (
	ReceiverContactTypeEmail ReceiverContactType = "EMAIL"
	ReceiverContactTypeSMS   ReceiverContactType = "PHONE_NUMBER"
)

func GetAllReceiverContactTypes

func GetAllReceiverContactTypes() []ReceiverContactType

type ReceiverIDs

type ReceiverIDs []string

type ReceiverInsert

type ReceiverInsert struct {
	PhoneNumber *string `db:"phone_number"`
	Email       *string `db:"email"`
	ExternalID  *string `db:"external_id"`
}

type ReceiverModel

type ReceiverModel struct{}

func (*ReceiverModel) Count

func (r *ReceiverModel) Count(ctx context.Context, sqlExec db.SQLExecuter, queryParams *QueryParams) (int, error)

Count returns the number of receivers matching the given query parameters.

func (*ReceiverModel) DeleteByContactInfo

func (r *ReceiverModel) DeleteByContactInfo(ctx context.Context, dbConnectionPool db.DBConnectionPool, contactInfo string) error

DeleteByContactInfo deletes a receiver by phone number or email. It also deletes the associated entries in other tables: messages, payments, receiver_verifications, receiver_wallets, receivers, disbursements, submitter_transactions.

func (*ReceiverModel) Get

func (r *ReceiverModel) Get(ctx context.Context, sqlExec db.SQLExecuter, id string) (*Receiver, error)

Get returns a RECEIVER matching the given ID.

func (*ReceiverModel) GetAll

func (r *ReceiverModel) GetAll(ctx context.Context, sqlExec db.SQLExecuter, queryParams *QueryParams, queryType QueryType) ([]Receiver, error)

GetAll returns all RECEIVERS matching the given query parameters.

func (*ReceiverModel) GetByContacts

func (r *ReceiverModel) GetByContacts(ctx context.Context, sqlExec db.SQLExecuter, contacts ...string) ([]*Receiver, error)

GetByContacts search for receivers by phone numbers and email.

func (*ReceiverModel) GetByWalletAddress

func (r *ReceiverModel) GetByWalletAddress(ctx context.Context, sqlExec db.SQLExecuter, walletAddress string) (*Receiver, error)

func (*ReceiverModel) Insert

func (r *ReceiverModel) Insert(ctx context.Context, sqlExec db.SQLExecuter, insert ReceiverInsert) (*Receiver, error)

Insert inserts a new receiver into the database.

func (*ReceiverModel) ParseReceiverIDs

func (r *ReceiverModel) ParseReceiverIDs(receivers []Receiver) ReceiverIDs

ParseReceiverIDs return the array of receivers IDs.

func (*ReceiverModel) Update

func (r *ReceiverModel) Update(ctx context.Context, sqlExec db.SQLExecuter, ID string, receiverUpdate ReceiverUpdate) error

Update updates the receiver Email and/or External ID.

type ReceiverRegistrationAttempt

type ReceiverRegistrationAttempt struct {
	PhoneNumber   string    `db:"phone_number"`
	Email         string    `db:"email"`
	AttemptTS     time.Time `db:"attempt_ts"`
	ClientDomain  string    `db:"client_domain"`
	TransactionID string    `db:"transaction_id"`
	WalletAddress string    `db:"wallet_address"`
	WalletMemo    string    `db:"wallet_memo"`
}

type ReceiverRegistrationAttemptModel

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

func (*ReceiverRegistrationAttemptModel) InsertReceiverRegistrationAttempt

func (m *ReceiverRegistrationAttemptModel) InsertReceiverRegistrationAttempt(ctx context.Context, attempt ReceiverRegistrationAttempt) error

InsertReceiverRegistrationAttempt logs a failed wallet-registration attempt in the database.

type ReceiverRegistrationRequest

type ReceiverRegistrationRequest struct {
	Email             string           `json:"email"`
	PhoneNumber       string           `json:"phone_number"`
	OTP               string           `json:"otp"`
	VerificationValue string           `json:"verification"`
	VerificationField VerificationType `json:"verification_field"`
	ReCAPTCHAToken    string           `json:"recaptcha_token"`
}

type ReceiverStats

type ReceiverStats struct {
	TotalPayments      string          `json:"total_payments,omitempty" db:"total_payments"`
	SuccessfulPayments string          `json:"successful_payments,omitempty" db:"successful_payments"`
	FailedPayments     string          `json:"failed_payments,omitempty" db:"failed_payments"`
	CanceledPayments   string          `json:"canceled_payments,omitempty" db:"canceled_payments"`
	RemainingPayments  string          `json:"remaining_payments,omitempty" db:"remaining_payments"`
	RegisteredWallets  string          `json:"registered_wallets,omitempty" db:"registered_wallets"`
	ReceivedAmounts    ReceivedAmounts `json:"received_amounts,omitempty" db:"received_amounts"`
}

type ReceiverUpdate

type ReceiverUpdate ReceiverInsert

func (ReceiverUpdate) IsEmpty

func (ru ReceiverUpdate) IsEmpty() bool

func (ReceiverUpdate) Validate

func (ru ReceiverUpdate) Validate() error

type ReceiverVerification

type ReceiverVerification struct {
	ReceiverID          string                  `json:"receiver_id" db:"receiver_id"`
	VerificationField   VerificationType        `json:"verification_field" db:"verification_field"`
	HashedValue         string                  `json:"hashed_value" db:"hashed_value"`
	Attempts            int                     `json:"attempts" db:"attempts"`
	CreatedAt           time.Time               `json:"created_at" db:"created_at"`
	ConfirmedByType     *ConfirmedByType        `json:"confirmed_by_type" db:"confirmed_by_type"`
	ConfirmedByID       *string                 `json:"confirmed_by_id" db:"confirmed_by_id"`
	UpdatedAt           time.Time               `json:"updated_at" db:"updated_at"`
	ConfirmedAt         *time.Time              `json:"confirmed_at" db:"confirmed_at"`
	FailedAt            *time.Time              `json:"failed_at" db:"failed_at"`
	VerificationChannel *message.MessageChannel `json:"verification_channel" db:"verification_channel"`
}

func CreateReceiverVerificationFixture

func CreateReceiverVerificationFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, insert ReceiverVerificationInsert) *ReceiverVerification

type ReceiverVerificationInsert

type ReceiverVerificationInsert struct {
	ReceiverID        string           `db:"receiver_id"`
	VerificationField VerificationType `db:"verification_field"`
	VerificationValue string           `db:"hashed_value"`
}

func (*ReceiverVerificationInsert) Validate

func (rvi *ReceiverVerificationInsert) Validate() error

type ReceiverVerificationModel

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

func (*ReceiverVerificationModel) ExceededAttempts

func (*ReceiverVerificationModel) ExceededAttempts(attempts int) bool

ExceededAttempts check if the number of attempts exceeded the max value.

func (*ReceiverVerificationModel) GetAllByReceiverID

func (m *ReceiverVerificationModel) GetAllByReceiverID(ctx context.Context, sqlExec db.SQLExecuter, receiverID string) ([]ReceiverVerification, error)

GetAllByReceiverID returns all receiver verifications by receiver id.

func (*ReceiverVerificationModel) GetByReceiverIDsAndVerificationField

func (m *ReceiverVerificationModel) GetByReceiverIDsAndVerificationField(ctx context.Context, sqlExec db.SQLExecuter, receiverIds []string, verificationField VerificationType) ([]*ReceiverVerification, error)

GetByReceiverIDsAndVerificationField returns receiver verifications by receiver IDs and verification type.

func (*ReceiverVerificationModel) GetLatestByContactInfo

func (m *ReceiverVerificationModel) GetLatestByContactInfo(ctx context.Context, contactInfo string) (*ReceiverVerification, error)

GetLatestByContactInfo returns the latest updated receiver verification for a receiver associated with a phone number or email.

func (*ReceiverVerificationModel) Insert

func (m *ReceiverVerificationModel) Insert(ctx context.Context, sqlExec db.SQLExecuter, verificationInsert ReceiverVerificationInsert) (string, error)

Insert inserts a new receiver verification

func (*ReceiverVerificationModel) UpdateReceiverVerification

func (m *ReceiverVerificationModel) UpdateReceiverVerification(ctx context.Context, update ReceiverVerificationUpdate, sqlExec db.SQLExecuter) error

UpdateReceiverVerification updates the attempts, confirmed_at, and failed_at values of a receiver verification.

func (*ReceiverVerificationModel) UpdateVerificationValue

func (m *ReceiverVerificationModel) UpdateVerificationValue(ctx context.Context,
	sqlExec db.SQLExecuter,
	receiverID string,
	verificationField VerificationType,
	verificationValue string,
) error

UpdateVerificationValue updates the hashed value of a receiver verification.

func (*ReceiverVerificationModel) UpsertVerificationValue

func (m *ReceiverVerificationModel) UpsertVerificationValue(ctx context.Context, sqlExec db.SQLExecuter, userID, receiverID string, verificationField VerificationType, verificationValue string) error

UpsertVerificationValue creates or updates the receiver's verification. Even if the verification exists and is already confirmed by the receiver, it will be updated.

type ReceiverVerificationUpdate

type ReceiverVerificationUpdate struct {
	ReceiverID          string                 `db:"receiver_id"`
	VerificationField   VerificationType       `db:"verification_field"`
	VerificationChannel message.MessageChannel `db:"verification_channel"`
	Attempts            *int                   `db:"attempts"`
	ConfirmedAt         *time.Time             `db:"confirmed_at"`
	ConfirmedByType     ConfirmedByType        `db:"confirmed_by_type"`
	ConfirmedByID       string                 `db:"confirmed_by_id"`
	FailedAt            *time.Time             `db:"failed_at"`
}

func (ReceiverVerificationUpdate) Validate

func (rvu ReceiverVerificationUpdate) Validate() error

type ReceiverWallet

type ReceiverWallet struct {
	ID                 string                       `json:"id" db:"id"`
	Receiver           Receiver                     `json:"receiver" db:"receiver"`
	Wallet             Wallet                       `json:"wallet" db:"wallet"`
	StellarAddress     string                       `json:"stellar_address,omitempty" db:"stellar_address"`
	StellarMemo        string                       `json:"stellar_memo,omitempty" db:"stellar_memo"`
	StellarMemoType    schema.MemoType              `json:"stellar_memo_type,omitempty" db:"stellar_memo_type"`
	Status             ReceiversWalletStatus        `json:"status" db:"status"`
	StatusHistory      ReceiversWalletStatusHistory `json:"status_history,omitempty" db:"status_history"`
	CreatedAt          time.Time                    `json:"created_at" db:"created_at"`
	UpdatedAt          time.Time                    `json:"updated_at" db:"updated_at"`
	OTP                string                       `json:"-" db:"otp"`
	OTPAttempts        int                          `json:"-" db:"otp_attempts"`
	OTPCreatedAt       *time.Time                   `json:"-" db:"otp_created_at"`
	OTPConfirmedAt     *time.Time                   `json:"otp_confirmed_at,omitempty" db:"otp_confirmed_at"`
	OTPConfirmedWith   string                       `json:"otp_confirmed_with,omitempty" db:"otp_confirmed_with"`
	SEP24TransactionID string                       `json:"sep24_transaction_id,omitempty" db:"sep24_transaction_id"`
	InvitedAt          *time.Time                   `json:"invited_at,omitempty" db:"invited_at"`
	LastMessageSentAt  *time.Time                   `json:"last_message_sent_at,omitempty" db:"last_message_sent_at"`
	InvitationSentAt   *time.Time                   `json:"invitation_sent_at" db:"invitation_sent_at"`
	ReceiverWalletStats
}

func CreateReceiverWalletFixture

func CreateReceiverWalletFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, receiverID, walletID string, status ReceiversWalletStatus) *ReceiverWallet

type ReceiverWalletAsset

type ReceiverWalletAsset struct {
	WalletID                                    string         `db:"wallet_id"`
	ReceiverWallet                              ReceiverWallet `db:"receiver_wallet"`
	Asset                                       Asset          `db:"asset"`
	DisbursementReceiverRegistrationMsgTemplate *string        `json:"-" db:"receiver_registration_message_template"`
}

type ReceiverWalletInsert

type ReceiverWalletInsert struct {
	ReceiverID string
	WalletID   string
}

type ReceiverWalletModel

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

func (*ReceiverWalletModel) GetAllPendingRegistrationByDisbursementID

func (rw *ReceiverWalletModel) GetAllPendingRegistrationByDisbursementID(ctx context.Context, sqlExec db.SQLExecuter, disbursementID string) ([]*ReceiverWallet, error)

func (*ReceiverWalletModel) GetAllPendingRegistrationByReceiverWalletIDs

func (rw *ReceiverWalletModel) GetAllPendingRegistrationByReceiverWalletIDs(ctx context.Context, sqlExec db.SQLExecuter, receiverWalletIDs []string) ([]*ReceiverWallet, error)

func (*ReceiverWalletModel) GetAllPendingRegistrations

func (rw *ReceiverWalletModel) GetAllPendingRegistrations(ctx context.Context, sqlExec db.SQLExecuter) ([]*ReceiverWallet, error)

func (*ReceiverWalletModel) GetByID

func (rw *ReceiverWalletModel) GetByID(ctx context.Context, sqlExec db.SQLExecuter, id string) (*ReceiverWallet, error)

GetByID returns a receiver wallet by ID

func (*ReceiverWalletModel) GetByIDs

func (rw *ReceiverWalletModel) GetByIDs(ctx context.Context, sqlExec db.SQLExecuter, ids ...string) ([]ReceiverWallet, error)

GetByIDs returns a receiver wallet by IDs

func (*ReceiverWalletModel) GetByReceiverIDAndWalletDomain

func (rw *ReceiverWalletModel) GetByReceiverIDAndWalletDomain(ctx context.Context, receiverID string, walletDomain string, sqlExec db.SQLExecuter) (*ReceiverWallet, error)

GetByReceiverIDAndWalletDomain returns a receiver wallet that match the receiver ID and wallet domain.

func (*ReceiverWalletModel) GetByReceiverIDsAndWalletID

func (rw *ReceiverWalletModel) GetByReceiverIDsAndWalletID(ctx context.Context, sqlExec db.SQLExecuter, receiverIds []string, walletID string) ([]*ReceiverWallet, error)

GetByReceiverIDsAndWalletID returns a list of receiver wallets by receiver IDs and wallet ID.

func (*ReceiverWalletModel) GetBySEP24TransactionID

func (rw *ReceiverWalletModel) GetBySEP24TransactionID(ctx context.Context, transactionID string) (*ReceiverWallet, error)

func (*ReceiverWalletModel) GetByStellarAccountAndMemo

func (rw *ReceiverWalletModel) GetByStellarAccountAndMemo(ctx context.Context, stellarAccount, clientDomain string, stellarMemo *string) (*ReceiverWallet, error)

GetByStellarAccountAndMemo returns a receiver wallets that match the Stellar Account, memo and client domain.

func (*ReceiverWalletModel) GetOrInsertReceiverWallet

func (rw *ReceiverWalletModel) GetOrInsertReceiverWallet(ctx context.Context, sqlExec db.SQLExecuter, insert ReceiverWalletInsert) (string, error)

GetOrInsertReceiverWallet inserts a new receiver wallet into the database.

func (*ReceiverWalletModel) GetWithReceiverIDs

func (rw *ReceiverWalletModel) GetWithReceiverIDs(ctx context.Context, sqlExec db.SQLExecuter, receiverIDs ReceiverIDs) ([]ReceiverWallet, error)

func (*ReceiverWalletModel) HasPaymentsInProgress

func (rw *ReceiverWalletModel) HasPaymentsInProgress(ctx context.Context, sqlExec db.SQLExecuter, receiverWalletID string) (bool, error)

HasPaymentsInProgress checks if there are any payments in progress for the given receiver wallet ID.

func (*ReceiverWalletModel) RetryInvitationMessage

func (rw *ReceiverWalletModel) RetryInvitationMessage(ctx context.Context, sqlExec db.SQLExecuter, receiverWalletID string) (*ReceiverWallet, error)

RetryInvitationMessage sets null the invitation_sent_at of a receiver wallet.

func (*ReceiverWalletModel) Update

func (rw *ReceiverWalletModel) Update(ctx context.Context, id string, update ReceiverWalletUpdate, sqlExec db.SQLExecuter) error

func (*ReceiverWalletModel) UpdateInvitationSentAt

func (rw *ReceiverWalletModel) UpdateInvitationSentAt(ctx context.Context, sqlExec db.SQLExecuter, receiverWalletID ...string) ([]ReceiverWallet, error)

func (*ReceiverWalletModel) UpdateOTPByReceiverContactInfoAndWalletDomain

func (rw *ReceiverWalletModel) UpdateOTPByReceiverContactInfoAndWalletDomain(ctx context.Context, receiverContactInfo, sep10ClientDomain, otp string) (numberOfUpdatedRows int, err error)

UpdateOTPByReceiverContactInfoAndWalletDomain updates receiver wallet OTP if its not verified yet, and returns the number of updated rows.

func (*ReceiverWalletModel) UpdateStatusByDisbursementID

func (rw *ReceiverWalletModel) UpdateStatusByDisbursementID(ctx context.Context, sqlExec db.SQLExecuter, disbursementID string, from, to ReceiversWalletStatus) error

UpdateStatusByDisbursementID updates the status of the receiver wallets associated with a disbursement.

func (*ReceiverWalletModel) UpdateStatusToReady

func (rw *ReceiverWalletModel) UpdateStatusToReady(ctx context.Context, id string) error

UpdateStatusToReady updates the status of a receiver wallet to "READY" and clears the stellar address and memo.

type ReceiverWalletStats

type ReceiverWalletStats struct {
	TotalPayments     string          `json:"total_payments,omitempty" db:"total_payments"`
	PaymentsReceived  string          `json:"payments_received,omitempty" db:"payments_received"`
	FailedPayments    string          `json:"failed_payments,omitempty" db:"failed_payments"`
	CanceledPayments  string          `json:"canceled_payments,omitempty" db:"canceled_payments"`
	RemainingPayments string          `json:"remaining_payments,omitempty" db:"remaining_payments"`
	ReceivedAmounts   ReceivedAmounts `json:"received_amounts,omitempty" db:"received_amounts"`
	// TotalInvitationResentAttempts holds how many times were resent the Invitation SMS to the receiver
	// since the last invitation has been sent.
	TotalInvitationResentAttempts int64 `json:"-" db:"total_invitation_resent_attempts"`
}

type ReceiverWalletUpdate

type ReceiverWalletUpdate struct {
	Status             ReceiversWalletStatus `db:"status"`
	SEP24TransactionID string                `db:"sep24_transaction_id"`
	StellarAddress     string                `db:"stellar_address"`
	StellarMemo        *string               `db:"stellar_memo"`
	StellarMemoType    *schema.MemoType      `db:"stellar_memo_type"`
	OTPConfirmedAt     time.Time             `db:"otp_confirmed_at"`
	OTPConfirmedWith   string                `db:"otp_confirmed_with"`
	OTPAttempts        *int                  `db:"otp_attempts"`
}

func (ReceiverWalletUpdate) Validate

func (rwu ReceiverWalletUpdate) Validate() error

type ReceiversWalletStatus

type ReceiversWalletStatus string
const (
	DraftReceiversWalletStatus      ReceiversWalletStatus = "DRAFT"
	ReadyReceiversWalletStatus      ReceiversWalletStatus = "READY"
	RegisteredReceiversWalletStatus ReceiversWalletStatus = "REGISTERED"
	FlaggedReceiversWalletStatus    ReceiversWalletStatus = "FLAGGED"
)

func ReceiversWalletStatuses

func ReceiversWalletStatuses() []ReceiversWalletStatus

ReceiversWalletStatuses returns a list of all possible receiver wallet statuses

func ToReceiversWalletStatus

func ToReceiversWalletStatus(s string) (ReceiversWalletStatus, error)

ToReceiversWalletStatus converts a string to a ReceiversWalletStatus.

func (ReceiversWalletStatus) State

func (status ReceiversWalletStatus) State() State

func (ReceiversWalletStatus) TransitionTo

func (status ReceiversWalletStatus) TransitionTo(targetState ReceiversWalletStatus) error

TransitionTo transitions the receiver wallet status to the target state

func (ReceiversWalletStatus) Validate

func (status ReceiversWalletStatus) Validate() error

Validate validates the receiver wallet status

type ReceiversWalletStatusHistory

type ReceiversWalletStatusHistory []ReceiversWalletStatusHistoryEntry

func (*ReceiversWalletStatusHistory) Scan

func (rwsh *ReceiversWalletStatusHistory) Scan(src interface{}) error

Scan implements the sql.Scanner interface.

func (ReceiversWalletStatusHistory) Value

Value implements the driver.Valuer interface.

type ReceiversWalletStatusHistoryEntry

type ReceiversWalletStatusHistoryEntry struct {
	Status    ReceiversWalletStatus `json:"status"`
	Timestamp time.Time             `json:"timestamp"`
}

type RegistrationContactType

type RegistrationContactType struct {
	ReceiverContactType   ReceiverContactType `json:"registration_contact_type"`
	IncludesWalletAddress bool                `json:"includes_wallet_address"`
}

RegistrationContactType represents the type of contact information to be used when creating and validating a disbursement.

func AllRegistrationContactTypes

func AllRegistrationContactTypes() []RegistrationContactType

func (RegistrationContactType) MarshalCSV

func (rct RegistrationContactType) MarshalCSV() (string, error)

func (RegistrationContactType) MarshalJSON

func (rct RegistrationContactType) MarshalJSON() ([]byte, error)

func (*RegistrationContactType) ParseFromString

func (rct *RegistrationContactType) ParseFromString(input string) error

ParseFromString parses the string, setting ReceiverContactType and IncludesWalletAddress based on suffix.

func (*RegistrationContactType) Scan

func (rct *RegistrationContactType) Scan(value interface{}) error

func (RegistrationContactType) String

func (rct RegistrationContactType) String() string

func (*RegistrationContactType) UnmarshalJSON

func (rct *RegistrationContactType) UnmarshalJSON(data []byte) error

func (RegistrationContactType) Value

func (rct RegistrationContactType) Value() (driver.Value, error)

type SQLColumnConfig

type SQLColumnConfig struct {
	// TableReference is the table name or alias in the FROM clause (e.g., "rw" in "FROM receivers_wallet rw")
	TableReference string
	// ResultAlias is the prefix for the result column name (e.g., "wallet" in SELECT rw.id AS "wallet.id")
	ResultAlias string
	// RawColumns is the list of column names to process
	RawColumns []string
	// CoalesceColumns indicates which columns should be wrapped in COALESCE(col, ”)
	CoalesceColumns []string
}

SQLColumnConfig contains configuration for generating SQL column names.

func (SQLColumnConfig) Build

func (c SQLColumnConfig) Build() []string

Build creates a slice of SQL column expressions based on the provided configuration. It handles table aliases, column prefixes, and COALESCE wrapping as specified in the config.

type ShortURL

type ShortURL struct {
	ID          string    `json:"id"`
	OriginalURL string    `json:"original_url"`
	CreatedAt   time.Time `json:"created_at"`
}

type SortField

type SortField string
const (
	SortFieldName      SortField = "name"
	SortFieldEmail     SortField = "email"
	SortFieldIsActive  SortField = "is_active"
	SortFieldCreatedAt SortField = "created_at"
	SortFieldUpdatedAt SortField = "updated_at"
)

type SortOrder

type SortOrder string
const (
	SortOrderASC  SortOrder = "ASC"
	SortOrderDESC SortOrder = "DESC"
)

type State

type State string

type StateMachine

type StateMachine struct {
	CurrentState State
	Transitions  map[State]map[State]bool
}

func DisbursementStateMachineWithInitialState

func DisbursementStateMachineWithInitialState(initialState DisbursementStatus) *StateMachine

DisbursementStateMachineWithInitialState returns a state machine for disbursements initialized with the given state

func NewStateMachine

func NewStateMachine(initialState State, transitions []StateTransition) *StateMachine

func PaymentStateMachineWithInitialState

func PaymentStateMachineWithInitialState(initialState PaymentStatus) *StateMachine

PaymentStateMachineWithInitialState returns a state machine for Payments initialized with the given state

func ReceiversWalletStateMachineWithInitialState

func ReceiversWalletStateMachineWithInitialState(initialState ReceiversWalletStatus) *StateMachine

ReceiversWalletStateMachineWithInitialState returns a state machine for ReceiversWallets initialized with the given state

func (*StateMachine) CanTransitionTo

func (sm *StateMachine) CanTransitionTo(targetState State) bool

func (*StateMachine) TransitionTo

func (sm *StateMachine) TransitionTo(targetState State) error

type StateTransition

type StateTransition struct {
	From State
	To   State
}

type URLShortenerModel

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

func NewURLShortenerModel

func NewURLShortenerModel(db db.DBConnectionPool) *URLShortenerModel

func (*URLShortenerModel) GetOrCreateShortCode

func (u *URLShortenerModel) GetOrCreateShortCode(ctx context.Context, originalURL string) (string, error)

func (*URLShortenerModel) GetOriginalURL

func (u *URLShortenerModel) GetOriginalURL(ctx context.Context, shortCode string) (string, error)

type UserRole

type UserRole string
const (
	// OwnerUserRole has permission to do everything. Also, it's in charge of creating new users and managing Org account.
	OwnerUserRole UserRole = "owner"
	// FinancialControllerUserRole has the same permissions as the OwnerUserRole except for user management.
	FinancialControllerUserRole UserRole = "financial_controller"
	// DeveloperUserRole has only configuration permissions. (wallets, assets management. Also, statistics access permission)
	DeveloperUserRole UserRole = "developer"
	// BusinessUserRole has read-only permissions - except for user management that they can't read any data.
	BusinessUserRole UserRole = "business"
	// InitiatorUserRole can create and save disbursements but not submit them. Mutually exclusive with ApproverUserRole.
	InitiatorUserRole UserRole = "initiator"
	// ApproverUserRole can submit disbursements but not create or save new ones. Mutually exclusive with InitiatorUserRole.
	ApproverUserRole UserRole = "approver"
)

Roles description reference: https://stellarfoundation.slack.com/archives/C04C9MLM9UZ/p1681238994830149

func GetAllRoles

func GetAllRoles() []UserRole

GetAllRoles returns all roles available.

func GetBusinessOperationRoles

func GetBusinessOperationRoles() []UserRole

GetBusinessOperationRoles returns roles related to business operations.

func (UserRole) IsValid

func (u UserRole) IsValid() bool

func (UserRole) String

func (u UserRole) String() string

type VerificationType

type VerificationType string
const (
	VerificationTypeDateOfBirth VerificationType = "DATE_OF_BIRTH"
	VerificationTypeYearMonth   VerificationType = "YEAR_MONTH"
	VerificationTypePin         VerificationType = "PIN"
	VerificationTypeNationalID  VerificationType = "NATIONAL_ID_NUMBER"
)

func GetAllVerificationTypes

func GetAllVerificationTypes() []VerificationType

GetAllVerificationTypes returns all the available verification types.

type Wallet

type Wallet struct {
	ID                string       `json:"id" csv:"-" db:"id"`
	Name              string       `json:"name" db:"name"`
	Homepage          string       `json:"homepage,omitempty" csv:"-" db:"homepage"`
	SEP10ClientDomain string       `json:"sep_10_client_domain,omitempty" csv:"-" db:"sep_10_client_domain"`
	DeepLinkSchema    string       `json:"deep_link_schema,omitempty" csv:"-" db:"deep_link_schema"`
	Enabled           bool         `json:"enabled" csv:"-" db:"enabled"`
	UserManaged       bool         `json:"user_managed,omitempty" csv:"-" db:"user_managed"`
	Assets            WalletAssets `json:"assets,omitempty" csv:"-" db:"assets"`
	CreatedAt         *time.Time   `json:"created_at,omitempty" csv:"-" db:"created_at"`
	UpdatedAt         *time.Time   `json:"updated_at,omitempty" csv:"-" db:"updated_at"`
	DeletedAt         *time.Time   `json:"-" csv:"-" db:"deleted_at"`
}

func ClearAndCreateWalletFixtures

func ClearAndCreateWalletFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter) []Wallet

ClearAndCreateWalletFixtures deletes all wallets in the database then creates new wallets for testing

func CreateDefaultWalletFixture

func CreateDefaultWalletFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter) *Wallet

func CreateWalletFixture

func CreateWalletFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, name, homepage, sep10ClientDomain, deepLinkSchema string) *Wallet

func CreateWalletFixtures

func CreateWalletFixtures(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter) []Wallet

CreateWalletFixtures creates a set of wallets for testing purposes.

func GetWalletFixture

func GetWalletFixture(t *testing.T, ctx context.Context, sqlExec db.SQLExecuter, name string) *Wallet

type WalletAssets

type WalletAssets []Asset

func (*WalletAssets) Scan

func (wa *WalletAssets) Scan(src interface{}) error

type WalletInsert

type WalletInsert struct {
	Name              string   `db:"name"`
	Homepage          string   `db:"homepage"`
	SEP10ClientDomain string   `db:"sep_10_client_domain"`
	DeepLinkSchema    string   `db:"deep_link_schema"`
	Enabled           bool     `db:"enabled"`
	AssetsIDs         []string `db:"assets_ids"`
}

type WalletModel

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

func (*WalletModel) FindWallets

func (wm *WalletModel) FindWallets(ctx context.Context, filters ...Filter) ([]Wallet, error)

FindWallets returns wallets filtering by enabled status.

func (*WalletModel) Get

func (wm *WalletModel) Get(ctx context.Context, id string) (*Wallet, error)

func (*WalletModel) GetAll

func (wm *WalletModel) GetAll(ctx context.Context) ([]Wallet, error)

GetAll returns all wallets in the database

func (*WalletModel) GetAssets

func (wm *WalletModel) GetAssets(ctx context.Context, walletID string) ([]Asset, error)

func (*WalletModel) GetByWalletName

func (wm *WalletModel) GetByWalletName(ctx context.Context, name string) (*Wallet, error)

GetByWalletName returns wallet filtering by wallet name.

func (*WalletModel) GetOrCreate

func (wm *WalletModel) GetOrCreate(ctx context.Context, name, homepage, deepLink, sep10Domain string) (*Wallet, error)

func (*WalletModel) HasPendingReceiverWallets

func (wm *WalletModel) HasPendingReceiverWallets(ctx context.Context, walletID string) (bool, error)

HasPendingReceiverWallets checks if a wallet has any receiver_wallets in DRAFT or READY status.

func (*WalletModel) Insert

func (wm *WalletModel) Insert(ctx context.Context, newWallet WalletInsert) (*Wallet, error)

func (*WalletModel) SoftDelete

func (wm *WalletModel) SoftDelete(ctx context.Context, walletID string) (*Wallet, error)

SoftDelete marks a wallet as deleted if it has no pending receiver_wallets in DRAFT or READY status.

func (*WalletModel) Update

func (wm *WalletModel) Update(ctx context.Context, walletID string, update WalletUpdate) (*Wallet, error)

type WalletUpdate

type WalletUpdate struct {
	Name              *string   `db:"name"`
	Homepage          *string   `db:"homepage"`
	SEP10ClientDomain *string   `db:"sep_10_client_domain"`
	DeepLinkSchema    *string   `db:"deep_link_schema"`
	Enabled           *bool     `db:"enabled"`
	AssetsIDs         *[]string `db:"assets_ids"`
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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