Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 6 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ output:

# all available settings of specific linters
linters-settings:
revive:
rules:
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#package-comments
- name: package-comments
severity: warning
disabled: true
dogsled:
# checks assignments with too many blank identifiers; default is 2
max-blank-identifiers: 2
Expand Down
2 changes: 1 addition & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ It is responsible for validating data and enforcing the protocol rules.

Data stores each have their own top level package, named to match the store.

At the moment there are two supported data stores, noop and payd. The payD store will communicate with a PayD server using Http, additional stores can be added as long as they implement to common interfaces.
At the moment there is one supported data store, noop. Additional stores can be added as long as they implement to common interfaces.

The data layer knows only about how to interact with the data store to store or retrieve data. This will be called by the service layer, but the service layer doesn't know or care about what data store it is interacting with.

Expand Down
18 changes: 5 additions & 13 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
## How to contribute to payd
## How to contribute to the Direct Payment Proxy

#### **Did you find a bug?**

* **Do not open up a GitHub issue if the bug is a security vulnerability
in payd**, and instead to refer to our [security policy](https://github.com/libsv/payd/blob/master/SECURITY.md).
in dpp-proxy**, and instead to refer to our [security policy](https://github.com/bitcoin-sv/dpp-proxy/blob/master/SECURITY.md).

* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/libsv/payd/issues).
* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/bitcoin-sv/dpp-proxy/issues).

* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/libsv/payd/issues/new/choose). Be sure to to follow our issues template as much as possible.
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/bitcoin-sv/dpp-proxy/issues/new/choose). Be sure to to follow our issues template as much as possible.

#### **Did you write a patch that fixes a bug?**

Expand All @@ -19,12 +19,4 @@

#### **Do you have questions about the source code?**

