Skip to content

feat(cast): add --sponsor-url for remote Tempo fee payer sponsorship#14790

Draft
decofe wants to merge 9 commits into
masterfrom
feat/sponsor-url
Draft

feat(cast): add --sponsor-url for remote Tempo fee payer sponsorship#14790
decofe wants to merge 9 commits into
masterfrom
feat/sponsor-url

Conversation

@decofe
Copy link
Copy Markdown
Contributor

@decofe decofe commented May 15, 2026

Summary

Adds --sponsor-url (alias --tempo.sponsor-url) to cast send. When set, the transaction is signed locally, then the raw signed bytes are forwarded to the remote sponsor service via eth_sendRawTransaction. The service adds its fee payer signature and broadcasts the fully-sponsored transaction.

Usage

cast send 0xDEAD... "transfer(address,uint256)" 0xBEEF... 100 \
  --sponsor-url https://sponsor.tempo.xyz/tp_abc123 \
  --private-key $PK

Or via env var:

export TEMPO_SPONSOR_URL=https://sponsor.tempo.xyz/tp_abc123
cast send 0xDEAD... --private-key $PK

How it works

  1. Build & fill the transaction using the regular RPC (gas estimation, nonce, etc.)
  2. Sign it locally with the user's key
  3. Encode the signed TxEnvelope to raw RLP bytes
  4. POST eth_sendRawTransaction to the sponsor URL
  5. The sponsor service (fee-payer in tempo-apps) adds the fee payer signature and broadcasts

No new RPC methods required — works with the existing fee-payer service as-is.

Changes

  • crates/cli/src/opts/tempo.rs: New --sponsor-url / --tempo.sponsor-url arg on TempoOpts, conflicts with --tempo.sponsor / --tempo.sponsor-signer / --tempo.sponsor-sig. Forces AA tx type (sets nonce_key=0) like the existing sponsor flow.
  • crates/cast/src/cmd/send.rs: New case in run_generic that signs locally, encodes, and sends to the sponsor URL. Added send_via_sponsor_url helper.
  • crates/cast/Cargo.toml: Added reqwest direct dependency for the HTTP call.

Adds --sponsor-url (alias --tempo.sponsor-url) to cast send. When set,
the transaction is signed locally and forwarded to the remote sponsor
service via eth_sendRawTransaction. The service adds its fee payer
signature and broadcasts the sponsored transaction.

Usage:
  cast send 0x... --sponsor-url https://sponsor.tempo.xyz/tp_abc123

This works with the existing fee-payer service in tempo-apps without
any changes — no new RPC methods required. The sponsor URL can also
be set via TEMPO_SPONSOR_URL env var.

Amp-Thread-ID: https://ampcode.com/threads/T-019e2d8c-7750-71a5-924c-2394c0c4e070
…nsor_url

- Use eth_signRawTransaction to get the sponsored tx from the service,
  then submit via the regular RPC's send_raw_transaction. This matches
  the viem withFeePayer sign-only protocol.
- Clone sponsor_url instead of take() so it's still present when
  TempoOpts::apply() runs, ensuring nonce_key=0 is set and the tx
  builds as a Tempo AA (0x76) type instead of EIP-1559 (0x02).
- Handle sponsor service error responses that have name/code but no
  message field.

Amp-Thread-ID: https://ampcode.com/threads/T-019e2d8c-7750-71a5-924c-2394c0c4e070
@mablr mablr self-assigned this May 18, 2026
mablr and others added 7 commits May 18, 2026 12:45
- Sign sponsored Tempo payload by setting a placeholder
  fee_payer_signature
  before local signing, so the sender commits to the sponsored variant
- Bail out when --sponsor-url is combined with --unlocked, --browser, or
  a
  Tempo access key instead of silently ignoring it
- Validate sponsor URL scheme (require https://, allow http only for
  localhost/127.0.0.1)
- Tighten JSON-RPC response parsing: accept arbitrary result types, drop
  non-standard 'name' error field

Co-authored-by: Amp <amp@ampcode.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants