| Crates.io | fogo-paymaster |
| lib.rs | fogo-paymaster |
| version | 0.7.2 |
| created_at | 2025-10-07 23:11:24.406382+00 |
| updated_at | 2026-01-23 20:06:46.112301+00 |
| description | Fogo paymaster service and transaction validator CLI |
| homepage | |
| repository | https://github.com/fogo-foundation/fogo-sessions |
| max_upload_size | |
| id | 1872918 |
| size | 417,390 |
The Sessions Paymaster service provides apps with a way to fund user transactions on their frontends. This allows users to conduct these transactions without needing to hold native FOGO.
You can view metrics for the service at port 4000.
The constraints API enables apps to set up filters for what kinds of transactions they wish to permit their paymasters to pay for. The paymaster filters are intended to regulate what transactions apps pay for, rather than constrain actions on the frontend to a non-exploitable surface. Accordingly, the constraints should be designed to outline appropriate use of the app's funds toward relevant user actions. This will help to ensure that these funds are only spent on legitimate use of the app's relevant frontend functions by retail users.
Thus, rather than avoid exploits, the paymaster filters should focus on constraining the action space to bonafide transactions that would be undertaken on the app's frontend.
The constraints are expressed in terms of TransactionVariation objects. Each TransactionVariation describes constraints on a transaction that must all be passed in order for a transaction to be considered valid. A transaction must pass at least one of an app's configured TransactionVariations in order to gain approval to use the paymaster's funds.
VariationProgramWhitelistv0 is a simple whitelist-based constraint set. A set of whitelisted programs is specified, and the transaction will pass iff every instruction's program is in the whitelist.
There are no constraints on instruction ordering, accounts, or data.
VariationOrderedInstructionConstraintsv1 is a more fleshed out constraint set. It introduces constraints on each instruction in the transaction as well as a max gas spend (this checks the signature gas cost plus the priority fee). A list of instruction constraints is specified in order, with each instruction constraint containing:
v1 does not enforce relationships across instructions (e.g. require instruction Y if instruction X is present, constrain data in instruction Y based on the value of data in instruction X). In this way, it is relatively stateless and allows for simple absolute constraints on the instructions.
docker-compose.yml)..env.example to .env and adjust the values to match your local setup.Start the Postgres container (and the optional pgweb UI) with:
docker compose up
Confirm that DATABASE_URL in your environment matches the credentials that the container exposes.
This will:
postgres://paymaster:paymaster@localhost:5432/paymasterMigrations are located in: services/paymaster/migrations, and can be run using:
cargo run --bin fogo-paymaster migrate
Seeding is optional, but simplifies bootstrapping a local configuration. Provide both a database URL, a path to a TOML config (an example lives at tilt/configs/paymaster.toml), and the network you'd like this config to live in (eg: testnet/mainnet):
cargo run --bin paymaster-config-sync -- --config="./tilt/configs/paymaster.toml" --db-url="postgres://paymaster:paymaster@localhost:5432/paymaster" --network-environment testnet
note that running the paymaster-config-sync multiple times will act as an upsert command where it will create variations if they don't exist or update them if they're already present in the db.
Launch the service with either environment variables or explicit flags. The minimum inputs are the database URL, HTTP RPC endpoint, network (eg. testnet/mainnet) and a mnemonic file path for the sponsor wallet. Example:
cargo run --bin fogo-paymaster run \
--db-url "postgres://paymaster:paymaster@localhost:5432/paymaster" \
--rpc-url-http https://testnet-alt.fogo.io \
--mnemonic-file ./tilt/secrets/mnemonic
--network-environment testnet
Optional flags:
--rpc-url-ws (defaults to replacing http with ws on the HTTP URL)--listen-address (default 0.0.0.0:4000)--otlp-endpoint for exporting OpenTelemetry traces (default http://localhost:4317)--db-refresh-interval-seconds for how frequently domain config is refreshed (default 10 secs)--valiant-api-key to enable swapping of accrued fee tokens into FOGO as per specifications in the config--valiant-override-url to override the default Valiant endpoint used by the paymaster. The default behavior is determined according to the --network-environment flag; this override flag is handy particularly in the case of localnet testing.You can also rely on the .env(see .env.example) values and simply run cargo run --bin fogo-paymaster run.
The paymaster service records some metrics via Prometheus and some spans for timing of the transaction validation/submission/confirmation flow via OpenTelemetry. The service exports these OpenTelemetry spans to localhost:4317 by default. You can configure sending these to a different destination by setting the OTEL_EXPORTER_OTLP_ENDPOINT environment variable, or by providing the otlp_endpoint CLI arg.
You can run a local all in one jaeger instance to collect and visualize these spans by running:
docker run --name jaeger \
-e COLLECTOR_OTLP_ENABLED=true \
-p 16686:16686 \
-p 4317:4317 \
jaegertracing/all-in-one:1.63.0
The crate also exposes a cli tool to validate arbitrary transactions against a specified config. You can run this via the following command:
cargo run --bin paymaster-tx-validator validate -c <CONFIG_PATH> --network <testnet|mainnet> --transaction-hash <ONCHAIN_TRANSACTION_HASH> (--rpc-url-http <RPC_URL_HTTP>)
Alternatively, you can provide a serialized transaction as a base64 string via the --transaction argument in place of the hash. Additionally, you could ask the tool to validate a specified number of the most recent transactions that interacted with this domain's sponsor pubkey via:
cargo run --bin paymaster-tx-validator validate -c <CONFIG_PATH> --network <testnet|mainnet> --domain <DOMAIN> --recent-sponsor-txs <NUMBER_OF_RECENT_TXS> (--rpc-url-http <RPC_URL_HTTP>)
Note that in this case, you must specify the domain you wish to match against and pull recent transactions for, unless your config only has 1 domain.
You can optionally provide the name of the domain you wish to match against via --domain. The tool will print out the set of transaction variations that the provided transaction matches against. If --domain is provided, you can optionally provide the name of a particular variation you wish to match against via --variation. The tool will then print out additional logging showing the exact errors in each case that a transaction does not match against this domain and variation combination.