* Ask any question about how to use LiBSV/payd on [stackoverflow](https://stackoverflow.com) using the `libsv` or `payd` tag. We try to be as responsive as possible.

LiBSV/payd is a volunteer effort. We encourage you to pitch in and interact with the project!

Thanks! :heart:

Libsv Team

Inspired from [Ruby on Rails CONTRIBUTING.MD](https://github.com/rails/rails/blob/master/CONTRIBUTING.md)
Pop onto the [Bitcoin SV](https://discord.gg/bsv) discord and ask in a development related channel.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ vendor-deps:
@go mod tidy && go mod vendor

install-swagger-gen:
@go get github.com/swaggo/swag/cmd/swag
@go install github.com/swaggo/swag/cmd/swag@v1.8.4

generate-swagger:
@swag init --parseVendor --parseDependency --parseInternal -g ./cmd/server/main.go
13 changes: 2 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

The Direct Payment Protocol (DPP - previously BIP270) Proxy, or dpp-proxy, is a basic reference implementation of a Direct Payment Protocol Proxy Server. This proxy service is used in order for wallets that are not directly accessible on the public internet to be able to be contacted through this proxy server.

This is written in go and integrates with a wallet running the Payment Protocol PayD Interface.
This is written in go and integrates with any wallet that connects to its APIs.

## Exploring Endpoints

Expand Down Expand Up @@ -46,15 +46,6 @@ Values can also be passed at build time to provide information such as build inf
| --------- | --------------------------------------------------------------------- | ------- |
| LOG_LEVEL | Level of logging we want within the server (debug, error, warn, info) | info |

### PayD Wallet

| Key | Description | Default |
| ----------- | -------------------------------------------------------- | ------- |
| PAYD_HOST | Host for the wallet we are connecting to | payd |
| PAYD_PORT | Port the PayD wallet is listening on | :8443 |
| PAYD_SECURE | If true the dpp-proxy server will validate the wallet TLS certs | false |
| PAYD_NOOP | If true we will use a dummy data store in place of payd | true |

## Working with dpp-proxy

There are a set of makefile commands listed under the [Makefile](Makefile) which give some useful shortcuts when working
Expand All @@ -66,7 +57,7 @@ Some of the more common commands are listed below:

`make build-image` - builds a local docker image, useful when testing dpp-proxy in docker.

`make run-compose` - runs dpp-proxy in compose, a reference PayD wallet will be added to compose soon NOTE the above command will need ran first.
`make run-compose` - runs dpp-proxy in compose.

### Rebuild on code change

Expand Down
68 changes: 9 additions & 59 deletions cmd/internal/setup.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
package internal

import (
"crypto/tls"
"fmt"
"net/http"
"time"

dppProxy "github.com/bitcoin-sv/dpp-proxy"
"github.com/bitcoin-sv/dpp-proxy/data"
"github.com/bitcoin-sv/dpp-proxy/data/payd"
"github.com/bitcoin-sv/dpp-proxy/data/sockets"
"github.com/bitcoin-sv/dpp-proxy/docs"
"github.com/bitcoin-sv/dpp-proxy/log"
dppHandlers "github.com/bitcoin-sv/dpp-proxy/transports/http"
Expand All @@ -35,39 +29,9 @@ import (

// Deps holds all the dependencies.
type Deps struct {
PaymentService dpp.PaymentService
PaymentRequestService dpp.PaymentRequestService
ProofsService dpp.ProofsService
}

// SetupDeps will setup all required dependent services.
func SetupDeps(cfg config.Config, l log.Logger) *Deps {
httpClient := &http.Client{Timeout: 5 * time.Second}
if !cfg.PayD.Secure { // for testing, don't validate server cert
// #nosec
httpClient.Transport = &http.Transport{
// #nosec
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
}
// stores
paydStore := payd.NewPayD(cfg.PayD, data.NewClient(httpClient))

// services
paymentSvc := service.NewPayment(l, paydStore)
paymentReqSvc := service.NewPaymentRequest(paydStore)
if cfg.PayD.Noop {
noopStore := noop.NewNoOp(log.Noop{})
paymentSvc = service.NewPayment(log.Noop{}, noopStore)
paymentReqSvc = service.NewPaymentRequest(noopStore)
}
proofService := service.NewProof(paydStore)

return &Deps{
PaymentService: paymentSvc,
PaymentRequestService: paymentReqSvc,
ProofsService: proofService,
}
PaymentService dpp.PaymentService
PaymentTermsService dpp.PaymentTermsService
ProofsService dpp.ProofsService
}

// SetupEcho will set up and return an echo server.
Expand Down Expand Up @@ -99,15 +63,6 @@ func SetupSwagger(cfg config.Server, e *echo.Echo) {
e.GET("/swagger/*", echoSwagger.WrapHandler)
}

// SetupHTTPEndpoints will register the http endpoints.
func SetupHTTPEndpoints(deps *Deps, e *echo.Echo) {
g := e.Group("/")
// handlers
dppHandlers.NewPaymentHandler(deps.PaymentService).RegisterRoutes(g)
dppHandlers.NewPaymentRequestHandler(deps.PaymentRequestService).RegisterRoutes(g)
dppHandlers.NewProofs(deps.ProofsService).RegisterRoutes(g)
}

// SetupSockets will setup handlers and socket server.
func SetupSockets(cfg config.Socket, e *echo.Echo) *server.SocketServer {
g := e.Group("/")
Expand All @@ -119,9 +74,9 @@ func SetupSockets(cfg config.Socket, e *echo.Echo) *server.SocketServer {
// add middleware, with panic going first
s.WithMiddleware(smw.PanicHandler, smw.Timeout(smw.NewTimeoutConfig()), smw.Metrics())

dppSoc.NewPaymentRequest().Register(s)
dppSoc.NewPaymentTerms().Register(s)
dppSoc.NewPayment().Register(s)
dppHandlers.NewProofs(service.NewProof(sockets.NewPayd(s))).RegisterRoutes(g)
dppHandlers.NewProofs(service.NewProof(socData.NewPaymentStore(s))).RegisterRoutes(g)

// this is our websocket endpoint, clients will hit this with the channelID they wish to connect to
e.GET("/ws/:channelID", wsHandler(s))
Expand All @@ -137,17 +92,17 @@ func SetupHybrid(cfg config.Config, l log.Logger, e *echo.Echo) *server.SocketSe
// add middleware, with panic going first
s.WithMiddleware(smw.PanicHandler, smw.Timeout(smw.NewTimeoutConfig()), smw.Metrics())

paymentStore := socData.NewPayd(s)
paymentStore := socData.NewPaymentStore(s)
paymentSvc := service.NewPayment(l, paymentStore)
if cfg.PayD.Noop {
noopStore := noop.NewNoOp(log.Noop{})
paymentSvc = service.NewPayment(log.Noop{}, noopStore)
}
paymentReqSvc := service.NewPaymentRequestProxy(paymentStore, cfg.Transports, cfg.Server)
paymentReqSvc := service.NewPaymentTermsProxy(paymentStore, cfg.Transports, cfg.Server)
proofsSvc := service.NewProof(paymentStore)

dppHandlers.NewPaymentHandler(paymentSvc).RegisterRoutes(g)
dppHandlers.NewPaymentRequestHandler(paymentReqSvc).RegisterRoutes(g)
dppHandlers.NewPaymentTermsHandler(paymentReqSvc).RegisterRoutes(g)
dppHandlers.NewProofs(proofsSvc).RegisterRoutes(g)
dppSoc.NewHealthHandler().Register(s)

Expand Down Expand Up @@ -175,12 +130,7 @@ func wsHandler(svr *server.SocketServer) echo.HandlerFunc {

if c.QueryParam("internal") != "true" {
if !svr.HasChannel(chID) {
return c.JSON(http.StatusNotFound, dppProxy.ClientError{
ID: "",
Code: "404",
Message: fmt.Sprintf("Connection for invoice '%s' not found", chID),
Title: "Not found",
})
return c.JSON(http.StatusNotFound, fmt.Sprintf("Connection for invoice '%s' not found", chID))
}
}

Expand Down
32 changes: 15 additions & 17 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ import (
const appname = "payment-protocol-rest-server"
const banner = `
====================================================================
_ _ _ _ _
/\ \ /\ \ /\ \ /\ \ _\ \
/ \ \ / \ \ \_\ \ / \ \ /\__ \
/ /\ \ \ / /\ \ \ /\__ \ / /\ \ \ / /_ \_\
/ / /\ \_\/ / /\ \_\/ /_ \ \ / / /\ \ \ / / /\/_/
/ / /_/ / / / /_/ / / / /\ \ \/ / / \ \_\ / / /
/ / /__\/ / / /__\/ / / / \/_/ / / \/_/ / / /
/ / /_____/ / /_____/ / / / / / / / / ____
/ / / / / / / / / / / /________ / /_/_/ ___/\
/ / / / / / /_/ / / / /_________/_______/\__\/
\/_/ \/_/ \_\/ \/____________\_______\/
_ _ _ _ _
/\ \ /\ \ /\ \ /\ \ _\ \
/ \ \ / \ \ \_\ \ / \ \ /\__ \
/ /\ \ \ / /\ \ \ /\__ \ / /\ \ \ / /_ \_\
/ / /\ \_\/ / /\ \_\/ /_ \ \ / / /\ \ \ / / /\/_/
/ / /_/ / / / /_/ / / / /\ \ \/ / / \ \_\ / / /
/ / /__\/ / / /__\/ / / / \/_/ / / \/_/ / / /
/ / /_____/ / /_____/ / / / / / / / / ____
/ / / / / / / / / / / /________ / /_/_/ ___/\
/ / / / / / /_/ / / / /_________/_______/\__\/
\/_/ \/_/ \_\/ \/____________\_______\/

====================================================================
`
Expand All @@ -38,17 +38,17 @@ const banner = `
// @license.url https://github.com/libsv/go-payment_protocol/blob/master/LICENSE
// @host localhost:8445
// @schemes:
// - http
// - https
// - http
// - https
func main() {
println("\033[32m" + banner + "\033[0m")
config.SetupDefaults()
cfg := config.NewViperConfig(appname).
WithServer().
WithDeployment(appname).
WithLog().
WithPayD().
WithSockets().
WithPayD().
WithTransports().
Load()
log := log.NewZero(cfg.Logging)
Expand All @@ -57,16 +57,14 @@ func main() {
log.Fatal(err, "config error")
}

e := internal.SetupEcho(cfg,log)
e := internal.SetupEcho(cfg, log)

if cfg.Server.SwaggerEnabled {
internal.SetupSwagger(*cfg.Server, e)
}

// setup transports
switch cfg.Transports.Mode {
case config.TransportModeHTTP:
internal.SetupHTTPEndpoints(internal.SetupDeps(*cfg, log), e)
case config.TransportModeSocket:
s := internal.SetupSockets(*cfg.Sockets, e)
internal.SetupSocketMetrics(s)
Expand Down
17 changes: 3 additions & 14 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ const (
EnvCommit = "env.commit"
EnvBuildDate = "env.builddate"
EnvLogLevel = "log.level"
EnvPaydHost = "payd.host"
EnvPaydPort = "payd.port"
EnvPaydSecure = "payd.secure"
EnvPaydCertPath = "payd.cert.path"
EnvPaydNoop = "payd.noop"
EnvSocketChannelTimeoutSeconds = "socket.channel.timeoutseconds"
EnvSocketMaxMessageBytes = "socket.maxmessage.bytes"
Expand All @@ -33,7 +29,6 @@ const (
LogWarn = "warn"

TransportModeHybrid = "hybrid"
TransportModeHTTP = "http"
TransportModeSocket = "socket"
)

Expand Down Expand Up @@ -77,23 +72,17 @@ type Logging struct {
type Server struct {
Port string
Hostname string
// FQDN - fully qualified domain name, used to form the paymentRequest
// FQDN - fully qualified domain name, used to form the PaymentTerms
// payment URL as this may be different from the hostname + port.
FQDN string
// SwaggerEnabled if true we will include an endpoint to serve swagger documents.
SwaggerEnabled bool
SwaggerHost string
}

// PayD is used to setup connection to a payd instance.
// In this case, we connect to only one merchant wallet
// implementors may need to connect to more.
// PayD is for mock testing.
type PayD struct {
Host string
Port string
Secure bool
CertificatePath string
Noop bool
Noop bool
}

// Socket contains config items for a socket server.
Expand Down
8 changes: 1 addition & 7 deletions config/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,10 @@ func SetupDefaults() {
// Log level defaults
viper.SetDefault(EnvLogLevel, "info")

// PayD wallet Defaults
viper.SetDefault(EnvPaydHost, "payd")
viper.SetDefault(EnvPaydPort, ":8443")
viper.SetDefault(EnvPaydSecure, false)
viper.SetDefault(EnvPaydNoop, false)

// Socket settings
viper.SetDefault(EnvSocketChannelTimeoutSeconds, 7200*time.Second) // 2 hrs in seconds
viper.SetDefault(EnvSocketMaxMessageBytes, 10000)

// Transport settings
viper.SetDefault(EnvTransportMode, TransportModeHTTP)
viper.SetDefault(EnvTransportMode, TransportModeHybrid)
}
2 changes: 1 addition & 1 deletion config/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import validator "github.com/theflyingcodr/govalidator"
func (c *Config) Validate() error {
v := validator.New()
if c.Transports != nil {
v = v.Validate("transport.mode", validator.AnyString(c.Transports.Mode, TransportModeHTTP, TransportModeHybrid, TransportModeSocket))
v = v.Validate("transport.mode", validator.AnyString(c.Transports.Mode, TransportModeHybrid, TransportModeSocket))
}

return v.Err()
Expand Down
6 changes: 1 addition & 5 deletions config/viper.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,7 @@ func (v *ViperConfig) WithLog() ConfigurationLoader {
// WithPayD sets up and returns PayD viper config.
func (v *ViperConfig) WithPayD() ConfigurationLoader {
v.PayD = &PayD{
Host: viper.GetString(EnvPaydHost),
Port: viper.GetString(EnvPaydPort),
Secure: viper.GetBool(EnvPaydSecure),
CertificatePath: viper.GetString(EnvPaydCertPath),
Noop: viper.GetBool(EnvPaydNoop),
Noop: viper.GetBool(EnvPaydNoop),
}
return v
}
Expand Down
Loading