Documentation
¶
Overview ¶
Package chargeclient contains the Tempo charge client method for creating Payment Credentials that satisfy Tempo HTTP 402 Challenges. It is usually imported as charge alongside the generic client package.
Package chargeclient creates Tempo charge Credentials for MPP HTTP clients.
Index ¶
- Variables
- type Config
- type Method
- func (m *Method) CanHandleChallenge(challenge *mpp.Challenge) bool
- func (m *Method) CreateCredential(ctx context.Context, challenge *mpp.Challenge) (*mpp.Credential, error)
- func (m *Method) Intent() string
- func (m *Method) Name() string
- func (m *Method) ValidateOrigin(origin *url.URL, challenge *mpp.Challenge) error
- type PaymentPolicy
- type TrustedProofRealm
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrPaymentPolicy = errors.New("tempo client: payment not allowed")
ErrPaymentPolicy is wrapped by the errors the PaymentPolicy helpers in this package return when they reject a payment.
var ErrSponsoredChallengeExpiresTooSoon = errors.New("tempo client: sponsored challenge expires too soon")
ErrSponsoredChallengeExpiresTooSoon reports a sponsored (fee-payer) charge challenge that expires less than tempo.FeePayerMinRemainingValidity from now. The client refuses it before signing or broadcasting anything, since a server would reject the sponsored transaction for too little validity.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Signer signs Tempo transactions and proof payloads.
Signer *temposigner.Signer
// PrivateKey constructs Signer when Signer is nil.
PrivateKey string
// RPC overrides the Tempo JSON-RPC client used for signing flows.
RPC tempo.RPCClient
// RPCURL is used to build an RPC client when RPC is nil.
RPCURL string
// ChainID constrains the challenge to a specific Tempo chain when set,
// such as tempo.ChainIDMainnet or tempo.ChainIDModerato.
ChainID int64
// ClientID is folded into automatically generated attribution memos.
ClientID string
// CredentialType selects transaction, hash, or proof credentials.
CredentialType tempo.CredentialType
// PaymentPolicy must authorize every nonzero payment before signing or broadcasting.
// Nil rejects paid challenges. Check the normalized amount (including splits),
// currency, recipient, and verified RPC chain; enforce cumulative budgets atomically if needed.
// The callback may run concurrently and must not mutate the request.
//
// Build it from the PaymentPolicy helpers, for example at most 0.50 OUSD
// per payment on mainnet:
//
// PaymentPolicy: charge.AllPolicies(
// charge.MaxAmount(tempo.OUSDAddress, "0.50", 6),
// charge.AllowChainIDs(tempo.ChainIDMainnet),
// ),
PaymentPolicy func(context.Context, tempo.ChargeRequest) error
// TrustedProofRealms lets the method sign zero-amount proofs for a realm
// that differs from the hostname of the server sending the challenge. A
// proof authenticates the payer at the challenge realm, so by default
// the method signs one only when an HTTPS server on the default port
// names its own hostname as the realm, and never over MCP.
TrustedProofRealms []TrustedProofRealm
}
Config configures a Tempo charge client method.
type Method ¶
type Method struct {
// contains filtered or unexported fields
}
Method implements Tempo charge credential creation for the generic MPP client.
func (*Method) CanHandleChallenge ¶ added in v0.4.0
CanHandleChallenge skips a sponsored charge challenge that expires too soon to sign, so a transport offered other challenges can pay with one of those instead of failing on this one.
func (*Method) CreateCredential ¶
func (m *Method) CreateCredential(ctx context.Context, challenge *mpp.Challenge) (*mpp.Credential, error)
CreateCredential turns a Tempo charge Challenge into a Tempo Credential.
Concurrent calls for the same challenge share one in-flight signing, so they cannot produce two independently settleable transactions. Once that signing finishes, successfully or not, a later call signs afresh. Calls share a signing only when every challenge field matches, and each caller gets its own copy of the credential.
func (*Method) ValidateOrigin ¶ added in v0.6.0
ValidateOrigin implements client.OriginValidator. It refuses a zero-amount charge challenge, which the method pays with a proof that authenticates the payer at the challenge realm, unless origin is an HTTPS URL on the default port whose hostname is the realm, or Config.TrustedProofRealms trusts the realm for origin. origin is nil on transports without one, such as MCP. Other challenges pass.
type PaymentPolicy ¶ added in v0.6.0
type PaymentPolicy func(ctx context.Context, request tempo.ChargeRequest) error
PaymentPolicy authorizes a nonzero Tempo charge before the client signs or broadcasts it; returning an error rejects the payment. The request has the normalized base-unit amount (including splits), the currency, the recipient and the chain ID verified with the RPC. It may run concurrently and must not mutate the request. Build one with MaxAmount, MaxAtomicAmount and AllowChainIDs, combined with AllPolicies, or write your own, for example to enforce a cumulative budget atomically.
func AllPolicies ¶ added in v0.6.0
func AllPolicies(policies ...PaymentPolicy) PaymentPolicy
AllPolicies returns a PaymentPolicy that allows a payment only when every policy allows it, checking them in order and returning the first rejection. Nil policies are skipped; with no policies it allows every payment.
func AllowChainIDs ¶ added in v0.6.0
func AllowChainIDs(ids ...int64) PaymentPolicy
AllowChainIDs returns a PaymentPolicy that rejects payments on chains other than ids, such as tempo.ChainIDMainnet, like mppx's allowedChainIds. The chain is the one the client verified with its RPC.
func MaxAmount ¶ added in v0.6.0
func MaxAmount(currency, maxAmount string, decimals int) PaymentPolicy
MaxAmount returns a PaymentPolicy that rejects a single payment above maxAmount, a decimal amount in display units of a token with the given decimals, such as MaxAmount(tempo.OUSDAddress, "0.50", 6) for at most 0.50 OUSD, like mppx's maxAmount. The limit is per payment, not cumulative, and covers the whole amount including splits.
With a currency, it also rejects payments in any other currency, compared case-insensitively. An empty currency applies the limit to every currency, which suits the Tempo stablecoins, which all have 6 decimals. An invalid maxAmount or negative decimals rejects every payment.
Example ¶
package main
import (
"fmt"
"github.com/tempoxyz/mpp-go/pkg/client"
"github.com/tempoxyz/mpp-go/pkg/tempo"
charge "github.com/tempoxyz/mpp-go/pkg/tempo/client"
)
func main() {
method, err := charge.New(charge.Config{
PrivateKey: "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
ChainID: tempo.ChainIDMainnet,
// Pay at most 0.50 OUSD per request, and only on mainnet.
PaymentPolicy: charge.AllPolicies(
charge.MaxAmount(tempo.OUSDAddress, "0.50", 6),
charge.AllowChainIDs(tempo.ChainIDMainnet),
),
})
if err != nil {
panic(err)
}
httpClient, err := client.NewHTTPClient([]client.Method{method})
if err != nil {
panic(err)
}
fmt.Println(httpClient != nil)
}
Output: true
func MaxAtomicAmount ¶ added in v0.6.0
func MaxAtomicAmount(currency string, maxAmount *big.Int) PaymentPolicy
MaxAtomicAmount returns a PaymentPolicy that rejects a single payment above maxAmount base units, like mppx's maxAtomicAmount. currency works as in MaxAmount. A nil or negative maxAmount rejects every payment.
type TrustedProofRealm ¶ added in v0.6.0
type TrustedProofRealm struct {
// Origin is the scheme://host[:port] origin of the HTTP server, such as
// "http://localhost:8080". Empty trusts Realm on transports without an
// origin, such as MCP.
Origin string
// Realm is the challenge realm, compared exactly.
Realm string
}
TrustedProofRealm trusts a server to request zero-amount proofs for Realm.