package model import ( "strings" "time" "github.com/tech/sendico/pkg/db/storable" "github.com/tech/sendico/pkg/mservice" moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1" ) type TransferStatus string const ( TransferStatusPending TransferStatus = "pending" TransferStatusSigning TransferStatus = "signing" TransferStatusSubmitted TransferStatus = "submitted" TransferStatusConfirmed TransferStatus = "confirmed" TransferStatusFailed TransferStatus = "failed" TransferStatusCancelled TransferStatus = "cancelled" ) // ServiceFee represents a fee component applied to a transfer. type ServiceFee struct { FeeCode string `bson:"feeCode" json:"feeCode"` Amount *moneyv1.Money `bson:"amount" json:"amount"` Description string `bson:"description,omitempty" json:"description,omitempty"` } type TransferDestination struct { ManagedWalletRef string `bson:"managedWalletRef,omitempty" json:"managedWalletRef,omitempty"` ExternalAddress string `bson:"externalAddress,omitempty" json:"externalAddress,omitempty"` Memo string `bson:"memo,omitempty" json:"memo,omitempty"` } // Transfer models an on-chain transfer orchestrated by the gateway. type Transfer struct { storable.Base `bson:",inline" json:",inline"` TransferRef string `bson:"transferRef" json:"transferRef"` IdempotencyKey string `bson:"idempotencyKey" json:"idempotencyKey"` OrganizationRef string `bson:"organizationRef" json:"organizationRef"` SourceWalletRef string `bson:"sourceWalletRef" json:"sourceWalletRef"` Destination TransferDestination `bson:"destination" json:"destination"` Network string `bson:"network" json:"network"` TokenSymbol string `bson:"tokenSymbol" json:"tokenSymbol"` ContractAddress string `bson:"contractAddress" json:"contractAddress"` RequestedAmount *moneyv1.Money `bson:"requestedAmount" json:"requestedAmount"` NetAmount *moneyv1.Money `bson:"netAmount" json:"netAmount"` Fees []ServiceFee `bson:"fees,omitempty" json:"fees,omitempty"` Status TransferStatus `bson:"status" json:"status"` TxHash string `bson:"txHash,omitempty" json:"txHash,omitempty"` FailureReason string `bson:"failureReason,omitempty" json:"failureReason,omitempty"` ClientReference string `bson:"clientReference,omitempty" json:"clientReference,omitempty"` LastStatusAt time.Time `bson:"lastStatusAt" json:"lastStatusAt"` } // Collection implements storable.Storable. func (*Transfer) Collection() string { return mservice.ChainTransfers } // TransferFilter describes the parameters for listing transfers. type TransferFilter struct { SourceWalletRef string DestinationWalletRef string Status TransferStatus Cursor string Limit int32 } // TransferList contains paginated transfer results. type TransferList struct { Items []*Transfer NextCursor string } // Normalize trims strings for consistent indexes. func (t *Transfer) Normalize() { t.TransferRef = strings.TrimSpace(t.TransferRef) t.IdempotencyKey = strings.TrimSpace(t.IdempotencyKey) t.OrganizationRef = strings.TrimSpace(t.OrganizationRef) t.SourceWalletRef = strings.TrimSpace(t.SourceWalletRef) t.Network = strings.TrimSpace(strings.ToLower(t.Network)) t.TokenSymbol = strings.TrimSpace(strings.ToUpper(t.TokenSymbol)) t.ContractAddress = strings.TrimSpace(strings.ToLower(t.ContractAddress)) t.Destination.ManagedWalletRef = strings.TrimSpace(t.Destination.ManagedWalletRef) t.Destination.ExternalAddress = strings.TrimSpace(strings.ToLower(t.Destination.ExternalAddress)) t.Destination.Memo = strings.TrimSpace(t.Destination.Memo) t.ClientReference = strings.TrimSpace(t.ClientReference) }