pay.sh docs
SDKPython

Signers

Load the operator key that receives funds and signs settlement — local keypairs or env-driven config — and the demo-signer safety rail.

The operator identity is set on configure(operator=Operator(signer=...)). The signer co-signs x402 challenges and fee-pays settlement when configured. With no operator, the kit boots on a published demo signer on non-mainnet networks.

Local key material

from solana_pay_kit import Signer

Signer.file("operator.json")   # Solana CLI JSON keypair
Signer.env("OPERATOR_KEY")     # JSON / hex / base58 from an env var, auto-detected
Signer.demo()                  # the shared demo keypair (non-mainnet only)

Wire it into configure

import solana_pay_kit
from solana_pay_kit import Operator, Signer, Stablecoin

solana_pay_kit.configure(
    network="solana_mainnet",
    stablecoins=(Stablecoin.USDC, Stablecoin.PYUSD),
    operator=Operator(signer=Signer.file("operator.json")),
    rpc_url="https://mainnet.helius-rpc.com/?api-key=YOUR_KEY",
)

For env-driven deployments, solana_pay_kit.configure_from() reads the whole process config from environment variables instead.

App-level PayConfig

FastAPI's app-level paywall can read a PayConfig or plain mapping plus env overrides. This keeps host-app config files small while letting env vars win at deploy time:

from fastapi import FastAPI
from solana_pay_kit.fastapi import install_paywall

app = FastAPI()
install_paywall(
    app,
    {
        "enabled": True,
        "network": "solana_mainnet",
        "price_usd": "0.01",
        "recipient": "YOUR_WALLET",
        "rpc_url": "https://mainnet.helius-rpc.com/?api-key=YOUR_KEY",
        "signer_env": "PAY_OPERATOR_KEY",
    },
    env_prefix="PAY_",
)

With env_prefix="PAY_", these variables override the mapping:

FieldEnv varDefaultPurpose
enabledPAY_ENABLEDFalseInstall the paywall only when true.
networkPAY_NETWORKsolana_localnetSolana network for settlement and challenges.
price_usdPAY_PRICE_USD0.01Default flat price for paid routes.
recipientPAY_RECIPIENTNoneSettlement recipient; falls back to the operator signer.
rpc_urlPAY_RPC_URLNoneOverride the network default RPC URL.
signer_envPAY_SIGNER_ENVEXO_PAY_SIGNEREnv var containing JSON, hex, or base58 key material.
protocolsPAY_PROTOCOLSx402,mppComma-separated payment protocols.
stablecoinsPAY_STABLECOINSUSDCComma-separated settlement assets.
preflightPAY_PREFLIGHTTrueRun boot-time RPC/config validation.
preflightPAY_NO_PREFLIGHTunsetInverse shortcut: true disables preflight, false re-enables it.

install_paywall() builds a middleware-local SDK config. If you already configured custom MPP or x402 sub-configs globally, the paywall preserves those sub-configs while applying the app-level fields above.

The demo signer

Signer.demo() is the zero-config default recipient on non-mainnet networks — convenient for local development against the Surfpool sandbox. It is refused on mainnet: configure(network="solana_mainnet") with the demo signer raises DemoSignerOnMainnetError so real funds never route to a publicly known key.

On this page