Go SDK for the Machine Payments Protocol
MPP lets any client — agents, apps, or humans — pay for any service in the same HTTP request. It standardizes HTTP 402 with an open IETF specification, so servers can charge and clients can pay without API keys, billing accounts, or checkout flows.
You can get started today by reading the Go SDK docs, the module-level Go doc reference, exploring the protocol overview, or jumping straight to the quickstart.
Package docs:
go get github.com/tempoxyz/mpp-gopackage 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)
}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)
}| Example | Description |
|---|---|
| basic | Separate-process demo with a long-running server and standalone client, mirroring the mpp-rs sample layout |
| chi/server | Chi router example using the existing net/http middleware helpers |
| gin/server | Gin example using the dedicated adapter package and context helpers |
| echo/server | Echo example using the dedicated adapter package and context helpers |
| 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 | Push-mode charge flow with a hash credential, available in both one-command and separate-process layouts |
| 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 |
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 two most common non-stdlib frameworks, mpp-go now ships first-class adapters:
pkg/server/ginfor Ginpkg/server/echofor Echo
Chi needs no special adapter:
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:
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:
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",
}))Built on the "Payment" HTTP Authentication Scheme, an open specification proposed to the IETF. See mpp.dev/protocol for the full protocol overview, or the IETF specification for the wire format.
git clone https://github.com/tempoxyz/mpp-go
cd mpp-go
go test ./...
See SECURITY.md for reporting vulnerabilities.
Licensed under either of Apache License, Version 2.0 or MIT License 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.