https://github.com/tempoxyz/mpp-go
Go SDK for the Machine Payments Protocol
https://github.com/tempoxyz/mpp-go
Last synced: 29 days ago
JSON representation
Go SDK for the Machine Payments Protocol
- Host: GitHub
- URL: https://github.com/tempoxyz/mpp-go
- Owner: tempoxyz
- License: mit
- Created: 2026-03-18T14:04:22.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-05-29T13:01:06.000Z (about 1 month ago)
- Last Synced: 2026-05-29T13:21:55.194Z (about 1 month ago)
- Language: Go
- Size: 248 KB
- Stars: 7
- Watchers: 0
- Forks: 4
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Security: SECURITY.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# mpp-go
Go SDK for the [**Machine Payments Protocol**](https://mpp.dev)
[](https://mpp.dev)
[](https://mpp.dev/sdk/go)
[](https://pkg.go.dev/github.com/tempoxyz/mpp-go)
[](LICENSE)
[MPP](https://mpp.dev) lets any client — agents, apps, or humans — pay for any service in the same HTTP request. It standardizes [HTTP 402](https://mpp.dev/protocol/http-402) with an open [IETF specification](https://paymentauth.org), so servers can charge and clients can pay without API keys, billing accounts, or checkout flows.
## Documentation
You can get started today by reading the [Go SDK docs](https://mpp.dev/sdk/go), the module-level [Go doc reference](https://pkg.go.dev/github.com/tempoxyz/mpp-go), exploring the [protocol overview](https://mpp.dev/protocol/), or jumping straight to the [quickstart](https://mpp.dev/quickstart/).
Package docs:
- [`pkg/client`](https://pkg.go.dev/github.com/tempoxyz/mpp-go/pkg/client)
- [`pkg/server`](https://pkg.go.dev/github.com/tempoxyz/mpp-go/pkg/server)
- [`pkg/tempo`](https://pkg.go.dev/github.com/tempoxyz/mpp-go/pkg/tempo)
- [`pkg/tempo/client`](https://pkg.go.dev/github.com/tempoxyz/mpp-go/pkg/tempo/client)
- [`pkg/tempo/server`](https://pkg.go.dev/github.com/tempoxyz/mpp-go/pkg/tempo/server)
## Install
```bash
go get github.com/tempoxyz/mpp-go
```
## Quick Start
### Server
```go
package main
import (
"encoding/json"
"net/http"
"github.com/tempoxyz/mpp-go/pkg/server"
charge "github.com/tempoxyz/mpp-go/pkg/tempo/server"
)
func main() {
method, _ := charge.MethodFromConfig(charge.Config{
RPCURL: "https://rpc.moderato.tempo.xyz",
Recipient: "0x70997970c51812dc3a010c7d01b50e0d17dc79c8",
})
payment := server.New(method, "api.example.com", "replace-me")
handler := server.ChargeMiddleware(payment, server.ChargeParams{
Amount: "0.50",
Description: "Paid content",
})(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_ = json.NewEncoder(w).Encode(map[string]any{
"data": "paid content",
"payer": server.CredentialFromContext(r.Context()).Source,
})
}))
_ = http.ListenAndServe(":8080", handler)
}
```
### Client
```go
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"github.com/tempoxyz/mpp-go/pkg/client"
"github.com/tempoxyz/mpp-go/pkg/mpp"
charge "github.com/tempoxyz/mpp-go/pkg/tempo/client"
)
func main() {
method, _ := charge.New(charge.Config{
PrivateKey: os.Getenv("MPP_PRIVATE_KEY"),
RPCURL: "https://rpc.moderato.tempo.xyz",
})
c := client.New([]client.Method{method})
response, err := c.Get(context.Background(), "https://api.example.com/paid")
if err != nil {
panic(err)
}
defer response.Body.Close()
receipt, _ := mpp.ParseReceipt(response.Header.Get("Payment-Receipt"))
var body struct {
Data string `json:"data"`
Payer string `json:"payer"`
}
_ = json.NewDecoder(response.Body).Decode(&body)
fmt.Printf("paid request for %q from %s with receipt %s\n", body.Data, body.Payer, receipt.Reference)
}
```
## Examples
| Example | Description |
|---------|-------------|
| [basic](./examples/basic/) | Separate-process demo with a long-running server and standalone client, mirroring the `mpp-rs` sample layout |
| [chi/server](./examples/chi/server/) | Chi router example using the existing `net/http` middleware helpers |
| [gin/server](./examples/gin/server/) | Gin example using the dedicated adapter package and context helpers |
| [echo/server](./examples/echo/server/) | Echo example using the dedicated adapter package and context helpers |
| [fiber/server](./examples/fiber/server/) | Fiber example using the dedicated adapter package and context helpers |
| [charge-basic](./examples/charge-basic/) | Generic Tempo charge flow using the high-level MPP client and server helpers, available in both one-command and separate-process layouts |
| [charge-hash](./examples/charge-hash/) | Push-mode charge flow with a hash credential, available in both one-command and separate-process layouts |
| [charge-fee-payer](./examples/charge-fee-payer/) | Sponsored Tempo charge flow where the server co-signs as a fee payer, available in both one-command and separate-process layouts |
## Web Frameworks
The most common Go HTTP stacks today are `net/http`, Gin, Echo, Chi, and Fiber.
MPP already integrates directly with `net/http`, which also covers Chi because
Chi handlers and middleware use the standard `http.Handler` interfaces.
For the most common non-stdlib frameworks, mpp-go ships first-class adapters:
- [`pkg/server/gin`](https://pkg.go.dev/github.com/tempoxyz/mpp-go/pkg/server/gin) for Gin
- [`pkg/server/echo`](https://pkg.go.dev/github.com/tempoxyz/mpp-go/pkg/server/echo) for Echo
- [`pkg/server/fiber`](https://pkg.go.dev/github.com/tempoxyz/mpp-go/pkg/server/fiber) for Fiber
Chi needs no special adapter:
```go
router.With(server.ChargeMiddleware(payment, server.ChargeParams{
Amount: "0.50",
Description: "Paid content",
})).Get("/paid", func(w http.ResponseWriter, r *http.Request) {
credential := server.CredentialFromContext(r.Context())
receipt := server.ReceiptFromContext(r.Context())
_ = json.NewEncoder(w).Encode(map[string]any{
"payer": credential.Source,
"receipt": receipt.Reference,
})
})
```
Gin route middleware:
```go
router.GET("/paid", ginadapter.ChargeMiddleware(payment, server.ChargeParams{
Amount: "0.50",
Description: "Paid content",
}), func(c *gin.Context) {
credential := ginadapter.Credential(c)
receipt := ginadapter.Receipt(c)
c.JSON(http.StatusOK, gin.H{
"payer": credential.Source,
"receipt": receipt.Reference,
})
})
```
Echo route middleware:
```go
e.GET("/paid", func(c echo.Context) error {
credential := echoadapter.Credential(c)
receipt := echoadapter.Receipt(c)
return c.JSON(http.StatusOK, map[string]any{
"payer": credential.Source,
"receipt": receipt.Reference,
})
}, echoadapter.ChargeMiddleware(payment, server.ChargeParams{
Amount: "0.50",
Description: "Paid content",
}))
```
Fiber route middleware:
```go
app.Get("/paid", fiberadapter.ChargeMiddleware(payment, server.ChargeParams{
Amount: "0.50",
Description: "Paid content",
}), func(c *fiber.Ctx) error {
credential := fiberadapter.Credential(c)
receipt := fiberadapter.Receipt(c)
return c.Status(http.StatusOK).JSON(fiber.Map{
"payer": credential.Source,
"receipt": receipt.Reference,
})
})
```
## Protocol
Built on the ["Payment" HTTP Authentication Scheme](https://paymentauth.org), an open specification proposed to the IETF. See [mpp.dev/protocol](https://mpp.dev/protocol/) for the full protocol overview, or the [IETF specification](https://paymentauth.org) for the wire format.
## Contributing
```
git clone https://github.com/tempoxyz/mpp-go
cd mpp-go
go test ./...
```
## Security
See [`SECURITY.md`](./SECURITY.md) for reporting vulnerabilities.
## License
Licensed under either of [Apache License, Version 2.0](./LICENSE-APACHE) or [MIT License](./LICENSE-MIT) at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.