ledger account describibale support
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
)
|
||||
|
||||
type LedgerAccountType string
|
||||
@@ -32,6 +33,7 @@ type CreateLedgerAccount struct {
|
||||
AllowNegative bool `json:"allowNegative,omitempty"`
|
||||
IsSettlement bool `json:"isSettlement,omitempty"`
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
Describable *model.Describable `json:"describable,omitempty"`
|
||||
}
|
||||
|
||||
func (r *CreateLedgerAccount) Validate() error {
|
||||
|
||||
@@ -12,6 +12,8 @@ type Signup struct {
|
||||
Organization model.Describable `json:"organization"`
|
||||
OrganizationTimeZone string `json:"organizationTimeZone"`
|
||||
OwnerRole model.Describable `json:"ownerRole"`
|
||||
CryptoWallet model.Describable `json:"cryptoWallet"`
|
||||
LedgerWallet model.Describable `json:"ledgerWallet"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON enforces strict parsing to catch malformed or unexpected fields.
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
"github.com/tech/sendico/pkg/mservice"
|
||||
"github.com/tech/sendico/pkg/mutil/mzap"
|
||||
describablev1 "github.com/tech/sendico/pkg/proto/common/describable/v1"
|
||||
chainv1 "github.com/tech/sendico/pkg/proto/gateway/chain/v1"
|
||||
"github.com/tech/sendico/server/interface/api/srequest"
|
||||
"github.com/tech/sendico/server/interface/api/sresponse"
|
||||
@@ -252,6 +253,10 @@ func (a *AccountAPI) openOrgWallet(ctx context.Context, org *model.Organization,
|
||||
IdempotencyKey: uuid.NewString(),
|
||||
OrganizationRef: org.ID.Hex(),
|
||||
OwnerRef: org.ID.Hex(),
|
||||
Describable: &describablev1.Describable{
|
||||
Name: sr.CryptoWallet.Name,
|
||||
Description: sr.CryptoWallet.Description,
|
||||
},
|
||||
Asset: a.chainAsset,
|
||||
Metadata: map[string]string{
|
||||
"source": "signup",
|
||||
|
||||
@@ -15,14 +15,20 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
errConfirmationNotFound = errors.New("confirmation not found or expired")
|
||||
errConfirmationUsed = errors.New("confirmation already used")
|
||||
errConfirmationMismatch = errors.New("confirmation code mismatch")
|
||||
errConfirmationAttemptsExceeded = errors.New("confirmation attempts exceeded")
|
||||
errConfirmationCooldown = errors.New("confirmation cooldown active")
|
||||
errConfirmationResendLimit = errors.New("confirmation resend limit reached")
|
||||
errConfirmationNotFound confirmationError = "confirmation not found or expired"
|
||||
errConfirmationUsed confirmationError = "confirmation already used"
|
||||
errConfirmationMismatch confirmationError = "confirmation code mismatch"
|
||||
errConfirmationAttemptsExceeded confirmationError = "confirmation attempts exceeded"
|
||||
errConfirmationCooldown confirmationError = "confirmation cooldown active"
|
||||
errConfirmationResendLimit confirmationError = "confirmation resend limit reached"
|
||||
)
|
||||
|
||||
type confirmationError string
|
||||
|
||||
func (e confirmationError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
type ConfirmationStore struct {
|
||||
db confirmation.DB
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package ledgerapiimp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/tech/sendico/pkg/api/http/response"
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
"github.com/tech/sendico/pkg/mservice"
|
||||
ledgerv1 "github.com/tech/sendico/pkg/proto/ledger/v1"
|
||||
@@ -24,7 +24,7 @@ func (a *LedgerAPI) getBalance(r *http.Request, account *model.Account, token *s
|
||||
|
||||
accountRef := strings.TrimSpace(a.aph.GetID(r))
|
||||
if accountRef == "" {
|
||||
return response.BadReference(a.logger, a.Name(), a.aph.Name(), a.aph.GetID(r), errors.New("ledger account reference is required"))
|
||||
return response.BadReference(a.logger, a.Name(), a.aph.Name(), a.aph.GetID(r), merrors.InvalidArgument("ledger account reference is required"))
|
||||
}
|
||||
|
||||
ctx := r.Context()
|
||||
@@ -38,7 +38,7 @@ func (a *LedgerAPI) getBalance(r *http.Request, account *model.Account, token *s
|
||||
return response.AccessDenied(a.logger, a.Name(), "ledger balance read permission denied")
|
||||
}
|
||||
if a.client == nil {
|
||||
return response.Internal(a.logger, mservice.Ledger, errors.New("ledger client is not configured"))
|
||||
return response.Internal(a.logger, mservice.Ledger, merrors.Internal("ledger client is not configured"))
|
||||
}
|
||||
|
||||
resp, err := a.client.GetBalance(ctx, &ledgerv1.GetBalanceRequest{
|
||||
|
||||
@@ -2,7 +2,6 @@ package ledgerapiimp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -10,6 +9,7 @@ import (
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
"github.com/tech/sendico/pkg/mservice"
|
||||
describablev1 "github.com/tech/sendico/pkg/proto/common/describable/v1"
|
||||
ledgerv1 "github.com/tech/sendico/pkg/proto/ledger/v1"
|
||||
"github.com/tech/sendico/server/interface/api/srequest"
|
||||
"github.com/tech/sendico/server/interface/api/sresponse"
|
||||
@@ -52,7 +52,25 @@ func (a *LedgerAPI) createAccount(r *http.Request, account *model.Account, token
|
||||
}
|
||||
|
||||
if a.client == nil {
|
||||
return response.Internal(a.logger, mservice.Ledger, errors.New("ledger client is not configured"))
|
||||
return response.Internal(a.logger, mservice.Ledger, merrors.Internal("ledger client is not configured"))
|
||||
}
|
||||
|
||||
var describable *describablev1.Describable
|
||||
if payload.Describable != nil {
|
||||
name := strings.TrimSpace(payload.Describable.Name)
|
||||
var description *string
|
||||
if payload.Describable.Description != nil {
|
||||
trimmed := strings.TrimSpace(*payload.Describable.Description)
|
||||
if trimmed != "" {
|
||||
description = &trimmed
|
||||
}
|
||||
}
|
||||
if name != "" || description != nil {
|
||||
describable = &describablev1.Describable{
|
||||
Name: name,
|
||||
Description: description,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := a.client.CreateAccount(ctx, &ledgerv1.CreateAccountRequest{
|
||||
@@ -64,6 +82,7 @@ func (a *LedgerAPI) createAccount(r *http.Request, account *model.Account, token
|
||||
AllowNegative: payload.AllowNegative,
|
||||
IsSettlement: payload.IsSettlement,
|
||||
Metadata: payload.Metadata,
|
||||
Describable: describable,
|
||||
})
|
||||
if err != nil {
|
||||
a.logger.Warn("Failed to create ledger account", zap.Error(err), zap.String("organization_ref", orgRef.Hex()))
|
||||
@@ -82,6 +101,20 @@ func decodeLedgerAccountCreatePayload(r *http.Request) (*srequest.CreateLedgerAc
|
||||
}
|
||||
payload.AccountCode = strings.TrimSpace(payload.AccountCode)
|
||||
payload.Currency = strings.ToUpper(strings.TrimSpace(payload.Currency))
|
||||
if payload.Describable != nil {
|
||||
payload.Describable.Name = strings.TrimSpace(payload.Describable.Name)
|
||||
if payload.Describable.Description != nil {
|
||||
trimmed := strings.TrimSpace(*payload.Describable.Description)
|
||||
if trimmed == "" {
|
||||
payload.Describable.Description = nil
|
||||
} else {
|
||||
payload.Describable.Description = &trimmed
|
||||
}
|
||||
}
|
||||
if payload.Describable.Name == "" && payload.Describable.Description == nil {
|
||||
payload.Describable = nil
|
||||
}
|
||||
}
|
||||
if len(payload.Metadata) == 0 {
|
||||
payload.Metadata = nil
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package ledgerapiimp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/tech/sendico/pkg/api/http/response"
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
"github.com/tech/sendico/pkg/mservice"
|
||||
ledgerv1 "github.com/tech/sendico/pkg/proto/ledger/v1"
|
||||
@@ -32,7 +32,7 @@ func (a *LedgerAPI) listAccounts(r *http.Request, account *model.Account, token
|
||||
return response.AccessDenied(a.logger, a.Name(), "ledger accounts read permission denied")
|
||||
}
|
||||
if a.client == nil {
|
||||
return response.Internal(a.logger, mservice.Ledger, errors.New("ledger client is not configured"))
|
||||
return response.Internal(a.logger, mservice.Ledger, merrors.Internal("ledger client is not configured"))
|
||||
}
|
||||
|
||||
resp, err := a.client.ListAccounts(ctx, &ledgerv1.ListAccountsRequest{
|
||||
|
||||
@@ -3,13 +3,13 @@ package paymentapiimp
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/tech/sendico/pkg/api/http/response"
|
||||
"github.com/tech/sendico/pkg/discovery"
|
||||
me "github.com/tech/sendico/pkg/messaging/envelope"
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
"github.com/tech/sendico/server/interface/api/sresponse"
|
||||
mutil "github.com/tech/sendico/server/internal/mutil/param"
|
||||
@@ -21,7 +21,7 @@ const discoveryLookupTimeout = 3 * time.Second
|
||||
|
||||
func (a *PaymentAPI) listDiscoveryRegistry(r *http.Request, account *model.Account, _ *sresponse.TokenData) http.HandlerFunc {
|
||||
if a.discovery == nil {
|
||||
return response.Internal(a.logger, a.Name(), errors.New("discovery client is not configured"))
|
||||
return response.Internal(a.logger, a.Name(), merrors.Internal("discovery client is not configured"))
|
||||
}
|
||||
|
||||
orgRef, err := a.oph.GetRef(r)
|
||||
@@ -55,7 +55,7 @@ func (a *PaymentAPI) listDiscoveryRegistry(r *http.Request, account *model.Accou
|
||||
|
||||
func (a *PaymentAPI) getDiscoveryRefresh(r *http.Request, account *model.Account, _ *sresponse.TokenData) http.HandlerFunc {
|
||||
if a.refreshConsumer == nil {
|
||||
return response.Internal(a.logger, a.Name(), errors.New("discovery refresh consumer is not configured"))
|
||||
return response.Internal(a.logger, a.Name(), merrors.Internal("discovery refresh consumer is not configured"))
|
||||
}
|
||||
|
||||
orgRef, err := a.oph.GetRef(r)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package walletapiimp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/tech/sendico/pkg/api/http/response"
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
"github.com/tech/sendico/pkg/mservice"
|
||||
chainv1 "github.com/tech/sendico/pkg/proto/gateway/chain/v1"
|
||||
@@ -23,7 +23,7 @@ func (a *WalletAPI) getWalletBalance(r *http.Request, account *model.Account, to
|
||||
}
|
||||
walletRef := strings.TrimSpace(a.wph.GetID(r))
|
||||
if walletRef == "" {
|
||||
return response.BadReference(a.logger, a.Name(), a.wph.Name(), a.wph.GetID(r), errors.New("wallet reference is required"))
|
||||
return response.BadReference(a.logger, a.Name(), a.wph.Name(), a.wph.GetID(r), merrors.InvalidArgument("wallet reference is required"))
|
||||
}
|
||||
|
||||
ctx := r.Context()
|
||||
@@ -37,7 +37,7 @@ func (a *WalletAPI) getWalletBalance(r *http.Request, account *model.Account, to
|
||||
return response.AccessDenied(a.logger, a.Name(), "wallet balance read permission denied")
|
||||
}
|
||||
if a.chainGateway == nil {
|
||||
return response.Internal(a.logger, mservice.ChainGateway, errors.New("chain gateway client is not configured"))
|
||||
return response.Internal(a.logger, mservice.ChainGateway, merrors.Internal("chain gateway client is not configured"))
|
||||
}
|
||||
|
||||
resp, err := a.chainGateway.GetWalletBalance(ctx, &chainv1.GetWalletBalanceRequest{WalletRef: walletRef})
|
||||
@@ -49,7 +49,7 @@ func (a *WalletAPI) getWalletBalance(r *http.Request, account *model.Account, to
|
||||
bal := resp.GetBalance()
|
||||
if bal == nil {
|
||||
a.logger.Warn("Wallet balance missing in response", zap.String("wallet_ref", walletRef))
|
||||
return response.Auto(a.logger, mservice.ChainGateway, errors.New("wallet balance not available"))
|
||||
return response.Auto(a.logger, mservice.ChainGateway, merrors.Internal("wallet balance not available"))
|
||||
}
|
||||
|
||||
return sresponse.WalletBalance(a.logger, bal, token)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package walletapiimp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/tech/sendico/pkg/api/http/response"
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
"github.com/tech/sendico/pkg/model"
|
||||
"github.com/tech/sendico/pkg/mservice"
|
||||
chainv1 "github.com/tech/sendico/pkg/proto/gateway/chain/v1"
|
||||
@@ -33,7 +33,7 @@ func (a *WalletAPI) listWallets(r *http.Request, account *model.Account, token *
|
||||
return response.AccessDenied(a.logger, a.Name(), "wallets read permission denied")
|
||||
}
|
||||
if a.chainGateway == nil {
|
||||
return response.Internal(a.logger, mservice.ChainGateway, errors.New("chain gateway client is not configured"))
|
||||
return response.Internal(a.logger, mservice.ChainGateway, merrors.Internal("chain gateway client is not configured"))
|
||||
}
|
||||
|
||||
req := &chainv1.ListManagedWalletsRequest{
|
||||
|
||||
Reference in New Issue
Block a user