Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions actions/transactions/broadcast_callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
// broadcastCallback will handle a broadcastCallback call from the broadcast api
func broadcastCallback(c *gin.Context) {
logger := reqctx.Logger(c)
config := reqctx.AppConfig(c)
var callbackResp chainmodels.TXInfo

err := c.Bind(&callbackResp)
Expand All @@ -21,11 +20,7 @@ func broadcastCallback(c *gin.Context) {
return
}

if config.ExperimentalFeatures.V2 {
err = reqctx.Engine(c).TxSyncService().Handle(c, callbackResp)
} else {
err = reqctx.Engine(c).HandleTxCallback(c, &callbackResp)
}
err = reqctx.Engine(c).HandleTxCallback(c, &callbackResp)

if err != nil {
logger.Err(err).Any("TxInfo", callbackResp).Msgf("failed to update transaction in ARC broadcast callback handler")
Expand Down
51 changes: 51 additions & 0 deletions actions/v2/callback/callbacks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package callback

import (
"context"
"net/http"

"github.com/bitcoin-sv/spv-wallet/config"
"github.com/bitcoin-sv/spv-wallet/engine"
"github.com/bitcoin-sv/spv-wallet/engine/chain/models"
"github.com/bitcoin-sv/spv-wallet/engine/spverrors"
"github.com/bitcoin-sv/spv-wallet/engine/v2/utils/must"
"github.com/bitcoin-sv/spv-wallet/server/middleware"
"github.com/bitcoin-sv/spv-wallet/server/reqctx"
"github.com/gin-gonic/gin"
)

type txSyncService interface {
Handle(ctx context.Context, txInfo chainmodels.TXInfo) error
}

// RegisterRoutes registers endpoints for callbacks.
func RegisterRoutes(ginEngine *gin.Engine, cfg *config.AppConfig, engine engine.V2Interface) {
if cfg.ARCCallbackEnabled() {
callbackURL, err := cfg.ARC.Callback.ShouldGetURL()
must.HaveNoErrorf(err, "couldn't get callback URL from configuration")

broadcastCallback := ginEngine.Group("", middleware.CallbackTokenMiddleware())
broadcastCallback.POST(callbackURL.Path, broadcastCallbackHandler(engine.TxSyncService()))
}
}

func broadcastCallbackHandler(service txSyncService) gin.HandlerFunc {
return func(c *gin.Context) {
logger := reqctx.Logger(c)
var callbackResp chainmodels.TXInfo

err := c.Bind(&callbackResp)
if err != nil {
spverrors.ErrorResponse(c, spverrors.ErrCannotBindRequest, logger)
return
}

err = service.Handle(c, callbackResp)

if err != nil {
logger.Err(err).Ctx(c).Any("TxInfo", callbackResp).Msgf("failed to update transaction in ARC broadcast callback handler")
}

c.Status(http.StatusOK)
}
}
12 changes: 9 additions & 3 deletions actions/v2/register.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package v2

import (
"github.com/bitcoin-sv/spv-wallet/actions/paymailserver"
"github.com/bitcoin-sv/spv-wallet/actions/v2/callback"
"github.com/bitcoin-sv/spv-wallet/actions/v2/swagger"
"github.com/bitcoin-sv/spv-wallet/server/handlers"
"github.com/bitcoin-sv/spv-wallet/config"
"github.com/bitcoin-sv/spv-wallet/engine"
"github.com/gin-gonic/gin"
)

// RegisterNonOpenAPIRoutes collects all the action's routes that aren't part of the Open API documentation and registers them using the handlersManager.
func RegisterNonOpenAPIRoutes(handlersManager *handlers.Manager) {
swagger.RegisterRoutes(handlersManager)
func RegisterNonOpenAPIRoutes(ginEngine *gin.Engine, cfg *config.AppConfig, engine engine.V2Interface) {
paymailserver.Register(engine.PaymailServerConfiguration(), ginEngine)
swagger.RegisterRoutes(ginEngine, cfg)
callback.RegisterRoutes(ginEngine, cfg, engine)
}
10 changes: 5 additions & 5 deletions actions/v2/swagger/swagger-ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@ import (
"strings"

"github.com/bitcoin-sv/spv-wallet/api"
routes "github.com/bitcoin-sv/spv-wallet/server/handlers"
"github.com/bitcoin-sv/spv-wallet/config"
"github.com/gin-gonic/gin"
swaggerfiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
)

// RegisterRoutes creates the specific package routes
func RegisterRoutes(handlersManager *routes.Manager) {
root := handlersManager.Get(routes.GroupRoot)
func RegisterRoutes(engine *gin.Engine, cfg *config.AppConfig) {
root := engine.Group("")

root.GET("v2/swagger", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "v2/swagger/index.html")
})

api.Yaml = strings.Replace(api.Yaml, "version: main", fmt.Sprintf("version: '%s'", handlersManager.APIVersion()), 1)
api.Yaml = strings.Replace(api.Yaml, "https://github.com/bitcoin-sv/spv-wallet/blob/main", fmt.Sprintf("https://github.com/bitcoin-sv/spv-wallet/blob/%s", handlersManager.APIVersion()), 1)
api.Yaml = strings.Replace(api.Yaml, "version: main", fmt.Sprintf("version: '%s'", cfg.Version), 1)
api.Yaml = strings.Replace(api.Yaml, "https://github.com/bitcoin-sv/spv-wallet/blob/main", fmt.Sprintf("https://github.com/bitcoin-sv/spv-wallet/blob/%s", cfg.Version), 1)

root.GET("/api/gen.api.yaml", func(c *gin.Context) {
c.Header("Content-Type", "application/yaml")
Expand Down
131 changes: 41 additions & 90 deletions engine/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,7 @@ import (
paymailclient "github.com/bitcoin-sv/spv-wallet/engine/paymail"
"github.com/bitcoin-sv/spv-wallet/engine/spverrors"
"github.com/bitcoin-sv/spv-wallet/engine/taskmanager"
"github.com/bitcoin-sv/spv-wallet/engine/v2/addresses"
"github.com/bitcoin-sv/spv-wallet/engine/v2/data"
"github.com/bitcoin-sv/spv-wallet/engine/v2/database/repository"
"github.com/bitcoin-sv/spv-wallet/engine/v2/operations"
"github.com/bitcoin-sv/spv-wallet/engine/v2/paymails"
"github.com/bitcoin-sv/spv-wallet/engine/v2/transaction/outlines"
"github.com/bitcoin-sv/spv-wallet/engine/v2/transaction/record"
"github.com/bitcoin-sv/spv-wallet/engine/v2/transaction/txsync"
"github.com/bitcoin-sv/spv-wallet/engine/v2/users"
"github.com/bitcoin-sv/spv-wallet/engine/v2/engine"
"github.com/bitcoin-sv/spv-wallet/models/bsv"
"github.com/go-resty/resty/v2"
"github.com/mrz1836/go-cachestore"
Expand All @@ -37,39 +29,32 @@ type (
// Client is the SPV Wallet Engine client & options
Client struct {
options *clientOptions
// TEMPORARY: to limit the changes in the codebase
V2Interface
}

// clientOptions holds all the configuration for the client
clientOptions struct {
cacheStore *cacheStoreOptions // Configuration options for Cachestore (ristretto, redis, etc.)
cluster *clusterOptions // Configuration options for the cluster coordinator
dataStore *dataStoreOptions // Configuration options for the DataStore (PostgreSQL, etc.)
debug bool // If the client is in debug mode
encryptionKey string // Encryption key for encrypting sensitive information (IE: paymail xPub) (hex encoded key)
httpClient *resty.Client // HTTP client to use for http calls
iuc bool // (Input UTXO Check) True will check input utxos when saving transactions
logger *zerolog.Logger // Internal logging
metrics *metrics.Metrics // Metrics with a collector interface
notifications *notificationsOptions // Configuration options for Notifications
paymail *paymailOptions // Paymail options & client
transactionOutlinesService outlines.Service // Service for transaction outlines
transactionRecordService *record.Service // Service for recording transactions
taskManager *taskManagerOptions // Configuration options for the TaskManager (TaskQ, etc.)
userAgent string // User agent for all outgoing requests
chainService chain.Service // Chain service
arcConfig chainmodels.ARCConfig // Configuration for ARC
bhsConfig chainmodels.BHSConfig // Configuration for BHS
feeUnit *bsv.FeeUnit // Fee unit for transactions

// v2
repositories *repository.All // Repositories for all db models
users *users.Service // User domain service
paymails *paymails.Service // Paymail domain service
addresses *addresses.Service
operations *operations.Service
txSync *txsync.Service
data *data.Service
config *config.AppConfig
cacheStore *cacheStoreOptions // Configuration options for Cachestore (ristretto, redis, etc.)
cluster *clusterOptions // Configuration options for the cluster coordinator
dataStore *dataStoreOptions // Configuration options for the DataStore (PostgreSQL, etc.)
debug bool // If the client is in debug mode
encryptionKey string // Encryption key for encrypting sensitive information (IE: paymail xPub) (hex encoded key)
httpClient *resty.Client // HTTP client to use for http calls
iuc bool // (Input UTXO Check) True will check input utxos when saving transactions
logger *zerolog.Logger // Internal logging
metrics *metrics.Metrics // Metrics with a collector interface
notifications *notificationsOptions // Configuration options for Notifications
paymail *paymailOptions // Paymail options & client
taskManager *taskManagerOptions // Configuration options for the TaskManager (TaskQ, etc.)
userAgent string // User agent for all outgoing requests
feeUnit *bsv.FeeUnit // Fee unit for transactions

chainService chain.Service // Chain service
arcConfig chainmodels.ARCConfig // Configuration for ARC
bhsConfig chainmodels.BHSConfig // Configuration for BHS

config *config.AppConfig
}

// cacheStoreOptions holds the cache configuration and client
Expand Down Expand Up @@ -138,6 +123,16 @@ func NewClient(ctx context.Context, opts ...ClientOps) (ClientInterface, error)
client.options.logger = logging.GetDefaultLogger()
}

if client.options.config != nil && client.options.config.ExperimentalFeatures.V2 {
client.V2Interface = engine.NewEngine(
client.options.config,
*client.options.logger,
engine.WithResty(client.options.httpClient),
engine.WithPaymailClient(client.options.paymail.client),
)
return client, nil
}

// Load the Cachestore client
var err error
if err = client.loadCache(ctx); err != nil {
Expand All @@ -158,14 +153,6 @@ func NewClient(ctx context.Context, opts ...ClientOps) (ClientInterface, error)
return nil, err
}

client.loadRepositories()

client.loadUsersService()
client.loadPaymailsService()
client.loadAddressesService()
client.loadDataService()
client.loadOperationsService()

// Load the Paymail client and service (if does not exist)
if err = client.loadPaymailComponents(); err != nil {
return nil, err
Expand All @@ -182,11 +169,6 @@ func NewClient(ctx context.Context, opts ...ClientOps) (ClientInterface, error)
}

client.loadChainService()
client.loadTxSyncService()

if err = client.loadTransactionRecordService(); err != nil {
return nil, err
}

// Register all cron jobs
if err = client.registerCronJobs(); err != nil {
Expand All @@ -203,10 +185,6 @@ func NewClient(ctx context.Context, opts ...ClientOps) (ClientInterface, error)
}
}

if err = client.loadTransactionOutlinesService(); err != nil {
return nil, err
}

// Return the client
return client, nil
}
Expand All @@ -229,6 +207,14 @@ func (c *Client) Cluster() cluster.ClientInterface {

// Close will safely close any open connections (cache, datastore, etc.)
func (c *Client) Close(ctx context.Context) error {
if c.V2Interface != nil {
err := c.V2Interface.Close(ctx)
if err != nil {
return spverrors.Wrapf(err, "failed to close envine V2")
}
return nil
}

// Close WebhookManager
if c.options.notifications != nil && c.options.notifications.webhookManager != nil {
c.options.notifications.webhookManager.Stop()
Expand Down Expand Up @@ -351,38 +337,3 @@ func (c *Client) LogBHSReadiness(ctx context.Context) {
func (c *Client) FeeUnit() bsv.FeeUnit {
return *c.options.feeUnit
}

// Repositories will return all the repositories
func (c *Client) Repositories() *repository.All {
return c.options.repositories
}

// UsersService will return the user domain service
func (c *Client) UsersService() *users.Service {
return c.options.users
}

// PaymailsService will return the paymail domain service
func (c *Client) PaymailsService() *paymails.Service {
return c.options.paymails
}

// AddressesService will return the address domain service
func (c *Client) AddressesService() *addresses.Service {
return c.options.addresses
}

// DataService will return the data domain service
func (c *Client) DataService() *data.Service {
return c.options.data
}

// OperationsService will return the operations domain service
func (c *Client) OperationsService() *operations.Service {
return c.options.operations
}

// TxSyncService will return the transaction sync service
func (c *Client) TxSyncService() *txsync.Service {
return c.options.txSync
}
Loading
Loading