Skip to content

Commit

Permalink
Merge pull request #64 from bitcoin-sv/feat-641-shared-config
Browse files Browse the repository at this point in the history
feat(BUX-641) Shared- & Public- config
  • Loading branch information
chris-4chain authored Mar 13, 2024
2 parents 8375025 + ef7e481 commit 6900bc7
Show file tree
Hide file tree
Showing 13 changed files with 341 additions and 106 deletions.
33 changes: 33 additions & 0 deletions docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,25 @@ const docTemplate = `{
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/api/v1/config": {
"get": {
"produces": [
"application/json"
],
"tags": [
"sharedconfig"
],
"summary": "Get config returns config fields exposed to clients",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/config.PublicConfig"
}
}
}
}
},
"/api/v1/sign-in": {
"post": {
"consumes": [
Expand Down Expand Up @@ -244,6 +263,20 @@ const docTemplate = `{
}
}
},
"config.PublicConfig": {
"type": "object",
"properties": {
"experimental_features": {
"type": "object",
"additionalProperties": {
"type": "boolean"
}
},
"paymail_domain": {
"type": "string"
}
}
},
"spvwallet.FullTransaction": {
"type": "object",
"properties": {
Expand Down
33 changes: 33 additions & 0 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@
"version": "1.0"
},
"paths": {
"/api/v1/config": {
"get": {
"produces": [
"application/json"
],
"tags": [
"sharedconfig"
],
"summary": "Get config returns config fields exposed to clients",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/config.PublicConfig"
}
}
}
}
},
"/api/v1/sign-in": {
"post": {
"consumes": [
Expand Down Expand Up @@ -236,6 +255,20 @@
}
}
},
"config.PublicConfig": {
"type": "object",
"properties": {
"experimental_features": {
"type": "object",
"additionalProperties": {
"type": "boolean"
}
},
"paymail_domain": {
"type": "string"
}
}
},
"spvwallet.FullTransaction": {
"type": "object",
"properties": {
Expand Down
21 changes: 21 additions & 0 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ definitions:
password:
type: string
type: object
config.PublicConfig:
properties:
experimental_features:
additionalProperties:
type: boolean
type: object
paymail_domain:
type: string
type: object
spvwallet.FullTransaction:
properties:
blockHash:
Expand Down Expand Up @@ -110,6 +119,18 @@ info:
title: SPV Wallet WEB Backend
version: "1.0"
paths:
/api/v1/config:
get:
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/config.PublicConfig'
summary: Get config returns config fields exposed to clients
tags:
- sharedconfig
/api/v1/sign-in:
post:
consumes:
Expand Down
81 changes: 81 additions & 0 deletions domain/config/config_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package config

import (
"slices"
"sync"
"time"

backendconfig "github.com/bitcoin-sv/spv-wallet-web-backend/config"
"github.com/bitcoin-sv/spv-wallet-web-backend/domain/users"
"github.com/bitcoin-sv/spv-wallet/models"
"github.com/rs/zerolog"
"github.com/spf13/viper"
)

const cacheTTL = 10 * time.Minute

// ConfigService is a service for fetching and caching SharedConfig from the spv-wallet and providing PublicConfig.
type ConfigService struct {
adminWalletClient users.AdminWalletClient
log *zerolog.Logger

sharedConfig *models.SharedConfig
publicConfig *PublicConfig
mutex sync.Mutex
lastFetch time.Time
}

// NewConfigService creates a new ConfigService.
func NewConfigService(adminWalletClient users.AdminWalletClient, log *zerolog.Logger) *ConfigService {
return &ConfigService{
adminWalletClient: adminWalletClient,
log: log,
sharedConfig: nil,
publicConfig: nil,
}
}

// GetSharedConfig returns shared config.
// If shared config is not cached, it will be fetched from the spv-wallet.
// SharedConfig should not be exposed to the public - use PublicConfig instead.
func (s *ConfigService) GetSharedConfig() *models.SharedConfig {
s.makeConfigs()
return s.sharedConfig
}

// GetPublicConfig returns public config.
func (s *ConfigService) GetPublicConfig() *PublicConfig {
s.makeConfigs()
return s.publicConfig
}

func (s *ConfigService) makeConfigs() {
s.mutex.Lock()
defer s.mutex.Unlock()

if s.sharedConfig != nil && time.Since(s.lastFetch) < cacheTTL {
return
}
s.lastFetch = time.Now()

shared, err := s.adminWalletClient.GetSharedConfig()
if err != nil {
s.log.Error().Err(err).Msg("Failed to get shared config")
return
}

s.sharedConfig = shared
s.publicConfig = s.makePublicConfig(shared)
}

func (s *ConfigService) makePublicConfig(shared *models.SharedConfig) *PublicConfig {
configuredPaymailDomain := viper.GetString(backendconfig.EnvPaymailDomain)
if !slices.Contains(shared.PaymilDomains, configuredPaymailDomain) {
s.log.Warn().Str("configuredPaymailDomain", configuredPaymailDomain).Msg("Configured paymail domain is not in the list of paymail domains from SPV Wallet")
}

return &PublicConfig{
PaymilDomain: configuredPaymailDomain,
ExperimentalFeatures: shared.ExperimentalFeatures,
}
}
7 changes: 7 additions & 0 deletions domain/config/public_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package config

// PublicConfig represents a config that is exposed to the public.
type PublicConfig struct {
PaymilDomain string `json:"paymail_domain"`
ExperimentalFeatures map[string]bool `json:"experimental_features"`
}
3 changes: 3 additions & 0 deletions domain/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package domain

import (
db_users "github.com/bitcoin-sv/spv-wallet-web-backend/data/users"
"github.com/bitcoin-sv/spv-wallet-web-backend/domain/config"
"github.com/bitcoin-sv/spv-wallet-web-backend/domain/transactions"
"github.com/bitcoin-sv/spv-wallet-web-backend/domain/users"
"github.com/bitcoin-sv/spv-wallet-web-backend/transports/spvwallet"
Expand All @@ -14,6 +15,7 @@ type Services struct {
UsersService *users.UserService
TransactionsService *transactions.TransactionService
WalletClientFactory users.WalletClientFactory
ConfigService *config.ConfigService
}

// NewServices creates services instance.
Expand All @@ -31,5 +33,6 @@ func NewServices(usersRepo *db_users.UsersRepository, log *zerolog.Logger) (*Ser
UsersService: uService,
TransactionsService: transactions.NewTransactionService(adminWalletClient, walletClientFactory, log),
WalletClientFactory: walletClientFactory,
ConfigService: config.NewConfigService(adminWalletClient, log),
}, nil
}
1 change: 1 addition & 0 deletions domain/users/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ type (
AdminWalletClient interface {
RegisterXpub(xpriv *bip32.ExtendedKey) (string, error)
RegisterPaymail(alias, xpub string) (string, error)
GetSharedConfig() (*models.SharedConfig, error)
}

// WalletClientFactory defines methods to create user and admin clients.
Expand Down
63 changes: 30 additions & 33 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ go 1.21.5

require (
github.com/avast/retry-go/v4 v4.5.1
github.com/bitcoin-sv/spv-wallet-go-client v0.6.0
github.com/bitcoin-sv/spv-wallet/models v0.15.0
github.com/brianvoe/gofakeit/v6 v6.26.3
github.com/centrifugal/centrifuge v0.30.6
github.com/bitcoin-sv/spv-wallet-go-client v0.7.0
github.com/bitcoin-sv/spv-wallet/models v0.20.0
github.com/brianvoe/gofakeit/v6 v6.28.0
github.com/centrifugal/centrifuge v0.31.0
github.com/gin-contrib/sessions v0.0.5
github.com/golang/mock v1.6.0
github.com/libsv/go-bk v0.1.6
github.com/rs/zerolog v1.31.0
github.com/rs/zerolog v1.32.0
github.com/spf13/viper v1.18.2
github.com/stretchr/testify v1.8.4
github.com/stretchr/testify v1.9.0
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.0
github.com/swaggo/swag v1.16.2
github.com/swaggo/swag v1.16.3
github.com/xdg-go/pbkdf2 v1.0.0
go.elastic.co/ecszerolog v0.2.0
)
Expand All @@ -28,48 +28,45 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/bitcoinschema/go-bitcoin/v2 v2.0.5 // indirect
github.com/bitcoinsv/bsvd v0.0.0-20190609155523-4c29707f7173 // indirect
github.com/bytedance/sonic v1.10.2 // indirect
github.com/centrifugal/protocol v0.11.0 // indirect
github.com/bytedance/sonic v1.11.2 // indirect
github.com/centrifugal/protocol v0.12.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/spec v0.20.13 // indirect
github.com/go-openapi/swag v0.22.7 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/spec v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.16.0 // indirect
github.com/go-playground/validator/v10 v10.19.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/context v1.1.2 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/gorilla/sessions v1.2.2 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/igm/sockjs-go/v3 v3.0.3 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/libsv/go-bt/v2 v2.2.5 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.18.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/prometheus/client_golang v1.19.0 // indirect
github.com/prometheus/client_model v0.6.0 // indirect
github.com/prometheus/common v0.50.0 // indirect
github.com/prometheus/procfs v0.13.0 // indirect
github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect
github.com/redis/rueidis v1.0.25 // indirect
github.com/redis/rueidis v1.0.31 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/segmentio/asm v1.2.0 // indirect
Expand All @@ -80,13 +77,13 @@ require (
github.com/valyala/bytebufferpool v1.0.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.6.0 // indirect
golang.org/x/crypto v0.19.0 // indirect
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/tools v0.16.1 // indirect
google.golang.org/protobuf v1.32.0 // indirect
golang.org/x/arch v0.7.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/tools v0.19.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
)

require (
Expand All @@ -103,7 +100,7 @@ require (
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
Loading

0 comments on commit 6900bc7

Please sign in to comment.