Quickstart
This guide runs the current jup.sh 1.0 CLI with npx.
The CLI is useful for agent-facing payment flows:
agent intent -> policy decision -> Jupiter quote -> authorization -> receipt
The server path never signs or custodies funds. The CLI can sign and submit only when the user explicitly provides a local Solana keypair.
Prerequisites
You need:
- Node.js and npm.
The homepage keeps the first step intentionally short:
npx jup-sh init
npx jup-sh doctor
This page expands that into the full developer flow:
npx jup-sh init
npx jup-sh doctor
npx jup-sh policy trust api.vendor.example
npx jup-sh pay --agent deepseek --token SOL --amount 6 --settle USDC --recipient api.vendor.example --json
For source development, you also need a working Rust toolchain and git:
git clone https://github.com/jerrywang33/jup.git
cd jup
npm install
Use npm run cli:alpha -- for the local Node wrapper, or npm run cli -- to
run the Rust CLI directly through Cargo.
Command Flow
flowchart LR
Agent["agent or script"]
CLI["jup.sh CLI"]
Policy["local policy"]
Quote["mock or Jupiter quote"]
Store["local intent store"]
Result["JSON + exit code"]
Review["Risk Review URL"]
Agent -->|"pay command"| CLI
CLI --> Policy
CLI --> Quote
Policy --> Result
Quote --> Result
Result --> Store
Result -->|"review_required"| Review
The CLI always creates a local intent record when the command is valid enough to evaluate. The policy decision controls what the caller should do next.
1. Initialize Local Config
npx jup-sh init
This writes:
jup.config.json
jup.policy.json
jup.config.json controls local paths and defaults. jup.policy.json
controls risk thresholds. Use --force if you intentionally want to overwrite
them.
For source development, use:
npm run cli:alpha -- init
2. Check The Workspace
npx jup-sh doctor
npx jup-sh doctor --json
doctor verifies the local config, policy file, intent store, review URL,
quote provider, and trusted recipients. It is the fastest way to confirm that
the workspace is ready before an agent creates payment intents.
For source development, use:
npm run cli:alpha -- doctor
3. Configure Local Policy
npx jup-sh policy show
The default policy is conservative:
- verified tokens only;
- USDC settlement only;
- auto-pay limit of 5 USDC;
- hard max of 100 USDC;
- unknown recipients require review;
- high price impact requires review.
Create or overwrite only the local policy file:
npx jup-sh policy init
This writes:
jup.policy.json
Use --force if you intentionally want to overwrite it.
Trust a known API or vendor recipient:
npx jup-sh policy trust api.vendor.example
Raise the auto-pay limit:
npx jup-sh policy set max-auto 10
For source development, prefix the same commands with npm run cli:alpha --.
4. Create A Payment Intent
npx jup-sh pay --agent deepseek --token SOL --amount 20 --settle USDC
This creates a local payment intent and saves it under:
.jup-sh/intents/<intent_id>.json
By default, the command uses the mock quote provider. That makes tests stable and does not call external APIs.
5. Use JSON Mode For Agents
Agents and scripts should use --json:
npx jup-sh pay \
--agent deepseek \
--token SOL \
--amount 20 \
--settle USDC \
--json
--json prints one structured object to stdout. Agents should branch on the
exit code and nextAction.
| Exit code | Decision | Agent behavior |
|---|---|---|
0 |
auto_pay |
Intent is inside policy and ready for local authorization in a future phase. |
2 |
review_required |
Open or return the Risk Review URL. This is a controlled policy outcome. |
1 |
rejected or command failure |
Stop the payment flow. |
The field-level contract is documented in CLI JSON Contract.
For a fuller caller guide, see Agent Integration.
6. Test The Three Policy Outcomes
Trust the demo recipient first:
npx jup-sh policy trust jup-sh-demo
Auto-pay candidate with a trusted recipient and small amount:
npx jup-sh pay \
--agent deepseek \
--token SOL \
--amount 2 \
--settle USDC \
--recipient jup-sh-demo \
--json
Review-required payment with the default policy:
npx jup-sh pay \
--agent deepseek \
--token SOL \
--amount 20 \
--settle USDC \
--json
Rejected payment with an unsupported token:
npx jup-sh pay \
--agent deepseek \
--token FAKE \
--amount 20 \
--settle USDC \
--json
7. Use Jupiter Execution Mode
npx jup-sh pay \
--agent deepseek \
--token SOL \
--amount 20 \
--settle USDC \
--recipient-token-account <RECIPIENT_USDC_TOKEN_ACCOUNT> \
--quote-provider jupiter
This asks Jupiter for an ExactOut quote that can be turned into a swap transaction. To execute from the CLI, sign locally with a user keypair:
npx jup-sh intent execute intent_xxx \
--keypair ~/.config/solana/id.json \
--rpc-url https://api.mainnet-beta.solana.com \
--json
The CLI submits the signed transaction and writes a local receipt.
Optional settings:
--jupiter-api-key <key>
--jupiter-quote-url <url>
--slippage-bps 50
You can also set:
JUPITER_API_KEY=...
See Jupiter Quote-Only Design for the settlement boundary.
8. Inspect Local Intents
List saved intents:
npx jup-sh intent list
Show one intent:
npx jup-sh intent show intent_xxx
Export a Risk Review URL:
npx jup-sh intent export intent_xxx
Or use the review shortcut:
npx jup-sh review intent_xxx
The exported URL contains a fragment payload:
https://jup.sh/pay/intent_xxx#intent=<base64url-json-payload>
See Risk Review Export Design for the static review model.
9. Try The SDK Surface
The first TypeScript SDK surface is local and source-only:
import { createPaymentIntent } from "../sdk/index.js";
const intent = await createPaymentIntent({
agent: "deepseek",
token: "SOL",
amount: 20,
settle: "USDC",
});
Typecheck the SDK and example:
npm run sdk:check
npm run sdk:smoke
npm run sdk:jupiter:live
The SDK returns the same PaymentIntent contract as the CLI JSON mode. The SDK
itself is still source-only and does not call a hosted backend yet.
Use the SDK Jupiter quote-only provider:
import { createJupiterQuoteProvider, createPaymentIntent } from "../sdk/index.js";
const intent = await createPaymentIntent(
{
agent: "deepseek",
token: "SOL",
amount: 20,
settle: "USDC",
},
{
quoteProvider: createJupiterQuoteProvider(),
}
);
This calls Jupiter for a quote estimate only. It does not sign, submit, or execute a swap.
sdk:jupiter:live is skipped by default. Set JUP_SH_LIVE_JUPITER=1 when you
want to call Jupiter’s live quote API from the example.
Generate a Risk Review URL from the SDK:
import {
createPaymentIntent,
createRiskReviewUrl,
} from "../sdk/index.js";
const intent = await createPaymentIntent({
agent: "deepseek",
token: "SOL",
amount: 20,
settle: "USDC",
});
if (intent.nextAction === "open_review") {
const reviewUrl = createRiskReviewUrl(intent, {
reviewBaseUrl: "https://www.jup.sh",
});
console.log(reviewUrl);
}
This uses the same #intent=<base64url-json-payload> model as CLI
intent export, so the URL opens directly in the hosted Risk Review page.
Try SDK policy profiles:
import {
createPaymentIntent,
getPolicyProfile,
} from "../sdk/index.js";
const intent = await createPaymentIntent(
{
agent: "deepseek",
token: "SOL",
amount: 20,
settle: "USDC",
},
{
policy: getPolicyProfile("sandbox"),
}
);
Available profiles:
| Profile | Intended use |
|---|---|
sandbox |
Agent demos, hackathons, and local testing with fewer review interruptions. |
balanced |
Known agents paying known APIs. This is the default alpha behavior. |
strict |
New agents, unknown recipients, or higher-risk environments. |
Add a trusted recipient to a profile:
import {
createPaymentIntent,
getPolicyProfile,
withTrustedRecipients,
} from "../sdk/index.js";
const policy = withTrustedRecipients(getPolicyProfile("balanced"), [
"api.vendor.example",
]);
const intent = await createPaymentIntent(
{
agent: "deepseek",
token: "SOL",
amount: 2,
settle: "USDC",
recipient: "api.vendor.example",
},
{ policy }
);
This keeps small known-recipient payments inside policy while still sending unknown recipients to Risk Review.
Explain a policy decision:
import {
createPaymentIntent,
explainPolicyDecision,
getPolicyProfile,
} from "../sdk/index.js";
const intent = await createPaymentIntent(
{
agent: "deepseek",
token: "SOL",
amount: 20,
settle: "USDC",
},
{
policy: getPolicyProfile("balanced"),
}
);
const explanation = explainPolicyDecision(intent);
console.log(explanation.summary);
console.log(explanation.riskFactors);
console.log(explanation.recommendedAction);
This is useful for agent logs, Risk Review, and local audit trails. It explains
the existing policyChecks; it does not change the payment decision.
10. Run The Release Gate
Before a release checkpoint:
npm run release:check
This runs:
- JavaScript syntax checks;
- Rust workspace checks;
- alpha smoke tests;
- npm package dry-run checks;
- Rust tests.
The release gate exists because agent payment tools need predictable command behavior before they touch signing or money movement.