🌈 jup.sh docs

Jupiter Quote-Only Design

Jupiter is the settlement primitive for jup.sh.

The payer should be able to use any verified token. The recipient should settle in USDC. The current alpha only asks Jupiter for quote estimates; it does not request swap transactions or execute routes.

Settlement Goal

The command is settlement-first:

jup-sh pay --agent deepseek --token SOL --amount 20 --settle USDC

This means:

With Jupiter enabled:

jup-sh pay \
  --agent deepseek \
  --token SOL \
  --amount 20 \
  --settle USDC \
  --quote-provider jupiter

Quote Flow

flowchart LR
  Intent["payment intent<br/>token + USDC amount"]
  PrePolicy["pre-quote policy<br/>token + amount + recipient"]
  Jupiter["Jupiter quote<br/>ExactOut"]
  QuotePolicy["quote-aware policy<br/>settlement + price impact"]
  Result{"final decision"}

  Intent --> PrePolicy
  PrePolicy -->|"rejected"| Stop["stop before quote"]
  PrePolicy -->|"valid"| Jupiter --> QuotePolicy --> Result

The quote is not just display data. It becomes policy evidence.

Why ExactOut

jup.sh promises recipient settlement in USDC. The important amount is the recipient amount, not the payer input amount.

For that reason, the alpha uses Jupiter quote mode equivalent to:

swapMode=ExactOut

Request shape:

GET https://api.jup.ag/swap/v1/quote
  ?inputMint=<payer token mint>
  &outputMint=<USDC mint>
  &amount=<USDC raw amount>
  &slippageBps=50
  &swapMode=ExactOut

If configured, JUPITER_API_KEY is sent as x-api-key.

CLI options:

--quote-provider jupiter
--jupiter-api-key <key>
--jupiter-quote-url <url>
--slippage-bps 50

Quote Provider Boundary

The Rust core owns the quote abstraction:

pub trait SettlementQuoter {
    fn quote_settlement(
        &self,
        input: &CreatePaymentIntentInput,
    ) -> Result<SettlementQuote, JupShError>;
}

Implemented providers:

Provider Source Purpose
mock MockSettlementQuoter Stable local tests and development.
jupiter JupiterSettlementQuoter Real quote estimate without execution.

The policy engine depends on the quote shape, not on a specific HTTP client. That keeps local tests deterministic and makes Jupiter optional in the alpha.

Token Map

The first implementation uses a deliberately small token map:

Symbol Mint Decimals
SOL So11111111111111111111111111111111111111112 9
USDC EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v 6
JUP JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN 6
BONK DezXAZ8z7PnrnRJjz3my2u6r5KiL3HR8APpPB2634B2 5

Future versions should replace this with a verified token registry. The token registry should be a risk input, not only a UX convenience.

Returned Quote

The quote is embedded inside PaymentIntent.quote:

{
  "source": "jupiter_swap_exact_out",
  "inputToken": "SOL",
  "inputAmount": 0.225525465,
  "settleAmount": 20,
  "settleToken": "USDC",
  "priceImpactBps": 0
}

The quote preserves the product language:

Quote-Aware Policy

After a quote is available, the core appends quote-aware checks:

Check Meaning
quote_available The provider returned a usable quote.
quote_settlement_token The quote settles to the requested settlement token.
quote_price_impact Price impact is inside policy or requires review.

Default policy:

{
  "maxPriceImpactBps": 100,
  "reviewHighPriceImpact": true
}

If priceImpactBps exceeds maxPriceImpactBps, the intent becomes review_required unless high price impact review is disabled.

Failure Behavior

The current alpha treats quote failure as a command failure for Jupiter mode. That is conservative: if route data is unavailable, the CLI should not pretend the payment is ready.

Later versions may support a policy option such as:

{
  "reviewWhenQuoteUnavailable": true
}

That would convert route failure into review_required instead of a hard command failure.

Non-Goals

This phase does not:

Next Steps

  1. Add route quality checks beyond price impact.
  2. Store route metadata for Risk Review.
  3. Add a verified token registry.
  4. Use the Transaction Request Skeleton Design as the first Solana Pay transaction request boundary.
  5. Keep Jupiter route construction behind the same SettlementQuoter boundary.