Skip to content

feat: add USDC price cache and per-session spend cap - #42

Open
nirholas wants to merge 1 commit into
aws-samples:mainfrom
nirholas:feat/cost-cache-and-spend-cap
Open

feat: add USDC price cache and per-session spend cap#42
nirholas wants to merge 1 commit into
aws-samples:mainfrom
nirholas:feat/cost-cache-and-spend-cap

Conversation

@nirholas

Copy link
Copy Markdown

cost_estimator.py: cache USDC price for 60 seconds
get_usdc_price() previously hit the CoinGecko API on every
estimate_image_cost() call. The price is now stored in a
process-level dict protected by threading.Lock and only refreshed
when the 60-second TTL expires. Falls back to 1.0 on network error.

tools.py: per-session spend cap
Adds SESSION_SPEND_CAP_USD (env var, default $1.00). Before
authorizing a payment, make_payment() checks that the session's
running total plus the new cost would not exceed the cap. After a
successful image generation the cost is added to
session.total_spent_usd so subsequent requests correctly reflect
cumulative usage.

Issue #, if available:

Description of changes:

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

cost_estimator.py: cache USDC price for 60 seconds
  get_usdc_price() previously hit the CoinGecko API on every
  estimate_image_cost() call. The price is now stored in a
  process-level dict protected by threading.Lock and only refreshed
  when the 60-second TTL expires. Falls back to 1.0 on network error.

tools.py: per-session spend cap
  Adds SESSION_SPEND_CAP_USD (env var, default $1.00). Before
  authorizing a payment, make_payment() checks that the session's
  running total plus the new cost would not exceed the cap. After a
  successful image generation the cost is added to
  session.total_spent_usd so subsequent requests correctly reflect
  cumulative usage.
@Sergio87Felix

Copy link
Copy Markdown

Nice — the 60s USDC price cache + SESSION_SPEND_CAP_USD is exactly the right pattern for pay-per-use rails. Two hardening thoughts from running similar x402 seller gateways:

  1. Cap validation belongs before 402 authorization, not just at ledger write. If make_payment() checks the running total only at debit time, a burst of concurrent calls can all pass the pre-check before any hits the spend cap. Validate against a lock-guarded running balance before issuing the payment requirements header so the cap is the authorization boundary, not just an accounting boundary.

  2. Price-cache staleness under volatility. Falling back to 1.0 USDC on network error is safe for testnet, but on mainnet a stale/assumed 1.0 price can under-price a call and let the cap be exceeded in real-dollar terms. Consider a short hard-fail window or a stored last-good price with a max-age guard instead of a silent 1.0, at least for the seller-side cost estimator.

General question: are you tracking spend caps per-session only, or considering a broader per-agent/per-API-key budget across sessions? The per-session cap is a good default, but builders often need a parent-level budget too (e.g. a team allowance that spans many agent sessions). Keen to know if that's on the roadmap — happy to share notes on how we structure multi-level budgets in our gateway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants