diff --git a/mintlify-migration/README.md b/mintlify-migration/README.md new file mode 100644 index 00000000..66c5f11f --- /dev/null +++ b/mintlify-migration/README.md @@ -0,0 +1,44 @@ +# Mintlify Starter Kit + +Use the starter kit to get your docs deployed and ready to customize. + +Click the green **Use this template** button at the top of this repo to copy the Mintlify starter kit. The starter kit contains examples with + +- Guide pages +- Navigation +- Customizations +- API reference pages +- Use of popular components + +**[Follow the full quickstart guide](https://starter.mintlify.com/quickstart)** + +## Development + +Install the [Mintlify CLI](https://www.npmjs.com/package/mint) to preview your documentation changes locally. To install, use the following command: + +``` +npm i -g mint +``` + +Run the following command at the root of your documentation, where your `docs.json` is located: + +``` +mint dev +``` + +View your local preview at `http://localhost:3000`. + +## Publishing changes + +Install our GitHub app from your [dashboard](https://dashboard.mintlify.com/settings/organization/github-app) to propagate changes from your repo to your deployment. Changes are deployed to production automatically after pushing to the default branch. + +## Need help? + +### Troubleshooting + +- If your dev environment isn't running: Run `mint update` to ensure you have the most recent version of the CLI. +- If a page loads as a 404: Make sure you are running in a folder with a valid `docs.json`. + +### Resources +- [Mintlify documentation](https://mintlify.com/docs) +- [Mintlify community](https://mintlify.com/community) diff --git a/mintlify-migration/api.mdx b/mintlify-migration/api.mdx new file mode 100644 index 00000000..41c1b8a8 --- /dev/null +++ b/mintlify-migration/api.mdx @@ -0,0 +1,34 @@ +--- +title: "API Reference" +sidebarTitle: "Overview" +--- + + + + 6 items + + + 4 items + + + 1 item + + + 5 items + + + 6 items + + + 2 items + + + 2 items + + + 4 items + + + 5 items + + diff --git a/mintlify-migration/api/lend-api.mdx b/mintlify-migration/api/lend-api.mdx new file mode 100644 index 00000000..83e66bc7 --- /dev/null +++ b/mintlify-migration/api/lend-api.mdx @@ -0,0 +1,10 @@ +--- +title: "Lend API" +sidebarTitle: "Overview" +--- + + + + 11 items + + diff --git a/mintlify-migration/api/lend-api/earn.mdx b/mintlify-migration/api/lend-api/earn.mdx new file mode 100644 index 00000000..3f4abb9c --- /dev/null +++ b/mintlify-migration/api/lend-api/earn.mdx @@ -0,0 +1,40 @@ +--- +title: "Earn (Beta)" +sidebarTitle: "Overview" +--- + + + + Request for a base64-encoded unsigned earn deposit transaction to deposit assets + + + Request for a base64-encoded unsigned earn withdraw transaction to withdraw assets + + + Request for a base64-encoded unsigned earn mint transaction to mint shares + + + Request for a base64-encoded unsigned earn redeem transaction to redeem shares + + + Request for the instruction of an earn deposit transaction to deposit assets + + + Request for the instruction of an earn withdraw transaction to withdraw assets + + + Request for the instruction of an earn mint transaction to mint shares + + + Request for the instruction of an earn redeem transaction to redeem shares + + + Request for the tokens available to be deposited and their information + + + Request for the position data of one or multiple users + + + Request for the earnings of one or multiple posi + + diff --git a/mintlify-migration/api/lend-api/earn/deposit-instructions.mdx b/mintlify-migration/api/lend-api/earn/deposit-instructions.mdx new file mode 100644 index 00000000..f0ee664a --- /dev/null +++ b/mintlify-migration/api/lend-api/earn/deposit-instructions.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/lend/lend.yaml post /earn/deposit-instructions +--- \ No newline at end of file diff --git a/mintlify-migration/api/lend-api/earn/deposit.mdx b/mintlify-migration/api/lend-api/earn/deposit.mdx new file mode 100644 index 00000000..84b88476 --- /dev/null +++ b/mintlify-migration/api/lend-api/earn/deposit.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/lend/lend.yaml post /earn/deposit +--- \ No newline at end of file diff --git a/mintlify-migration/api/lend-api/earn/earnings.mdx b/mintlify-migration/api/lend-api/earn/earnings.mdx new file mode 100644 index 00000000..1c8f2e8c --- /dev/null +++ b/mintlify-migration/api/lend-api/earn/earnings.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/lend/lend.yaml get /earn/earnings +--- \ No newline at end of file diff --git a/mintlify-migration/api/lend-api/earn/mint-instructions.mdx b/mintlify-migration/api/lend-api/earn/mint-instructions.mdx new file mode 100644 index 00000000..22dfece6 --- /dev/null +++ b/mintlify-migration/api/lend-api/earn/mint-instructions.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/lend/lend.yaml post /earn/mint-instructions +--- \ No newline at end of file diff --git a/mintlify-migration/api/lend-api/earn/mint.mdx b/mintlify-migration/api/lend-api/earn/mint.mdx new file mode 100644 index 00000000..4c5500b3 --- /dev/null +++ b/mintlify-migration/api/lend-api/earn/mint.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/lend/lend.yaml post /earn/mint +--- \ No newline at end of file diff --git a/mintlify-migration/api/lend-api/earn/positions.mdx b/mintlify-migration/api/lend-api/earn/positions.mdx new file mode 100644 index 00000000..e39db5a6 --- /dev/null +++ b/mintlify-migration/api/lend-api/earn/positions.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/lend/lend.yaml get /earn/positions +--- \ No newline at end of file diff --git a/mintlify-migration/api/lend-api/earn/redeem-instructions.mdx b/mintlify-migration/api/lend-api/earn/redeem-instructions.mdx new file mode 100644 index 00000000..218dc56c --- /dev/null +++ b/mintlify-migration/api/lend-api/earn/redeem-instructions.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/lend/lend.yaml post /earn/redeem-instructions +--- \ No newline at end of file diff --git a/mintlify-migration/api/lend-api/earn/redeem.mdx b/mintlify-migration/api/lend-api/earn/redeem.mdx new file mode 100644 index 00000000..9e118559 --- /dev/null +++ b/mintlify-migration/api/lend-api/earn/redeem.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/lend/lend.yaml post /earn/redeem +--- \ No newline at end of file diff --git a/mintlify-migration/api/lend-api/earn/tokens.mdx b/mintlify-migration/api/lend-api/earn/tokens.mdx new file mode 100644 index 00000000..853147ec --- /dev/null +++ b/mintlify-migration/api/lend-api/earn/tokens.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/lend/lend.yaml get /earn/tokens +--- \ No newline at end of file diff --git a/mintlify-migration/api/lend-api/earn/withdraw-instructions.mdx b/mintlify-migration/api/lend-api/earn/withdraw-instructions.mdx new file mode 100644 index 00000000..982b0769 --- /dev/null +++ b/mintlify-migration/api/lend-api/earn/withdraw-instructions.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/lend/lend.yaml post /earn/withdraw-instructions +--- \ No newline at end of file diff --git a/mintlify-migration/api/lend-api/earn/withdraw.mdx b/mintlify-migration/api/lend-api/earn/withdraw.mdx new file mode 100644 index 00000000..eb4b0d94 --- /dev/null +++ b/mintlify-migration/api/lend-api/earn/withdraw.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/lend/lend.yaml post /earn/withdraw +--- \ No newline at end of file diff --git a/mintlify-migration/api/price-api.mdx b/mintlify-migration/api/price-api.mdx new file mode 100644 index 00000000..a6f03d5d --- /dev/null +++ b/mintlify-migration/api/price-api.mdx @@ -0,0 +1,13 @@ +--- +title: "Price API" +sidebarTitle: "Overview" +--- + + + + 1 item + + + 1 item + + diff --git a/mintlify-migration/api/price-api/v2.mdx b/mintlify-migration/api/price-api/v2.mdx new file mode 100644 index 00000000..14fa3949 --- /dev/null +++ b/mintlify-migration/api/price-api/v2.mdx @@ -0,0 +1,10 @@ +--- +title: "Price API V2 (Deprecated)" +sidebarTitle: "Overview" +--- + + + + Returns prices of specified tokens. + + diff --git a/mintlify-migration/api/price-api/v2/price.mdx b/mintlify-migration/api/price-api/v2/price.mdx new file mode 100644 index 00000000..d99d62df --- /dev/null +++ b/mintlify-migration/api/price-api/v2/price.mdx @@ -0,0 +1,4 @@ +--- +openapi: /docs/openapi-spec/price/v2/price.yaml get / +deprecated: true +--- \ No newline at end of file diff --git a/mintlify-migration/api/price-api/v3.mdx b/mintlify-migration/api/price-api/v3.mdx new file mode 100644 index 00000000..15f6ce7d --- /dev/null +++ b/mintlify-migration/api/price-api/v3.mdx @@ -0,0 +1,10 @@ +--- +title: "Price API V3 (Beta)" +sidebarTitle: "Overview" +--- + + + + Returns prices of specified tokens. + + diff --git a/mintlify-migration/api/price-api/v3/price.mdx b/mintlify-migration/api/price-api/v3/price.mdx new file mode 100644 index 00000000..433244b8 --- /dev/null +++ b/mintlify-migration/api/price-api/v3/price.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/price/v3/price.yaml get /price/v3 +--- \ No newline at end of file diff --git a/mintlify-migration/api/recurring-api.mdx b/mintlify-migration/api/recurring-api.mdx new file mode 100644 index 00000000..a47f8ed1 --- /dev/null +++ b/mintlify-migration/api/recurring-api.mdx @@ -0,0 +1,25 @@ +--- +title: "Recurring API" +sidebarTitle: "Overview" +--- + + + + Request for a base64-encoded unsigned recurring order creation transaction to be used in `POST /recurring/v1/execute` + + + Execute the signed transaction and get the execution status + + + Request for a base64-encoded unsigned recurring order cancellation transaction to be used in `POST /recurring/v1/execute` + + + **DEPRECATED**: This endpoint is deprecated. Please use time-based recurring orders instead. + + + **DEPRECATED**: This endpoint is deprecated. Please use time-based recurring orders instead. + + + Request for the active or historical orders associated to the provided account + + diff --git a/mintlify-migration/api/recurring-api/cancel-order.mdx b/mintlify-migration/api/recurring-api/cancel-order.mdx new file mode 100644 index 00000000..72afb462 --- /dev/null +++ b/mintlify-migration/api/recurring-api/cancel-order.mdx @@ -0,0 +1,11 @@ +--- +openapi: /docs/openapi-spec/recurring/recurring.yaml post /cancelOrder +--- + + + **NOTE** + + - `recurringType` is used to denote the type of recurring order, only `time` + - **DEPRECATED**: `recurringType: price` based orders are deprecated + - Refer to [Recurring API doc](/docs/recurring-api/cancel-order) for more information. + diff --git a/mintlify-migration/api/recurring-api/create-order.mdx b/mintlify-migration/api/recurring-api/create-order.mdx new file mode 100644 index 00000000..160b864d --- /dev/null +++ b/mintlify-migration/api/recurring-api/create-order.mdx @@ -0,0 +1,11 @@ +--- +openapi: /docs/openapi-spec/recurring/recurring.yaml post /createOrder +--- + + + **NOTE** + + - Pass in the correct recurring type in the `params` field, only `time` + - **DEPRECATED**: `params.price` based orders are deprecated + - Refer to [Recurring API doc](/docs/recurring-api/create-order) for more information. + diff --git a/mintlify-migration/api/recurring-api/execute.mdx b/mintlify-migration/api/recurring-api/execute.mdx new file mode 100644 index 00000000..1ac0b87a --- /dev/null +++ b/mintlify-migration/api/recurring-api/execute.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/recurring/recurring.yaml post /execute +--- diff --git a/mintlify-migration/api/recurring-api/get-recurring-orders.mdx b/mintlify-migration/api/recurring-api/get-recurring-orders.mdx new file mode 100644 index 00000000..4d78382f --- /dev/null +++ b/mintlify-migration/api/recurring-api/get-recurring-orders.mdx @@ -0,0 +1,10 @@ +--- +openapi: /docs/openapi-spec/recurring/recurring.yaml get /getRecurringOrders +--- + + + **NOTE** + +- `recurringType` is used to denote the type of recurring order, only `time` +- **DEPRECATED**: `recurringType: price` based orders are deprecated + diff --git a/mintlify-migration/api/recurring-api/price-deposit.mdx b/mintlify-migration/api/recurring-api/price-deposit.mdx new file mode 100644 index 00000000..ac54c980 --- /dev/null +++ b/mintlify-migration/api/recurring-api/price-deposit.mdx @@ -0,0 +1,4 @@ +--- +openapi: /docs/openapi-spec/recurring/recurring.yaml post /priceDeposit +deprecated: true +--- \ No newline at end of file diff --git a/mintlify-migration/api/recurring-api/price-withdraw.mdx b/mintlify-migration/api/recurring-api/price-withdraw.mdx new file mode 100644 index 00000000..57fdbf1c --- /dev/null +++ b/mintlify-migration/api/recurring-api/price-withdraw.mdx @@ -0,0 +1,4 @@ +--- +openapi: /docs/openapi-spec/recurring/recurring.yaml post /priceWithdraw +deprecated: true +--- \ No newline at end of file diff --git a/mintlify-migration/api/send-api.mdx b/mintlify-migration/api/send-api.mdx new file mode 100644 index 00000000..2be306dd --- /dev/null +++ b/mintlify-migration/api/send-api.mdx @@ -0,0 +1,19 @@ +--- +title: "Send API" +sidebarTitle: "Overview" +--- + + + + Request for a base64-encoded unsigned Send transaction + + + Request for a base64-encoded unsigned Send transaction + + + Request for the pending invites of an address + + + Request for the invite history of an address + + diff --git a/mintlify-migration/api/send-api/craft-clawback.mdx b/mintlify-migration/api/send-api/craft-clawback.mdx new file mode 100644 index 00000000..d0574d07 --- /dev/null +++ b/mintlify-migration/api/send-api/craft-clawback.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/send/send.yaml post /craft-clawback +--- \ No newline at end of file diff --git a/mintlify-migration/api/send-api/craft-send.mdx b/mintlify-migration/api/send-api/craft-send.mdx new file mode 100644 index 00000000..cff8f64e --- /dev/null +++ b/mintlify-migration/api/send-api/craft-send.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/send/send.yaml post /craft-send +--- \ No newline at end of file diff --git a/mintlify-migration/api/send-api/invite-history.mdx b/mintlify-migration/api/send-api/invite-history.mdx new file mode 100644 index 00000000..effaa485 --- /dev/null +++ b/mintlify-migration/api/send-api/invite-history.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/send/send.yaml get /invite-history +--- \ No newline at end of file diff --git a/mintlify-migration/api/send-api/pending-invites.mdx b/mintlify-migration/api/send-api/pending-invites.mdx new file mode 100644 index 00000000..f29d964d --- /dev/null +++ b/mintlify-migration/api/send-api/pending-invites.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/send/send.yaml get /pending-invites +--- \ No newline at end of file diff --git a/mintlify-migration/api/studio-api.mdx b/mintlify-migration/api/studio-api.mdx new file mode 100644 index 00000000..df04f391 --- /dev/null +++ b/mintlify-migration/api/studio-api.mdx @@ -0,0 +1,22 @@ +--- +title: "Studio API" +sidebarTitle: "Overview" +--- + + + + Request for a base64-encoded unsigned transaction to create a Dynamic Bonding Curve pool with token metadata + + + Execute the signed transaction, and optionally upload content and header image + + + Request for pool addresses for a given token mint + + + Request for unclaimed creator trading fees of a Dynamic Bonding Curve pool + + + Request for a base64-encoded unsigned transaction to claim creator trading fees of a Dynamic Bonding Curve pool + + diff --git a/mintlify-migration/api/studio-api/dbc-fee-create-tx.mdx b/mintlify-migration/api/studio-api/dbc-fee-create-tx.mdx new file mode 100644 index 00000000..a2fca1e7 --- /dev/null +++ b/mintlify-migration/api/studio-api/dbc-fee-create-tx.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/studio/studio.yaml post /dbc/fee/create-tx +--- \ No newline at end of file diff --git a/mintlify-migration/api/studio-api/dbc-fee.mdx b/mintlify-migration/api/studio-api/dbc-fee.mdx new file mode 100644 index 00000000..f818f723 --- /dev/null +++ b/mintlify-migration/api/studio-api/dbc-fee.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/studio/studio.yaml post /dbc/fee +--- \ No newline at end of file diff --git a/mintlify-migration/api/studio-api/dbc-pool-addresses-by-mint.mdx b/mintlify-migration/api/studio-api/dbc-pool-addresses-by-mint.mdx new file mode 100644 index 00000000..86a6b765 --- /dev/null +++ b/mintlify-migration/api/studio-api/dbc-pool-addresses-by-mint.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/studio/studio.yaml get /dbc-pool/addresses/{mint} +--- \ No newline at end of file diff --git a/mintlify-migration/api/studio-api/dbc-pool-create-tx.mdx b/mintlify-migration/api/studio-api/dbc-pool-create-tx.mdx new file mode 100644 index 00000000..0707e6b2 --- /dev/null +++ b/mintlify-migration/api/studio-api/dbc-pool-create-tx.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/studio/studio.yaml post /dbc-pool/create-tx +--- \ No newline at end of file diff --git a/mintlify-migration/api/studio-api/dbc-pool-submit.mdx b/mintlify-migration/api/studio-api/dbc-pool-submit.mdx new file mode 100644 index 00000000..ec495351 --- /dev/null +++ b/mintlify-migration/api/studio-api/dbc-pool-submit.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/studio/studio.yaml post /dbc-pool/submit +--- \ No newline at end of file diff --git a/mintlify-migration/api/swap-api.mdx b/mintlify-migration/api/swap-api.mdx new file mode 100644 index 00000000..8fc997b2 --- /dev/null +++ b/mintlify-migration/api/swap-api.mdx @@ -0,0 +1,19 @@ +--- +title: "Swap API" +sidebarTitle: "Overview" +--- + + + + Request for a quote to be used in `POST /swap` + + + Request for a base64-encoded unsigned swap transaction based on the `/quote` response + + + Request for swap instructions that you can use from the quote you get from `/quote` + + + Returns a hash, which key is the program id and value is the label. + + diff --git a/mintlify-migration/api/swap-api/program-id-to-label.mdx b/mintlify-migration/api/swap-api/program-id-to-label.mdx new file mode 100644 index 00000000..de062e02 --- /dev/null +++ b/mintlify-migration/api/swap-api/program-id-to-label.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/swap/swap.yaml get /program-id-to-label +--- \ No newline at end of file diff --git a/mintlify-migration/api/swap-api/quote.mdx b/mintlify-migration/api/swap-api/quote.mdx new file mode 100644 index 00000000..9fbfc18f --- /dev/null +++ b/mintlify-migration/api/swap-api/quote.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/swap/swap.yaml get /quote +--- \ No newline at end of file diff --git a/mintlify-migration/api/swap-api/swap-instructions.mdx b/mintlify-migration/api/swap-api/swap-instructions.mdx new file mode 100644 index 00000000..46ed927e --- /dev/null +++ b/mintlify-migration/api/swap-api/swap-instructions.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/swap/swap.yaml post /swap-instructions +--- \ No newline at end of file diff --git a/mintlify-migration/api/swap-api/swap.mdx b/mintlify-migration/api/swap-api/swap.mdx new file mode 100644 index 00000000..e7095617 --- /dev/null +++ b/mintlify-migration/api/swap-api/swap.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/swap/swap.yaml post /swap +--- \ No newline at end of file diff --git a/mintlify-migration/api/token-api.mdx b/mintlify-migration/api/token-api.mdx new file mode 100644 index 00000000..ea1e04e6 --- /dev/null +++ b/mintlify-migration/api/token-api.mdx @@ -0,0 +1,13 @@ +--- +title: "Token API" +sidebarTitle: "Overview" +--- + + + + 4 items + + + 6 items + + diff --git a/mintlify-migration/api/token-api/v1.mdx b/mintlify-migration/api/token-api/v1.mdx new file mode 100644 index 00000000..e1cf1439 --- /dev/null +++ b/mintlify-migration/api/token-api/v1.mdx @@ -0,0 +1,25 @@ +--- +title: "Token API V1 (Deprecated)" +sidebarTitle: "V1 (Deprecated)" +--- + + + + Returns the specified mint address's token information and metadata. + + + Returns the mints involved in a market. + + + Returns a list of all mints tradable via Jupiter routing. + + + Returns a list of mints with specified tag(s) along with their metadata. + + + Returns new tokens with metadata, created at timestamp and markets. + + + Returns all tokens with all metadata. + + diff --git a/mintlify-migration/api/token-api/v1/all.mdx b/mintlify-migration/api/token-api/v1/all.mdx new file mode 100644 index 00000000..1150f7df --- /dev/null +++ b/mintlify-migration/api/token-api/v1/all.mdx @@ -0,0 +1,4 @@ +--- +openapi: /docs/openapi-spec/token/v1/token.yaml get /all +deprecated: true +--- \ No newline at end of file diff --git a/mintlify-migration/api/token-api/v1/mints-in-market.mdx b/mintlify-migration/api/token-api/v1/mints-in-market.mdx new file mode 100644 index 00000000..2a786072 --- /dev/null +++ b/mintlify-migration/api/token-api/v1/mints-in-market.mdx @@ -0,0 +1,4 @@ +--- +openapi: /docs/openapi-spec/token/v1/token.yaml get /market/{market_address}/mints +deprecated: true +--- \ No newline at end of file diff --git a/mintlify-migration/api/token-api/v1/new.mdx b/mintlify-migration/api/token-api/v1/new.mdx new file mode 100644 index 00000000..ca980362 --- /dev/null +++ b/mintlify-migration/api/token-api/v1/new.mdx @@ -0,0 +1,4 @@ +--- +openapi: /docs/openapi-spec/token/v1/token.yaml get /new +deprecated: true +--- \ No newline at end of file diff --git a/mintlify-migration/api/token-api/v1/tagged.mdx b/mintlify-migration/api/token-api/v1/tagged.mdx new file mode 100644 index 00000000..8f71310b --- /dev/null +++ b/mintlify-migration/api/token-api/v1/tagged.mdx @@ -0,0 +1,4 @@ +--- +openapi: /docs/openapi-spec/token/v1/token.yaml get /tagged/{tag} +deprecated: true +--- \ No newline at end of file diff --git a/mintlify-migration/api/token-api/v1/token-information.mdx b/mintlify-migration/api/token-api/v1/token-information.mdx new file mode 100644 index 00000000..37ebe232 --- /dev/null +++ b/mintlify-migration/api/token-api/v1/token-information.mdx @@ -0,0 +1,4 @@ +--- +openapi: /docs/openapi-spec/token/v1/token.yaml get /token/{mint_address} +deprecated: true +--- \ No newline at end of file diff --git a/mintlify-migration/api/token-api/v1/tradable.mdx b/mintlify-migration/api/token-api/v1/tradable.mdx new file mode 100644 index 00000000..327588a8 --- /dev/null +++ b/mintlify-migration/api/token-api/v1/tradable.mdx @@ -0,0 +1,4 @@ +--- +openapi: /docs/openapi-spec/token/v1/token.yaml get /mints/tradable +deprecated: true +--- \ No newline at end of file diff --git a/mintlify-migration/api/token-api/v2.mdx b/mintlify-migration/api/token-api/v2.mdx new file mode 100644 index 00000000..2883599b --- /dev/null +++ b/mintlify-migration/api/token-api/v2.mdx @@ -0,0 +1,18 @@ +--- +title: "Token API V2 (Beta)" +--- + + + + Request a search by token's symbol, name or mint address + + + Request an array of mints and their information by a tag + + + Returns an array of mints and their information for the given category and interval + + + Returns an array of mints that recently had their **first created pool** + + diff --git a/mintlify-migration/api/token-api/v2/category.mdx b/mintlify-migration/api/token-api/v2/category.mdx new file mode 100644 index 00000000..bbf56d63 --- /dev/null +++ b/mintlify-migration/api/token-api/v2/category.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/token/v2/token.yaml get /{category}/{interval} +--- \ No newline at end of file diff --git a/mintlify-migration/api/token-api/v2/recent.mdx b/mintlify-migration/api/token-api/v2/recent.mdx new file mode 100644 index 00000000..0430923a --- /dev/null +++ b/mintlify-migration/api/token-api/v2/recent.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/token/v2/token.yaml get /recent +--- \ No newline at end of file diff --git a/mintlify-migration/api/token-api/v2/search.mdx b/mintlify-migration/api/token-api/v2/search.mdx new file mode 100644 index 00000000..53291d56 --- /dev/null +++ b/mintlify-migration/api/token-api/v2/search.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/token/v2/token.yaml get /search +--- \ No newline at end of file diff --git a/mintlify-migration/api/token-api/v2/tag.mdx b/mintlify-migration/api/token-api/v2/tag.mdx new file mode 100644 index 00000000..77e85313 --- /dev/null +++ b/mintlify-migration/api/token-api/v2/tag.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/token/v2/token.yaml get /tag +--- \ No newline at end of file diff --git a/mintlify-migration/api/trigger-api.mdx b/mintlify-migration/api/trigger-api.mdx new file mode 100644 index 00000000..bfd9fa53 --- /dev/null +++ b/mintlify-migration/api/trigger-api.mdx @@ -0,0 +1,22 @@ +--- +title: "Trigger API" +sidebarTitle: "Overview" +--- + + + + Request for a base64-encoded unsigned trigger order creation transaction to be used in `POST /trigger/v1/execute` + + + Execute the signed transaction and get the execution status + + + Request for a base64-encoded unsigned trigger order cancellation transaction to be used in `POST /trigger/v1/execute` + + + Request for a base64-encoded unsigned trigger order cancellation transaction(s) to be used in `POST /trigger/v1/execute` + + + Request for the active or historical orders associated to the provided account + + diff --git a/mintlify-migration/api/trigger-api/cancel-order.mdx b/mintlify-migration/api/trigger-api/cancel-order.mdx new file mode 100644 index 00000000..30c0abd2 --- /dev/null +++ b/mintlify-migration/api/trigger-api/cancel-order.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/trigger/trigger.yaml post /cancelOrder +--- diff --git a/mintlify-migration/api/trigger-api/cancel-orders.mdx b/mintlify-migration/api/trigger-api/cancel-orders.mdx new file mode 100644 index 00000000..298272a0 --- /dev/null +++ b/mintlify-migration/api/trigger-api/cancel-orders.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/trigger/trigger.yaml post /cancelOrders +--- diff --git a/mintlify-migration/api/trigger-api/create-order.mdx b/mintlify-migration/api/trigger-api/create-order.mdx new file mode 100644 index 00000000..3d4957cb --- /dev/null +++ b/mintlify-migration/api/trigger-api/create-order.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/trigger/trigger.yaml post /createOrder +--- diff --git a/mintlify-migration/api/trigger-api/execute.mdx b/mintlify-migration/api/trigger-api/execute.mdx new file mode 100644 index 00000000..9c71aeda --- /dev/null +++ b/mintlify-migration/api/trigger-api/execute.mdx @@ -0,0 +1,8 @@ +--- +openapi: /docs/openapi-spec/trigger/trigger.yaml post /execute +--- + + +**NOTE** +- Do note that the `requestId` is found in the response of `/createOrder` or `/cancelOrder` + \ No newline at end of file diff --git a/mintlify-migration/api/trigger-api/get-trigger-orders.mdx b/mintlify-migration/api/trigger-api/get-trigger-orders.mdx new file mode 100644 index 00000000..3215c677 --- /dev/null +++ b/mintlify-migration/api/trigger-api/get-trigger-orders.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/trigger/trigger.yaml get /getTriggerOrders +--- diff --git a/mintlify-migration/api/ultra-api.mdx b/mintlify-migration/api/ultra-api.mdx new file mode 100644 index 00000000..35180515 --- /dev/null +++ b/mintlify-migration/api/ultra-api.mdx @@ -0,0 +1,25 @@ +--- +title: "Ultra API" +sidebarTitle: "Overview" +--- + + + + Request for a base64-encoded unsigned swap transaction to be used in `POST /ultra/v1/execute` + + + Execute the signed transaction and get the execution status + + + Request for token balances of an account + + + Request for token information and warnings of mints + + + Request a search by token's symbol, name or mint address + + + Request for the list of routers available in the routing engine of Ultra, which is [Juno](/docs/routing#juno-liquidity-engine) + + diff --git a/mintlify-migration/api/ultra-api/balances.mdx b/mintlify-migration/api/ultra-api/balances.mdx new file mode 100644 index 00000000..bf2e6c10 --- /dev/null +++ b/mintlify-migration/api/ultra-api/balances.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/ultra/ultra.yaml get /balances/{address} +--- \ No newline at end of file diff --git a/mintlify-migration/api/ultra-api/execute.mdx b/mintlify-migration/api/ultra-api/execute.mdx new file mode 100644 index 00000000..5300a845 --- /dev/null +++ b/mintlify-migration/api/ultra-api/execute.mdx @@ -0,0 +1,8 @@ +--- +openapi: /docs/openapi-spec/ultra/ultra.yaml post /execute +--- + + +**NOTE** +- The `requestId` is found in the response of `/order` + \ No newline at end of file diff --git a/mintlify-migration/api/ultra-api/order.mdx b/mintlify-migration/api/ultra-api/order.mdx new file mode 100644 index 00000000..38221a5c --- /dev/null +++ b/mintlify-migration/api/ultra-api/order.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/ultra/ultra.yaml get /order +--- \ No newline at end of file diff --git a/mintlify-migration/api/ultra-api/routers.mdx b/mintlify-migration/api/ultra-api/routers.mdx new file mode 100644 index 00000000..b5857fe1 --- /dev/null +++ b/mintlify-migration/api/ultra-api/routers.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/ultra/ultra.yaml get /order/routers +--- \ No newline at end of file diff --git a/mintlify-migration/api/ultra-api/search.mdx b/mintlify-migration/api/ultra-api/search.mdx new file mode 100644 index 00000000..9c627bf1 --- /dev/null +++ b/mintlify-migration/api/ultra-api/search.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/ultra/ultra.yaml get /search +--- \ No newline at end of file diff --git a/mintlify-migration/api/ultra-api/shield.mdx b/mintlify-migration/api/ultra-api/shield.mdx new file mode 100644 index 00000000..c72dd8b0 --- /dev/null +++ b/mintlify-migration/api/ultra-api/shield.mdx @@ -0,0 +1,3 @@ +--- +openapi: /docs/openapi-spec/ultra/ultra.yaml get /shield +--- \ No newline at end of file diff --git a/mintlify-migration/docs.json b/mintlify-migration/docs.json new file mode 100644 index 00000000..3045a4cc --- /dev/null +++ b/mintlify-migration/docs.json @@ -0,0 +1,562 @@ +{ + "$schema": "https://mintlify.com/docs.json", + "theme": "mint", + "name": "Jupiter", + "colors": { + "primary": "#00b45a", + "light": "#c7f284", + "dark": "#c7f284" + }, + "favicon": "/favicon.png", + "contextual": { + "options": ["copy", "chatgpt", "claude", "view"] + }, + "appearance": { + "default": "dark" + }, + "background": { + "decoration": "gradient" + }, + "navigation": { + "tabs": [ + { + "tab": "Home", + "groups": [ + { + "group": " ", + "pages": ["index"] + } + ] + }, + { + "tab": "APIs", + "menu": [ + { + "item": "Getting Started", + "icon": "rocket", + "groups": [ + { + "group": " ", + "pages": ["docs/index"] + }, + { + "group": "Development", + "pages": [ + "docs/environment-setup", + "docs/development-basics" + ] + }, + { + "group": "Portal", + "pages": [ + "docs/api-setup", + "docs/api-responses", + "docs/api-rate-limit", + "docs/api-faq" + ] + } + ] + }, + { + "item": "Ultra API", + "icon": "bolt", + "groups": [ + { + "group": " ", + "pages": ["docs/ultra-api"] + }, + { + "group": "Ultra API", + "pages": [ + "docs/ultra-api/get-order", + "docs/ultra-api/execute-order", + "docs/ultra-api/get-balances", + "docs/ultra-api/get-shield", + "docs/ultra-api/search-token" + ] + }, + { + "group": "Ultra API Guides", + "pages": [ + "docs/ultra-api/add-fees-to-ultra", + "docs/ultra-api/plugin-integration" + ] + } + ] + }, + { + "item": "Swap API", + "icon": "swap", + "groups": [ + { + "group": " ", + "pages": ["docs/swap-api"] + }, + { + "group": "Swap API", + "pages": [ + "docs/swap-api/get-quote", + "docs/swap-api/build-swap-transaction", + "docs/swap-api/send-swap-transaction" + ] + }, + { + "group": "Swap API Guides", + "pages": [ + "docs/swap-api/add-fees-to-swap", + "docs/swap-api/payments-through-swap", + "docs/swap-api/requote-with-lower-max-accounts", + "docs/swap-api/solana-unity-sdk" + ] + }, + { + "group": "Debugging", + "pages": ["docs/swap-api/common-errors"] + } + ] + }, + { + "item": "Lend API (Beta)", + "icon": "money-bill-transfer", + "groups": [ + { + "group": " ", + "pages": ["docs/lend-api"] + }, + { + "group": "Lend API", + "pages": [ + "docs/lend-api/earn", + "docs/lend-api/borrow" + ] + } + ] + }, + { + "item": "Trigger API", + "icon": "arrow-right-arrow-left", + "groups": [ + { + "group": " ", + "pages": ["docs/trigger-api"] + }, + { + "group": "Trigger API", + "pages": [ + "docs/trigger-api/create-order", + "docs/trigger-api/execute-order" + ] + }, + { + "group": "Order Management", + "pages": [ + "docs/trigger-api/cancel-order", + "docs/trigger-api/get-trigger-orders" + ] + }, + { + "group": "Debugging", + "pages": ["docs/trigger-api/best-practices"] + } + ] + }, + { + "item": "Recurring API", + "icon": "clock-rotate-left", + "groups": [ + { + "group": " ", + "pages": ["docs/recurring-api"] + }, + { + "group": "Recurring API", + "pages": [ + "docs/recurring-api/create-order", + "docs/recurring-api/execute-order" + ] + }, + { + "group": "Order Management", + "pages": [ + "docs/recurring-api/cancel-order", + "docs/recurring-api/deposit-price-order", + "docs/recurring-api/withdraw-price-order", + "docs/recurring-api/get-recurring-orders" + ] + }, + { + "group": "Debugging", + "pages": ["docs/recurring-api/best-practices"] + } + ] + }, + { + "item": "Token API", + "icon": "key", + "groups": [ + { + "group": " ", + "pages": ["docs/token-api"] + }, + { + "group": "Versions", + "pages": [ + "docs/token-api/v2", + "docs/token-api/v1" + ] + }, + { + "group": "Expanding on Token API", + "pages": [ + "docs/token-api/organic-score", + "docs/token-api/token-tag-standard" + ] + } + ] + }, + { + "item": "Price API", + "icon": "tag", + "groups": [ + { + "group": " ", + "pages": ["docs/price-api"] + }, + { + "group": "Versions", + "pages": [ + "docs/price-api/v3", + "docs/price-api/v2" + ] + } + ] + }, + { + "item": "Send API (Beta)", + "icon": "paper-plane", + "groups": [ + { + "group": " ", + "pages": ["docs/send-api"] + }, + { + "group": "Send API", + "pages": [ + "docs/send-api/invite-code", + "docs/send-api/craft-send", + "docs/send-api/craft-clawback", + "docs/send-api/manage-invites" + ] + } + ] + }, + { + "item": "Studio API (Beta)", + "icon": "building-columns", + "groups": [ + { + "group": " ", + "pages": ["docs/studio-api"] + }, + { + "group": "Studio API", + "pages": [ + "docs/studio-api/create-token", + "docs/studio-api/claim-fee" + ] + } + ] + }, + { + "item": "Prep API", + "icon": "chart-line", + "groups": [ + { + "group": " ", + "pages": ["docs/prep-api"] + }, + { + "group": "Prep Program", + "pages": [ + "docs/perp-api/position-account", + "docs/perp-api/position-request-account", + "docs/perp-api/pool-account", + "docs/perp-api/custody-account" + ] + } + ] + } + ] + }, + { + "tab": "Tool Kits", + "groups": [ + { + "group": " ", + "pages": ["docs/tool-kits"] + }, + { + "group": "Jupiter Plugin", + "pages": [ + "docs/tool-kits/plugin", + "docs/tool-kits/plugin/nextjs-app-example", + "docs/tool-kits/plugin/react-app-example", + "docs/tool-kits/plugin/html-app-example", + "docs/tool-kits/plugin/customization", + "docs/tool-kits/plugin/faq" + ] + }, + { + "group": "Jupiter Mobile Adapter", + "pages": ["docs/tool-kits/mobile-adapter"] + }, + { + "group": "Jupiter Wallet Kit", + "pages": ["docs/tool-kits/wallet-kit"] + }, + { + "group": "Jupiter Referral Program", + "pages": ["docs/tool-kits/referral-program"] + } + ] + }, + { + "tab": "Routing Integration", + "groups": [ + { + "group": " ", + "pages": ["docs/routing"] + }, + { + "group": "Routing Integrations", + "pages": [ + "docs/routing/dex-integration", + "docs/routing/rfq-integration" + ] + } + ] + }, + { + "tab": "API Reference", + "groups": [ + { + "group": " ", + "pages": ["api"] + }, + { + "group": "API Reference", + "pages": [ + { + "group": "Ultra API Schema", + "pages": [ + "api/ultra-api", + "api/ultra-api/order", + "api/ultra-api/execute", + "api/ultra-api/balances", + "api/ultra-api/shield", + "api/ultra-api/search", + "api/ultra-api/routers" + ] + }, + { + "group": "Swap API Schema", + "pages": [ + "api/swap-api", + "api/swap-api/quote", + "api/swap-api/swap", + "api/swap-api/swap-instructions", + "api/swap-api/program-id-to-label" + ] + }, + { + "group": "Lend API Schema", + "pages": [ + "api/lend-api", + { + "group": "Earn (Beta)", + "pages": [ + "api/lend-api/earn", + "api/lend-api/earn/deposit", + "api/lend-api/earn/withdraw", + "api/lend-api/earn/mint", + "api/lend-api/earn/redeem", + "api/lend-api/earn/deposit-instructions", + "api/lend-api/earn/withdraw-instructions", + "api/lend-api/earn/mint-instructions", + "api/lend-api/earn/redeem-instructions", + "api/lend-api/earn/tokens", + "api/lend-api/earn/positions", + "api/lend-api/earn/earnings" + ] + } + ] + }, + { + "group": "Trigger API Schema", + "pages": [ + "api/trigger-api", + "api/trigger-api/create-order", + "api/trigger-api/execute", + "api/trigger-api/cancel-order", + "api/trigger-api/cancel-orders", + "api/trigger-api/get-trigger-orders" + ] + }, + { + "group": "Recurring API Schema", + "pages": [ + "api/recurring-api", + "api/recurring-api/create-order", + "api/recurring-api/execute", + "api/recurring-api/cancel-order", + "api/recurring-api/price-deposit", + "api/recurring-api/price-withdraw", + "api/recurring-api/get-recurring-orders" + ] + }, + { + "group": "Token API Schema", + "pages": [ + "api/token-api", + { + "group": "V2 (Beta)", + "pages": [ + "api/token-api/v2", + "api/token-api/v2/search", + "api/token-api/v2/tag", + "api/token-api/v2/category", + "api/token-api/v2/recent" + ] + }, + { + "group": "V1 (Deprecated)", + "pages": [ + "api/token-api/v1", + "api/token-api/v1/token-information", + "api/token-api/v1/mints-in-market", + "api/token-api/v1/tradable", + "api/token-api/v1/tagged", + "api/token-api/v1/new", + "api/token-api/v1/all" + ] + } + ] + }, + { + "group": "Price API Schema", + "pages": [ + "api/price-api", + { + "group": "V3 (Beta)", + "pages": [ + "api/price-api/v3", + "api/price-api/v3/price" + ] + }, + { + "group": "V2 (Deprecated)", + "pages": ["api/price-api/v2", "api/price-api/v2/price"] + } + ] + }, + { + "group": "Send API Schema (Beta)", + "pages": [ + "api/send-api", + "api/send-api/craft-send", + "api/send-api/craft-clawback", + "api/send-api/pending-invites", + "api/send-api/invite-history" + ] + }, + { + "group": "Studio API Schema (Beta)", + "pages": [ + "api/studio-api", + "api/studio-api/dbc-pool-create-tx", + "api/studio-api/dbc-pool-submit", + "api/studio-api/dbc-pool-addresses-by-mint", + "api/studio-api/dbc-fee", + "api/studio-api/dbc-fee-create-tx" + ] + } + ] + } + ] + }, + { + "tab": "Updates", + "groups": [ + { + "group": " ", + "pages": ["updates"] + } + ] + }, + { + "tab": "Misc", + "groups": [ + { + "group": " ", + "pages": ["misc"] + }, + { + "group": "Legal & Guidelines", + "pages": [ + "misc/sdk-api-license-agreement", + "misc/terms-of-use", + "misc/privacy-policy", + "misc/integrator-guidelines", + "misc/audits" + ] + } + ] + } + ], + "global": { + "anchors": [ + { + "anchor": "Portal", + "href": "https://portal.jup.ag/", + "icon": "key" + }, + { + "anchor": "Status", + "href": "https://status.jup.ag/", + "icon": "signal" + }, + { + "anchor": "Support", + "href": "https://discord.gg/jup", + "icon": "discord" + } + ] + } + }, + "logo": { + "light": "/logo/logo.png", + "dark": "/logo/logo.png", + "href": "https://dev.jup.ag/" + }, + "navbar": { + "links": [ + { + "label": "Portal", + "href": "https://portal.jup.ag/" + } + ], + "primary": { + "type": "github", + "href": "https://github.com/jup-ag/docs" + } + }, + "footer": { + "socials": { + "x": "https://x.com/JupiterExchange", + "discord": "https://discord.gg/jup", + "telegram": "https://t.me/jup_dev", + "github": "https://github.com/jup-ag", + "youtube": "https://www.youtube.com/@Jupiter-Exchange" + } + } +} diff --git a/mintlify-migration/docs/api-faq.mdx b/mintlify-migration/docs/api-faq.mdx new file mode 100644 index 00000000..97dba252 --- /dev/null +++ b/mintlify-migration/docs/api-faq.mdx @@ -0,0 +1,50 @@ +--- +title: "API FAQ" +description: "This section covers the FAQ of the API Key set up and rate limits systems. Please read [API Setup](/api-setup) and [API Rate Limit](/api-rate-limit) docs as well." +--- + + + + +* No, you do not need to pay for Lite or Ultra. +* For Lite, just request directly to `lite-api.jup.ag` without an API Key. +* For Ultra, you will need to log in first to generate an API Key and use it with `api.jup.ag/ultra` + + + + +* By purchasing a Pro plan, you are only accessing higher rate limits with no differences in usage nor freshness of data. + + + + +* Yes, API keys are universal across both Fixed Rate Limit and Dynamic Rate Limit system. + + + + +* No, it will take 2-5 minutes for it to reflect. + + + + +* You can only upgrade/downgrade your Pro plan. +* The amount payable is pro-rated. +* Upgrade happens immediately (2 - 5 minutes) is still required to be reflected. +* Downgrade will happen at the end of the billing period if you are to renew the plan. + + + + +* Yes. You can maintain a Pro subscription for all other API routes while integrating Ultra endpoints separately. +* Do note that purchasing a Pro plan, does not apply its rate limits to Ultra API. + + + +#### For more support + +* Please reach out to us. +* If you have increasing demand and growth in your app, and need custom rate limits or payment options beyond the provided in Portal. +* If you require higher base quota for Ultra plan to bootstrap your product. +* If you have questions or need support on Portal, [open a ticket](https://support.jup.ag/hc/en-us/requests/new?ticket_form_id=18069133114012\&tf_18541841140892=api_or_developer_support). +* Join the [Telegram channel](https://t.me/jup_dev) or [Discord channel](https://discord.com/channels/897540204506775583/1115543693005430854) to subscribe to updates. diff --git a/mintlify-migration/docs/api-rate-limit.mdx b/mintlify-migration/docs/api-rate-limit.mdx new file mode 100644 index 00000000..fd24bf6b --- /dev/null +++ b/mintlify-migration/docs/api-rate-limit.mdx @@ -0,0 +1,114 @@ +--- +title: "API Rate Limiting" +description: "In this section, you can find the rate limiting details for the Jupiter API." +--- + +## Overview + +**Fixed Rate Limit** + +* All Jupiter APIs that are public and documented are free to use via the Lite tier. +* By purchasing a Pro plan, you are only accessing higher rate limits with no differences in usage nor freshness of data. + +**Dynamic Rate Limit** + +* Only Ultra API has a unique dynamic rate limit system, [you can find more details in this section](#dynamic-rate-limit). + +**API Key rules** + +* API Keys are universal + + * Use the same API Key for Ultra API (Dynamic Rate Limit) and all Pro APIs `api.jup.ag` (Fixed Rate Limit). + * You do not need an API Key for Lite APIs `lite-api.jup.ag`. + +* Rate limits apply on a per account basis, not to individual API keys. + +| API Tier | Rate Limit Model | API Key Required | Base URL | +| :--------- | :----------------- | :---------------- | :----------------------------- | +| **Lite** | Fixed (Free Tier) | No | `https://lite-api.jup.ag/**` | +| **Pro** | Fixed (Tiered) | Yes | `https://api.jup.ag/**` | +| **Ultra** | Dynamic | Yes | `https://api.jup.ag/ultra/**` | + +## Fixed Rate Limit + +The Fixed Rate Limit system applies to the Lite and Pro plans (does not include Ultra API), using the sliding window method to enforce request quotas. + +| Property | Lite | Pro | +| :----------------------- | :-------------------------- | :----------------------------- | +| **Base URL** | `https://lite-api.jup.ag/` | `https://api.jup.ag/` | +| **Cost** | Free | Paid per month, based on tier | +| **API Key** | Not required | Required | +| **Requests Per Minute** | 60 | Based on tier | +| **Window** | 60 seconds | 10 seconds | + +### Rate Limit + +Rate limits are defined over 10-second windows (except Lite at 60-second window). For example, if your tier allows 100 requests per 10 seconds, any more within that window will receive a 429 response, regardless of how few you used in the previous window. + +| Tier | Est. Requests per Minute | Requests Per Period | Sliding Window Period | +| :------- | :------------------------ | :------------------- | :--------------------- | +| Lite | 60 | 60 | 60 seconds | +| Pro I | \~600 | 100 | 10 seconds | +| Pro II | \~3,000 | 500 | 10 seconds | +| Pro III | \~6,000 | 1,000 | 10 seconds | +| Pro IV | \~30,000 | 5,000 | 10 seconds | + +Requests are distributed to each bucket: + +1. **Price API Bucket** – dedicated for `/price/v3/` only - separate from Default Bucket. +2. **Default Bucket** – used for all APIs except the Price API. + + + **NOTE** + + * Each bucket enforces its own sliding window independently. + * For example, Pro II = 500 per 10 seconds to the Default Bucket and 500 per 10 seconds to the Price API Bucket. + * Lite users do not have a separate Price API Bucket — all requests are counted against the Default Bucket. + + +## Dynamic Rate Limit (BETA) + +The [**Ultra API**](/docs/ultra-api) uses a unique rate limiting mechanism that scales with your **executed swap volume** over time. + +| Property | Dynamic | +| :----------------------- | :--------------------------------------- | +| **Base URL** | `https://api.jup.ag/ultra/` | +| **Cost** | Free to use, but Ultra incurs swap fees | +| **API Key** | Required | +| **Requests Per Minute** | Base Quota + Added Quota | + +### How Dynamic Rate Limit Works + +Every **10 minutes** + +* The system aggregates your swap volume from `/execute` on Ultra for **the current rolling day** (volume of (current timestamp - 1 day) up to present). +* After which, the Added Quota will update, which will be added on top of the Base Quota. + +| Swap Volume | Requests Per Period | Sliding Window Period | +| :---------- | :------------------------ | :-------------------- | +| $0 | 50 Base + 0 Added = 50 | 10 seconds | +| $10,000 | 50 Base + 1 Added = 51 | 10 seconds | +| $100,000 | 50 Base + 11 Added = 61 | 10 seconds | +| $1,000,000 | 50 Base + 115 Added = 165 | 10 seconds | + + + **NOTE** + + The formula is subject to changes as we experiment with the Dynamic Rate Limit system. + + If you find that the rate limit is too restrictive, please reach out to us in Discord. + + +## Managing Rate Limits + +If you receive a 429 response, you should: + +1. Implement exponential backoff in your retry logic +2. Wait for sliding window to allow for more requests +3. **Upgrade your tier (Pro)** or **scale your Ultra usage** to unlock higher limits. + + + **CAUTION** + + Bursting beyond your allocation may result in **temporary 429s/rate limits**, even after the refill period. Avoid aggressive retry patterns. + diff --git a/mintlify-migration/docs/api-responses.mdx b/mintlify-migration/docs/api-responses.mdx new file mode 100644 index 00000000..6a7185c5 --- /dev/null +++ b/mintlify-migration/docs/api-responses.mdx @@ -0,0 +1,22 @@ +--- +title: "API Responses" +description: "In this section, you can find the list of responses that can be returned by the Jupiter API." +--- + + + **PROGRAM ERRORS** + + For more information on error codes from programs, see the [Swap API - Common Errors](/docs/swap-api/common-errors). + + +| Common Codes | Description | Debug | +| :------------ | :--------------------- | :------------------------------------------------------------------------------------------- | +| 200 | Good | Success! | +| 400 | Bad Request | Likely a problem with the request, check the request parameters, syntax, etc. | +| 401 | Unauthorized | Likely a problem with the API key, check if the API key is correct. | +| 404 | Not Found | Likely a broken or invalid endpoint. | +| 429 | Rate Limited | You are being rate limited. Either slow down requests, reduce bursts, or upgrade your plan. | +| 500 | Internal Server Error | Please reach out in [Discord](https://discord.gg/jup). | +| 502 | Bad Gateway | Please reach out in [Discord](https://discord.gg/jup). | +| 503 | Service Unavailable | Please reach out in [Discord](https://discord.gg/jup). | +| 504 | Gateway Timeout | Please reach out in [Discord](https://discord.gg/jup). | diff --git a/mintlify-migration/docs/api-setup.mdx b/mintlify-migration/docs/api-setup.mdx new file mode 100644 index 00000000..a27ad62e --- /dev/null +++ b/mintlify-migration/docs/api-setup.mdx @@ -0,0 +1,82 @@ +--- +title: "API Key Setup" +description: "Get started by setting up an account on the dashboard to generate API Keys and managing payments via Helio." +--- + + + **API USAGE** + + Refer to [API Rate Limit](/docs/api-rate-limit) for more detailed information. + + | API Tier | Rate Limit Model | API Key | Base URL | + | :--------- | :----------------- | :------- | :----------------------------- | + | **Lite** | Fixed (Free Tier) | No | `https://lite-api.jup.ag/**` | + | **Pro** | Fixed (Tiered) | Yes | `https://api.jup.ag/**` | + | **Ultra** | Dynamic | Yes | `https://api.jup.ag/ultra/**` | + +```js + headers: { + 'Content-Type': 'application/json', + 'x-api-key': '' // enter api key here +}, +``` + + +## Overview + + + + Open Portal at [https://portal.jup.ag/](https://portal.jup.ag/) + + + Browse and select plan + + + Connect via email + + + Pay via Helio (Payment is currently done on per month basis) + + +## Types of Plans + + + **NOTE** + + You can always change your plans later. + + You can upgrade/downgrade your Pro plans on the UI any time. + + +Depending on your needs, you can choose from the following plans: + +| Plan | Rate Limit Model | Why choose this plan | +| :----- | :------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Lite | Free Tier | You are just starting out and want to test the Jupiter APIs. | +| Pro | Fixed Tiered Rate Limits | Both small projects or large enterprises can utilize this with the tiered rate limits. Rate limits range from 1 RPS to 500 RPS plans. | +| Ultra | Dynamic Rate Limits based on executed swap volume | [Using Ultra API comes with many benefits](/docs/ultra-api) where Jupiter will handle slippage, transaction sending, and more without the need of an RPC from you. With that, the Ultra API is governed by a Dynamic Rate Limit model that will scale with your swap executions. | + +## Payment + + + **NOTE** + + We are working on adding more payment methods. + + + + **PLAN RENEWAL** + + The payment is currently done on a monthly basis, which means you will need to manually renew each month. + + * 7 days before the plan expires, you will see the state change in the dashboard's table and receive an automated email as a reminder to renew. + * Upon expiry, your key will remain valid for a grace period but will be disabled (but not deleted) when it ends. + * The plan will be renewed to the same plan as the previous. + * If you have any issues with the payment, [please open a ticket](https://support.jup.ag/hc/en-us/requests/new?ticket_form_id=18069133114012\&tf_18541841140892=api_or_developer_support). + + +The current payment method we support is via Helio. + +* Only Pro plans require payments. +* The payment is currently done on a monthly basis. +* The payment is done in Solana USDC only. diff --git a/mintlify-migration/docs/development-basics.mdx b/mintlify-migration/docs/development-basics.mdx new file mode 100644 index 00000000..8f362c07 --- /dev/null +++ b/mintlify-migration/docs/development-basics.mdx @@ -0,0 +1,117 @@ +--- +title: "Development Basics" +description: "Solana uses an account-based architecture where data are stored in accounts. However, Solana keeps Programs (also known as smart contracts on other blockchains) and Accounts distinct." +--- + + + **WHERE IS JUPITER?** + + Jupiter is built on Solana MAINNET only! + + +In order to mutate the data in Accounts, you will need to send transactions to the network which execute Instructions defined by Programs. + +* [Programs](https://solana.com/docs/core/programs) on Solana are executable code deployed on-chain. They are designed to execute instructions, process transactions and interact with accounts. +* [Instructions](https://solana.com/docs/core/transactions#instruction) on Solana are defined by the Program, similar to API endpoints exposed by a program. +* [Accounts](https://solana.com/docs/core/accounts) store data and are mutable, meaning they can be updated by the program who interacts with them. +* [Transactions](https://solana.com/docs/core/transactions#transaction) is what we send to interact with the network which can include one or more instructions to execute what is needed. + +## Interacting with Solana + +The Solana Web3.js and Rust client libraries serve as essential interfaces for interacting with Solana in JavaScript/TypeScript and Rust environments, respectively. They abstract complex interactions with the network, providing easier and more accessible functions for developers building on Solana. Here’s an overview of what each library offers and some of the most common functions they simplify: + +1. Connecting to the network via RPC (Remote Procedure Call) endpoints +2. Building Transactions +3. Interfacing with Solana Programs and Accounts + + + **LINKS** + + Explore the rich features and detailed documentation of these libraries in the official Solana Developer Documentation: [Web3.js](https://solana.com/docs/clients/javascript) and [Rust client](https://solana.com/docs/clients/rust) + + +## Interacting with Jupiter Programs + +To interact with the Jupiter Swap Aggregator Program, there are a few ways to do it: + +| Method | Description | +| :----------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Swap API | Simply call the Quote API to get a quote based on Jupiter’s routing engine and call the Swap API to get a serialized transaction to send to the network. | +| Flash Fill method | If you are building your own on-chain program, an alternative method from CPI, using Versioned Transaction and Address Lookup Tables, thus reducing the size of each account (used to be a limitation of using CPI method). | +| [Cross Program Invocation (CPI)](https://solana.com/docs/core/cpi) | CPI method is now recommended. As of January 2025, Jupiter Swap via CPI is recommended for most users. [The `Loosen CPI restriction` feature has been deployed on Solana, you can read more here](https://github.com/solana-labs/solana/issues/26641). | + +## Building Transactions + +Before you send a transaction to the network, you will need to build the transaction that defines the instructions to execute and accounts to read/write to. It can be complex to handle this yourself when building with Jupiter, you can [read more about it here](https://solana.com/docs/core/transactions). + +However, good news! Most of our APIs and SDKs just handles it for you, so you get a response with the transaction to be prepared and sent to the network. + + + **SWAP API TIP** + + The Swap API returns you the serialized transaction which you can directly send it to your RPC endpoint to execute on Solana. Alternatively, if you plan to manipulate the instructions and build your own custom transactions, you can request from the `/swap-instructions` endpoint. + + +## Sending Transactions + +Transactions on Solana can only be sent to the network through an RPC (Remote Procedure Call) endpoint. The Solana network operates with a client-server model where RPC nodes handle transactions and interact with the validators of the blockchain. We recommend using 3rd party RPC providers like [Triton](https://triton.one/) or [Helius](https://helius.dev/) for production applications. + +There are a few key points to note when sending transactions to the Solana network. At Jupiter, we do our best to help you optimize transaction sending and make it easier for you. + +1. Solana transaction base fee +2. Priority fee +3. Compute units +4. Transaction broadcasting methods +5. Slippage (100% slippage will probably always work but also mean you can possibly get the worst outcome, so we need to find the balance between success optimizations and best output price) + +## More about these factors? + +### What is Priority Fee? + +Transactions submitted to the blockchain are prioritized based on a fee-bidding process. The higher the priority fee, the higher your transaction will be placed in the execution queue. + + + **OVERPAYING PRIORITY FEE** + + It is important to note that overpaying for priority fee can be detrimental in the long run. If transactions continuously outbid each other, the overall fees required to process across the network will increase over time. + + +**Priority Fee** is an optional fee you can pay additionally to improve the chance of landing your transactions faster. + +* Priority Fee = **Compute Budget \* Compute Unit Price** +* This is excluding the base transaction fee (5,000 lamports or 0.000005 SOL) that you always need to pay. +* You not only need to outbid other transactions trying to be included in the block, but also outbid those trying to write to the same account. + +| Terminologies | | +| :------------------- | :------------------------------------------------------------------------------- | +| Global Priority Fee | The Priority Fee estimation across the entire network. | +| Local Fee Market | The Priority Fee estimation when modifying a writable account (or hot account). | +| Priority Fee | Compute Budget \* Compute Unit Price | +| Compute Budget | How much compute unit the transaction is supposed to consume | +| Compute Unit Price | Micro lamports per compute unit the transaction will use | + +When querying the micro-lamport per compute unit for a particular program or account, it will contain both the Global and Local Fee markets. + +### What is Compute Unit? + +Compute Unit (CU) is a standardized metric for evaluating how much "work" or "resource" is required by the transaction to execute. Different operations on Solana has varying amounts of CUs. In order to keep the blockchain efficient yet fast, each transaction, the Solana runtime has an absolute max compute unit limit of 1.4 million CU and sets a default requested max limit of 200k CU per instruction. + + + **SET CUSTOM COMPUTE UNIT LIMIT** + + A transaction can request a more specific and optimal compute unit limit by including a single `SetComputeUnitLimit` instruction. Either a higher or lower limit. But it may never request higher than the absolute max limit per transaction. + + +However, we must note that higher CU also means higher Priority Fee it might need to help prioritize it. + +### What are some transaction broadcasting methods? + +1. Typical RPCs +2. RPCs with SWQoS +3. Jito RPC + +### What is Slippage? + +A percentage or bps threshold the user specify and if the actual executed output is less than quoted output by the percentage/bps, the transaction will fail. + +It is more like a safeguard but the tighter threshold you go, the harder it can become to land the transaction as markets can move rapidly. diff --git a/mintlify-migration/docs/environment-setup.mdx b/mintlify-migration/docs/environment-setup.mdx new file mode 100644 index 00000000..e2ae2bbe --- /dev/null +++ b/mintlify-migration/docs/environment-setup.mdx @@ -0,0 +1,66 @@ +--- +title: "Environment Setup" +--- + + + **ABOUT THE DOCUMENTATION** + + In the documentation, we are using the Solana `web3.js` library to set up connection, sign transactions, etc. + + +## Useful Libraries + +**JavaScript Libraries** + +* `@solana/web3.js` +* `@solana/spl-token` +* `@jup-ag/referral-sdk` + +## Useful Scripts + +**Set up RPC Connection** + + + **NOTE** + + Solana provides a [default RPC endpoint](https://solana.com/docs/core/clusters). However, as your application grows, we recommend you to always use your own or provision a 3rd party provider’s RPC endpoint such as [Helius](https://helius.dev/) or [Triton](https://triton.one/). + + +```bash +const connection = new Connection('https://api.mainnet-beta.solana.com'); +``` + +**Set up Development Wallet** + + + **NOTE** + + * You can paste in your private key for testing purposes but this is not recommended for production applications. + * If you want to store your private key in the project directly, you can do it via a `.env` file. + + +To set up a development wallet via `.env` file, you can use the following script. + +```js +// index.js +import { Keypair } from '@solana/web3.js'; +import dotenv from 'dotenv'; +require('dotenv').config(); + +const wallet = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY || ''))); +``` + +```bash +// .env +PRIVATE_KEY="" +``` + +To set up a development wallet via a wallet generated via [Solana CLI](https://solana.com/docs/intro/installation#solana-cli-basics), you can use the following script. + +```js +import { Keypair } from '@solana/web3.js'; +import fs from 'fs'; + +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/to/.config/solana/id.json', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); +``` diff --git a/mintlify-migration/docs/index.mdx b/mintlify-migration/docs/index.mdx new file mode 100644 index 00000000..bed6cdcf --- /dev/null +++ b/mintlify-migration/docs/index.mdx @@ -0,0 +1,43 @@ +--- +title: "Welcome!" +description: "Welcome to Jupiter Developer Documentation! You'll find detailed API guides, schemas, and powerful tool kits built by the team and DevRel Working Group to help you build with Jupiter." +sidebarTitle: "Get Started" +--- + + +**BREAKING CHANGES** + +Refer to the [Updates](/updates) section for the latest API updates and breaking changes. + + +## Get Started + +**For new developers or new to blockchain development**: We recommend you to start with the [Environment Setup](/docs/environment-setup) and [Development Basics](/docs/development-basics) guides. + +**For existing developers**: Please refer to the [Updates](/updates) section for the latest API updates and breaking changes. + +**For routing integrations**: Please refer to the [DEX Integration](/docs/routing/dex-integration) and [RFQ Integration](/docs/routing/rfq-integration) guides to complete the prerequisites before we look into integrating. + +**Quick Links** to APIs and Tool Kits: + + + + + + + + + + + + + + + + +**Reach out to us** on [Discord](https://discord.gg/jup) for developer support + +* If you have any feedback. +* If you have technical questions. +* If you need API Portal support. +* Refer to these channels to receive updates: [Telegram channel](https://t.me/jup_dev) or [Discord channel](https://discord.com/channels/897540204506775583/1115543693005430854) diff --git a/mintlify-migration/docs/lend-api.mdx b/mintlify-migration/docs/lend-api.mdx new file mode 100644 index 00000000..da471fc3 --- /dev/null +++ b/mintlify-migration/docs/lend-api.mdx @@ -0,0 +1,75 @@ +--- +title: "About Lend API" +description: "The Jupiter Lend API is built on top of Jupiter Lend Program." +--- + +## About Earn + + + + +The Earn Protocol is the 'Deposit and Earn' side of Jupiter Lend. Simply deposit assets to the Jupiter Earn and earn yield. + + + + + Jupiter Lend uses a unified liquidity layer where both Earn (lending) and Borrow (vault) protocol can source liquidity from. For depositors this means you earn the best possible rate at all times without having to migrate your funds when new protocols are launched on Jupiter Lend. You can supply once and earn the most up to date yield from the Jupiter Lend protocol. + + + + + There is no limits on supplying funds to the Earn Protocol. Withdrawals from Jupiter Lend utilize an Automated Debt Ceiling. Withdrawals increase every block creating a smoothing curve for withdrawals preventing any sudden large movements. + + + + + + Jupiter Lend is a novel protocol and like all DeFi protocols contains smart contract risk, market risk and other factors which can cause loss of user funds. + + + + + There are no fees to use the Earn Protocol on Jupiter Lend. + + + + +## About Borrow + + + + + + Borrow Vaults are a known standard mechanism for locking collateral and borrowing debt. Jupiter Lend utilizes this familiar single asset - single debt vault approach. Jupiter Lend takes borrow vaults to the next level by being the most capital efficient and optimized protocol enabling up to 95% LTV on collateral. + + + + + Jupiter borrow vaults has the most advanced liquidation mechanisms, and are able to provide the highest LTVs in the market, the protocol easily removes bad debt and enables the most gas efficient liquidation mechanism in DeFi. + + + + + When your NFT or position is liquidated, a portion of your collateral is sold to repay your debt and return your position to a safe state. In addition to selling a part of your collateral, a liquidation penalty is also charged. + + + + + While the Liquidation Threshold determines when a vault can be liquidated, the protocol also has a 'hard' ceiling for liquidation. When a vault passes the max liquidation threshold it is entirely (100%) liquidated automatically. + + + + + **Yes your position is still at risk of being liquidated!** Once your position passes the threshold it can be liquidated, but it may not happen immediately. If your position is still at risk you can take the time now to unwind/reduce your risk ratio to make your position safe and prevent a liquidation event. + + + +## Program ID + +* LIQUIDITY\_PROGRAM: `jupeiUmn818Jg1ekPURTpr4mFo29p46vygyykFJ3wZC` +* LENDING\_PROGRAM: `jup3YeL8QhtSx1e253b2FDvsMNC87fDrgQZivbrndc9` +* LRRM\_PROGRAM: `jup7TthsMgcR9Y3L277b8Eo9uboVSmu1utkuXHNUKar` +* ORACLE\_PROGRAM: `jupnw4B6Eqs7ft6rxpzYLJZYSnrpRgPcr589n5Kv4oc` +* VAULTS\_PROGRAM: `jupr81YtYssSyPt8jbnGuiWon5f6x9TcDEFxYe3Bdzi` +* [IDL](https://github.com/jup-ag/jupiter-lend/tree/main/target/idl) +* [Audits](/misc/audits) \ No newline at end of file diff --git a/mintlify-migration/docs/lend-api/borrow.mdx b/mintlify-migration/docs/lend-api/borrow.mdx new file mode 100644 index 00000000..0893769e --- /dev/null +++ b/mintlify-migration/docs/lend-api/borrow.mdx @@ -0,0 +1,9 @@ +--- +title: "Borrow (Soon)" +--- + + + **WARNING** + + The Jupiter Lend Borrow API is still a **work in progress**, stay tuned! + diff --git a/mintlify-migration/docs/lend-api/earn.mdx b/mintlify-migration/docs/lend-api/earn.mdx new file mode 100644 index 00000000..a3ca2968 --- /dev/null +++ b/mintlify-migration/docs/lend-api/earn.mdx @@ -0,0 +1,393 @@ +--- +title: "Earn (Beta)" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/lend/v1/earn` + * Pro URL: `https://api.jup.ag/lend/v1/earn` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + + + **API REFERENCE** + + To fully utilize the Lend API, check out the [Lend API Reference](/api/lend-api). + + +## Prerequisite + + + + + + ```bash + npm install @solana/web3.js@1 # Using v1 of web3.js instead of v2 +npm install dotenv # If required for wallet setup + ``` + + + + + **Set up RPC** + + + **NOTE** + + Solana provides a [default RPC endpoint](https://solana.com/docs/core/clusters). However, as your application grows, we recommend you to always use your own or provision a 3rd party provider’s RPC endpoint such as [Helius](https://helius.dev/) or [Triton](https://triton.one/). + + + ```js + import { Connection } from "@solana/web3.js"; + + const connection = new Connection('https://api.mainnet-beta.solana.com'); + ``` + + + + + **Set up Development Wallet** + + + **NOTE** + + * You can paste in your private key for testing purposes but this is not recommended for production applications. + * If you want to store your private key in the project directly, you can do it via a `.env` file. + + To set up a development wallet via `.env` file, you can use the following script. + + +```js +// index.js +import { Keypair } from '@solana/web3.js'; +import dotenv from 'dotenv'; +require('dotenv').config(); + +const wallet = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY || '')); + ``` + +```bash +# .env +PRIVATE_KEY="" +``` + + To set up a development wallet via a wallet generated via [Solana CLI](https://solana.com/docs/intro/installation#solana-cli-basics), you can use the following script. + +```js +import { Keypair } from '@solana/web3.js'; +import fs from 'fs'; + +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/To/.config/solana/id.json', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); +``` + + + + +```js +transaction.sign([wallet]); +const transactionBinary = transaction.serialize(); +console.log(transactionBinary); +console.log(transactionBinary.length); +const blockhashInfo = await connection.getLatestBlockhashAndContext({ commitment: "finalized" }); + +const signature = await connection.sendRawTransaction(transactionBinary, { + maxRetries: 0, + skipPreflight: true, +}); + +console.log(`Transaction sent: https://solscan.io/tx/${signature}`); + +try { + const confirmation = await connection.confirmTransaction({ + signature, + blockhash: blockhashInfo.value.blockhash, + lastValidBlockHeight: blockhashInfo.value.lastValidBlockHeight, + }, "confirmed"); + + if (confirmation.value.err) { + console.error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`); + console.log(`Examine the failed transaction: https://solscan.io/tx/${signature}`); + } else { + console.log(`Transaction successful: https://solscan.io/tx/${signature}`); + } +} catch (error) { + console.error(`Error confirming transaction: ${error}`); + console.log(`Examine the transaction status: https://solscan.io/tx/${signature}`); +}; +``` + + + +## Deposit and Withdraw + +Using the Deposit or Withdraw endpoint, the user can do so based on the `amount` of assets to be deposited/withdrawn. + + + **USAGE STEPS** + + + + User chooses the token. + + + User chooses the amount of assets to deposit or withdraw in the specific token mint. + + + Post request to get the transaction. + + + User sign and send the transaction to the network. + + + The mint authority mints/burns the vault tokens to/from the user. + + + + +```js +const depositTransactionResponse = await ( + await ( + await fetch('https://lite-api.jup.ag/lend/v1/earn/deposit', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + asset: mint, + amount: '100000', + signer: wallet.publicKey, + }) + }) + ) +); +``` + +```js +const withdrawTransactionResponse = await ( + await ( + await fetch('https://lite-api.jup.ag/lend/v1/earn/withdraw', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + asset: mint, + amount: '100000', + signer: wallet.publicKey, + }) + }) + ) +); +``` + +## Mint and Redeem + +Using the Mint or Redeem endpoint, the user can do so based on the number `shares` to be minted/redeemed. + + + **USAGE STEPS** + + + + User chooses the token. + + + User chooses the number of shares to deposit or withdraw in the specific token mint. + + + Post request to get the transaction. + + + User sign and send the transaction to the network. + + + The mint authority mints/burns the vault tokens to/from the user. + + + + +```js +const mintTransactionResponse = await ( + await ( + await fetch('https://lite-api.jup.ag/lend/v1/earn/mint', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + asset: mint, + signer: wallet.publicKey, + shares: '100000', + }) + }) + ) +); +``` + +```js +const redeemTransactionResponse = await ( + await ( + await fetch('https://lite-api.jup.ag/lend/v1/earn/redeem', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + asset: mint, + signer: wallet.publicKey, + shares: '100000', + }) + }) + ) +); +``` + +## Build Your Own Transaction + +The Lend API provides 2 ways to interface with the Earn functions in the Jupiter Lend Program. You can either make a post request to directly get the **Transaction**, or **Instruction** which can be used for CPI or composing with additional instructions. + +### Transaction + +To use the Transaction method, simply request to the endpoints without `-instructions` suffix directly, as shown in the examples above. The API will respond with an unsigned base64 transaction for the signer to sign, then sent to the network for execution. + +### Instruction + +In some use cases, you'd prefer to utilize the instructions instead of the serialized transaction, so you can utilize with CPI or compose with other instructions. You can make a post request to `-instructions`endpoints instead. + + + +Example code snippet of using `/deposit-instructions` endpoint and building a transaction with the instructions. + +```js +import { Connection, Keypair, PublicKey, TransactionMessage, TransactionInstruction, VersionedTransaction } from '@solana/web3.js'; +import fs from 'fs'; + +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/to/private/key', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); +const connection = new Connection('insert-your-own-rpc'); + +const depositIx = await ( + await fetch ( + 'https://lite-api.jup.ag/lend/v1/earn/deposit-instructions', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + asset: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + amount: '1000000', + signer: wallet.publicKey, + }, null, 2) + } + ) +).json(); + +console.log(JSON.stringify(depositIx, null, 2)); + +const deserializeInstruction = (instruction) => { + return new TransactionInstruction({ + programId: new PublicKey(instruction.programId), + keys: instruction.accounts.map((key) => ({ + pubkey: new PublicKey(key.pubkey), + isSigner: key.isSigner, + isWritable: key.isWritable, + })), + data: Buffer.from(instruction.data, 'base64'), + }); +}; + +const blockhash = (await connection.getLatestBlockhash()).blockhash; +const messageV0 = new TransactionMessage({ + payerKey: wallet.publicKey, + recentBlockhash: blockhash, + instructions: [ + ...depositIx.instructions.map(deserializeInstruction) + ], +}).compileToV0Message(); + +const transaction = new VersionedTransaction(messageV0); +transaction.sign([wallet]); +const transactionBinary = transaction.serialize(); +console.log(transactionBinary); +console.log(transactionBinary.length); +const blockhashInfo = await connection.getLatestBlockhashAndContext({ commitment: "finalized" }); + +const signature = await connection.sendRawTransaction(transactionBinary, { + maxRetries: 0, + skipPreflight: true, +}); + +console.log(`Transaction sent: https://solscan.io/tx/${signature}`); + +try { + const confirmation = await connection.confirmTransaction({ + signature, + blockhash: blockhashInfo.value.blockhash, + lastValidBlockHeight: blockhashInfo.value.lastValidBlockHeight, + }, "confirmed"); + + if (confirmation.value.err) { + console.error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`); + console.log(`Examine the failed transaction: https://solscan.io/tx/${signature}`); + } else { + console.log(`Transaction successful: https://solscan.io/tx/${signature}`); + } +} catch (error) { + console.error(`Error confirming transaction: ${error}`); + console.log(`Examine the transaction status: https://solscan.io/tx/${signature}`); +}; +``` + + +### CPI + +* Refer to [https://github.com/jup-ag/jupiter-lend/blob/main/docs/earn/cpi.md](https://github.com/jup-ag/jupiter-lend/blob/main/docs/earn/cpi.md) for CPI example +* Refer to [https://github.com/jup-ag/jupiter-lend/blob/main/target/idl/lending.json](https://github.com/jup-ag/jupiter-lend/blob/main/target/idl/lending.json) for IDL + +## Tokens + +Jupiter Lend provides Earnings for individual tokens, meaning SOL and USDC will be deposited in isolation. To get all token information such as the underlying token, supply, rates and liquidity information. + +```js +const vaults = await ( + await fetch ( + 'https://lite-api.jup.ag/lend/v1/earn/tokens' + ) +).json(); +``` + +## User Data + +Below are the endpoints to aid user to better manage their positions with data of each existing positions, earnings, etc. + +### Positions + +Given a user, you are able to get their existing position data such as shares, underlying assets, balance and allowance. + +```js +const userPositions = await ( + await fetch ( + 'https://lite-api.jup.ag/lend/v1/earn/positions?users={user1},{user2}' + ) +).json(); +``` + +### Earnings + +Given a user, you are able to get the rewards of a specific position, for example, the amount earned for USDC token position. + +```js +const userRwards = await ( + await fetch ( + 'https://lite-api.jup.ag/lend/v1/earn/earnings?user={user1}&positions={position1},{position2}' + ) +).json(); +``` diff --git a/mintlify-migration/docs/openapi-spec/lend/lend.yaml b/mintlify-migration/docs/openapi-spec/lend/lend.yaml new file mode 100644 index 00000000..6370b4eb --- /dev/null +++ b/mintlify-migration/docs/openapi-spec/lend/lend.yaml @@ -0,0 +1,479 @@ +openapi: 3.0.3 +info: + title: Quickstart + version: 1.0.0 + +servers: + - url: https://lite-api.jup.ag/lend/v1 + description: Free tier API endpoint with rate limits + - url: https://api.jup.ag/lend/v1 + description: Paid tier API endpoint with higher rate limits to be used with an API Key + +paths: + /earn/deposit: + post: + summary: deposit + description: | + Request for a base64-encoded unsigned earn deposit transaction to deposit assets + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EarnAmountRequestBody' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/TransactionResponse' + + /earn/deposit-instructions: + post: + summary: deposit-instructions + description: | + Request for the instruction of an earn deposit transaction to deposit assets + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EarnAmountRequestBody' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/InstructionResponse' + + /earn/withdraw: + post: + summary: withdraw + description: | + Request for a base64-encoded unsigned earn withdraw transaction to withdraw assets + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EarnAmountRequestBody' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/TransactionResponse' + + /earn/withdraw-instructions: + post: + summary: withdraw-instructions + description: | + Request for the instruction of an earn withdraw transaction to withdraw assets + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EarnAmountRequestBody' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/InstructionResponse' + + /earn/mint: + post: + summary: mint + description: | + Request for a base64-encoded unsigned earn mint transaction to mint shares + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EarnSharesRequestBody' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/TransactionResponse' + + /earn/mint-instructions: + post: + summary: mint-instructions + description: | + Request for the instruction of an earn mint transaction to mint shares + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EarnSharesRequestBody' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/InstructionResponse' + + /earn/redeem: + post: + summary: redeem + description: | + Request for a base64-encoded unsigned earn redeem transaction to redeem shares + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EarnSharesRequestBody' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/TransactionResponse' + + /earn/redeem-instructions: + post: + summary: redeem-instructions + description: | + Request for the instruction of an earn redeem transaction to redeem shares + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EarnSharesRequestBody' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/InstructionResponse' + + /earn/tokens: + get: + summary: tokens + description: | + Request for the tokens available to be deposited and their information + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/TokensResponse' + + /earn/positions: + get: + summary: positions + description: | + Request for the position data of one or multiple users + parameters: + - name: users + in: query + description: | + User wallet addresses (comma separated) + required: true + schema: + type: string + example: "HYbxGkNvEwvZ14RzJHPB9h3dWfXjxwAEhkyzJRHx1hBf,jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3" + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/UserPositionsResponse' + + /earn/earnings: + get: + summary: earnings + description: | + Request for the earnings of one or multiple positions of a user + parameters: + - name: user + in: query + description: | + User wallet address + required: true + schema: + type: string + example: "HYbxGkNvEwvZ14RzJHPB9h3dWfXjxwAEhkyzJRHx1hBf" + - name: positions + in: query + description: | + User token positions (comma-separated) + required: true + schema: + type: string + example: "9BEcn9aPEmhSPbPQeFGjidRiEKki46fVQDyPpSQXPA2D,2uQsyo1fXXQkDtcpXnLofWy88PxcvnfH2L8FPSE62FVU" + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/UserEarningsResponse' + + +components: + schemas: + EarnAmountRequestBody: + type: object + required: + - asset + - signer + - amount + properties: + asset: + type: string + signer: + type: string + amount: + type: string + example: + asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" + signer: "HYbxGkNvEwvZ14RzJHPB9h3dWfXjxwAEhkyzJRHx1hBf" + amount: "1000000" + + EarnSharesRequestBody: + type: object + required: + - asset + - signer + - shares + properties: + asset: + type: string + signer: + type: string + shares: + type: string + example: + asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" + signer: "HYbxGkNvEwvZ14RzJHPB9h3dWfXjxwAEhkyzJRHx1hBf" + shares: "1000000" + + TransactionResponse: + type: object + required: + - transaction + properties: + transaction: + type: string + + InstructionResponse: + type: object + required: + - programId + - accounts + - data + properties: + programId: + type: string + accounts: + type: array + items: + $ref: '#/components/schemas/AccountMeta' + data: + type: string + + AccountMeta: + type: object + required: + - pubkey + - isSigner + - isWritable + properties: + pubkey: + type: string + isSigner: + type: boolean + isWritable: + type: boolean + + TokensResponse: + type: array + items: + $ref: '#/components/schemas/TokenInfo' + + UserPositionsResponse: + type: array + items: + $ref: '#/components/schemas/UserPosition' + + UserEarningsResponse: + type: object + required: + - address + - ownerAddress + - totalDeposits + - totalWithdraws + - totalBalance + - totalAssets + - earnings + properties: + address: + type: string + ownerAddress: + type: string + totalDeposits: + type: string + totalWithdraws: + type: string + totalBalance: + type: string + totalAssets: + type: string + earnings: + type: string + + UserPosition: + type: object + required: + - token + - ownerAddress + - shares + - underlyingAssets + - underlyingBalance + - allowance + properties: + token: + $ref: '#/components/schemas/TokenInfo' + ownerAddress: + type: string + shares: + type: string + underlyingAssets: + type: string + underlyingBalance: + type: string + allowance: + type: string + + TokenInfo: + type: object + required: + - id + - address + - name + - symbol + - decimals + - assetAddress + - asset + - totalAssets + - totalSupply + - convertToShares + - convertToAssets + - rewardsRate + - supplyRate + - totalRate + - rebalanceDifference + - liquiditySupplyData + properties: + id: + type: integer + address: + type: string + name: + type: string + symbol: + type: string + decimals: + type: integer + assetAddress: + type: string + asset: + $ref: '#/components/schemas/AssetInfo' + totalAssets: + type: string + totalSupply: + type: string + convertToShares: + type: string + convertToAssets: + type: string + rewardsRate: + type: string + supplyRate: + type: string + totalRate: + type: string + rebalanceDifference: + type: string + liquiditySupplyData: + $ref: '#/components/schemas/LiquiditySupplyData' + + AssetInfo: + type: object + required: + - address + - chain_id + - name + - symbol + - decimals + - logo_url + - price + - coingecko_id + properties: + address: + type: string + chain_id: + type: string + name: + type: string + symbol: + type: string + decimals: + type: integer + logo_url: + type: string + format: uri + price: + type: string + coingecko_id: + type: string + + LiquiditySupplyData: + type: object + required: + - modeWithInterest + - supply + - withdrawalLimit + - lastUpdateTimestamp + - expandPercent + - expandDuration + - baseWithdrawalLimit + - withdrawableUntilLimit + - withdrawable + properties: + modeWithInterest: + type: boolean + supply: + type: string + withdrawalLimit: + type: string + lastUpdateTimestamp: + type: string + expandPercent: + type: string + expandDuration: + type: string + baseWithdrawalLimit: + type: string + withdrawableUntilLimit: + type: string + withdrawable: + type: string diff --git a/mintlify-migration/docs/openapi-spec/price/v2/price.yaml b/mintlify-migration/docs/openapi-spec/price/v2/price.yaml new file mode 100644 index 00000000..e438cb06 --- /dev/null +++ b/mintlify-migration/docs/openapi-spec/price/v2/price.yaml @@ -0,0 +1,159 @@ +openapi: 3.0.3 +info: + title: Quickstart + version: 2.0.0 + description: | + | Link | + | --- | + | [V3](/docs/price-api/v3) | + | [V2 (Deprecated)](/docs/price-api/v2) | + +servers: + - url: https://lite-api.jup.ag/price/v2 + description: Free tier API endpoint with rate limits + - url: https://api.jup.ag/price/v2 + description: Paid tier API endpoint with higher rate limits to be used with an API Key + +paths: + "/": + get: + summary: price + deprecated: true + description: | + Returns prices of specified tokens. + + **DEPRECATED** + + This endpoint has been deprecated and may be replaced or removed in future versions of the API. + + + + **NOTE** + + - Refer to [Price API doc](/docs/price-api) for more information. + + parameters: + - name: ids + in: query + description: "Comma separate to pass in multiple" + required: true + schema: + type: string + example: 'So11111111111111111111111111111111111111112,EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' + - name: vsToken + in: query + description: "By default, prices are denominated by USD. To denominate price in SOL, use `vsToken` with SOL mint address" + required: false + schema: + type: string + - name: showExtraInfo + in: query + description: "To use, pass in `showExtraInfo=true`, cannot use `vsToken` with this parameter" + required: false + schema: + type: string + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/PriceResponse' + '400': + description: Bad request + '500': + description: Internal server error + +components: + schemas: + PriceResponse: + type: object + properties: + data: + type: object + additionalProperties: + $ref: '#/components/schemas/TokenPriceInfo' + timeTaken: + type: number + format: float + + TokenPriceInfo: + type: object + properties: + id: + type: string + type: + type: string + example: "derivedPrice" + price: + type: string + extraInfo: + $ref: '#/components/schemas/ExtraInfo' + + ExtraInfo: + type: object + properties: + lastSwappedPrice: + $ref: '#/components/schemas/LastSwappedPrice' + quotedPrice: + $ref: '#/components/schemas/QuotedPrice' + confidenceLevel: + type: string + enum: [high, medium, low] + depth: + $ref: '#/components/schemas/Depth' + + LastSwappedPrice: + type: object + properties: + lastJupiterSellAt: + type: integer + format: int64 + lastJupiterSellPrice: + type: string + lastJupiterBuyAt: + type: integer + format: int64 + lastJupiterBuyPrice: + type: string + + QuotedPrice: + type: object + properties: + buyPrice: + type: string + buyAt: + type: integer + format: int64 + sellPrice: + type: string + sellAt: + type: integer + format: int64 + + Depth: + type: object + properties: + buyPriceImpactRatio: + $ref: '#/components/schemas/PriceImpactRatio' + sellPriceImpactRatio: + $ref: '#/components/schemas/PriceImpactRatio' + + PriceImpactRatio: + type: object + properties: + depth: + type: object + properties: + "10": + type: number + format: float + "100": + type: number + format: float + "1000": + type: number + format: float + timestamp: + type: integer + format: int64 diff --git a/mintlify-migration/docs/openapi-spec/price/v3/price.yaml b/mintlify-migration/docs/openapi-spec/price/v3/price.yaml new file mode 100644 index 00000000..c4958478 --- /dev/null +++ b/mintlify-migration/docs/openapi-spec/price/v3/price.yaml @@ -0,0 +1,58 @@ +openapi: 3.0.3 +info: + title: Quickstart + version: 3.0.0 + description: | + | Link | + | --- | + | [V3](/docs/price-api/v3) | + | [V2 (Deprecated)](/docs/price-api/v2) | + +servers: + - url: https://lite-api.jup.ag + description: Free tier API endpoint with rate limits + - url: https://api.jup.ag + description: Paid tier API endpoint with higher rate limits to be used with an API Key + +paths: + "/price/v3": + get: + summary: price + description: | + Returns prices of specified tokens. + parameters: + - name: ids + in: query + description: "Comma separate to pass in multiple" + required: true + schema: + type: string + example: 'So11111111111111111111111111111111111111112,EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + additionalProperties: + description: Token addresses as keys + type: object + properties: + blockId: + type: integer + nullable: true + decimals: + type: integer + usdPrice: + type: number + priceChange24h: + type: number + nullable: true + required: + - decimals + - usdPrice + '400': + description: Bad request + '500': + description: Internal server error diff --git a/mintlify-migration/docs/openapi-spec/recurring/execute.yaml b/mintlify-migration/docs/openapi-spec/recurring/execute.yaml new file mode 100644 index 00000000..71077de2 --- /dev/null +++ b/mintlify-migration/docs/openapi-spec/recurring/execute.yaml @@ -0,0 +1,76 @@ +openapi: 3.0.0 +info: + title: Recurring Order API + version: 1.0.0 + description: | + | Link | + | --- | + | [Create Order](/docs/recurring-api/create-order) | + | [Execute Order](/docs/recurring-api/execute-order) | + | [Cancel Order](/docs/recurring-api/cancel-order) | + | [Price Deposit](/docs/recurring-api/deposit-price-order) | + | [Price Withdraw](/docs/recurring-api/withdraw-price-order) | + | [Get Recurring Orders](/docs/recurring-api/get-recurring-orders) | + +servers: + - url: https://lite-api.jup.ag/recurring/v1 + description: Free tier API endpoint with rate limits + - url: https://api.jup.ag/recurring/v1 + description: Paid tier API endpoint with higher rate limits to be used with an API Key + +paths: + /execute: + post: + summary: execute + operationId: execute + description: | + Execute the signed transaction and get the execution status + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ExecuteRecurring' + required: true + responses: + '200': + description: Transaction executed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ExecuteRecurringResponse' + '400': + description: Bad request + '500': + description: Internal server error +components: + schemas: + ExecuteRecurring: + type: object + required: + - requestId + - signedTransaction + properties: + requestId: + type: string + signedTransaction: + type: string + ExecuteRecurringResponse: + type: object + required: + - signature + - status + properties: + error: + type: string + nullable: true + order: + type: string + nullable: true + description: "Base-58 account which is the Recurring Order account" + signature: + type: string + status: + type: string + enum: + - Success + - Failed diff --git a/mintlify-migration/docs/openapi-spec/recurring/recurring.yaml b/mintlify-migration/docs/openapi-spec/recurring/recurring.yaml new file mode 100644 index 00000000..98871f52 --- /dev/null +++ b/mintlify-migration/docs/openapi-spec/recurring/recurring.yaml @@ -0,0 +1,800 @@ +openapi: 3.0.0 +info: + title: Recurring Order API + version: 1.0.0 + description: | + | Link | + | --- | + | [Create Order](/docs/recurring-api/create-order) | + | [Execute Order](/docs/recurring-api/execute-order) | + | [Cancel Order](/docs/recurring-api/cancel-order) | + | [Price Deposit](/docs/recurring-api/deposit-price-order) | + | [Price Withdraw](/docs/recurring-api/withdraw-price-order) | + | [Get Recurring Orders](/docs/recurring-api/get-recurring-orders) | + +servers: + - url: https://lite-api.jup.ag/recurring/v1 + description: Free tier API endpoint with rate limits + - url: https://api.jup.ag/recurring/v1 + description: Paid tier API endpoint with higher rate limits to be used with an API Key + +paths: + /cancelOrder: + post: + summary: cancelOrder + operationId: cancel-order + description: | + Request for a base64-encoded unsigned recurring order cancellation transaction to be used in `POST /recurring/v1/execute` + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CloseRecurring' + required: true + responses: + '200': + description: Recurring order closed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/RecurringResponse' + '400': + description: Bad request + '500': + description: Internal server error + /createOrder: + post: + summary: createOrder + operationId: create-order + description: | + Request for a base64-encoded unsigned recurring order creation transaction to be used in `POST /recurring/v1/execute` + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateRecurring' + required: true + responses: + '200': + description: Recurring order created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/RecurringResponse' + '400': + description: Bad request + '500': + description: Internal server error + /execute: + post: + summary: execute + operationId: execute + description: | + Execute the signed transaction and get the execution status + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ExecuteRecurring' + required: true + responses: + '200': + description: Transaction executed successfully + content: + application/json: + schema: + $ref: '#/components/schemas/ExecuteRecurringResponse' + '400': + description: Bad request + '500': + description: Internal server error + /getRecurringOrders: + get: + summary: getRecurringOrders + parameters: + - name: recurringType + in: query + required: true + schema: + $ref: '#/components/schemas/RecurringOrderType' + - name: orderStatus + in: query + required: true + schema: + $ref: '#/components/schemas/OrderState' + - name: user + in: query + required: true + schema: + type: string + - name: page + in: query + required: true + schema: + type: integer + format: int64 + minimum: 1 + nullable: true + - name: mint + in: query + required: true + schema: + type: string + nullable: true + - name: includeFailedTx + in: query + required: true + schema: + type: boolean + responses: + '200': + description: Successfully retrieved recurring orders + content: + application/json: + schema: + $ref: '#/components/schemas/GetRecurringOrderResponse' + '400': + description: Bad request + '500': + description: Internal server error + /priceDeposit: + post: + summary: priceDeposit + operationId: price-deposit + deprecated: true + description: | + **DEPRECATED**: This endpoint is deprecated. Please use time-based recurring orders instead. + + Request for a base64-encoded unsigned price-based recurring order deposit transaction to be used in `POST /recurring/v1/execute` + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DepositPriceRecurring' + required: true + responses: + '200': + description: Deposit transaction created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/RecurringResponse' + '400': + description: Bad request + '500': + description: Internal server error + /priceWithdraw: + post: + summary: priceWithdraw + operationId: price-withdraw + deprecated: true + description: | + **DEPRECATED**: This endpoint is deprecated. Please use time-based recurring orders instead. + + Request for a base64-encoded unsigned price-based recurring order withdrawal transaction to be used in `POST /recurring/v1/execute` + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/WithdrawPriceRecurring' + required: true + responses: + '200': + description: Withdraw transaction created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/RecurringResponse' + '400': + description: Bad request + '500': + description: Internal server error +components: + schemas: + AllRecurringResponse: + oneOf: + - allOf: + - $ref: '#/components/schemas/TimeRecurringResponse' + - type: object + required: + - recurringType + properties: + recurringType: + type: string + enum: + - time + - allOf: + - $ref: '#/components/schemas/PriceRecurringResponse' + - type: object + required: + - recurringType + properties: + recurringType: + type: string + enum: + - price + deprecated: true + description: "DEPRECATED: Price-based recurring orders are deprecated" + CloseRecurring: + type: object + required: + - user + - order + - recurringType + properties: + order: + type: string + description: "Base-58 account which is the Recurring Order account" + recurringType: + $ref: '#/components/schemas/CloseRecurringType' + user: + type: string + CloseRecurringType: + type: string + enum: + - time + - price + description: | + - Type of recurring order to close. + - **DEPRECATED**: The 'price' value is deprecated. + CreateRecurring: + type: object + required: + - user + - inputMint + - outputMint + - params + properties: + inputMint: + type: string + outputMint: + type: string + params: + $ref: '#/components/schemas/RecurringType' + user: + type: string + example: + user: "jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3" + inputMint: "So11111111111111111111111111111111111111112" + outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" + params: + time: + inAmount: 1000000000 + numberOfOrders: 10 + interval: 86400 + DepositPriceRecurring: + type: object + deprecated: true + description: "DEPRECATED: Price-based recurring orders are deprecated" + required: + - user + - order + - amount + properties: + amount: + type: integer + format: int64 + minimum: 0 + order: + type: string + description: "Base-58 account which is the Recurring Order account" + user: + type: string + ExecuteRecurring: + type: object + required: + - requestId + - signedTransaction + properties: + requestId: + type: string + signedTransaction: + type: string + ExecuteRecurringResponse: + type: object + required: + - signature + - status + properties: + error: + type: string + nullable: true + order: + type: string + nullable: true + description: "Base-58 account which is the Recurring Order account" + signature: + type: string + status: + type: string + enum: + - Success + - Failed + GetRecurringOrderParams: + type: object + required: + - recurringType + - orderStatus + - user + - includeFailedTx + properties: + includeFailedTx: + type: boolean + mint: + type: string + nullable: true + orderStatus: + $ref: '#/components/schemas/OrderState' + page: + type: integer + nullable: true + format: int64 + minimum: 1 + recurringType: + $ref: '#/components/schemas/RecurringOrderType' + user: + type: string + GetRecurringOrderResponse: + oneOf: + - type: object + required: + - user + - orderStatus + - time + - totalPages + - page + properties: + orderStatus: + $ref: '#/components/schemas/OrderState' + page: + type: integer + format: int64 + minimum: 1 + time: + type: array + items: + $ref: '#/components/schemas/TimeRecurringResponse' + totalPages: + type: integer + format: int64 + minimum: 1 + user: + type: string + - type: object + deprecated: true + description: "DEPRECATED: Price-based recurring orders are deprecated" + required: + - user + - orderStatus + - price + - totalPages + - page + properties: + orderStatus: + $ref: '#/components/schemas/OrderState' + page: + type: integer + format: int64 + minimum: 1 + price: + type: array + items: + $ref: '#/components/schemas/PriceRecurringResponse' + totalPages: + type: integer + format: int64 + minimum: 1 + user: + type: string + - type: object + required: + - user + - orderStatus + - all + - totalPages + - page + properties: + all: + type: array + items: + $ref: '#/components/schemas/AllRecurringResponse' + orderStatus: + $ref: '#/components/schemas/OrderState' + page: + type: integer + format: int64 + minimum: 1 + totalPages: + type: integer + format: int64 + minimum: 1 + user: + type: string + OpenIxArgsWithoutIdx: + type: object + deprecated: true + description: "DEPRECATED: Price-based recurring orders are deprecated" + required: + - interval + - depositAmount + - incrementUsdcValue + properties: + depositAmount: + type: integer + format: int64 + minimum: 0 + incrementUsdcValue: + type: integer + format: int64 + minimum: 0 + interval: + type: integer + format: int64 + description: In unix seconds + startAt: + type: integer + nullable: true + format: int64 + description: In unix timestamp + OrderHistoryResponse: + type: object + required: + - orderKey + - keeper + - inputMint + - outputMint + - inputAmount + - outputAmount + - rawInputAmount + - rawOutputAmount + - feeMint + - feeAmount + - rawFeeAmount + - txId + - confirmedAt + - action + properties: + action: + type: string + confirmedAt: + type: string + format: date-time + feeAmount: + type: string + feeMint: + type: string + inputAmount: + type: string + inputMint: + type: string + keeper: + type: string + orderKey: + type: string + outputAmount: + type: string + outputMint: + type: string + productMeta: + description: | + Extra metadata for sub-products which will never be queried + + with filters. + + + See structs `DbOrderHistoryValueAverageMeta` and + `DbOrderHistoryPerpetualMeta` + + to craft the JSONB object. + rawFeeAmount: + type: string + rawInputAmount: + type: string + rawOutputAmount: + type: string + txId: + type: string + OrderState: + type: string + enum: + - active + - history + PriceRecurringResponse: + type: object + deprecated: true + description: "DEPRECATED: Price-based recurring orders are deprecated" + required: + - userPubkey + - orderKey + - inputMint + - outputMint + - inDeposited + - inWithdrawn + - inLeft + - inUsed + - outReceived + - outWithdrawn + - orderInterval + - incrementalUsdValue + - supposedUsdValue + - estimatedUsdcValueSpent + - rawInDeposited + - rawInWithdrawn + - rawInLeft + - rawInUsed + - rawOutReceived + - rawOutWithdrawn + - rawIncrementalUsdValue + - rawSupposedUsdValue + - rawEstimatedUsdcValueSpent + - status + - closedBy + - openTx + - closeTx + - createdAt + - startAt + - updatedAt + - trades + properties: + closeTx: + type: string + closedBy: + type: string + createdAt: + type: string + format: date-time + estimatedUsdcValueSpent: + type: string + inDeposited: + type: string + inLeft: + type: string + inUsed: + type: string + description: Amount used to fulfill orders + inWithdrawn: + type: string + incrementalUsdValue: + type: string + inputMint: + type: string + openTx: + type: string + orderInterval: + type: string + orderKey: + type: string + outReceived: + type: string + description: Amount received in escrow without auto-withdraw enabled + outWithdrawn: + type: string + description: | + Amount withdrawn from escrow account with/without auto-withdraw + enabled + outputMint: + type: string + rawEstimatedUsdcValueSpent: + type: string + rawInDeposited: + type: string + rawInLeft: + type: string + rawInUsed: + type: string + description: Amount used to fulfill orders + rawInWithdrawn: + type: string + rawIncrementalUsdValue: + type: string + rawOutReceived: + type: string + description: Amount received in escrow without auto-withdraw enabled + rawOutWithdrawn: + type: string + description: | + Amount withdrawn from escrow account with/without auto-withdraw + enabled + rawSupposedUsdValue: + type: string + startAt: + type: string + format: date-time + status: + type: string + supposedUsdValue: + type: string + trades: + type: array + items: + $ref: '#/components/schemas/OrderHistoryResponse' + updatedAt: + type: string + format: date-time + userPubkey: + type: string + RecurringOrderType: + type: string + enum: + - time + - price + - all + description: | + Type of recurring order. + **DEPRECATED**: The 'price' value is deprecated. + RecurringResponse: + type: object + required: + - requestId + - transaction + properties: + requestId: + type: string + description: "Required to make a request to `/execute`" + transaction: + type: string + description: "Unsigned base-64 encoded transaction" + RecurringType: + oneOf: + - type: object + required: + - time + properties: + time: + $ref: '#/components/schemas/TimeRecurringCreationParams' + - type: object + deprecated: true + description: "DEPRECATED: Price-based recurring orders are deprecated" + required: + - price + properties: + price: + $ref: '#/components/schemas/OpenIxArgsWithoutIdx' + TimeRecurringCreationParams: + type: object + required: + - inAmount + - numberOfOrders + - interval + properties: + inAmount: + type: integer + format: int64 + minimum: 0 + interval: + type: integer + format: int64 + description: In unix seconds + maxPrice: + type: number + nullable: true + format: double + minPrice: + type: number + nullable: true + format: double + numberOfOrders: + type: integer + format: int64 + minimum: 0 + startAt: + type: integer + nullable: true + format: int64 + description: In unix timestamp + TimeRecurringResponse: + type: object + required: + - userPubkey + - orderKey + - inputMint + - outputMint + - inDeposited + - inWithdrawn + - rawInDeposited + - rawInWithdrawn + - cycleFrequency + - outWithdrawn + - inAmountPerCycle + - minOutAmount + - maxOutAmount + - inUsed + - outReceived + - rawOutWithdrawn + - rawInAmountPerCycle + - rawMinOutAmount + - rawMaxOutAmount + - rawInUsed + - rawOutReceived + - openTx + - closeTx + - userClosed + - createdAt + - updatedAt + - trades + properties: + closeTx: + type: string + createdAt: + type: string + format: date-time + cycleFrequency: + type: string + inAmountPerCycle: + type: string + inDeposited: + type: string + inUsed: + type: string + inWithdrawn: + type: string + inputMint: + type: string + maxOutAmount: + type: string + minOutAmount: + type: string + openTx: + type: string + orderKey: + type: string + outReceived: + type: string + outWithdrawn: + type: string + outputMint: + type: string + rawInAmountPerCycle: + type: string + rawInDeposited: + type: string + rawInUsed: + type: string + rawInWithdrawn: + type: string + rawMaxOutAmount: + type: string + rawMinOutAmount: + type: string + rawOutReceived: + type: string + rawOutWithdrawn: + type: string + trades: + type: array + items: + $ref: '#/components/schemas/OrderHistoryResponse' + updatedAt: + type: string + format: date-time + userClosed: + type: boolean + userPubkey: + type: string + WithdrawPriceRecurring: + type: object + deprecated: true + description: "DEPRECATED: Price-based recurring orders are deprecated" + required: + - user + - order + - inputOrOutput + properties: + amount: + type: string + nullable: true + description: "If no `amount` is provided, it will withdraw the entire amount" + format: int64 + minimum: 0 + inputOrOutput: + $ref: '#/components/schemas/Withdrawal' + order: + type: string + description: "Base-58 account which is the Recurring Order account" + user: + type: string + Withdrawal: + type: string + enum: + - In + - Out diff --git a/mintlify-migration/docs/openapi-spec/send/send.yaml b/mintlify-migration/docs/openapi-spec/send/send.yaml new file mode 100644 index 00000000..cf73bdc8 --- /dev/null +++ b/mintlify-migration/docs/openapi-spec/send/send.yaml @@ -0,0 +1,328 @@ +openapi: 3.0.3 + +info: + title: Quickstart + version: 1.0.0 + description: | + | Link | + | --- | + +servers: + - url: https://lite-api.jup.ag/send/v1 + description: Free tier API endpoint with rate limits + - url: https://api.jup.ag/send/v1 + description: Paid tier API endpoint with higher rate limits to be used with an API Key + +paths: + /craft-send: + post: + summary: craft-send + description: | + Request for a base64-encoded unsigned Send transaction + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - inviteSigner + - sender + - amount + properties: + inviteSigner: + type: string + description: | + - Public key address generated from the hash of the invite code + - Do note that, the invite code requires to be generated client side, [refer to docs](/docs/send-api) + - Please handle invite code and secret key with highest security as user funds are involved + sender: + type: string + description: | + - Public key address of the sender + - This address will be funding the amount to be sent and the token accounts involved + amount: + type: string + description: | + - Amount in atomic value (before decimals) + - E.g. to send 1 USDC is equivalent of `amount='1000000'` + - Do note that there will be additional SOL amount being used in the transaction for transaction fees and token accounts + mint: + type: string + description: | + - Defaults to WSOL mint + - Only pass in this parameter with other mint when required + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + required: + - tx + - expiry + - totalFeeLamports + properties: + tx: + type: string + description: | + - Base64-encoded unsigned Send transaction + expiry: + type: string + description: | + - Unix timestamp of when the invite will expire + - Expired invites will automatically clawback to sender + totalFeeLamports: + type: string + description: | + - Amount of fees required for network's transaction fee and token accounts + '400': + description: Bad request body + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + '500': + description: Internal error + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + + /craft-clawback: + post: + summary: craft-clawback + description: | + Request for a base64-encoded unsigned Send transaction + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - invitePDA + - sender + properties: + invitePDA: + type: string + description: | + - Program Derived Address derived by `"invite"` and the public key of the invite + - Do note that, the invitePDA requires to be generated client side, [refer to docs](/docs/send-api) + - Please handle invite code and secret key with highest security as user funds are involved + sender: + type: string + description: | + - Public key address of the sender + - Since this address funded the invite, it will be the receiving address of the full amount + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + required: + - tx + properties: + tx: + type: string + description: | + - Base64-encoded unsigned Send transaction + '400': + description: Bad request body + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + '500': + description: Internal error + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + + /pending-invites: + get: + summary: pending-invites + description: | + Request for the pending invites of an address + parameters: + - name: address + in: query + description: | + - Pubkey of Sender + required: true + schema: + type: string + - name: page + in: query + description: | + - Pagination of response + schema: + type: integer + minimum: 1 + default: 1 + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/InviteDataResponse' + '400': + description: Bad request body + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + '500': + description: Internal error + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + + /invite-history: + get: + summary: invite-history + description: | + Request for the invite history of an address + parameters: + - name: address + in: query + description: | + - Pubkey can be sender or recipient + required: true + schema: + type: string + - name: page + in: query + description: | + - Pagination of response + schema: + type: integer + minimum: 1 + default: 1 + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/InviteDataResponse' + '400': + description: Bad request body + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + '500': + description: Internal error + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + +components: + schemas: + InviteDataResponse: + type: object + required: + - invites + - hasMoreData + properties: + invites: + type: array + items: + type: object + required: + - invite_signer + - invite_pda + - sender + - expiry + - amount + - creation_tx + - deletion_tx + - receiver + - action + - creation_time + - deletion_time + - mint + - confirmed + properties: + invite_signer: + type: string + invite_pda: + type: string + sender: + type: string + expiry: + type: string + amount: + type: string + creation_tx: + type: string + deletion_tx: + type: string + nullable: true + receiver: + type: string + nullable: true + action: + type: string + nullable: true + creation_time: + type: string + deletion_time: + type: string + nullable: true + mint: + type: string + nullable: true + confirmed: + type: integer + nullable: true + hasMoreData: + type: boolean diff --git a/mintlify-migration/docs/openapi-spec/studio/studio.yaml b/mintlify-migration/docs/openapi-spec/studio/studio.yaml new file mode 100644 index 00000000..5c13d6a6 --- /dev/null +++ b/mintlify-migration/docs/openapi-spec/studio/studio.yaml @@ -0,0 +1,512 @@ +openapi: 3.0.3 +info: + title: Quickstart + version: 2.0.0 + description: | + | Link | + | --- | + +servers: + - url: https://lite-api.jup.ag/studio/v1 + description: Free tier API endpoint with rate limits + - url: https://api.jup.ag/studio/v1 + description: Paid tier API endpoint with higher rate limits to be used with an API Key + +paths: + /dbc-pool/create-tx: + post: + summary: dbc-pool-create-tx + description: | + Request for a base64-encoded unsigned transaction to create a Dynamic Bonding Curve pool with token metadata + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateDBCTransactionRequestBody' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/CreateDBCTransactionResponse' + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + errors: + type: object + error: + type: string + '500': + description: Internal server error + content: + application/json: + schema: + type: object + properties: + error: + type: string + details: + type: string + + /dbc-pool/submit: + post: + summary: dbc-pool-submit + description: | + Execute the signed transaction, and optionally upload content and header image + requestBody: + content: + multipart/form-data: + schema: + $ref: '#/components/schemas/SubmitDBCTransactionRequestBody' + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + data: + type: object + properties: + mint: + type: string + configKey: + type: string + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + errors: + type: object + error: + type: string + '500': + description: Internal server error + + /dbc-pool/addresses/{mint}: + get: + summary: dbc-pool-addresses-by-mint + description: | + Request for pool addresses for a given token mint + parameters: + - name: mint + in: path + required: true + schema: + type: string + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + data: + type: object + properties: + dammv2PoolAddress: + type: string + nullable: true + dbcPoolAddress: + type: string + nullable: true + configKey: + type: string + nullable: true + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + errors: + type: object + description: Validation errors + '404': + description: Pool addresses not found + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Pool addresses not found + '500': + description: Internal server error + content: + application/json: + schema: + type: object + properties: + error: + type: string + + /dbc/fee: + post: + summary: dbc-fee + description: | + Request for unclaimed creator trading fees of a Dynamic Bonding Curve pool + requestBody: + content: + application/json: + schema: + type: object + required: + - poolAddress + properties: + poolAddress: + type: string + description: | + - Dynamic Bonding Curve pool address + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + required: + - unclaimed + - total + properties: + unclaimed: + type: string + description: | + - Unclaimed creator quote fee amount + total: + type: string + description: | + - Total trading quote fee amount divided by 2 (creator share) + + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + errors: + type: object + additionalProperties: + type: array + items: + type: string + '500': + description: Internal server error + + /dbc/fee/create-tx: + post: + summary: dbc-fee-create-tx + description: | + Request for a base64-encoded unsigned transaction to claim creator trading fees of a Dynamic Bonding Curve pool + - Handles both direct creator ownership and proxy-based ownership. + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateClaimFeeDBCTransactionRequestBody' + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + required: + - transaction + properties: + transaction: + type: string + description: Base64-encoded transaction ready for signing + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + errors: + type: object + additionalProperties: + type: array + items: + type: string + '403': + description: Not authorized to claim fees from this pool + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: You are not the owner of this pool + '404': + description: Proxy account not found for the creator + content: + application/json: + schema: + type: object + properties: + error: + type: string + example: Proxy account not found for the creator + '500': + description: Internal server error + + +components: + schemas: + CreateDBCTransactionRequestBody: + type: object + required: + - buildCurveByMarketCapParam + - antiSniping + - fee + - tokenName + - tokenSymbol + - tokenImageContentType + - creator + properties: + buildCurveByMarketCapParam: + type: object + required: + - quoteMint + - initialMarketCap + - migrationMarketCap + - tokenQuoteDecimal + - lockedVestingParam + properties: + quoteMint: + type: string + description: | + - Quote mint address + - Either USDC, SOL, or JUP + example: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v + initialMarketCap: + type: number + description: | + - Initial market cap in quote token units + - 16000 passed in = 16000 USDC/SOL/JUP initial market cap + example: 16000 + migrationMarketCap: + type: number + description: | + - Migration market cap in quote token units + - 69000 passed in = 69000 USDC/SOL/JUP migration market cap + example: 69000 + tokenQuoteDecimal: + type: number + enum: + - 6 + - 9 + description: | + - Token quote decimal places + lockedVestingParam: + type: object + required: + - totalLockedVestingAmount + - cliffUnlockAmount + - numberOfVestingPeriod + - totalVestingDuration + - cliffDurationFromMigrationTime + properties: + totalLockedVestingAmount: + type: number + description: | + - Total locked vesting amount of tokens (0% to 80% of total supply) + cliffUnlockAmount: + type: number + description: | + - Amount of tokens unlocked at cliff + numberOfVestingPeriod: + type: number + enum: + - 0 + - 6 + - 12 + - 183 + - 365 + description: | + - Number of vesting periods in days (183/365) or months (6/12) + totalVestingDuration: + type: number + enum: + - 0 + - 15552000 + - 15811200 + - 31536000 + description: | + - Total vesting duration in seconds + cliffDurationFromMigrationTime: + type: number + enum: + - 0 + - 15552000 + - 15811200 + - 31536000 + description: | + - Cliff duration from migration time in seconds + antiSniping: + type: boolean + description: | + - Enable anti-sniping protection + - Apply an additional swap fee immediately after launch to discourage bots + - Starts at 99% and decreases 1% linearly over a randomized period + fee: + type: object + description: | + - Fee configuration parameters + - If not provided, the default fee will be 100 basis points (1%) + properties: + totalDuration: + type: number + enum: + - 60 + - 120 + - 180 + - 240 + - 300 + description: Total duration for fee schedule + baseFeeMode: + type: string + enum: + - linear + - exponential + description: Base fee mode for fee scheduler + feeBps: + type: number + enum: + - 100 + - 200 + description: Ending fee in basis points (100 or 200) + default: 100 + required: + - feeBps + isLpLocked: + type: boolean + description: | + - Whether LP tokens should be locked + - If enabled, 50% of graduated LP unlocks after 1 year + - Useful for creators to strategize in the long term + default: true + tokenName: + type: string + minLength: 1 + tokenSymbol: + type: string + minLength: 1 + tokenImageContentType: + type: string + description: | + - Token image content type + enum: + - image/jpeg + - image/png + - image/gif + - image/webp + creator: + type: string + description: | + - Creator wallet public key + + CreateDBCTransactionResponse: + type: object + required: + - transaction + - mint + - imagePresignedUrl + - metadataPresignedUrl + - imageUrl + properties: + transaction: + type: string + description: Base64-encoded transaction ready for signing + mint: + type: string + description: Generated token mint address + imagePresignedUrl: + type: string + format: uri + description: | + - Presigned URL for image upload via `PUT` request + - This is for you to make a PUT request to upload your token image to the on-chain uri metadata + - [Refer to the Token Metadata section for better understanding](/docs/studio-api/create-token#token-metadata) + metadataPresignedUrl: + type: string + format: uri + description: | + - Presigned URL for metadata upload via `PUT` request + - This is for you to make a PUT request to upload your token metadata to the on-chain uri metadata + - [Refer to the Token Metadata section for better understanding](/docs/studio-api/create-token#token-metadata) + imageUrl: + type: string + format: uri + description: Final image URL + + SubmitDBCTransactionRequestBody: + type: object + required: + - transaction + - owner + properties: + transaction: + type: string + description: | + - Base64-encoded signed transaction + owner: + type: string + description: | + - Owner wallet public key + content: + type: string + description: | + - Optional content description displayed on Studio dedicated token page + - This is stored off-chain for our frontend to display + - This is NOT the on-chain token metadata + - The on-chain token metadata is done by making a PUT request to the presigned URL + headerImage: + type: string + format: binary + description: | + - Optional header image file displayed on Studio token page + - This is stored off-chain for our frontend to display + - This is NOT the on-chain token metadata + - The on-chain token metadata is done by making a PUT request to the presigned URL + + CreateClaimFeeDBCTransactionRequestBody: + type: object + required: + - ownerWallet + - poolAddress + - maxQuoteAmount + properties: + ownerWallet: + type: string + description: | + - Owner wallet public key + poolAddress: + type: string + description: | + - Dynamic Bonding Curve pool address + maxQuoteAmount: + type: number + description: | + - Maximum quote amount to claim + minimum: 0 diff --git a/mintlify-migration/docs/openapi-spec/swap/swap.yaml b/mintlify-migration/docs/openapi-spec/swap/swap.yaml new file mode 100644 index 00000000..ffe6f060 --- /dev/null +++ b/mintlify-migration/docs/openapi-spec/swap/swap.yaml @@ -0,0 +1,600 @@ +openapi: 3.0.3 +info: + title: Quickstart + version: 1.0.0 + description: | + | Link | + | --- | + | [Get Quote](/docs/swap-api/get-quote) | + | [Build Swap Transaction](/docs/swap-api/build-swap-transaction) | + | [Send Swap Transaction](/docs/swap-api/send-swap-transaction) | + +servers: + - url: https://lite-api.jup.ag/swap/v1 + description: Free tier API endpoint with rate limits + - url: https://api.jup.ag/swap/v1 + description: Paid tier API endpoint with higher rate limits to be used with an API Key + - url: https://preprod-quote-api.jup.ag/ + description: This is a staging endpoint for tests + +paths: + /quote: + get: + tags: + - Swap + summary: quote + description: | + Request for a quote to be used in `POST /swap` + parameters: + - $ref: '#/components/parameters/InputMintParameter' + - $ref: '#/components/parameters/OutputMintParameter' + - $ref: '#/components/parameters/AmountParameter' + - $ref: '#/components/parameters/SlippageParameter' + - $ref: '#/components/parameters/SwapModeParameter' + - $ref: '#/components/parameters/DexesParameter' + - $ref: '#/components/parameters/ExcludeDexesParameter' + - $ref: '#/components/parameters/RestrictIntermediateTokensParameter' + - $ref: '#/components/parameters/OnlyDirectRoutesParameter' + - $ref: '#/components/parameters/AsLegacyTransactionParameter' + - $ref: '#/components/parameters/PlatformFeeBpsParameter' + - $ref: '#/components/parameters/MaxAccountsParameter' + - $ref: '#/components/parameters/DynamicSlippage' + responses: + '200': + description: "Successful response to be used in `/swap`" + content: + application/json: + schema: + $ref: '#/components/schemas/QuoteResponse' + /swap: + post: + tags: + - Swap + summary: swap + description: | + Request for a base64-encoded unsigned swap transaction based on the `/quote` response + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SwapRequest' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/SwapResponse' + /swap-instructions: + post: + tags: + - Swap + summary: swap-instructions + description: | + Request for swap instructions that you can use from the quote you get from `/quote` + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SwapRequest' + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/SwapInstructionsResponse' + /program-id-to-label: + get: + tags: + - Swap + summary: program-id-to-label + description: | + Returns a hash, which key is the program id and value is the label. + This is used to help map error from transaction by identifying the fault program id. + This can be used in conjunction with the `excludeDexes` or `dexes` parameter. + responses: + '200': + description: Default response + content: + application/json: + schema: + type: object + additionalProperties: + type: string + +components: + schemas: + Instruction: + type: object + properties: + programId: + type: string + accounts: + type: array + items: + $ref: '#/components/schemas/AccountMeta' + data: + type: string + required: + - programId + - accounts + - data + + AccountMeta: + type: object + properties: + pubkey: + type: string + isSigner: + type: boolean + isWritable: + type: boolean + required: + - pubkey + - isSigner + - isWritable + + QuoteResponse: + type: object + required: + - inputMint + - outputMint + - inAmount + - outAmount + - otherAmountThreshold + - swapMode + - slippageBps + - priceImpactPct + - routePlan + properties: + inputMint: + type: string + inAmount: + type: string + outputMint: + type: string + outAmount: + type: string + description: | + - Calculated output amount from routing engine + - The value includes platform fees and DEX fees, excluding slippage + otherAmountThreshold: + type: string + description: | + - Calculated minimum output amount after accounting for `slippageBps` on the `outAmount` value + - Not used by `/swap` endpoint to build transaction + swapMode: + $ref: '#/components/schemas/SwapMode' + required: true + slippageBps: + type: integer + format: uint16 + minimum: 0 + platformFee: + $ref: '#/components/schemas/PlatformFee' + priceImpactPct: + type: string + routePlan: + type: array + items: + $ref: '#/components/schemas/RoutePlanStep' + contextSlot: + type: integer + format: uint64 + timeTaken: + type: number + + SwapMode: + type: string + enum: + - ExactIn + - ExactOut + + PlatformFee: + type: object + properties: + amount: + type: string + feeBps: + type: integer + format: uint16 + + RoutePlanStep: + type: object + properties: + swapInfo: + $ref: '#/components/schemas/SwapInfo' + percent: + type: integer + format: uint8 + bps: + type: integer + format: uint16 + required: + - swapInfo + - percent + + SwapInfo: + type: object + required: + - ammKey + - inputMint + - outputMint + - inAmount + - outAmount + - feeAmount + - feeMint + properties: + ammKey: + type: string + label: + type: string + inputMint: + type: string + outputMint: + type: string + inAmount: + type: string + outAmount: + type: string + feeAmount: + type: string + feeMint: + type: string + + SwapRequest: + type: object + required: + - userPublicKey + - quoteResponse + properties: + userPublicKey: + type: string + payer: + description: | + - Allow a custom payer to pay for the transaction fees and rent of token accounts + - Note that users can close their ATAs elsewhere and have you reopen them again, your fees should account for this + type: string + wrapAndUnwrapSol: + description: | + - To automatically wrap/unwrap SOL in the transaction, as WSOL is an SPL token while native SOL is not + - When true, it will strictly use SOL amount to wrap it to swap, and each time after you swap, it will unwrap all WSOL back to SOL + - When false, it will strictly use WSOL amount to swap, and each time after you swap, it will not unwrap the WSOL back to SOL + - To set this parameter to false, you need to have the WSOL token account initialized + - Parameter will be ignored if `destinationTokenAccount` is set because the `destinationTokenAccount` may belong to a different user that we have no authority to close + type: boolean + default: true + useSharedAccounts: + description: | + - The default is determined dynamically by the routing engine, allowing us to optimize for compute units, etc + - This enables the usage of shared program accounts, this is essential as complex routing will require multiple intermediate token accounts which the user might not have + - If true, you do not need to handle the creation of intermediate token accounts for the user + - Do note, shared accounts route will fail on some new AMMs (low liquidity token) + type: boolean + feeAccount: + description: | + - An token account that will be used to collect fees + - The mint of the token account **can only be either the input or output mint of the swap** + - You no longer are required to use the Referral Program + - See [Add Fees](/docs/swap-api/add-fees-to-swap) guide for more details + type: string + trackingAccount: + description: | + - Specify any public key that belongs to you to track the transactions + - Useful for integrators to get all the swap transactions from this public key + - Query the data using a block explorer like Solscan/SolanaFM or query like Dune/Flipside + type: string + prioritizationFeeLamports: + description: | + - To specify a level or amount of additional fees to prioritize the transaction + - It can be used for EITHER priority fee OR Jito tip (not both at the same time) + - If you want to include both, you will need to use `/swap-instructions` to add both at the same time + type: object + properties: + priorityLevelWithMaxLamports: + type: object + properties: + priorityLevel: + type: string + enum: + - medium + - high + - veryHigh + maxLamports: + description: | + - Maximum lamports to cap the priority fee estimation, to prevent overpaying + type: integer + format: uint64 + jitoTipLamports: + type: integer + format: uint64 + description: | + - Exact amount of tip to use in a tip instruction + - Refer to Jito docs on how to estimate the tip amount based on percentiles + - It has to be used together with a connection to a Jito RPC + - [See their docs](https://docs.jito.wtf/) + asLegacyTransaction: + description: | + - Builds a legacy transaction rather than the default versioned transaction + - Used together with `asLegacyTransaction` in `/quote`, otherwise the transaction might be too large + type: boolean + default: false + destinationTokenAccount: + description: | + - Public key of a token account that will be used to receive the token out of the swap + - If not provided, the signer's token account will be used + - If provided, we assume that the token account is already initialized + type: string + dynamicComputeUnitLimit: + description: | + - When enabled, it will do a swap simulation to get the compute unit used and set it in ComputeBudget's compute unit limit + - This incurs one extra RPC call to simulate this + - We recommend to enable this to estimate compute unit correctly and reduce priority fees needed or have higher chance to be included in a block + type: boolean + default: false + skipUserAccountsRpcCalls: + description: | + - When enabled, it will not do any additional RPC calls to check on required accounts + - The returned swap transaction will still attempt to create required accounts regardless if it exists or not + type: boolean + default: false + dynamicSlippage: + description: | + - When enabled, it estimates slippage and apply it in the swap transaction directly, overwriting the `slippageBps` parameter in the quote response. + - Used together with `dynamicSlippage` in `/quote`, otherwise the slippage used will be the one in the `/quote`'s `slippageBps` + - [See notes for more information](/docs/swap-api/send-swap-transaction#how-jupiter-estimates-slippage) + type: boolean + default: false + computeUnitPriceMicroLamports: + description: | + - To use an exact compute unit price to calculate priority fee + - `computeUnitLimit (1400000) * computeUnitPriceMicroLamports` + - We recommend using `prioritizationFeeLamports` and `dynamicComputeUnitLimit` instead of passing in your own compute unit price + type: integer + format: uint64 + blockhashSlotsToExpiry: + description: | + - Pass in the number of slots we want the transaction to be valid for + - Example: If you pass in 10 slots, the transaction will be valid for ~400ms * 10 = approximately 4 seconds before it expires + type: integer + format: uint8 + quoteResponse: + $ref: '#/components/schemas/QuoteResponse' + example: + userPublicKey: "jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3" + quoteResponse: + inputMint: "So11111111111111111111111111111111111111112" + inAmount: "1000000" + outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" + outAmount: "125630" + otherAmountThreshold: "125002" + swapMode: "ExactIn" + slippageBps: 50 + platformFee: null + priceImpactPct: "0" + routePlan: + - swapInfo: + ammKey: "AvBSC1KmFNceHpD6jyyXBV6gMXFxZ8BJJ3HVUN8kCurJ" + label: "Obric V2" + inputMint: "So11111111111111111111111111111111111111112" + outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" + inAmount: "1000000" + outAmount: "125630" + feeAmount: "5" + feeMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" + percent: 100 + prioritizationFeeLamports: + priorityLevelWithMaxLamports: + maxLamports: 10000000 + priorityLevel: "veryHigh" + dynamicComputeUnitLimit: true + + SwapResponse: + type: object + properties: + swapTransaction: + type: string + lastValidBlockHeight: + type: integer + format: uint64 + prioritizationFeeLamports: + type: integer + format: uint64 + required: + - swapTransaction + - lastValidBlockHeight + + SwapInstructionsResponse: + type: object + properties: + otherInstructions: + description: | + - If you set `{\"prioritizationFeeLamports\": {\"jitoTipLamports\": 5000}}`, you will see a custom tip instruction to Jito here. + type: array + items: + $ref: '#/components/schemas/Instruction' + computeBudgetInstructions: + description: | + - To setup the compute budget for the transaction. + type: array + items: + $ref: '#/components/schemas/Instruction' + setupInstructions: + description: | + - To setup required token accounts for the users. + type: array + items: + $ref: '#/components/schemas/Instruction' + swapInstruction: + description: | + - The actual swap instruction. + $ref: '#/components/schemas/Instruction' + cleanupInstruction: + description: | + - To wrap and unwrap the SOL. + $ref: '#/components/schemas/Instruction' + addressLookupTableAddresses: + description: | + - The lookup table addresses if you are using versioned transaction. + type: array + items: + type: string + required: + - computeBudgetInstructions + - setupInstructions + - swapInstruction + - addressLookupTableAddresses + + IndexedRouteMapResponse: + type: object + required: + - mintKeys + - indexedRouteMap + properties: + mintKeys: + type: array + items: + type: string + description: All the mints that are indexed to match in indexedRouteMap + indexedRouteMap: + type: object + description: All the possible route and their corresponding output mints + additionalProperties: + type: array + items: + type: number + example: + '1': + - 2 + - 3 + - 4 + '2': + - 1 + - 3 + - 4 + + parameters: + InputMintParameter: + name: inputMint + in: query + required: true + schema: + type: string + OutputMintParameter: + name: outputMint + in: query + required: true + schema: + type: string + AmountParameter: + name: amount + description: | + - Raw amount to swap (before decimals) + - Input Amount if `SwapMode=ExactIn` + - Output Amount if `SwapMode=ExactOut` + in: query + required: true + schema: + type: integer + format: uint64 + SlippageParameter: + name: slippageBps + in: query + schema: + type: integer + format: uint16 + SwapModeParameter: + name: swapMode + description: | + - ExactOut is for supporting use cases where you need an exact output amount, like using [Swap API as a payment service](/docs/swap-api/payments-through-swap) + - In the case of `ExactIn`, the slippage is on the output token + - In the case of `ExactOut`, the slippage is on the input token + - Not all AMMs support `ExactOut`: Currently only Orca Whirlpool, Raydium CLMM, Raydium CPMM + in: query + schema: + type: string + enum: + - ExactIn + - ExactOut + default: ExactIn + DexesParameter: + name: dexes + description: | + - Multiple DEXes can be pass in by comma separating them + - For example: `dexes=Raydium,Orca+V2,Meteora+DLMM` + - If a DEX is indicated, the route will **only use** that DEX + - [Full list of DEXes here](https://lite-api.jup.ag/swap/v1/program-id-to-label) + in: query + schema: + type: array + items: + type: string + ExcludeDexesParameter: + name: excludeDexes + description: | + - Multiple DEXes can be pass in by comma separating them + - For example: `excludeDexes=Raydium,Orca+V2,Meteora+DLMM` + - If a DEX is indicated, the route will **not use** that DEX + - [Full list of DEXes here](https://lite-api.jup.ag/swap/v1/program-id-to-label) + in: query + schema: + type: array + items: + type: string + RestrictIntermediateTokensParameter: + name: restrictIntermediateTokens + description: | + - Restrict intermediate tokens within a route to a set of more stable tokens + - This will help to reduce exposure to potential high slippage routes + in: query + schema: + type: boolean + default: true + OnlyDirectRoutesParameter: + name: onlyDirectRoutes + description: | + - Direct Routes limits Jupiter routing to single hop routes only + - This may result in worse routes + in: query + schema: + type: boolean + default: false + AsLegacyTransactionParameter: + name: asLegacyTransaction + description: | + - Instead of using versioned transaction, this will use the legacy transaction + in: query + schema: + type: boolean + default: false + MaxAccountsParameter: + name: maxAccounts + description: | + - Rough estimate of the max accounts to be used for the quote + - Useful if composing your own transaction or to be more precise in resource accounting for better routes + in: query + schema: + type: integer + format: uint64 # usize + default: 64 + PlatformFeeBpsParameter: + name: platformFeeBps + description: | + - Take fees in basis points + - Used together with `feeAccount` in /swap, see [Adding Fees](/docs/swap-api/add-fees-to-swap) guide + in: query + schema: + type: integer + format: uint16 + DynamicSlippage: + name: dynamicSlippage + description: | + - If true, `slippageBps` will be overriden by Dynamic Slippage's estimated value + - The value is returned in `/swap` endpoint + in: query + schema: + type: boolean + default: false diff --git a/mintlify-migration/docs/openapi-spec/token/v1/token.yaml b/mintlify-migration/docs/openapi-spec/token/v1/token.yaml new file mode 100644 index 00000000..47c64202 --- /dev/null +++ b/mintlify-migration/docs/openapi-spec/token/v1/token.yaml @@ -0,0 +1,359 @@ +openapi: 3.0.3 +info: + title: Quickstart + version: 1.0.0 + description: | + | Link | + | --- | + | [V2](/docs/token-api/v2) | + | [V1 Deprecated](/docs/token-api/v1) | + +servers: + - url: https://lite-api.jup.ag/tokens/v1 + description: Free tier API endpoint with rate limits + - url: https://api.jup.ag/tokens/v1 + description: Paid tier API endpoint with higher rate limits to be used with an API Key + +paths: + /token/{mint_address}: + get: + summary: token information + deprecated: true + description: | + Returns the specified mint address's token information and metadata. + + + **DEPRECATED** + + This endpoint has been deprecated and may be replaced or removed in future versions of the API. + + + + **NOTE** + + - Refer to [Token API doc](/docs/token-api/v1) for more information. + + parameters: + - name: mint_address + in: path + description: The token's mint address + required: true + schema: + type: string + example: So11111111111111111111111111111111111111112 + responses: + '200': + description: Returns metadata about a particular token + content: + application/json: + schema: + "$ref": "#/components/schemas/MintIncludingDuplicates" + /market/{market_address}/mints: + get: + summary: mints in market + deprecated: true + description: | + Returns the mints involved in a market. + + **DEPRECATED** + + This endpoint has been deprecated and may be replaced or removed in future versions of the API. + + + + **NOTE** + + - Refer to [Token API doc](/docs/token-api/v1) for more information. + + parameters: + - name: market_address + in: path + description: A market/pool address + required: true + schema: + type: string + example: BVRbyLjjfSBcoyiYFuxbgKYnWuiFaF9CSXEa5vdSZ9Hh + responses: + '200': + description: Returns the mints involved in a market + content: + application/json: + schema: + type: array + items: + type: string + /mints/tradable: + get: + summary: tradable + deprecated: true + description: | + Returns a list of all mints tradable via Jupiter routing. + + + **DEPRECATED** + + This endpoint has been deprecated and may be replaced or removed in future versions of the API. + + + + **NOTE** + + - Refer to [Token API doc](/docs/token-api/v1) for more information. + + responses: + '200': + description: List of mints which are tradable via Jupiter routing + content: + application/json: + schema: + type: array + items: + type: string + /tagged/{tag}: + get: + summary: tagged + deprecated: true + description: | + Returns a list of mints with specified tag(s) along with their metadata. + + **DEPRECATED** + + This endpoint has been deprecated and may be replaced or removed in future versions of the API. + + + + **NOTE** + + - Refer to [Token API doc](/docs/token-api/v1) for more information. + + parameters: + - name: tag + in: path + description: A list of one or more tags, comma separated. The list is the + union of tokens with these tags. + required: true + schema: + type: string + example: lst,token-2022 + responses: + '200': + description: The list of tokens with the tags given + content: + application/json: + schema: + "$ref": "#/components/schemas/MintIncludingDuplicates" + /new: + get: + summary: new + deprecated: true + description: | + Returns new tokens with metadata, created at timestamp and markets. + + + **DEPRECATED** + + This endpoint has been deprecated and may be replaced or removed in future versions of the API. + + + + **NOTE** + + - Refer to [Token API doc](/docs/token-api/v1) for more information. + + parameters: + - name: limit + in: query + description: How many records to output in the result + required: false + schema: + type: integer + nullable: true + format: int64 + example: '10' + - name: offset + in: query + description: |- + The offset into the result set. Used in conjunction with + `limit` to page through the data. + required: false + schema: + type: integer + format: int64 + nullable: true + default: 0 + example: '20' + responses: + '200': + description: List of new tokens which are tradable with SOL + content: + application/json: + schema: + type: array + items: + "$ref": "#/components/schemas/MintWithCreationTimeAndMarkets" + /all: + get: + summary: all + deprecated: true + description: | + Returns all tokens with all metadata. + + + **DEPRECATED** + + This endpoint has been deprecated and may be replaced or removed in future versions of the API. + + + + **NOTE** + - Refer to [Token API doc](/docs/token-api/v1) for more information. + + responses: + '200': + description: List of all tokens with all metadata + content: + application/json: + schema: + type: array + items: + "$ref": "#/components/schemas/Mint" + +components: + schemas: + Mint: + type: object + required: + - address + - name + - symbol + - decimals + - tags + - created_at + - extensions + properties: + address: + type: string + created_at: + type: string + format: date-time + daily_volume: + type: number + nullable: true + format: double + decimals: + type: integer + format: int32 + extensions: {} + freeze_authority: + type: string + nullable: true + logoURI: + type: string + nullable: true + mint_authority: + type: string + nullable: true + minted_at: + type: string + nullable: true + format: date-time + name: + type: string + permanent_delegate: + type: string + nullable: true + symbol: + type: string + tags: + type: array + items: + type: string + nullable: true + MintIncludingDuplicates: + type: object + required: + - address + - name + - symbol + - decimals + - tags + - created_at + - extensions + properties: + address: + type: string + created_at: + type: string + format: date-time + daily_volume: + type: integer + nullable: true + format: double + decimals: + type: integer + format: int32 + extensions: {} + freeze_authority: + type: string + nullable: true + logoURI: + type: string + nullable: true + mint_authority: + type: string + nullable: true + minted_at: + type: string + nullable: true + format: date-time + name: + type: string + permanent_delegate: + type: string + nullable: true + symbol: + type: string + tags: + type: array + items: + type: string + nullable: true + MintWithCreationTimeAndMarkets: + type: object + required: + - mint + - created_at + - metadata_updated_at + - name + - symbol + - decimals + - known_markets + properties: + created_at: + type: string + format: date-time + decimals: + type: integer + format: int32 + freeze_authority: + type: string + nullable: true + known_markets: + type: array + items: + type: string + logo_uri: + type: string + nullable: true + metadata_updated_at: + type: string + format: date-time + mint: + type: string + mint_authority: + type: string + nullable: true + name: + type: string + symbol: + type: string diff --git a/mintlify-migration/docs/openapi-spec/token/v2/token.yaml b/mintlify-migration/docs/openapi-spec/token/v2/token.yaml new file mode 100644 index 00000000..9dd42082 --- /dev/null +++ b/mintlify-migration/docs/openapi-spec/token/v2/token.yaml @@ -0,0 +1,387 @@ +openapi: 3.0.3 +info: + title: Quickstart + version: 2.0.0 + description: | + | Link | + | --- | + | [V1](/docs/token-api/v1) | + | [V2](/docs/token-api/v2) | + | [V1 Deprecated](/docs/token-api/v1) | + +servers: + - url: https://lite-api.jup.ag/tokens/v2 + description: Free tier API endpoint with rate limits + - url: https://api.jup.ag/tokens/v2 + description: Paid tier API endpoint with higher rate limits to be used with an API Key + +paths: + /search: + get: + summary: search + description: | + Request a search by token's symbol, name or mint address + parameters: + - in: query + name: query + schema: + type: string + required: true + description: | + - Search for a token and its information by its symbol, name or mint address + - Comma-separate to ONLY search for multiple mint addresses + - Limit to 100 mint addresses in query + - Default to 20 mints in response when searching via symbol or name + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/MintInformation" + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + '500': + description: Internal server error + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + /tag: + get: + summary: tag + description: | + Request an array of mints and their information by a tag + - Note that this will return the entire array of existing mints that belongs to the tag. + parameters: + - in: query + name: query + schema: + type: string + enum: + - lst + - verified + required: true + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/MintInformation" + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + '500': + description: Internal server error + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + /{category}/{interval}: + get: + summary: category + description: | + Returns an array of mints and their information for the given category and interval + parameters: + - in: path + name: category + required: true + schema: + type: string + enum: [toporganicscore, toptraded, toptrending] + description: | + - Top tokens in different trading categories + - The result filters out generic top tokens like SOL, USDC, etc + - Default to 50 mints in response + - in: path + name: interval + required: true + schema: + type: string + enum: [5m, 1h, 6h, 24h] + description: | + - Query by time interval for more accuracy + - in: query + name: limit + schema: + type: integer + minimum: 1 + maximum: 100 + required: false + description: | + - Maximum number of results to return (default 50, max 100) + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/MintInformation' + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + '500': + description: Internal server error + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + /recent: + get: + summary: recent + description: | + Returns an array of mints that recently had their **first created pool** + - Default to 30 mints in response + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/MintInformation' + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + '500': + description: Internal server error + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + +components: + schemas: + MintInformation: + type: object + properties: + id: + type: string + description: The token's mint address + name: + type: string + symbol: + type: string + icon: + type: string + nullable: true + decimals: + type: number + twitter: + type: string + nullable: true + telegram: + type: string + nullable: true + website: + type: string + nullable: true + dev: + type: string + nullable: true + description: The token's developer address + circSupply: + type: number + nullable: true + totalSupply: + type: number + nullable: true + tokenProgram: + type: string + description: The token program address + launchpad: + type: string + nullable: true + partnerConfig: + type: string + nullable: true + graduatedPool: + type: string + nullable: true + graduatedAt: + type: string + nullable: true + holderCount: + type: number + nullable: true + fdv: + type: number + nullable: true + mcap: + type: number + nullable: true + usdPrice: + type: number + nullable: true + priceBlockId: + type: number + nullable: true + liquidity: + type: number + nullable: true + stats5m: + $ref: "#/components/schemas/SwapStats" + nullable: true + stats1h: + $ref: "#/components/schemas/SwapStats" + nullable: true + stats6h: + $ref: "#/components/schemas/SwapStats" + nullable: true + stats24h: + $ref: "#/components/schemas/SwapStats" + nullable: true + firstPool: + type: object + nullable: true + properties: + id: + type: string + createdAt: + type: string + audit: + type: object + nullable: true + properties: + isSus: + type: boolean + nullable: true + mintAuthorityDisabled: + type: boolean + nullable: true + freezeAuthorityDisabled: + type: boolean + nullable: true + topHoldersPercentage: + type: number + nullable: true + devBalancePercentage: + type: number + nullable: true + devMigrations: + type: number + nullable: true + organicScore: + type: number + organicScoreLabel: + type: string + enum: [high, medium, low] + isVerified: + type: boolean + nullable: true + cexes: + type: array + items: + type: string + nullable: true + tags: + type: array + items: + type: string + nullable: true + updatedAt: + type: string + format: date-time + SwapStats: + type: object + properties: + priceChange: + type: number + nullable: true + holderChange: + type: number + nullable: true + liquidityChange: + type: number + nullable: true + volumeChange: + type: number + nullable: true + buyVolume: + type: number + nullable: true + sellVolume: + type: number + nullable: true + buyOrganicVolume: + type: number + nullable: true + sellOrganicVolume: + type: number + nullable: true + numBuys: + type: number + nullable: true + numSells: + type: number + nullable: true + numTraders: + type: number + nullable: true + numOrganicBuyers: + type: number + nullable: true + numNetBuyers: + type: number + nullable: true diff --git a/mintlify-migration/docs/openapi-spec/trigger/trigger.yaml b/mintlify-migration/docs/openapi-spec/trigger/trigger.yaml new file mode 100644 index 00000000..1bfc04cb --- /dev/null +++ b/mintlify-migration/docs/openapi-spec/trigger/trigger.yaml @@ -0,0 +1,758 @@ +openapi: 3.0.0 +info: + title: Trigger Order API + version: 1.0.0 + description: | + Formerly known as Limit Order API + + | Link | + | --- | + | [Create Order](/docs/trigger-api/create-order) | + | [Execute Order](/docs/trigger-api/execute-order) | + | [Cancel Order](/docs/trigger-api/cancel-order) | + | [Get Trigger Orders](/docs/trigger-api/get-trigger-orders) | + +servers: + - url: 'https://lite-api.jup.ag/trigger/v1' + description: Free tier API endpoint with rate limits + - url: https://api.jup.ag/trigger/v1 + description: Paid tier API endpoint with higher rate limits to be used with an API Key + +components: + schemas: {} + parameters: {} +paths: + /cancelOrders: + post: + summary: cancelOrders + description: | + Request for a base64-encoded unsigned trigger order cancellation transaction(s) to be used in `POST /trigger/v1/execute` + requestBody: + content: + application/json: + schema: + type: object + properties: + maker: + type: string + computeUnitPrice: + type: string + default: auto + description: | + In microlamports, defaults to 95th percentile of priority fees + orders: + type: array + items: + type: string + description: | + Array of orders to cancel, if none is provided, the API will generate cancel instructions for all open orders belonging to the maker + required: + - maker + title: cancelOrdersRequestBody + example: + maker: jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3 + orders: + - 6fe8ByaiFHisjnYnH5qdpyiNtkn89mMBQUemRkVmKhro + - 9jwzPKHxcrSozdrTYzPnTqy7psRvNGxaYUAiiyxwZKjj + computeUnitPrice: auto + responses: + '200': + description: | + Returns the base64-encoded unsigned transaction(s) of all open orders associated to the provided "maker" + - If no orders were specified, it will batch 5 cancel order instructions in 1 transaction + content: + application/json: + schema: + type: object + properties: + requestId: + type: string + description: "Required to make a request to `/execute`" + transactions: + type: array + items: + type: string + description: "Array of unsigned base-64 encoded transaction(s)" + required: + - requestId + - transactions + example: + requestId: f7d5dd40-a416-4dae-8367-7dc10cab6554 + transactions: + - | + AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAkOCWPK8t5w2W1nIsonBw2T/TCNCKkrgBQia9/YVlLEcjM9zTXA2aZIqK0k40U/eCZ0Zu1176lxIuHLsY6UyQjTdash6wigo20Auc3RVYRWME9FjnpbdgdRKYjLJLe0lVi47IZO5XCZ/U0AirZsOIWLoumtNiLomxcYL6d2R2rSxzkNgnQl2IV0spQPT+7K7zraa8oytEZyZ4HSFpxmV2v3WgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEImJzcxhjwZ2dKxnfimarbEo/iDZzNgo5QjJ8b+bMOuSf2yH7EMQBZfZLsgOHg/C5SyLv/x1D4MHZgRX7jOy4YyXJY9OJInxuz0QKRSODYMLWhOZ2v8QhASOe9jb6fhZAwZGb+UhFzL/7K26csOb57yM5bvF9xJrLEObOkAAAADG+nrzvtutOj1l82qryXQxsbvkwtL24OR8pgIDRS9dYQrDSpbBZnFaYMEjPsolig3zCx7IWOB0XHNqEmJmY0siBpuIV/6rgYT7aH9jRhjANdrEOdwa6ztVmKDwAAAAAAEG3fbh12Whk9nL4UbO63msHLSF7V9bN5E6jPWFfv8AqXeleaIpvDk6bHUITYxyjNU3ParFA70LbecfV6NupbbBCAkABQKgAwIACQAJAy48AAAAAAAACAYABAAMBQ0BAQUCAAQMAgAAAIDw+gIAAAAADQEEAREIBgABAAoFDQEBCw8AAAIDBAYLDAoNDQUIBwsihW5Kr3Cf9Z9OyUY1qj0LZYDw+gIAAAAAAOH1BQAAAAAAAA0DBAAAAQk= + - | + AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAkOCWPK8t5w2W1nIsonBw2T/TCNCKkrgBQia9/YVlLEcjM9zTXA2aZIqK0k40U/eCZ0Zu1176lxIuHLsY6UyQjTdash6wigo20Auc3RVYRWME9FjnpbdgdRKYjLJLe0lVi47IZO5XCZ/U0AirZsOIWLoumtNiLomxcYL6d2R2rSxzkNgnQl2IV0spQPT+7K7zraa8oytEZyZ4HSFpxmV2v3WgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEImJzcxhjwZ2dKxnfimarbEo/iDZzNgo5QjJ8b+bMOuSf2yH7EMQBZfZLsgOHg/C5SyLv/x1D4MHZgRX7jOy4YyXJY9OJInxuz0QKRSODYMLWhOZ2v8QhASOe9jb6fhZAwZGb+UhFzL/7K26csOb57yM5bvF9xJrLEObOkAAAADG+nrzvtutOj1l82qryXQxsbvkwtL24OR8pgIDRS9dYQrDSpbBZnFaYMEjPsolig3zCx7IWOB0XHNqEmJmY0siBpuIV/6rgYT7aH9jRhjANdrEOdwa6ztVmKDwAAAAAAEG3fbh12Whk9nL4UbO63msHLSF7V9bN5E6jPWFfv8AqXeleaIpvDk6bHUITYxyjNU3ParFA70LbecfV6NupbbBCAkABQKgAwIACQAJAy48AAAAAAAACAYABAAMBQ0BAQUCAAQMAgAAAIDw+gIAAAAADQEEAREIBgABAAoFDQEBCw8AAAIDBAYLDAoNDQUIBwsihW5Kr3Cf9Z9OyUY1qj0LZYDw+gIAAAAAAOH1BQAAAAAAAA0DBAAAAQk= + '400': + description: Bad request body + content: + application/json: + schema: + type: object + properties: + error: + type: string + code: + type: number + cause: + type: string + signature: + type: string + description: 'Signature of the transaction, if generated' + example: | + 38CtpugRBobyj1JMkHj9umQyj1D8q6bs1jcMRcw7Fiyp4BXv4uh4bD4TyJs6fsqYCDDfQpeRewA7HjLA1Eprc8uR + status: + type: string + enum: + - Failed + required: + - error + - code + example: + error: invalid maker pubkey + code: 400 + '500': + description: Internal error + content: + application/json: + schema: + type: object + properties: + error: + type: string + code: + type: number + cause: + type: string + signature: + type: string + description: 'Signature of the transaction, if generated' + example: | + 38CtpugRBobyj1JMkHj9umQyj1D8q6bs1jcMRcw7Fiyp4BXv4uh4bD4TyJs6fsqYCDDfQpeRewA7HjLA1Eprc8uR + status: + type: string + enum: + - Failed + required: + - error + - code + example: + error: something went wrong while generating cancel instructions + code: 500 + /createOrder: + post: + summary: createOrder + description: | + Request for a base64-encoded unsigned trigger order creation transaction to be used in `POST /trigger/v1/execute` + requestBody: + content: + application/json: + schema: + type: object + properties: + inputMint: + type: string + outputMint: + type: string + maker: + type: string + payer: + type: string + params: + type: object + properties: + makingAmount: + type: string + description: Amount of input mint to swap + takingAmount: + type: string + description: Amount of output mint to receive + expiredAt: + type: string + slippageBps: + type: string + description: | + Amount of slippage the order can be executed with + default: 0 + feeBps: + type: string + description: | + Requires the `feeAccount` parameter, the amount of fees in bps that will be sent to the fee account + required: + - makingAmount + - takingAmount + computeUnitPrice: + type: string + default: auto + description: | + In microlamports, defaults to 95th percentile of priority fees + feeAccount: + description: | + - A token account (via the Referral Program) that will receive the fees + - Refer to [Referral Program Github](https://github.com/TeamRaccoons/referral/tree/main) for more information + type: string + wrapAndUnwrapSol: + type: boolean + default: true + description: If either input or output mint is native SOL + required: + - inputMint + - outputMint + - maker + - payer + - params + title: createOrdersRequestBody + example: + maker: jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3 + payer: jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3 + inputMint: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v + outputMint: So11111111111111111111111111111111111111112 + params: + makingAmount: '100000000' + takingAmount: '50000000' + computeUnitPrice: auto + responses: + '200': + description: | + Returns the base64-encoded unsigned transaction from the provided request body. + content: + application/json: + schema: + type: object + properties: + requestId: + type: string + description: "Required to make a request to `/execute`" + transaction: + type: string + description: "Unsigned base-64 encoded transaction" + order: + type: string + description: "Base-58 account which is the Trigger Order account" + required: + - requestId + - transaction + example: + requestId: f7d5dd40-a416-4dae-8367-7dc10cab6554 + transaction: | + AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAkOCWPK8t5w2W1nIsonBw2T/TCNCKkrgBQia9/YVlLEcjM9zTXA2aZIqK0k40U/eCZ0Zu1176lxIuHLsY6UyQjTdash6wigo20Auc3RVYRWME9FjnpbdgdRKYjLJLe0lVi47IZO5XCZ/U0AirZsOIWLoumtNiLomxcYL6d2R2rSxzkNgnQl2IV0spQPT+7K7zraa8oytEZyZ4HSFpxmV2v3WgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEImJzcxhjwZ2dKxnfimarbEo/iDZzNgo5QjJ8b+bMOuSf2yH7EMQBZfZLsgOHg/C5SyLv/x1D4MHZgRX7jOy4YyXJY9OJInxuz0QKRSODYMLWhOZ2v8QhASOe9jb6fhZAwZGb+UhFzL/7K26csOb57yM5bvF9xJrLEObOkAAAADG+nrzvtutOj1l82qryXQxsbvkwtL24OR8pgIDRS9dYQrDSpbBZnFaYMEjPsolig3zCx7IWOB0XHNqEmJmY0siBpuIV/6rgYT7aH9jRhjANdrEOdwa6ztVmKDwAAAAAAEG3fbh12Whk9nL4UbO63msHLSF7V9bN5E6jPWFfv8AqXeleaIpvDk6bHUITYxyjNU3ParFA70LbecfV6NupbbBCAkABQKgAwIACQAJAy48AAAAAAAACAYABAAMBQ0BAQUCAAQMAgAAAIDw+gIAAAAADQEEAREIBgABAAoFDQEBCw8AAAIDBAYLDAoNDQUIBwsihW5Kr3Cf9Z9OyUY1qj0LZYDw+gIAAAAAAOH1BQAAAAAAAA0DBAAAAQk= + order: CX2iPk4nxarGPkk7ziViJTfL1z2e1LnGWRDimVQ4tzYf + '400': + description: Bad request body + content: + application/json: + schema: + type: object + properties: + error: + type: string + code: + type: number + cause: + type: string + signature: + type: string + description: 'Signature of the transaction, if generated' + example: | + 38CtpugRBobyj1JMkHj9umQyj1D8q6bs1jcMRcw7Fiyp4BXv4uh4bD4TyJs6fsqYCDDfQpeRewA7HjLA1Eprc8uR + status: + type: string + enum: + - Failed + required: + - error + - code + example: + error: invalid create order request + cause: 'input mint making amount must be at least 5 USD, received: 1' + code: 400 + '500': + description: Internal error + content: + application/json: + schema: + type: object + properties: + error: + type: string + code: + type: number + cause: + type: string + signature: + type: string + description: 'Signature of the transaction, if generated' + example: | + 38CtpugRBobyj1JMkHj9umQyj1D8q6bs1jcMRcw7Fiyp4BXv4uh4bD4TyJs6fsqYCDDfQpeRewA7HjLA1Eprc8uR + status: + type: string + enum: + - Failed + required: + - error + - code + example: + error: unable to get latest blockhash + code: 500 + /cancelOrder: + post: + summary: cancelOrder + description: | + Request for a base64-encoded unsigned trigger order cancellation transaction to be used in `POST /trigger/v1/execute` + requestBody: + content: + application/json: + schema: + type: object + properties: + maker: + type: string + order: + type: string + computeUnitPrice: + type: string + default: auto + description: | + In microlamports, defaults to 95th percentile of priority fees + required: + - maker + - order + example: + maker: jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3 + order: 6fe8ByaiFHisjnYnH5qdpyiNtkn89mMBQUemRkVmKhro + computeUnitPrice: auto + responses: + '200': + description: | + Returns the base64-encoded unsigned transaction needed to cancel an order + content: + application/json: + schema: + type: object + properties: + requestId: + type: string + description: "Required to make a request to `/execute`" + transaction: + type: string + description: "Unsigned base-64 encoded transaction" + required: + - requestId + - transaction + example: + requestId: f7d5dd40-a416-4dae-8367-7dc10cab6554 + transaction: | + AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAkOCWPK8t5w2W1nIsonBw2T/TCNCKkrgBQia9/YVlLEcjM9zTXA2aZIqK0k40U/eCZ0Zu1176lxIuHLsY6UyQjTdash6wigo20Auc3RVYRWME9FjnpbdgdRKYjLJLe0lVi47IZO5XCZ/U0AirZsOIWLoumtNiLomxcYL6d2R2rSxzkNgnQl2IV0spQPT+7K7zraa8oytEZyZ4HSFpxmV2v3WgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEImJzcxhjwZ2dKxnfimarbEo/iDZzNgo5QjJ8b+bMOuSf2yH7EMQBZfZLsgOHg/C5SyLv/x1D4MHZgRX7jOy4YyXJY9OJInxuz0QKRSODYMLWhOZ2v8QhASOe9jb6fhZAwZGb+UhFzL/7K26csOb57yM5bvF9xJrLEObOkAAAADG+nrzvtutOj1l82qryXQxsbvkwtL24OR8pgIDRS9dYQrDSpbBZnFaYMEjPsolig3zCx7IWOB0XHNqEmJmY0siBpuIV/6rgYT7aH9jRhjANdrEOdwa6ztVmKDwAAAAAAEG3fbh12Whk9nL4UbO63msHLSF7V9bN5E6jPWFfv8AqXeleaIpvDk6bHUITYxyjNU3ParFA70LbecfV6NupbbBCAkABQKgAwIACQAJAy48AAAAAAAACAYABAAMBQ0BAQUCAAQMAgAAAIDw+gIAAAAADQEEAREIBgABAAoFDQEBCw8AAAIDBAYLDAoNDQUIBwsihW5Kr3Cf9Z9OyUY1qj0LZYDw+gIAAAAAAOH1BQAAAAAAAA0DBAAAAQk= + '400': + description: Bad request body + content: + application/json: + schema: + type: object + properties: + error: + type: string + code: + type: number + cause: + type: string + signature: + type: string + description: 'Signature of the transaction, if generated' + example: | + 38CtpugRBobyj1JMkHj9umQyj1D8q6bs1jcMRcw7Fiyp4BXv4uh4bD4TyJs6fsqYCDDfQpeRewA7HjLA1Eprc8uR + status: + type: string + enum: + - Failed + required: + - error + - code + example: + error: invalid maker pubkey + code: 400 + '500': + description: Internal error + content: + application/json: + schema: + type: object + properties: + error: + type: string + code: + type: number + cause: + type: string + signature: + type: string + description: 'Signature of the transaction, if generated' + example: | + 38CtpugRBobyj1JMkHj9umQyj1D8q6bs1jcMRcw7Fiyp4BXv4uh4bD4TyJs6fsqYCDDfQpeRewA7HjLA1Eprc8uR + status: + type: string + enum: + - Failed + required: + - error + - code + example: + error: something went wrong while generating cancel instructions + code: 500 + /execute: + post: + summary: execute + description: | + Execute the signed transaction and get the execution status + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + requestId: + type: string + description: "Found in the response of `/createOrder` or `/cancelOrder`" + signedTransaction: + type: string + description: "The signed transaction to execute" + required: + - requestId + - signedTransaction + title: executeRequestBody + responses: + '200': + description: Signature of the successful transaction + content: + application/json: + schema: + type: object + properties: + code: + type: number + signature: + type: string + description: Signature of the successful transaction + status: + type: string + enum: + - Success + - Failed + required: + - signature + - status + - code + example: + signature: | + 38CtpugRBobyj1JMkHj9umQyj1D8q6bs1jcMRcw7Fiyp4BXv4uh4bD4TyJs6fsqYCDDfQpeRewA7HjLA1Eprc8uR + status: Success + '400': + description: Bad request body + content: + application/json: + schema: + type: object + properties: + error: + type: string + code: + type: number + cause: + type: string + signature: + type: string + description: 'Signature of the transaction, if generated' + example: | + 38CtpugRBobyj1JMkHj9umQyj1D8q6bs1jcMRcw7Fiyp4BXv4uh4bD4TyJs6fsqYCDDfQpeRewA7HjLA1Eprc8uR + status: + type: string + enum: + - Failed + required: + - error + - code + example: + error: invalid transaction + code: 400 + status: Failed + '500': + description: Internal error + content: + application/json: + schema: + type: object + properties: + error: + type: string + code: + type: number + cause: + type: string + signature: + type: string + description: 'Signature of the transaction, if generated' + example: | + 38CtpugRBobyj1JMkHj9umQyj1D8q6bs1jcMRcw7Fiyp4BXv4uh4bD4TyJs6fsqYCDDfQpeRewA7HjLA1Eprc8uR + status: + type: string + enum: + - Failed + required: + - error + - code + example: + error: unable to confirm transaction + code: 500 + signature: | + 38CtpugRBobyj1JMkHj9umQyj1D8q6bs1jcMRcw7Fiyp4BXv4uh4bD4TyJs6fsqYCDDfQpeRewA7HjLA1Eprc8uR + status: Failed + /getTriggerOrders: + get: + summary: getTriggerOrders + description: | + Request for the active or historical orders associated to the provided account + + parameters: + - schema: + type: string + example: jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3 + required: true + name: user + in: query + - schema: + type: string + default: '1' + required: false + name: page + in: query + - schema: + type: string + enum: + - 'true' + - 'false' + description: 'Whether to include failed transactions, expects ''true'' or ''false''' + required: false + description: 'Whether to include failed transactions, expects ''true'' or ''false''' + name: includeFailedTx + in: query + - schema: + type: string + enum: + - active + - history + description: The status of the orders to return + required: true + description: The status of the orders to return + name: orderStatus + in: query + - schema: + type: string + required: false + description: The input mint to filter by + name: inputMint + in: query + - schema: + type: string + required: false + description: The output mint to filter by + name: outputMint + in: query + responses: + '200': + description: Returns the open orders associated to the provided account hash + content: + application/json: + schema: + type: object + properties: + user: + type: string + description: The requested user's wallet public key + orderStatus: + type: string + enum: + - active + - history + description: The status of the requested orders + orders: + type: array + items: + type: object + properties: + userPubkey: + type: string + orderKey: + type: string + inputMint: + type: string + outputMint: + type: string + makingAmount: + type: string + takingAmount: + type: string + remainingMakingAmount: + type: string + remainingTakingAmount: + type: string + rawMakingAmount: + type: string + rawTakingAmount: + type: string + rawRemainingMakingAmount: + type: string + rawRemainingTakingAmount: + type: string + slippageBps: + type: string + expiredAt: + type: string + nullable: true + createdAt: + type: string + updatedAt: + type: string + status: + type: string + description: | + An open order with trades indicates that it has been + partially filled + openTx: + type: string + closeTx: + type: string + programVersion: + type: string + trades: + type: array + items: + type: object + properties: + orderKey: + type: string + keeper: + type: string + inputMint: + type: string + outputMint: + type: string + inputAmount: + type: string + outputAmount: + type: string + rawInputAmount: + type: string + rawOutputAmount: + type: string + feeMint: + type: string + feeAmount: + type: string + rawFeeAmount: + type: string + txId: + type: string + confirmedAt: + type: string + action: + type: string + productMeta: + nullable: true + required: + - orderKey + - keeper + - inputMint + - outputMint + - inputAmount + - outputAmount + - rawInputAmount + - rawOutputAmount + - feeMint + - feeAmount + - rawFeeAmount + - txId + - confirmedAt + - action + required: + - userPubkey + - orderKey + - inputMint + - outputMint + - makingAmount + - takingAmount + - remainingMakingAmount + - remainingTakingAmount + - rawMakingAmount + - rawTakingAmount + - rawRemainingMakingAmount + - rawRemainingTakingAmount + - slippageBps + - expiredAt + - createdAt + - updatedAt + - status + - openTx + - closeTx + - programVersion + - trades + totalPages: + type: number + description: Total number of pages + page: + type: number + required: + - user + - orderStatus + - orders + - totalPages + - page + example: + user: jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3 + orderStatus: history + orders: + - userPubkey: jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3 + orderKey: 99uWTWukow8k7dqcpbYoHxTAWGvn1YkT1VMmnEeTjuDr + inputMint: So11111111111111111111111111111111111111112 + outputMint: HeLp6NuQkmYB4pYWo2zYs22mESHXPQYzXbB8n4V98jwC + makingAmount: '0.05' + takingAmount: '32.071840924' + remainingMakingAmount: '0' + remainingTakingAmount: '0' + rawMakingAmount: '50000000' + rawTakingAmount: '32071840924' + rawRemainingMakingAmount: '0' + rawRemainingTakingAmount: '0' + slippageBps: '0' + expiredAt: null + createdAt: '2025-03-17T08:07:25Z' + updatedAt: '2025-03-17T08:09:37Z' + status: Completed + openTx: | + 466G3XxE4NzxCj136SXe4BSjXzCVBQdvn6RsHMNGN2DGCS9PSceJSACqEWCxx22hsCXcEskvEFdm44wsHCF1auvL + closeTx: | + 3PDo3pMJLqvAfNXwYjY7BSP57ZNQ5DgYDeK6xYszUVMneHzAZBQzsBSskym8uveMoLC4G8N8DjPaLBY726ZsBZvT + programVersion: j1o2qRpjcyUwEvwtcfhEQefh773ZgjxcVRry7LDqg5X + trades: + - orderKey: 99uWTWukow8k7dqcpbYoHxTAWGvn1YkT1VMmnEeTjuDr + keeper: j1oAbxxiDUWvoHxEDhWE7THLjEkDQW2cSHYn2vttxTF + inputMint: So11111111111111111111111111111111111111112 + outputMint: HeLp6NuQkmYB4pYWo2zYs22mESHXPQYzXbB8n4V98jwC + inputAmount: '0.05' + outputAmount: '32.071840924' + rawInputAmount: '50000000' + rawOutputAmount: '32071840924' + feeMint: DtL4JtjXwsJQndqXyd6ytJSmWDLWLESoXc7MkYNRQF9J + feeAmount: '0' + rawFeeAmount: '0' + txId: | + 3PDo3pMJLqvAfNXwYjY7BSP57ZNQ5DgYDeK6xYszUVMneHzAZBQzsBSskym8uveMoLC4G8N8DjPaLBY726ZsBZvT + confirmedAt: '2025-03-17T08:09:37Z' + action: Fill + productMeta: null + totalPages: 1 + page: 1 + '400': + description: Bad request body + '500': + description: Internal error diff --git a/mintlify-migration/docs/openapi-spec/ultra/ultra.yaml b/mintlify-migration/docs/openapi-spec/ultra/ultra.yaml new file mode 100644 index 00000000..d3426fb3 --- /dev/null +++ b/mintlify-migration/docs/openapi-spec/ultra/ultra.yaml @@ -0,0 +1,751 @@ +openapi: 3.0.3 +info: + title: Quickstart + version: 1.0.0 + description: | + | Link | + | --- | + | [Get Order](/docs/ultra-api/get-order) | + | [Execute Order](/docs/ultra-api/execute-order) | + +servers: + - url: https://lite-api.jup.ag/ultra/v1 + description: Free tier API endpoint with rate limits + - url: https://api.jup.ag/ultra/v1 + description: Paid tier API endpoint with higher rate limits to be used with an API Key + +paths: + /order: + get: + summary: order + description: | + Request for a base64-encoded unsigned swap transaction to be used in `POST /ultra/v1/execute` + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + mode: + type: string + inputMint: + type: string + outputMint: + type: string + inAmount: + type: string + outAmount: + type: string + otherAmountThreshold: + type: string + swapMode: + type: string + slippageBps: + type: number + inUsdValue: + type: number + outUsdValue: + type: number + priceImpact: + type: number + swapUsdValue: + type: number + priceImpactPct: + type: string + description: | + - Please use `priceImpact` field instead, this is still available only for backwards compatibility + routePlan: + type: array + items: + type: object + properties: + swapInfo: + type: object + properties: + ammKey: + type: string + label: + type: string + inputMint: + type: string + outputMint: + type: string + inAmount: + type: string + outAmount: + type: string + feeAmount: + type: string + feeMint: + type: string + required: + - ammKey + - label + - inputMint + - outputMint + - inAmount + - outAmount + - feeAmount + - feeMint + percent: + type: number + required: + - swapInfo + - percent + feeMint: + type: string + feeBps: + type: number + prioritizationFeeLamports: + type: number + swapType: + type: string + description: | + - Deprecated, in favour of router + router: + type: string + enum: + - aggregator + - jupiterz + - hashflow + - dflow + - pyth + - okx + transaction: + type: string + nullable: true + description: | + - Unsigned base-64 encoded transaction to be signed and used in `/execute` + - If `taker` is null, this field will be null. Else, it will either be a valid base64 encoded transaction or the empty string + gasless: + type: boolean + requestId: + description: | + - Required to make a request to `/execute` + type: string + totalTime: + type: number + taker: + type: string + nullable: true + quoteId: + type: string + maker: + type: string + expireAt: + type: string + platformFee: + type: object + properties: + amount: + type: string + feeBps: + type: number + required: + - amount + - feeBps + errorMessage: + type: string + description: | + - This field will be present if `taker` is defined and `transaction` is the empty string + required: + - mode + - inputMint + - outputMint + - inAmount + - outAmount + - otherAmountThreshold + - priceImpactPct + - swapMode + - slippageBps + - routePlan + - feeBps + - prioritizationFeeLamports + - swapType + - router + - transaction + - gasless + - requestId + - totalTime + - taker + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + '500': + description: Internal server error + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + parameters: + - in: query + name: inputMint + schema: + type: string + required: true + - in: query + name: outputMint + schema: + type: string + required: true + - in: query + name: amount + schema: + type: string + required: true + - in: query + name: taker + schema: + type: string + required: false + - in: query + name: referralAccount + schema: + type: string + required: false + - in: query + name: referralFee + schema: + type: number + minimum: 50 + maximum: 255 + required: false + - in: query + name: excludeRouters + schema: + type: string + enum: + - metis + - jupiterz + - hashflow + - dflow + - pyth + - okx + required: false + - in: query + name: excludeDexes + description: | + - [Full list of DEXes here](https://lite-api.jup.ag/swap/v1/program-id-to-label), for example: `excludeDexes=Raydium,Orca+V2,Meteora+DLMM` + - **Important**: This only excludes DEXes on the Metis router, does not apply to other routers + - For example: + - **Exclude** Raydium: `excludeRouters=` and `excludeDexes=Raydium` + - **Only include** Meteora DLMM: `excludeRouters=` and `excludeDexes=` + schema: + type: string + /execute: + post: + summary: execute + description: | + Execute the signed transaction and get the execution status + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + status: + type: string + enum: + - Success + - Failed + signature: + type: string + slot: + type: string + error: + type: string + code: + type: number + totalInputAmount: + type: string + totalOutputAmount: + type: string + inputAmountResult: + type: string + outputAmountResult: + type: string + swapEvents: + type: array + items: + type: object + properties: + inputMint: + type: string + inputAmount: + type: string + outputMint: + type: string + outputAmount: + type: string + required: + - inputMint + - inputAmount + - outputMint + - outputAmount + required: + - status + - code + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: string + code: + type: number + required: + - error + - code + '500': + description: Internal server error + content: + application/json: + schema: + type: object + properties: + error: + type: string + code: + type: number + required: + - error + - code + requestBody: + content: + application/json: + schema: + type: object + properties: + signedTransaction: + type: string + description: | + - The signed transaction to execute + requestId: + type: string + description: | + - Found in response of `/order` + required: + - signedTransaction + - requestId + /balances/{address}: + get: + summary: balances + description: | + Request for token balances of an account + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + additionalProperties: + type: object + properties: + amount: + type: string + uiAmount: + type: number + slot: + type: number + isFrozen: + type: boolean + required: + - amount + - uiAmount + - slot + - isFrozen + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + '500': + description: Internal server error + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + parameters: + - schema: + type: string + in: path + name: address + required: true + /shield: + get: + summary: shield + description: | + Request for token information and warnings of mints + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + warnings: + type: object + additionalProperties: + description: | + - Token mint address as key + type: array + items: + type: object + properties: + type: + type: string + enum: + - NOT_VERIFIED + - LOW_LIQUIDITY + - NOT_SELLABLE + - LOW_ORGANIC_ACTIVITY + - HAS_MINT_AUTHORITY + - HAS_FREEZE_AUTHORITY + - HAS_PERMANENT_DELEGATE + - NEW_LISTING + - VERY_LOW_TRADING_ACTIVITY + - HIGH_SUPPLY_CONCENTRATION + - NON_TRANSFERABLE + - MUTABLE_TRANSFER_FEES + - SUSPICIOUS_DEV_ACTIVITY + - SUSPICIOUS_TOP_HOLDER_ACTIVITY + - HIGH_SINGLE_OWNERSHIP + - "{}%_TRANSFER_FEES" + description: | + - Type of warning for the token + message: + type: string + description: | + - Human-readable warning message + severity: + type: string + enum: + - info + - warning + - critical + description: | + - Severity level of the warning + source: + type: string + enum: + - RugCheck + description: | + - Optional external source of the warning + required: + - warnings + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + '500': + description: Internal server error + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + parameters: + - in: query + name: mints + schema: + type: string + required: true + description: | + - Comma separated list of mints to get information for + /order/routers: + get: + summary: routers + description: | + Request for the list of routers available in the routing engine of Ultra, which is [Juno](/docs/routing#juno-liquidity-engine) + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: array + items: + type: object + properties: + id: + type: string + name: + type: string + enum: + - Metis v1.6 + - JupiterZ + - Hashflow + - DFlow + - Pyth Express Relay + - OKX DEX Router + icon: + type: string + required: + - id + - name + /search: + get: + summary: search + description: | + Request a search by token's symbol, name or mint address + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: array + items: + "$ref": "#/components/schemas/MintInformation" + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + '500': + description: Internal server error + content: + application/json: + schema: + type: object + properties: + error: + type: string + required: + - error + parameters: + - in: query + name: query + schema: + type: string + required: true + description: | + - Search for a token and its information by its symbol, name or mint address + - Comma-separate to search for multiple + - Limit to 100 mint addresses in query + - Default to 20 mints in response when searching via symbol or name + +components: + schemas: + MintInformation: + type: object + properties: + id: + type: string + description: The token's mint address + name: + type: string + symbol: + type: string + icon: + type: string + nullable: true + decimals: + type: number + twitter: + type: string + nullable: true + telegram: + type: string + nullable: true + website: + type: string + nullable: true + dev: + type: string + nullable: true + description: The token's developer address + circSupply: + type: number + nullable: true + totalSupply: + type: number + nullable: true + tokenProgram: + type: string + description: The token program address + launchpad: + type: string + nullable: true + partnerConfig: + type: string + nullable: true + graduatedPool: + type: string + nullable: true + graduatedAt: + type: string + nullable: true + holderCount: + type: number + nullable: true + fdv: + type: number + nullable: true + mcap: + type: number + nullable: true + usdPrice: + type: number + nullable: true + priceBlockId: + type: number + nullable: true + liquidity: + type: number + nullable: true + stats5m: + $ref: "#/components/schemas/SwapStats" + nullable: true + stats1h: + $ref: "#/components/schemas/SwapStats" + nullable: true + stats6h: + $ref: "#/components/schemas/SwapStats" + nullable: true + stats24h: + $ref: "#/components/schemas/SwapStats" + nullable: true + firstPool: + type: object + nullable: true + properties: + id: + type: string + createdAt: + type: string + audit: + type: object + nullable: true + properties: + isSus: + type: boolean + nullable: true + mintAuthorityDisabled: + type: boolean + nullable: true + freezeAuthorityDisabled: + type: boolean + nullable: true + topHoldersPercentage: + type: number + nullable: true + devBalancePercentage: + type: number + nullable: true + devMigrations: + type: number + nullable: true + organicScore: + type: number + organicScoreLabel: + type: string + enum: [high, medium, low] + isVerified: + type: boolean + nullable: true + cexes: + type: array + items: + type: string + nullable: true + tags: + type: array + items: + type: string + nullable: true + updatedAt: + type: string + format: date-time + SwapStats: + type: object + properties: + priceChange: + type: number + nullable: true + holderChange: + type: number + nullable: true + liquidityChange: + type: number + nullable: true + volumeChange: + type: number + nullable: true + buyVolume: + type: number + nullable: true + sellVolume: + type: number + nullable: true + buyOrganicVolume: + type: number + nullable: true + sellOrganicVolume: + type: number + nullable: true + numBuys: + type: number + nullable: true + numSells: + type: number + nullable: true + numTraders: + type: number + nullable: true + numOrganicBuyers: + type: number + nullable: true + numNetBuyers: + type: number + nullable: true diff --git a/mintlify-migration/docs/perp-api/custody-account.mdx b/mintlify-migration/docs/perp-api/custody-account.mdx new file mode 100644 index 00000000..d34f1cc3 --- /dev/null +++ b/mintlify-migration/docs/perp-api/custody-account.mdx @@ -0,0 +1,62 @@ +--- +title: "Custody Account" +description: "This page contains an overview of the used in the Jupiter Perpetuals Program, and specifically the account." +--- + +The `Custody` account is a struct which represents a set of parameters and states associated to custodies (tokens) managed by the JLP pool which consists of the following custodies. + +| Custodies | | | | | +| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| [SOL](https://solscan.io/account/7xS2gz2bTp3fwCC7knJvUWTEU9Tycczu6VhJYKgi1wdz) | [ETH](https://solscan.io/account/AQCGyheWPLeo6Qp9WpYS9m3Qj479t7R636N9ey1rEjEn) | [BTC](https://solscan.io/account/5Pv3gM9JrFFH883SWAhvJC9RPYmo8UNxuFtv5bMMALkm) | [USDC](https://solscan.io/account/G18jKKXQwBbrHeiK3C9MRXhkHsLHf7XgCSisykV46EZa) | [USDT](https://solscan.io/account/4vkNeXiYEUizLdrpdPS1eC2mccyM4NUPRtERrk6ZETkk) | + + + This [repository](https://github.com/julianfssen/jupiter-perps-anchor-idl-parsing) contains Typescript code samples on interacting with the Jupiter Perpetuals program IDL with `anchor` and `@solana/web3.js` + + You can also find the [Custody Account fields in the repository](https://github.com/julianfssen/jupiter-perps-anchor-idl-parsing/blob/1a0b5dc71081958895691047a9aa8ba51d2a8765/src/idl/jupiter-perpetuals-idl.ts#L2397) or on a [blockchain explorer](https://solscan.io/account/PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu#anchorProgramIdl). + + +## Account Details + +Each `Custody` account contains the following data: + +| Field | Description | +| :------------------ | :------------------------------------------------------------------------------------------------------------------------------ | +| `pool` | **Type:** `publicKey`

The public key for the pool that this custody belongs to (i.e. the JLP pool). | +| `mint` | **Type:** `publicKey`

The public key for the custody's token mint account. | +| `tokenAccount` | **Type:** `publicKey`

The associated token account of the custody which holds the tokens under management for the pool. | +| `decimals` | **Type:** `u8`

The number of decimals used for the token which is the same as the number of decimals specified in the token mint account. This is stored for convenience. | +| `isStable` | **Type:** `bool`

A boolean flag indicating if the token in custody is a stable asset. | +| `oracle` | **Type:** `OracleParams`

Contains data for the price oracle used for the custody. | +| `pricing` | **Type:** [`PricingParams`](#pricingparams)

Contains data for the custody's price-related logic. | +| `permissions` | **Type:** `Permissions`

A set of global flags that can be set by the protocol's administrator to enable or disable trade actions which is useful during program upgrades or black swan events. | +| `targetRatioBps` | **Type:** `u64`

The target weightage (in basis points) for the custody in the JLP pool. | +| `assets` | **Type:** [`Assets`](#assets)

Contains data used to calculate PNL, AUM, and core business logic for the program. | +| `fundingRateState` | **Type:** [`FundingRateState`](#fundingratestate)

Contains data used to calculate borrow fees for open positions. | + +### `PricingParams` + +| Field | Description | +| :--------------------- | :----------------------------------------------------------------------------------------------------- | +| `tradeImpactFeeScalar` | **Type:** `u64`

Sets the base value when calculating price impact fees when opening or closing positions. | +| `maxLeverage` | **Type:** `u64`

Sets the max leverage for this custody's positions. The max leverage for all custodies is 500x at the time of writing. | +| `maxGlobalLongSizes` | **Type:** `u64`

The maximum total position size (USD) for long positions. | +| `maxGlobalShortSizes` | **Type:** `u64`

The maximum total position size (USD) for short positions. | + +### `Assets` + +| Field | Description | +| :-------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `feesReserves` | **Type:** `u64`

The fees collected by all open positions for the custody. `feesReserves` resets to zero when the fees are distributed to the pool and protocol. | +| `owned` | **Type:** `u64`

The number of tokens owned by the pool for the custody.
- The owned value is increased either by providing liquidity to the pool or depositing collateral when opening or updating positions.
- Conversely, the owned value decreases when liquidity is removed from the pool or collateral is withdrawn from closing positions. | +| `locked` | **Type:** `u64`

The number of tokens locked by the pool for the custody to pay off potential profits for open positions. | +| `guaranteedUsd` | **Type:** `u64`

This value represents the total amount borrowed in USD (position size - collateral) across all long positions.

It is updated whenever traders modify their collateral through deposits or withdrawals. The system uses this aggregated figure to efficiently calculate the total profit and loss (PNL) for all long positions, which in turn is used to calculate the AUM of the JLP pool. | +| `globalShortSizes` | **Type:** `u64`

Stores the total amount (USD) position sizes for all short positions. | +| `globalShortAveragePrices` | **Type:** `u64`

Stores the average price (USD) for all short positions.

This value and `globalShortSizes` are used to calculate the PNL for all short positions efficiently, and is again used to calculate the AUM of the JLP pool. | + +### `FundingRateState` + +| Field | Description | +| :------------------------| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `cumulativeInterestRate` | **Type:** `u128`

Traders are required to pay hourly borrow fees for opening leveraged positions. This fee is calculated based on two primary factors: the size of the trader's position and the current utilization of the pool for the custody.

To calculate borrow fees more efficiently, each custody account contains a value called `cumulativeInterestRate`.

Correspondingly, each position account stores a `cumulativeInterestSnapshot` which captures the value of `cumulativeInterestRate` at the time of the position's last update. Whenever there's a change in either the borrowed assets or the total assets within a custody, the `cumulativeInterestRate` for the custody is updated. The difference between the custody's `cumulativeInterestRate` and the position's `cumulativeInterestSnapshot` is then used to calculate the position's borrow fees. | +| `lastUpdate` | **Type:** `i64`

The UNIX timestamp for when the custody's borrow fee data was last updated. | +| `hourlyFundingDbps` | **Type:** `u64`

A constant used to calculate the hourly borrow fees for the custody. The Jupiter Perpetuals exchange works with Gauntlet and Chaos Labs to update and fine tune the `hourlyFundingDbps` to respond to traders' feedback and market conditions. | diff --git a/mintlify-migration/docs/perp-api/pool-account.mdx b/mintlify-migration/docs/perp-api/pool-account.mdx new file mode 100644 index 00000000..3edd8528 --- /dev/null +++ b/mintlify-migration/docs/perp-api/pool-account.mdx @@ -0,0 +1,62 @@ +--- +title: "Pool Account" +description: "This page contains an overview of the used in the Jupiter Perpetuals Program, and specifically the account." +--- + +The `Pool` account is a struct which represents a set of parameters and states associated to the data for JLP pool, including AUM and [`Custody`](/docs/perp-api/custody-account) data. + + + **ONLY ONE POOL ACCOUNT** + + There is only one [`Pool` account](https://solscan.io/account/5BUwFW4nRbftYTDMbgxykoFWqWHPzahFSNAaaaJtVKsq). + + + + **EXAMPLE TYPESCRIPT REPOSITORY** + + This [repository](https://github.com/julianfssen/jupiter-perps-anchor-idl-parsing) contains Typescript code samples on interacting with the Jupiter Perpetuals program IDL with `anchor` and `@solana/web3.js` + + You can also find the [Custody Account fields in the repository](https://github.com/julianfssen/jupiter-perps-anchor-idl-parsing/blob/1a0b5dc71081958895691047a9aa8ba51d2a8765/src/idl/jupiter-perpetuals-idl.ts#L2699) or on a [blockchain explorer](https://solscan.io/account/PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu#anchorProgramIdl). + + +## Account Details + +Each `Pool` account contains the following data: + +| Field | Description | +| :---------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | **Type:** `string`

The name for the account. | +| `custodies` | **Type:** `publicKey`

An array containing the public keys for the custodies (tokens) managed by the JLP pool. | +| `aumUsd` | **Type:** `u128`

The current AUM value (USD) for the JLP pool. The `aumUsd` value's calculation can be summarized by getting the USD value of the tokens managed by the pool minus the USD value reserved to pay off trader profits.

Refer to the [Custody account](/docs/perp-api/custody-account) details for more details on AUM calculation. | +| `limit` | **Type:** [`Limit`](#limit)

Contains values for the pool's limits. | +| `fees` | **Type:** [`Fees`](#fees)

Sets the fee amounts or percentages for the Jupiter Perpetuals exchange. | +| `poolApr` | **Type:** [`PoolApr`](#poolapr)

Contains data related to the pool's APR / APY calculations. | + +### `Limit` + +| Field | Description | +| :------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `maxAumUsd` | **Type:** `u128`

The max AUM for the JLP pool. This acts as a max cap / ceiling as the JLP will not accept deposits when the cap is hit. | +| `tokenWeightageBufferBps` | **Type:** `u128`

The token weightage buffer (in basis points) to calculate the token's maximum or minimum current weightage based on the target weightage.

Currently, `tokenWeightageBufferBps` is set to `2000` which means the the current weightage cannot be lower or higher than + / - 20% of the token's target weightage.

For example, if SOL's target weightage for the JLP pool is 50%, the current weightage cannot be less than 40% or exceed 60%. The pool will not allow deposits or withdrawals if the action causes the token to exceed its target weightage. | +| `maxPositionUsd` | **Type:** `u64`

Sets the maximum position size. The current `maxPositionUsd` value is `2_500_000_000_000` which means a position's max size is $2,500,000. | + +### `Fees` + +| Field | Description | +| :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `increasePositionBps` | **Type:** `string`

A fixed fee of 6 BPS (0.06%) is charged for opening or increasing a position. | +| `decreasePositionBps` | **Type:** `publicKey`

A fixed fee of 6 BPS (0.06%) is charged for closing or decreasing a position. | +| `addRemoveLiquidityBps` | **Type:** `u128`

Fee charged when adding or removing liquidity to/from the pool. | +| `swapBps` | **Type:** `Limit`

Swap fee for exchanging non-stablecoin tokens routed through the liquidity pool. `swap fee = swapBps ± swapTaxBps` | +| `taxBps` | **Type:** `PoolApr`

Tax fee for non-stablecoins, determined based on the difference between the current and target weightage. A larger difference results in a higher tax fee, encouraging liquidity providers to rebalance the pool to the target weightage. | +| `stableSwapBps` | **Type:** `Limit`

Swap fee for exchanges involving stablecoins, routed through the liquidity pool. `swap fee = stableSwapBps ± stableSwapTaxBps` | +| `stableSwapTaxBps` | **Type:** `Fees`

Tax fee for stablecoin swaps. Similar to taxBps, this fee is determined by the difference between the current and target weightage. | +| `protocolShareBps` | **Type:** `PoolApr`

Jupiter takes a share of 2500 BPS (25%) from the fees collected by the pool. | + +### `PoolApr` + +| Field | Description | +| :--------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `lastUpdated` | **Type:** `i64`

The UNIX timestamp when the pool's APR data was last updated. | +| `feeAprBps` | **Type:** `u64`

The pool's APR in BPS format. The APR is calculated weekly by dividing the pool's realized fees (minus the 25% collected by the protocol) by the total pool value, adjusting for the 1 week time period to annualize the rate. | +| `realizedFeeUsd` | **Type:** `u64`

The fees collected by the pool so far. This fee is reinvested back into the pool and is also used to calculate the APR as mentioned above. realizedFeeUsd resets to zero when the fee is reinvested into the pool hence causing the APR value to fluctuate weekly. | diff --git a/mintlify-migration/docs/perp-api/position-account.mdx b/mintlify-migration/docs/perp-api/position-account.mdx new file mode 100644 index 00000000..cf51fd6c --- /dev/null +++ b/mintlify-migration/docs/perp-api/position-account.mdx @@ -0,0 +1,55 @@ +--- +title: "Position Account" +description: "This page contains an overview of the used in the Jupiter Perpetuals Program, and specifically the account." +--- + +The `Position` account is a struct which represents a set of parameters and states associated to trade position data for a given token. + + + **`Position` account derivation** + + The `Position` account's address is derived from the trader's wallet address / public key, the custody account, the collateral custody account, and a few other constant seeds. This means traders will always have the same Position account address for their open positions. + + This also means that traders only have nine positions available at one time: + + * Long SOL + * Long wETH + * Long wBTC + * Short SOL (USDC as collateral) + * Short SOL (USDT as collateral) + * Short wETH (USDC as collateral) + * Short wETH (USDT as collateral) + * Short wBTC (USDC as collateral) + * Short wBTC (USDT as collateral) + + This is an example [`Position` account](https://solscan.io/account/FBLzd5VM67MEKkoWerXu7Nu1ksbLXQvJDx63y5aeLEvt). + + + + **EXAMPLE TYPESCRIPT CODE** + + This [repository](https://github.com/julianfssen/jupiter-perps-anchor-idl-parsing) contains Typescript code samples on interacting with the Jupiter Perpetuals program IDL with `anchor` and `@solana/web3.js` + + You can also find the [Custody Account fields in the repository](https://github.com/julianfssen/jupiter-perps-anchor-idl-parsing/blob/1a0b5dc71081958895691047a9aa8ba51d2a8765/src/idl/jupiter-perpetuals-idl.ts#L2699) or on a [blockchain explorer](https://solscan.io/account/PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu#anchorProgramIdl). + + +## Account Details + +Each `Position` account contains the following data: + +| Field | Description | +| :---------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `owner` | **Type:** `publicKey`

The public key of the trader's account. | +| `pool` | **Type:** `publicKey`

The public key of the [JLP pool account](/docs/perp-api/pool-account). | +| `custody` | **Type:** `publicKey`

The public key of the position's [`custody` account](/docs/perp-api/custody-account). | +| `collateralCustody` | **Type:** `publicKey`

The public key of the position's collateral custody account.

Like the `custody` account, a `collateralCustody` account contains information for the token that's used as collateral for the position (SOL / wETH / wBTC for long positions, USDC / USDT for short positions).

The borrow rates for the position will also be calculated based on the position's `collateralCustody`. | +| `openTime` | **Type:** `i64`

The open time of the position in UNIX timestamp format. | +| `updateTime` | **Type:** `i64`

The last updated time of the position in UNIX timestamp format. | +| `side` | **Type:** `Side`

The position's side, either `long` or `short`. | +| `price` | **Type:** `u64`

The entry price of the position when it was opened. The entry price is an integer in the atomic value (before decimals), a USDC (6 decimals) value of `158225872` is equivalent to $158.22. | +| `sizeUsd` | **Type:** `u64`

The position size after leverage in USD in the atomic value (before decimals). A position with `sizeUsd = 0` is treated as a closed position. | +| `collateralUsd` | **Type:** `u64`

The position's collateral size after fees in USD in the atomic value (before decimals). | +| `realisedPnlUsd` | **Type:** `i64`

The position's realized PNL when closing the position partially.

When a position is closed completely, the position's `realisedPnlUsd` will be `0` as the position is considered closed (as described in `sizeUsd`). | +| `cumulativeInterestSnapshot` | **Type:** `u128`

Stores the position's interest rate snapshot when it was last updated.

- The `collateralCustody` account for the respective collateral token stores a monotonically increasing counter in `collateralCustody .fundingRateState .cumulativeInterestRate`.

- The difference between the `collateralCustody .fundingRateState .cumulativeInterestRate` and the position's `cumulativeInterestSnapshot` is used to calculate the borrow fees for the position. | +| `lockedAmount` | **Type:** `u64`

The amount of tokens (SOL / wETH / wBTC for long positions, USDC / USDT for short positions) locked to pay off the position's max potential profit. It acts as a cap on the maximum potential profit of the position. This amount is locked in the collateral custody to ensure the platform has sufficient tokens to pay out profitable trades. | +| `bump` | **Type:** `u8`

The bump seed used to derive the PDA for the `Position` account. | diff --git a/mintlify-migration/docs/perp-api/position-request-account.mdx b/mintlify-migration/docs/perp-api/position-request-account.mdx new file mode 100644 index 00000000..95921b7e --- /dev/null +++ b/mintlify-migration/docs/perp-api/position-request-account.mdx @@ -0,0 +1,70 @@ +--- +title: "PositionRequest Account" +description: "This page contains an overview of the used in the Jupiter Perpetuals Program, and specifically the account." +--- + +The `PositionRequest` account is a struct which represents a set of parameters and states associated to a request to open or close a position, the `PositionRequest` account consists of mostly similar properties as [`Position` account](/docs/perp-api/position-account). + + + **`PositionRequest` ACCOUNT DERIVATION** + + It is a Program-Derived Address (PDA) derived from the underlying `Position` account's address, several constant seeds, and a random integer seed which makes each `PositionRequest` account unique. + + The is an example [`PositionRequest` account](https://solscan.io/account/DNnX2B1oiYqKLrbLLod1guuaZA28DQwJ8HuHsgDafoQK). + + + + **`PositionRequestATA` ACCOUNT** + + A `PositionRequestATA` account is created for each `PositionRequest` account. + + The `PositionRequestATA` account is an [associated token account](https://spl.solana.com/associated-token-account) derived from the `PositionRequest` that contains the tokens from the trader's deposits or withdrawals from withdrawing collateral or closing positions. + + The tokens are then transferred to the position token's custody token account or returned to the trader's wallet when the `PositionRequestATA` account is closed. + + + + **TAKE PROFIT / STOP LOSS REQUESTS** + + `PositionRequest` accounts for non TP / SL requests are closed as soon as the request is executed or rejected. + + TP / SL requests are also stored onchain via `PositionRequest` accounts. However, they will only be closed when the TP / SL request is triggered and executed. + + Active TP / SL requests can be fetched onchain (through blockchain explorers like Solscan or SolanaFM) by searching for the `PositionRequest` address or public key associated with the TP / SL request. + + + + **EXAMPLE TYPESCRIPT REPOSITORY** + + This [repository](https://github.com/julianfssen/jupiter-perps-anchor-idl-parsing) contains Typescript code samples on interacting with the Jupiter Perpetuals program IDL with `anchor` and `@solana/web3.js` + + You can also find the [Custody Account fields in the repository](https://github.com/julianfssen/jupiter-perps-anchor-idl-parsing/blob/1a0b5dc71081958895691047a9aa8ba51d2a8765/src/idl/jupiter-perpetuals-idl.ts#L2583) or on a [blockchain explorer](https://solscan.io/account/PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu#anchorProgramIdl). + + +## Account Details + +Each `PositionRequest` account contains the following data: + +| Field | Description | +| :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `owner` | **Type:** `publicKey`

The public key of the trader's account. | +| `pool` | **Type:** `publicKey`

The public key of the [JLP pool account](/docs/perp-api/pool-account). | +| `custody` | **Type:** `publicKey`

The public key of the position's [`custody` account](/docs/perp-api/custody-account). | +| `collateralCustody` | **Type:** `publicKey`

The public key of the position's collateral custody account.

Like the `custody` account, a `collateralCustody` account contains information for the token that's used as collateral for the position (SOL / wETH / wBTC for long positions, USDC / USDT for short positions). The borrow rates for the position will also be calculated based on the position's `collateralCustody`. | +| `mint` | **Type:** `publicKey`

For opening positions and collateral deposits, mint refers to the input mint requested by the trader.

For example, if a trader opens a position by providing the initial margin with SOL, then mint will be equal to SOL's mint address. If the trader deposits collateral in USDC, then mint will be equal to USDC's mint address.

For closing positions and collateral withdrawals, mint is equal the to position collateral token's mint address. For example, if a trader closes a long SOL position, mint will be equal to SOL's mint address. If a trader closes a short SOL position, mint is equal to USDC or USDT's mint address depending on the position's collateral. | +| `openTime` | **Type:** `i64`

The time when the request of position is created in UNIX timestamp format. | +| `updateTime` | **Type:** `i64`

The time when the request of position is last updated in UNIX timestamp format. | +| `sizeUsdDelta` | **Type:** `u64`

The USD amount to increase or decrease the position size by. The amount is an integer in the atomic value (before decimals which is 6 for USDC / UST mints).

For example, a position request to increase an open position's size by 10 USDC will have a `sizeUsdDelta = 10000000`. | +| `collateralDelta` | **Type:** `u64`

For opening positions and collateral deposits, `collateralDelta` is the token amount to increase or decrease the position collateral size by. The token amount is represented in atomic values (before decimals). | +| `requestChange` | **Type:** `RequestChange`

`requestChange` will be equal to `Increase` for open position and collateral deposit requests, and `Decrease` for close position and collateral withdrawal requests. | +| `requestType` | **Type:** `RequestType`

`Market` for all position requests except for TP / SL requests, which have a different `requestType` known as `Trigger`. | +| `side` | **Type:** `Side`

`Long` for long positions, `Short` for short positions | +| `priceSlippage` | **Type:** `u64`

The maximum price with slippage for position requests when opening, closing, or updating the position size.

- When increasing the size of a long position or decreasing the size of a short position, the request will fail if the current price of the position's token is greater than `priceSlippage`.

- When decreasing the size of a long position or increasing the size of a short position, the request will fail if `priceSlippage` is greater than the current price of the position's token. | +| `jupiterMinimumOut` | **Type:** `u64`

For requests that require token swaps, the output amount of the token swap must be greater than or equal to `jupiterMinimumOut`, else the request will fail. | +| `preSwapAmount` | **Type:** `u64`

This is an internal attribute used by the program to calculate the `collateralDelta` for position requests that require token swaps. | +| `triggerPrice` | **Type:** `u64`

The price (USD) used for TP / SL position requests. | +| `triggerAboveThreshold` | **Type:** `bool`

When `triggerAboveThreshold` is true, the TP / SL position request will be triggered when the position's token price is greater than or equal to `triggerPrice`. When `triggerAboveThreshold` is false, the TP / SL position request will be triggered when the position's token price is less than or equal to `triggerPrice`. | +| `entirePosition` | **Type:** `bool`

This attribute is only checked when closing or decreasing position sizes. When `entirePosition` is true, the entire position will be closed (i.e. a close position request). When `entirePosition` is false, the position size will be reduced according to sizeUsdDelta. | +| `executed` | **Type:** `bool`

Determines whether the position request is executed or not. | +| `counter` | **Type:** `u64`

The random integer seed used to derive the position request address. | +| `bump` | **Type:** `u8`

The bump seed used to derive the position request address. | diff --git a/mintlify-migration/docs/prep-api.mdx b/mintlify-migration/docs/prep-api.mdx new file mode 100644 index 00000000..33f38127 --- /dev/null +++ b/mintlify-migration/docs/prep-api.mdx @@ -0,0 +1,20 @@ +--- +title: "About Perp API" +--- + + + **WARNING** + + The Perp API is still a **work in progress**, stay tuned! + + + + **TIP** + + In the meantime, you can use this amazing github repository to direct Anchor IDL parse the Perp Program. + + * Fetch Perp or JLP pool data + * Interact with the Perp Program + + [https://github.com/julianfssen/jupiter-perps-anchor-idl-parsing](https://github.com/julianfssen/jupiter-perps-anchor-idl-parsing) + diff --git a/mintlify-migration/docs/price-api.mdx b/mintlify-migration/docs/price-api.mdx new file mode 100644 index 00000000..6212f9a1 --- /dev/null +++ b/mintlify-migration/docs/price-api.mdx @@ -0,0 +1,43 @@ +--- +title: "About Price API" +description: "The Jupiter Price API aims to be the source of truth of token prices across all Jupiter UIs and integrator platforms, providing a seamless experience for developers and a reliable and accurate price source for users." +--- + + + **DEPRECATED** + + [Price API V2](/docs/price-api/v2) will be/is deprecated by 1 August 2025. + + Please migrate to [Price API V3](/docs/price-api/v3) which consists of breaking changes. + + +## Challenges + +Accurately pricing tokens on-chain is deceptively complex. Unlike traditional markets with centralized pricing mechanisms and consistent liquidity, decentralized finance (DeFi) presents a set of dynamic and often adversarial conditions. The Price API V3 is built with these realities in mind, abstracting away challenges to deliver accurate, real-time token prices with integrity and consistency. + +| Challenge | Description | +| :--- | :--- | +| **Gamification of Price** | In decentralized environments, token prices can be manipulated or "gamed" for appearances or exploitative purposes. Common patterns include:
* Wash trading to inflate volume or imply activity
* Circular swaps to fabricate higher valuations | +| **Fragmented, Volatile or Imbalanced Liquidity Across Venues** | Liquidity on Solana (and other chains) is spread across numerous protocols and AMMs. No single source can represent the entire market. Different pools might have wildly different pricing and can change very quickly. | +| **Low Liquidity Tokens** | Some tokens trade rarely or only within shallow pools. In such cases, even small orders can cause large price swings, making pricing unreliable. | + +## How Price is Derived + +The latest version of Price API is V3 - which uses the **last swapped price (across all transactions)**. The swaps are priced by working outwards from a small set of reliable tokens (like SOL) whose price we get from external oracle sources. + +While and also after deriving the last swap price, we also utilize a number of heuristics to ensure the accuracy of the price and eliminate any outliers: + +* Asset origin and launch method +* Market liquidity metrics +* Market behaviour patterns +* Holder distribution statistics +* Trading activity indicators +* Market value to liquidity ratios + +:::caution +When using Price API, do note that you may face many tokens where price is not available or returns null. + +This is because, we use the aforementioned heuristics to determine the price of a token and if the price is reliable - if certain combinations of these factors indicate potential issues with price reliability or market health, the token will be flagged and not provided a price. + +This is to safeguard users and prevent an inaccurate price from being returned. +::: \ No newline at end of file diff --git a/mintlify-migration/docs/price-api/v2.mdx b/mintlify-migration/docs/price-api/v2.mdx new file mode 100644 index 00000000..fe60bb38 --- /dev/null +++ b/mintlify-migration/docs/price-api/v2.mdx @@ -0,0 +1,228 @@ +--- +title: "Price API V2 (Deprecated)" +sidebarTitle: "V2 (Deprecated)" +description: "Price API V2 aims to enhance accuracy by incorporating both **buy** and **sell-side liquidity** to derive the **average price** of the two." +--- + + + **DEPRECATED** + + This version of the Price API V2 will be/is deprecated by 30th September 2025. + + Please migrate to [Price API V3](/docs/price-api/v3) which consists of breaking changes. + + +This provides more reliable real-time data for SPL tokens. Additionally, V2 provides extra help information like depth and confidence to aid you or your users with decisions. + + + **TIP** + + The prices are derived **from Jupiter Swap**, which is an aggregate of most markets on Solana. + + +## Let’s Get Started + +In this guide, we will be going through the simple price responses and the extra help information. + +## Get Price (Only Price) + +Using the root URL and parameters to pass in, it is as simple as the example code below! + +Notice the `ids` parameter with the public key or token address of a token mint, you can also input more than 1 address by comma-separating them. + +#### Price vs USDC by default + +```js +const priceResponse = await fetch( + 'https://lite-api.jup.ag/price/v2?ids=JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN,So11111111111111111111111111111111111111112' +); + +const priceData = await priceResponse.json(); + +console.log(priceData); +``` + +#### Price vsToken + +```js +console.log(JSON.stringify(priceData, null, 2)); + +const priceResponseWithVsToken = await fetch( + 'https://lite-api.jup.ag/price/v2?ids=JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN,So11111111111111111111111111111111111111112&vsToken=So11111111111111111111111111111111111111112' +); + +const priceDataWithVsToken = await priceResponseWithVsToken.json(); + +console.log(JSON.stringify(priceDataWithVsToken, null, 2)); +``` + +From the above example, you should see this response. + +Notice 2 details here: + +* Usage of `vsToken`: The first set of data shows price denoted in USDC while the second set of data denotes in the price of SOL. +* With no `showExtraInfo`: There is only 1 price, the derived price is the buy price. + +```json expandable +{ + "data": { + "So11111111111111111111111111111111111111112": { + "id": "So11111111111111111111111111111111111111112", + "type": "derivedPrice", + "price": "210.195311500" + }, + "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN": { + "id": "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN", + "type": "derivedPrice", + "price": "1.084247" + } + }, + "timeTaken": 0.00488491 +} +{ + "data": { + "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN": { + "id": "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN", + "type": "derivedPrice", + "price": "0.005158283466279884" + }, + "So11111111111111111111111111111111111111112": { + "id": "So11111111111111111111111111111111111111112", + "type": "derivedPrice", + "price": "1" + } + }, + "timeTaken": 0.00203215 +} +``` + +## Get Price (with Extra Info) + +To get extra help information such as confidence level or depth, you will need to pass in `showExtraInfo=true`. However, do note that if this is set to `true`, you will not be able to apply `vsToken`. + +```js +const priceResponseShowExtraInfo = await fetch( + 'https://lite-api.jup.ag/price/v2?ids=JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN,So11111111111111111111111111111111111111112&showExtraInfo=true' +); + +const priceDataShowExtraInfo = await priceResponseShowExtraInfo.json(); + +console.log(JSON.stringify(priceDataShowExtraInfo, null, 2)); +``` + +Here is the sample response. + +Notice a few details here: + +* You can see both last swap and current quote prices. +* You can see both buy and sell prices of the different types. +* You can see the unix timestamps. +* You can see the confidence and depth information. + +```json expandable +{ + "data": { + "So11111111111111111111111111111111111111112": { + "id": "So11111111111111111111111111111111111111112", + "type": "derivedPrice", + "price": "210.734462500", + "extraInfo": { + "lastSwappedPrice": { + "lastJupiterSellAt": 1731599242, + "lastJupiterSellPrice": "210.52136418853988", + "lastJupiterBuyAt": 1731599242, + "lastJupiterBuyPrice": "210.5553945976539" + }, + "quotedPrice": { + "buyPrice": "210.578367000", + "buyAt": 1731599236, + "sellPrice": "210.890558000", + "sellAt": 1731599236 + }, + "confidenceLevel": "high", + "depth": { + "buyPriceImpactRatio": { + "depth": { + "10": 0.08186978526745424, + "100": 0.1154072102743595, + "1000": 0.13766677800178445 + }, + "timestamp": 1731599207 + }, + "sellPriceImpactRatio": { + "depth": { + "10": 0.1211367007033883, + "100": 0.059088081285986374, + "1000": 0.16445602954342006 + }, + "timestamp": 1731599207 + } + } + } + }, + "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN": { + "id": "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN", + "type": "derivedPrice", + "price": "1.088080", + "extraInfo": { + "lastSwappedPrice": { + "lastJupiterSellAt": 1731599239, + "lastJupiterSellPrice": "1.0857748923629837", + "lastJupiterBuyAt": 1731599241, + "lastJupiterBuyPrice": "1.0879206578017573" + }, + "quotedPrice": { + "buyPrice": "1.088085", + "buyAt": 1731599236, + "sellPrice": "1.088076", + "sellAt": 1731599236 + }, + "confidenceLevel": "high", + "depth": { + "buyPriceImpactRatio": { + "depth": { + "10": 0.05662764967204097, + "100": 0.17463135504551536, + "1000": 0.7379832960897882 + }, + "timestamp": 1731599207 + }, + "sellPriceImpactRatio": { + "depth": { + "10": 0.03504801758790863, + "100": 0.16858843747627028, + "1000": 3.0578377037958586 + }, + "timestamp": 1731599207 + } + } + } + } + }, + "timeTaken": 0.003665979 +} +``` + +## Limitations + +**Query limits** + +1. You can query up to 100 `id`s at once. + +**If the price for a token cannot be found, it is either because** + +1. The token is not tradable on Jupiter - it does not fit Jupiter’s routing criteria. +2. There is no route for this token to SOL. +3. `sellPrice`, `sellAt` & `lastSwappedPrice` might be null in cases +4. If `sellPrice` & `sellAt` is not cached and cannot be retrieved the provided information will be `buyPrice`. +5. `lastSwappedPrice` might be null if the token has not been traded recently or cannot be retrieved. +6. Tokens that have not been traded via USDC in the last 3 days. +7. Note that this is only for swaps done via Jupiter, it will not be done for swaps done e.g. directly on Raydium’s platform + +**`buyPriceImpactRatio` & `sellPriceImpactRatio` in the depth field might be null in cases** + +1. We are to get the respective price impacts for the 10, 100 and 1000 SOL buys or sells +2. It could be because the token’s liquidity does not have enough liquidity for larger values +3. We cannot find the sell quote for the respective token and the buy/sell values + + diff --git a/mintlify-migration/docs/price-api/v3.mdx b/mintlify-migration/docs/price-api/v3.mdx new file mode 100644 index 00000000..d633384c --- /dev/null +++ b/mintlify-migration/docs/price-api/v3.mdx @@ -0,0 +1,94 @@ +--- +title: "Price API V3 (Beta)" +sidebarTitle: "V3 (Beta)" +description: "Price API V3 aims to provide a one source of truth across all Jupiter UIs and integrator platforms. The simplified format allows easy integration while letting Jupiter handle the complexity of ensuring the accuracy of the provided prices." +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/price/v3` + * Pro URL: `https://api.jup.ag/price/v3` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + + + **INFO** + + This is in Beta and subject to changes, if you need help please reach out to us in [Discord](https://discord.gg/jup) + + +## How Price is Derived + +Price API V3 price tokens by using the **last swapped price (across all transactions)**. The swaps are priced by working outwards from a small set of reliable tokens (like SOL) whose price we get from external oracle sources. + +While and also after deriving the last swap price, we also utilize a number of heuristics to ensure the accuracy of the price and eliminate any outliers: + +* Asset origin and launch method +* Market liquidity metrics +* Market behaviour patterns +* Holder distribution statistics +* Trading activity indicators +* [Organic Score](/docs/token-api/organic-score) + +## Get Price + +Simply request via the base URL with the query parameters of your desired mint addresses. You can also comma-separate them to request for multiple prices. + +```js +const price = await ( + await fetch( + 'https://lite-api.jup.ag/price/v3?ids=So11111111111111111111111111111111111111112,JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN' + ) +).json(); +console.log(JSON.stringify(price, null, 2)); +``` + +## Price Response + +Here is the sample response, notice a few details here: + +* The `usdPrice` is the only price. +* The `decimals` response is helpful to display price information on the UI. +* The `blockId` can be used to verify the recency of the price. + +```js +{ + "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN": { + "usdPrice": 0.4056018512541055, + "blockId": 348004026, + "decimals": 6, + "priceChange24h": 0.5292887924920519 + }, + "So11111111111111111111111111111111111111112": { + "usdPrice": 147.4789340738336, + "blockId": 348004023, + "decimals": 9, + "priceChange24h": 1.2907622140620008 + } +} +``` + +## Limitations + +**Query limits** + +* You can query up to 50 `ids` at once. + +**If the price of a token cannot be found** + +* Typically, it is likely that the token has not been traded recently - in the last 7 days. +* Additionally, we also use the aforementioned heuristics to determine the price of a token and if the price is reliable - if certain combinations of these factors indicate potential issues with price reliability or market health, the token will be flagged and not provided a price. +* The token is flagged as suspicious and this can be cross referenced with the Token API V2's `audit.isSus` field. + +**V2 had more information** + +* Yes V2 had more information, however, we think that it is not the best representation of price and it also caused different interpretations of price across the different platforms. +* With Price API V3, we are handling the complexities to ensure price accuracy and elimate outliers [using the heuristics as mentioned above](#how-price-is-derived), so there will only be one stable and accurate price source for all. +* If you require more information like Price API V2, you can use the `/quote` endpoint of the Swap API to derive those data ([you can refer to this post about how Price API V2 is derived](https://www.jupresear.ch/t/introducing-the-price-v2-api/22175)). diff --git a/mintlify-migration/docs/recurring-api.mdx b/mintlify-migration/docs/recurring-api.mdx new file mode 100644 index 00000000..28b471af --- /dev/null +++ b/mintlify-migration/docs/recurring-api.mdx @@ -0,0 +1,44 @@ +--- +title: "About Recurring API" +description: "The Jupiter Recurring API enables you to create automated recurring orders on Solana, allowing users to set up regular token swaps that execute automatically based on time intervals or price conditions." +--- + +The Recurring API is ideal for: + +* DeFi applications that want to offer dollar-cost average or value average features +* Wallets and platforms looking to provide automated investment options +* Projects that want to implement treasury management strategies + +## Features + +| Feature | Description | +| :------------------------ | :----------------------------------------------------------------------------------------------------------- | +| **Time-based recurring** | Set up regular token swaps that execute automatically at specified time intervals. | +| **Price-based recurring** | Create price-based recurring orders that execute when certain market conditions are met. | +| **Any token pair** | Create recurring orders between any token pairs supported on Jupiter's Metis Routing Engine. | +| **Best execution** | Orders are executed through Jupiter's Metis Routing Engine to get the best possible price across all DEXes. | +| **Flexible scheduling** | Configure the frequency and timing of recurring orders to match your needs. | +| **Price strategy** | Set a price range in time-based recurring orders. | + +## Getting Started with Recurring API + +1. [**Create Order**](/docs/recurring-api/create-order): Create a new recurring order with your desired parameters. +2. [**Cancel Order**](/docs/recurring-api/cancel-order): Cancel an existing recurring order. +3. [**Deposit in Price-based Orders**](/docs/recurring-api/deposit-price-order): Deposit funds in price-based orders. +4. [**Withdraw from Price-based Orders**](/docs/recurring-api/withdraw-price-order): Withdraw funds from price-based orders. +5. [**Get Recurring Orders**](/docs/recurring-api/get-recurring-orders): Retrieve the history of recurring orders for a specific wallet address. +6. [**Best Practices**](/docs/recurring-api/best-practices): Best practices for using Recurring API. + +## FAQ + + + + +Recurring API takes 0.1% as fees. + + + + +Currently no. + + diff --git a/mintlify-migration/docs/recurring-api/best-practices.mdx b/mintlify-migration/docs/recurring-api/best-practices.mdx new file mode 100644 index 00000000..bb8bc4d6 --- /dev/null +++ b/mintlify-migration/docs/recurring-api/best-practices.mdx @@ -0,0 +1,11 @@ +--- +title: "Best Practices" +description: "Some best practices when using the Recurring API." +--- + +| Item | Recommendation | +| :---------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------- | +| Understand the Recurring Product. | The Recurring API supports order creation for both recurring and smart recurring strategies. Understand the difference between the two and choose the appropriate one for your needs. | +| Both types of orders require minimum total amount of 100 USD. | As per the Jupiter Recurring API's requirements to prevent small orders from being created.This is similar to jup.ag's frontend check for minimum order amount. | +| Time-based orders require minimum number of orders of 2 and 50 USD per order. | As per the Jupiter Recurring API's requirements to prevent small orders from being created.This is similar to jup.ag's frontend check for minimum order amount. | +| Token-2022 tokens | The Recurring API does not currently support Token-2022 mints. Ensure you’re only scheduling orders for standard SPL tokens (Token Program) until Token-2022 support is added. | diff --git a/mintlify-migration/docs/recurring-api/cancel-order.mdx b/mintlify-migration/docs/recurring-api/cancel-order.mdx new file mode 100644 index 00000000..1b28d08d --- /dev/null +++ b/mintlify-migration/docs/recurring-api/cancel-order.mdx @@ -0,0 +1,94 @@ +--- +title: "Cancel Order" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/recurring/v1/cancelOrder` + * Pro URL: `https://api.jup.ag/recurring/v1/cancelOrder` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +## Cancel Order + +If you want to cancel order(s), you need to do these steps: + + + + Get a list of the order accounts you want to cancel via `/getRecurringOrders` endpoint. + + + Choose the order account to cancel by making a post request to the `/cancelOrder` endpoint to get the transaction to cancel the order. + + + Sign then send the transaction to the network either via `/execute` endpoint or by yourself. + + + + + **GET RECURRING ORDERS** + + [Refer to the `/getRecurringOrders` section](/docs/recurring-api/get-recurring-orders) to prepare the list of order accounts you want to cancel. + + + + **NOTE** + + The `/cancelOrder` endpoint only supports 1 cancellation per transaction. + + + + **CAUTION** + + Price-based orders via API is deprecated. + + +```js +const cancelOrderResponse = await ( + await fetch('https://lite-api.jup.ag/recurring/v1/cancelOrder', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + order: "4DWzP4TdTsuwvYMaMWrRqzya4UTFKFoVjfUWNWh8zhzd", + user: wallet.publicKey, + recurringType: "time", + }), + }) +).json(); +``` + +## Cancel Order Response + +**Success Example Response** + +```json +{ + "requestId": "36779346-ae51-41e9-97ce-8613c8c50553", + "transaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAgORL7cu4ZNuxh1wI9W7GVURyr3A06dH348HDpIQzcAJ4oZOZHXAukWalAX/odOiV55UZa1ePBg8d2tRKQyqCjV6C/H8IQcrfZR4QeOJFykenP3QJznc6vNpqe2D57HTD7Gd1R4MYi595YUO8ViNwpWb17+Q9DxkVcz5fWpSqjtDyiji2RfCl7yoUfzkV42QPexQNFjBK5/+pJhV8QuWShN6r9vLZM5XJNS670dgAgf7wC+wCLLIFWHgjgWx32LJMnJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADBkZv5SEXMv/srbpyw5vnvIzlu8X3EmssQ5s6QAAAAAabiFf+q4GE+2h/Y0YYwDXaxDncGus7VZig8AAAAAABBt324ddloZPZy+FGzut5rBy0he1fWzeROoz1hX7/AKmMlyWPTiSJ8bs9ECkUjg2DC1oTmdr/EIQEjnvY2+n4WbB1qAZjecpv43A3/wwo1VSm5NY22ehRjP5uuuk/Ujb+tSfUXWQOPsFfYV1bDiOlSpa4PwuCC/cGNfJDSsZAzATG+nrzvtutOj1l82qryXQxsbvkwtL24OR8pgIDRS9dYVCj/auTzJLgPke1v9c3puAy81rBYgsabmuLUTEQsZyVAwcABQL9WQEABwAJA0ANAwAAAAAADA0AAg0IAQQDBQYJCgsMCBYHIWKotyLz" +} +``` + +**Failed Example Response** + +```json +{ + "code": 400, + "error": "Failed to deserialize account data: failed to fill whole buffer", + "status": "Bad Request" +} +``` + +## Execute Cancel Order + +To sign then send the transaction to the network to execute the cancellation, you can use the `/execute` endpoint or by yourself. + +Refer to the [Execute Order](/docs/recurring-api/execute-order) section for more details. diff --git a/mintlify-migration/docs/recurring-api/create-order.mdx b/mintlify-migration/docs/recurring-api/create-order.mdx new file mode 100644 index 00000000..d34395e8 --- /dev/null +++ b/mintlify-migration/docs/recurring-api/create-order.mdx @@ -0,0 +1,158 @@ +--- +title: "Create Order" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/recurring/v1/createOrder` + * Pro URL: `https://api.jup.ag/recurring/v1/createOrder` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +## Create Order + +This is a POST request to `/createOrder` endpoint, where you pass in the necessary parameters and our backend will create the transaction for you to sign and send to the network seamlessly. + + + **INFO** + + The Recurring API supports both Time-based and Price-based (DEPRECATED) strategies. + + The `createOrder` endpoint is used to create both types of orders based on the parameters you pass in. + + +### Time-based Order + +Pass in the **`time`** object in the `params` field. + + + Some notes to help you understand the parameters. + + * The amount to be spent per cycle is calculated based on your input amount and the total number of orders. + + ```js + Amount to be spent per cycle = inAmount / numberOfOrders + e.g. 1_000 USDC / 10 orders = 100 USDC per order + ``` + + * The total time to complete is definite as the amount to be spent per cycle is fixed. + + ```js + Total time to complete = numberOfOrders * interval + e.g. 10 orders * 86_400 seconds = 864_000 seconds = 10 days + ``` + + +```js expandable +const createOrderResponse = await ( + await fetch('https://lite-api.jup.ag/recurring/v1/createOrder', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + user: wallet.publicKey, + inputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + outputMint: "So11111111111111111111111111111111111111112", + params: { + time: { + inAmount: 104000000, // Raw amount of input token to deposit now (before decimals) + numberOfOrders: 2, // Total number of orders to execute + interval: 86400, // Time between each order in unix seconds + minPrice: null, // Minimum price or null + maxPrice: null, // Maximum price or null + startAt: null, // Unix timestamp of start time or null - null starts immediately + }, + }, + }), + }) +).json(); +``` + +### Price-based Order (DEPRECATED) + +Pass in the **`price`** object in the `params` field. + + + **CAUTION** + + Price-based orders via API is deprecated. + + + + **NOTE** + + Some notes to help you understand the parameters. + + * Price-based orders are opened indefinitely until the user closes them. + * Once low on funds, the order will not be closed and can continue to execute if the user deposits more into the order. Refer to the [Deposit Price Order](/docs/recurring-api/deposit-price-order) endpoint to deposit more funds into the order. + * Alternatively, the user can also withdraw funds from the order without closing it. Refer to the [Withdraw Price Order](/docs/recurring-api/withdraw-price-order) endpoint to withdraw funds from the order. + * Do note that the price-based orders auto withdraws the output tokens to the user's wallet every time the order is executed. + * The total time to use up all funds is not definite as the amount to be spent per cycle is variable based on the USDC value of the input token. + + +```js +const createOrderResponse = await ( + await fetch('https://lite-api.jup.ag/recurring/v1/createOrder', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + user: wallet.publicKey, + inputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + outputMint: "So11111111111111111111111111111111111111112", + params: { + price: { + depositAmount: 110000000, // Raw amount of input token to deposit now (before decimals) + incrementUsdcValue: 10000000, // Raw amount of USDC to increment per cycle (before decimals) + interval: 86400, // Time between each cycle in unix seconds + startAt: null, // Unix timestamp of start time or null - null starts immediately + }, + }, + }), + }) +).json(); +``` + +Now that you have the order transaction, you can sign and send to the network. There are 2 methods, after signing the transaction, you can either send it to the network yourself or use the Recurring API's `/execute` endpoint to do it for you. + + + + + +## Create Order Response + +The response from the `createOrder` endpoint is as follows. + + + **INFO** + + Do note that both time-based and price-based orders will return the same response structure. + + +**Successful Example Response** + +```json +{ + "requestId": "1d1f3586-eb72-4337-8c7e-1bbb9870ee4b", + "transaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAgNRL7cu4ZNuxh1wI9W7GVURyr3A06dH348HDpIQzcAJ4o8bJlCl2Wc6MzpcvkV0INcJ7u23GV89soNJ/8i5QPLuk+NOvCjbAbTzOyNoSWuhO5fYq+hNGrGQ2JdDy82Gw0bv28tkzlck1LrvR2ACB/vAL7AIssgVYeCOBbHfYskycnT/icRrhr4nbjk0DzDqAkM4ntju8NXHrILEpE0TUKNKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwZGb+UhFzL/7K26csOb57yM5bvF9xJrLEObOkAAAAAGm4hX/quBhPtof2NGGMA12sQ53BrrO1WYoPAAAAAAAQbd9uHXZaGT2cvhRs7reawctIXtX1s3kTqM9YV+/wCpjJclj04kifG7PRApFI4NgwtaE5na/xCEBI572Nvp+FmwdagGY3nKb+NwN/8MKNVUpuTWNtnoUYz+brrpP1I2/rUn1F1kDj7BX2FdWw4jpUqWuD8Lggv3BjXyQ0rGQMwExvp6877brTo9ZfNqq8l0MbG75MLS9uDkfKYCA0UvXWG7njQ5EK9zaEM059+IQanso4m+YzpvFchLCtBxOCdR5QcGAAUCGSwAAAYACQNADQMAAAAAAAkGAAMABwUIAQEFAgADDAIAAAAAwusLAAAAAAgBAwERCw0EAAAHDAMBAgUICQoLK453K22iNAuxgF7IZwAAAAAAwusLAAAAAADh9QUAAAAALAEAAAAAAAAAAAAIBAMAAAABCQ==" +} +``` + +**Failed Example Response** + +```json +{ + "code": 400, + "error": "Order is valued at 2.99 USDC, minimum is 100.00 USDC", + "status": "Bad Request" +} +``` diff --git a/mintlify-migration/docs/recurring-api/deposit-price-order.mdx b/mintlify-migration/docs/recurring-api/deposit-price-order.mdx new file mode 100644 index 00000000..ca50e0a0 --- /dev/null +++ b/mintlify-migration/docs/recurring-api/deposit-price-order.mdx @@ -0,0 +1,88 @@ +--- +title: "Deposit Price Order" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/recurring/v1/priceDeposit` + * Pro URL: `https://api.jup.ag/recurring/v1/priceDeposit` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + + + **CAUTION** + + Price-based orders via API is deprecated. + + +## Deposit Order + +If you want to deposit funds into a price-based order, you need to do these steps: + + + + Get a list of the order accounts you want to deposit via `/getRecurringOrders` endpoint. + + + Choose the order account to deposit by making a post request to the `/priceDeposit` endpoint to get the transaction to deposit into the order. + + + Sign then send the transaction to the network either via `/execute` endpoint or by yourself. + + + + + **GET RECURRING ORDERS** + + [Refer to the `/getRecurringOrders` section](/docs/recurring-api/get-recurring-orders) to prepare the order account you want to deposit into. + + +```js +const priceDepositResponse = await ( + await fetch('https://lite-api.jup.ag/recurring/v1/priceDeposit', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + order: "EpTsCUnKComCd8FDNZn3kVrQBQo2uEn5rRzYk9ocqFPH", + user: wallet.publicKey, + amount: 1000000 + }), + }) +).json(); +``` + +## Deposit Order Response + +**Success Example Response** + +```json +{ + "requestId": "cbc021a6-8a61-49cd-8c5a-9ea29fc2dd4d", + "transaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAcLRL7cu4ZNuxh1wI9W7GVURyr3A06dH348HDpIQzcAJ4ou00rM6bvrYH/o3YhDOZ97jIgg/zdwEtLlVk6ddEK3BXdUeDGIufeWFDvFYjcKVm9e/kPQ8ZFXM+X1qUqo7Q8ozVCa3wbmwfzRz1Av5JAlFtGgdIbvPspoQDO0MABdFvQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMGRm/lIRcy/+ytunLDm+e8jOW7xfcSayxDmzpAAAAABt324ddloZPZy+FGzut5rBy0he1fWzeROoz1hX7/AKkHNtIX+MwRgQakd3fYovqoEXuKqaHTmdCmjuWoQiMib4yXJY9OJInxuz0QKRSODYMLWhOZ2v8QhASOe9jb6fhZxvp6877brTo9ZfNqq8l0MbG75MLS9uDkfKYCA0UvXWHbZsKfr6NrDjI7Q7M2CqAquH41g9AMbtaLYPfmHMqbN3la+2QyLhVSaIunpVo3X8k4VAEj0cBT/ANSk2IKq9g1BAUABQL3nQAABQAJA0ANAwAAAAAACAYAAgAJBAYBAQcIAAMJAQIGCgcQ8iPGiVLh8rZAQg8AAAAAAA==" +} +``` + +**Failed Example Response** + +```json +{ + "code": 400, + "error": "Failed to deserialize account data: failed to fill whole buffer", + "status": "Bad Request" +} +``` + +## Execute Deposit Order + +To sign then send the transaction to the network to execute the deposit, you can use the `/execute` endpoint or by yourself. + +Refer to the [Execute Order](/docs/recurring-api/execute-order) section for more details. diff --git a/mintlify-migration/docs/recurring-api/execute-order.mdx b/mintlify-migration/docs/recurring-api/execute-order.mdx new file mode 100644 index 00000000..c4ad22d7 --- /dev/null +++ b/mintlify-migration/docs/recurring-api/execute-order.mdx @@ -0,0 +1,120 @@ +--- +title: "Execute Order" +--- + + + * Lite URL: `https://lite-api.jup.ag/recurring/v1/execute` + * Pro URL: `https://api.jup.ag/recurring/v1/execute` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +After getting the order transaction, you can sign and send to the network yourself or use the Recurring API's `/execute` endpoint to do it for you. + +## Sign Transaction + +Using the Solana `web3.js` v1 library, you can sign the transaction as follows: + +```js +// ... GET /createOrder's response + +// Extract the transaction from the order response +const transactionBase64 = createOrderResponse.transaction + +// Deserialize the transaction +const transaction = VersionedTransaction.deserialize(Buffer.from(transactionBase64, 'base64')); + +// Sign the transaction +transaction.sign([wallet]); + +// Serialize the transaction to base64 format +const signedTransaction = Buffer.from(transaction.serialize()).toString('base64'); +``` + +## Execute Order + +By making a post request to the `/execute` endpoint, Jupiter executes the order transaction on behalf of you/your users. This includes handling of transaction handling, priority fees, RPC connection, etc. + + + **INFO** + + Do note that you need both the signed transaction and the order id to execute the order. + + The order id is returned in the [`createOrder` response](/docs/recurring-api/create-order). + + +```js +const executeResponse = await ( + await fetch('https://lite-api.jup.ag/recurring/v1/execute', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + signedTransaction: signedTransaction, + requestId: createOrderResponse.requestId, + }), + }) +).json(); +``` + +## Execute Order Response + +After making the post request to the `/execute` endpoint, you will receive a response with the status of the order. + +**Example response of successful order:** + +```json +{ + "signature": "...", + "status": "Success", + "order": "4DWzP4TdTsuwvYMaMWrRqzya4UTFKFoVjfUWNWh8zhzd", + "error": null +} +``` + +**Example response of failed order:** + +```json +{ + "signature": "...", + "status": "Failed", + "order": null, + "error": "Insufficient funds for the operation requested.", +} +``` + +## Send Transaction Yourself + +If you want to handle the transaction, you can sign and send the transaction to the network yourself. + +```js expandable +const transactionBase64 = createOrderResponse.transaction +const transaction = VersionedTransaction.deserialize(Buffer.from(transactionBase64, 'base64')); + +transaction.sign([wallet]); + +const transactionBinary = transaction.serialize(); + +const blockhashInfo = await connection.getLatestBlockhashAndContext({ commitment: "finalized" }); + +const signature = await connection.sendRawTransaction(transactionBinary, { + maxRetries: 1, + skipPreflight: true +}); + +const confirmation = await connection.confirmTransaction({ +signature, +blockhash: blockhashInfo.value.blockhash, +lastValidBlockHeight: blockhashInfo.value.lastValidBlockHeight, +}, "finalized"); + +if (confirmation.value.err) { + throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}\n\nhttps://solscan.io/tx/${signature}`); +} else console.log(`Transaction successful: https://solscan.io/tx/${signature}`); +``` diff --git a/mintlify-migration/docs/recurring-api/get-recurring-orders.mdx b/mintlify-migration/docs/recurring-api/get-recurring-orders.mdx new file mode 100644 index 00000000..590f3ea5 --- /dev/null +++ b/mintlify-migration/docs/recurring-api/get-recurring-orders.mdx @@ -0,0 +1,65 @@ +--- +title: "Get Recurring Orders" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/recurring/v1/getRecurringOrders` + * Pro URL: `https://api.jup.ag/recurring/v1/getRecurringOrders` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +This is a GET request to `/getRecurringOrders` endpoint. The response is paginated for every 10 orders and you can view different pages using the `page` parameter. + +## Get Recurring Orders + + + **NOTE** + + * orderStatus can be either `active` or `history` + * recurringType can be either `time` (`price` is deprecated) + * includeFailedTx can be either `true` or `false` + + + + **CAUTION** + + Price-based orders via API is deprecated. + + +## Active Orders + +To get the active orders, you can pass in the `orderStatus` parameter as `active`. + + + **TIP** + + You can optionally pass in the input and output token mint addresses to filter the open orders. + + +```js +const openOrdersResponse = await ( + await fetch( + 'https://lite-api.jup.ag/recurring/v1/getRecurringOrders?user=replaceWithPublicKey&orderStatus=active&recurringType=time' + ) +).json(); +``` + +## Order History + +To get the order history, you can pass in the `orderStatus` parameter as `history`. + +```js +const orderHistoryResponse = await ( + await fetch( + 'https://lite-api.jup.ag/recurring/v1/getRecurringOrders?user=replaceWithPublicKey&orderStatus=history&recurringType=price' + ) +).json(); +``` diff --git a/mintlify-migration/docs/recurring-api/withdraw-price-order.mdx b/mintlify-migration/docs/recurring-api/withdraw-price-order.mdx new file mode 100644 index 00000000..38fd8421 --- /dev/null +++ b/mintlify-migration/docs/recurring-api/withdraw-price-order.mdx @@ -0,0 +1,93 @@ +--- +title: "Withdraw Price Order" +--- + + + * Lite URL: `https://lite-api.jup.ag/recurring/v1/priceWithdraw` + * Pro URL: `https://api.jup.ag/recurring/v1/priceWithdraw` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + + + **CAUTION** + + Price-based orders via API is deprecated. + + +## Withdraw Order + +If you want to withdraw funds from a price-based order, you need to do these steps: + + + + Get a list of the order accounts you want to withdraw via `/getRecurringOrders` endpoint. + + + Choose the order account to deposit by making a post request to the `/priceDeposit` endpoint to get the transaction to deposit into the order. + + + Sign then send the transaction to the network either via `/execute` endpoint or by yourself. + + + + + **GET RECURRING ORDERS** + + [Refer to the `/getRecurringOrders` section](/docs/recurring-api/get-recurring-orders) to prepare order account you want to withdraw from. + + + + **WARNING** + + If you do not pass in `amount`, the transaction will be built to withdraw the full amount of the order. + + +```js +const priceWithdrawResponse = await ( + await fetch('https://lite-api.jup.ag/recurring/v1/priceWithdraw', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + order: "EpTsCUnKComCd8FDNZn3kVrQBQo2uEn5rRzYk9ocqFPH", + user: wallet.publicKey, + inputOrOutput: "In", // either "In" or "Out" mint, note that price-based orders auto withdraws the output tokens to the user's wallet every time the order is executed + amount: 1000000 + }), + }) +).json(); +``` + +## Withdraw Order Response + +**Success Example Response** + +```js +{ + "requestId": "cb1c0e03-8e4a-4f85-ac36-e353c7981f5b", + "transaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAcNRL7cu4ZNuxh1wI9W7GVURyr3A06dH348HDpIQzcAJ4oHNtIX+MwRgQakd3fYovqoEXuKqaHTmdCmjuWoQiMiby7TSszpu+tgf+jdiEM5n3uMiCD/N3AS0uVWTp10QrcFd1R4MYi595YUO8ViNwpWb17+Q9DxkVcz5fWpSqjtDyjKhKdx27tkl2VPxhBBJcKx9gSuUqMJnrF2JWtuKPpRPM1Qmt8G5sH80c9QL+SQJRbRoHSG7z7KaEAztDAAXRb0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADBkZv5SEXMv/srbpyw5vnvIzlu8X3EmssQ5s6QAAAAAabiFf+q4GE+2h/Y0YYwDXaxDncGus7VZig8AAAAAABBt324ddloZPZy+FGzut5rBy0he1fWzeROoz1hX7/AKmMlyWPTiSJ8bs9ECkUjg2DC1oTmdr/EIQEjnvY2+n4Wcb6evO+2606PWXzaqvJdDGxu+TC0vbg5HymAgNFL11h22bCn6+jaw4yO0OzNgqgKrh+NYPQDG7Wi2D35hzKmzcjGx2VRtfxzpYauPv7ArfDDH2VHlwLKs45O0rZTboL4wMHAAUCnqwAAAcACQNADQMAAAAAAAEOAAAFCwgCAwEEBgkKDAEStxJGnJRtoSIBQEIPAAAAAAAA" +} +``` + +**Failed Example Response** + +```js +{ + "code": 400, + "error": "Failed to deserialize account data: failed to fill whole buffer", + "status": "Bad Request" +} +``` + +## Execute Withdraw Order + +To sign then send the transaction to the network to execute the withdrawal, you can use the `/execute` endpoint or by yourself. + +Refer to the [Execute Order](/docs/recurring-api/execute-order) section for more details. diff --git a/mintlify-migration/docs/routing.mdx b/mintlify-migration/docs/routing.mdx new file mode 100644 index 00000000..0c0a8d52 --- /dev/null +++ b/mintlify-migration/docs/routing.mdx @@ -0,0 +1,65 @@ +--- +title: "About Routing" +--- + + +**NOTE** + +If you are an exchange or market maker and want to participate in our routing system, please refer to our [DEX Integration](/docs/routing/dex-integration) and [RFQ Integration](/docs/routing/rfq-integration) guides. + + +## Juno Liquidity Engine + +Juno is Jupiter's latest liquidity engine, it is built with the combined learnings from Metis and JupiterZ, with one single objective - to ensure the best possible execution price and success rate across all engines and liquidity sources. Juno employs a sophisticated self-learning mechanism to maintain high availability of competitive routes while automatically sidelining underperforming or potentially problematic quotes. Juno will be incrementally introducing new third-party liquidity sources and a continual effort to improve Metis and JupiterZ routing capabilities. + +| | | +| :--- | :--- | +| **Multi-liquidity sources** | Integrates third-party liquidity sources and Jupiter's proprietary routing engines to ensure best possible rates. Currently, Juno consists of Metis, JupiterZ, Hashflow, DFlow and more in the pipeline. | +| **Self-learning** | Automatically detects and sidelines underperforming or problematic sources, while continuously learning to provide competitive quotes. | +| **Continuous optimizations** | By integrating external liquidity sources directly, Juno creates a competitive environment that drives continuous improvement across all routing engines. This approach ensures users consistently receive optimal execution rates while providing valuable performance data to enhance both Metis and JupiterZ routing capabilities. | + +Juno is directly powering the Ultra Swap on Jupiter frontend (jup.ag) and is also accessible via [**Ultra API**](/docs/ultra-api): The Jupiter Ultra API is the *only* API you ever need to experience or build the best trading experience on Solana - Jupiter handles all the complexities such as RPCs, slippage, broadcast method and landing rates, all while accessing the best liquidity available through Juno. + +## Jupiter Metis Routing Engine + +Since its inception in 2023, Jupiter's proprietary DEX aggregation engine, Metis v1, has become a cornerstone of Solana blockchain's DeFi ecosystem. Metis functions as a sophisticated aggregation layer for on-chain liquidity, with one single objective - to algorithmically determine the most efficient trade route for any given token pair, considering factors like price, slippage, and quoted-to-executed price across multiple DEXes and AMMs. This ensures users receive the best possible execution price available on-chain at the moment that they wish to trade. + +As of 2025, we've deployed Metis v1.5 which has experimented with modified algorithms to enable more granular splits and allows for a larger set of tokens to act as intermediate tokens in a route. From our analysis so far, this translates to 4.6x less spread between quoted and executed price. This is a continued effort to experiment with better configurations and algorithms to improve Metis. + + + Read more about Metis's history, learnings and future plans + + + +| | | +| :--- | :--- | +| **Overcoming SVM constraints** | Employs a sophisticated and efficient transaction construction to enable multi-hop-multi-split swaps. | +| **Integrating diverse DEXes** | Utilizes a standardized interface to integrate with a wide range of DEXes, abstracting away the complexities of each individual DEX. | +| **Optimizing for price and execution** | Ensuring the quoted price is as close as the actual price, while also ensuring the transaction is executed successfully. | +| **Accessing markets immediately and safely** | Employs necessary infrastructure powered by a network of robust RPC nodes to include markets and checks their liquidity in real-time. | + +The engine integrates with most DEXes on Solana and is accessible via the Swap API. You can find a complete list of supported DEXes via the [/swap/v1/program-id-to-label](https://lite-api.jup.ag/swap/v1/program-id-to-label) endpoint. + +**Metis v1** + +Metis v1's impact extends far beyond simple facilitation of on-chain trades. It is the de-facto liquidity engine on Solana, playing an instrumental role in onboarding millions of users to the network and facilitating trillions of dollars in cumulative trading volume. Its stability and general-purpose design have made it a reliable foundation for countless developers and protocols building on Solana. + +Currently, Metis v1 powers the [**Swap API**](/docs/swap-api): A robust interface designed for developers and applications requiring programmatic access to Solana's liquidity. It currently has tens of thousands of requests per second, with demonstrated capacity to handle peak loads reaching hundreds of thousands of requests per second. + +## Jupiter Z (RFQ) Routing Engine + +Since its launch in 2024, Jupiter Z has emerged as a transformative addition to Jupiter's routing capabilities. Jupiter Z functions as an RFQ (Request For Quote) system that connects users directly with market makers, enabling market makers to provide competitive quotes for top token pairs. This ensures users receive the best possible execution price available from both on-chain and off-chain liquidity at the moment they wish to trade. + +| | | +| :--- | :--- | +| **Intent-based architecture** | Employs an intent-based system where users express their desired trade and market makers compete to fulfill it. | +| **Integrating diverse market makers** | Utilizes a standardized interface to integrate with multiple market makers, abstracting away the complexities of each liquidity provider. | +| **Optimizing for price and execution** | Creates a competitive environment where market makers compete to provide the best quotes, while ensuring the transaction is executed successfully and efficiently. | +| **Real-time quote aggregation** | Employs a versatile proxy to collect and compare quotes from multiple routing sources (such as Jupiter Metis v1 and Jupiter Z) in real-time. | +| **Gasless transactions** | Enables users to execute trades without incurring transaction fees, providing a seamless and cost-effective trading experience. | + +Jupiter Z has been handling a large portion of trades on the Jupiter frontend (jup.ag) - which has demonstrated Jupiter Z's reliability and effectiveness in providing competitive quotes and successful trade execution. + +Currently, Jupiter Z is accessible through the **Ultra API**: A streamlined interface that makes it simple for developers and applications to tap into Metis v1, Jupiter Z and other routing sources. + +For more information about Jupiter Z, please refer to our [RFQ Integration](/docs/routing/rfq-integration) guide. diff --git a/mintlify-migration/docs/routing/dex-integration.mdx b/mintlify-migration/docs/routing/dex-integration.mdx new file mode 100644 index 00000000..58a2fd5a --- /dev/null +++ b/mintlify-migration/docs/routing/dex-integration.mdx @@ -0,0 +1,178 @@ +--- +title: "DEX Integration" +description: "Jupiter is one of the most widely integrated protocols, so a lot of work is involved in minimizing issues on new integrations and making each integration valuable to our users and partners. Our top priority is ensuring security and providing the best prices and the best token selection for our users, so we will focus on DEXes that will bring the most benefits to them." +sidebarTitle: "Jupiter Metis v1" +--- + +In this section, we will walk you through the process of integrating your DEX into the Jupiter Metis v1 Routing Engine that powers the Swap API. + + +**WE DO NOT CHARGE FEES FOR INTEGRATION.** + + +## Integration Prerequisites + +As Solana grows and more DEXes are built, we have to be more cautious in the DEXes we integrate, we look into a variety of factors. + +* **Code health**: It will help with integration and ensure maintainability in the future. +* **Security audit**: This is important to ensure users' funds are secure and the program is not malicious. +* **Traction**: We look at the traction of the DEX to ensure it has market demand and is well-used. +* **Team and backers**: This is a good indicator of the quality of the DEX if they are backed by or built by reputable or verifiable entities. + +### AMM Interface + +To facilitate integration of your DEX into the Jupiter Core Engine: + +* Provide a DEX SDK that works with the [Jupiter AMM Interface](https://docs.rs/crate/jupiter-amm-interface). +* Enable us to fork your SDK, this ensures our users that we can guarantee maintenance, support for the SDK, and fix potential bugs related to integrated DEXs. + + +**NOTE** + + `get_accounts_to_update` provides the necessary accounts to fetch, they are batched and cached by the Jupiter Core Engine and delivered through `update` to the AMM instance, there might be multiple calls to `quote` using the same cache so **we do not allow any network calls** in the entire implementation. + + + +**RESOURCE AND SUPPORT** + + You can refer to the implementation guide [https://github.com/jup-ag/rust-amm-implementation](https://github.com/jup-ag/rust-amm-implementation) for easier integration with Jupiter. + + If you require assistance or have questions, reach out to us at [Discord](https://discord.gg/jup) + + + + ```js + pub trait Amm { + // Maybe trait was made too restrictive? + fn from_keyed_account(keyed_account: &KeyedAccount, amm_context: &AmmContext) -> Result + where + Self: Sized; + /// A human readable label of the underlying DEX + fn label(&self) -> String; + fn program_id(&self) -> Pubkey; + /// The pool state or market state address + fn key(&self) -> Pubkey; + /// The mints that can be traded + fn get_reserve_mints(&self) -> Vec; + /// The accounts necessary to produce a quote + fn get_accounts_to_update(&self) -> Vec; + /// Picks necessary accounts to update it's internal state + /// Heavy deserialization and precomputation caching should be done in this function + fn update(&mut self, account_map: &AccountMap) -> Result<()>; + + fn quote(&self, quote_params: &QuoteParams) -> Result; + + /// Indicates which Swap has to be performed along with all the necessary account metas + fn get_swap_and_account_metas(&self, swap_params: &SwapParams) -> Result; + + /// Indicates if get_accounts_to_update might return a non constant vec + fn has_dynamic_accounts(&self) -> bool { + false + } + + /// Indicates whether `update` needs to be called before `get_reserve_mints` + fn requires_update_for_reserve_mints(&self) -> bool { + false + } + + // Indicates that whether ExactOut mode is supported + fn supports_exact_out(&self) -> bool { + false + } + + fn get_user_setup(&self) -> Option { + None + } + + fn clone_amm(&self) -> Box; + + /// It can only trade in one direction from its first mint to second mint, assuming it is a two mint AMM + fn unidirectional(&self) -> bool { + false + } + + /// For testing purposes, provide a mapping of dependency programs to function + fn program_dependencies(&self) -> Vec<(Pubkey, String)> { + vec![] + } + + fn get_accounts_len(&self) -> usize { + 32 // Default to a near whole legacy transaction to penalize no implementation + } + + /// The identifier of the underlying liquidity + /// + /// Example: + /// For RaydiumAmm uses Openbook market A this will return Some(A) + /// For Openbook market A, it will also return Some(A) + fn underlying_liquidities(&self) -> Option> { + None + } + + /// Provides a shortcut to establish if the AMM can be used for trading + /// If the market is active at all + fn is_active(&self) -> bool { + true + } +} + ``` + + +*** + +## Market Listing + +This section explains how markets are listed and maintained on Jupiter. It covers the different types of routing (instant and normal), the criteria for a market to be included in routing, and the liquidity requirements that must be met for a market to remain routable. Understanding these rules is essential for DEX teams to ensure their markets are eligible for and remain in the Jupiter Metis routing engine. + +### Routing Type + +There are 2 types of market listing on Jupiter. + +1. **Instant routing** + + * We automatically list all new markets that are created on specific DEXes (list is below). + * These markets have a grace period, where the liquidity criteria is not applied. + * After the grace period has passed, the liquidity criteria will apply (refer to normal routing). + * For bonding curves, if it does not graduate after the grace period, it will be removed from routing. + * Only when the bonding curve has graduated to a new market, the graduated market will be added to routing. + + + - Meteora Dynamic Bonding Curve + - Meteora Dynamic AMM + - Meteora DAMM V2 + - Meteora DLMM + - Raydium + - Raydium CLMM + - Raydium CPMM + - Raydium Launchlab + - Pump.fun AMM + - Pump.fun + - Fluxbeam + - Whirlpool + - Moonshot + - Virtuals + - Boop.fun + + +2. **Normal routing** + + * This is the default for all markets. + * Every 30 minutes, we will check the liquidity of the market. + * If the liquidity is not enough, we will remove the market from routing. + +### Market Liquidity Requirements + +The market must fit one of the following criteria for it to be routable: + +1. **Less than 30\% price difference on \$500** + +Using a benchmark position size of \$500, a user should encounter less than 30% price difference after buying \$500 worth and then selling back on the same market. + +Price Difference = (\$500 - Final USD value) / \$500 If the price difference is more than 30%, it means that there is insufficient liquidity in the market for the benchmark position size of \$500. + +2. **Less than 20\% price impact on market** + +If the above (sell back \$500 worth) fails, we will compare the price per token received from buying \$1000 worth vs the price per token received from buying \$500 worth to calculate price impact. + +If the price impact is more than 20\%, it means that the market is illiquid. + diff --git a/mintlify-migration/docs/routing/rfq-integration.mdx b/mintlify-migration/docs/routing/rfq-integration.mdx new file mode 100644 index 00000000..5f38b8df --- /dev/null +++ b/mintlify-migration/docs/routing/rfq-integration.mdx @@ -0,0 +1,190 @@ +--- +title: "RFQ Integration" +description: "This section will cover the integration of your RFQ service into Jupiter's routing system." +sidebarTitle: "Jupiter Z (RFQ)" +--- + + +**CAUTION** + +The integration requirements are subjected to change and please provide suggestions or feedbacks on ways to improve the integration process. + + + + RFQ Flow + + +## Integration Prerequisites + +- Host a service that adheres to our RFQ API schema +- Provide a webhook for Jupiter to send quotes and swap transactions +- Complete end-to-end integration tests +- When ready, you will be onboarded to Edge before going live on production + + +**NOTE** + +Please reach out to us in [Discord](https://discord.gg/jup) in the [Developer Support channel](https://discord.com/channels/897540204506775583/910250162402779146) +- If you are interested to participate in Jupiter Z +- If you need any help or clarification regarding the integration. +- To begin onboarding to Edge. + + +### Example Integration + +To facilitate the integration, we provide an [integration SDK in this repository](https://github.com/jup-ag/rfq-webhook-toolkit). + +- [**Sample server**](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/server-example/): Implements the webhook API in Rust. +- [**API Schema**](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/openapi): OpenAPI schema for the RFQ API. +- [**Integration tests**](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/tests/): Verify the implementation of the webhook. +- [**Troubleshooting**](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/tests/README.md#troubleshooting): Common issues that arise during integration. + +### RFQ API Schema + +To facilitate the integration into Jupiter's RFQ module, you will need to provide a webhook for us to register the quotation and swap endpoints with the corresponding request and response format. + +| Endpoint | Method | URL | Description | +| :-------- | :------ | :-------------------------------------------------- | :------------------------------------------------------------------------------------------------------------- | +| Base URL | - | `https://your-api-endpoint.com/jupiter/rfq` | Example URL that we will register into our API. | +| Quote | POST | `https://your-api-endpoint.com/jupiter/rfq/quote` | Called to request quotes. | +| Swap | POST | `https://your-api-endpoint.com/jupiter/rfq/swap` | Called to execute swaps. | +| Tokens | GET | `https://your-api-endpoint.com/jupiter/rfq/tokens` | Called periodically to fetch supported tokens ([see the token section below](#advertising-supported-tokens)). | + + +**API KEY** + +If you require an API key to access your endpoints, please provide it to us during the registration process. The API Key will be passed to the webhook as a header `X-API-KEY`. + + + +### Response Codes + +Market Makers should return appropriate HTTP status codes along with error messages. + +| Status Code | Description | +| :------------------- | :------------------------------------------------------------------------------------------------------------- | +| `200 OK` | The request was successful, and the webhook will return a quote. | +| `404 Not Found` | The webhook will not return a quote for this request (e.g. the pair or the size are not supported). | +| `400 Bad Request` | The request sent to the webhook is malformed (e.g. missing an expected parameter). | +| `401 Unauthorized` | Authorization failed. For example the `X-API-KEY` is missing or incorrect. | +| `50x Server Errors` | The webhook is offline or unable to respond. If the status persist, the webhook will be temporarily suspended and will not receive requests. | + + +**TIMEOUTS** + +A webhook must adhere to the [fulfillment and response time requirements](#fulfillment-requirements). When sending the quote request, the RFQ system includes the following headers: + +| Header | Description | +| :------------------- | :------------------------------------------------------------------ | +| `x-request-start` | The millisecond timestamp indicating when the request was sent. | +| `x-request-timeout` | The millisecond timeout for the request (currently set to 250 ms). | + + + +## Integration Notes + +### Order Engine + +The RFQ functionality depends on the mainnet deployment of the [Order Engine Program](https://solscan.io/account/61DFfeTKM7trxYcPQCM78bJ794ddZprZpAwAnLiwTpYH) for order fulfillment. + +- **Source Code**: The program's source is located in the [programs/order-engine](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/programs/order-engine) directory. +- **IDL**: The Interface Definition Language (IDL) file is available [here](https://github.com/jup-ag/rfq-webhook-toolkit/tree/main/idls). + +### Fulfillment Requirements + +To ensure market makers stay competitive and responsive, we enforce a minimum benchmark for fulfillment and response times. + +- **Fulfillment**: Market makers are expected to comply and fulfill **95%** of the quotes provided within a 1-hour window. If this is not met, the market maker will be turned off. +- **Response Time**: A webhook must respond within **250 ms** of receiving a quote request. If it fails to do so, the RFQ system will proceed with the available quotes at the time. + + +**CAUTION** + +To resume operations, we will need to manually re-enable your webhook, please reach out to us if this happens. + + + +### Expiry + +We enforce a fixed expiry timing flow for all quotes and transactions. This simplifies the integration by removing the need for market makers to specify custom expiry times in quote requests, providing consistent behavior across all quotes and transactions, and establishing clear timeout boundaries at different stages of the flow. + +**Breakdown of the expiry flow:** + +- **Total of 50 seconds**: Transaction expiry time +- **1st 25 seconds**: Reserved for the webhook to verify, sign, and send the transaction on-chain +- **2nd 25 seconds**: Allocated for the user to accept the quote + + +**NOTE** + +The frontend automatically re-quotes every 5 seconds. + + + + +**CAUTION** + +These expiry thresholds may be adjusted based on performance and feedback. + + + +### Fees + +Jupiter RFQ allows MMs a way to provide liquidity, adjust their quotes without being subject to the volatility of on-chain gas prices or chain health. RFQ fills are also much less CU intensive (\< 10x) compared to AMM swaps, and can save gas in the long run on fills. Today, RFQ, when operating in Ultra mode, charges a dynamic fee that is selected based on factors like tokens and size. + +**Dynamic Fee** + +The dynamic fee amount is forwarded to webhooks in the quote request parameters and it is contained in the message that both taker and maker sign ([see the payload section below](#non-standard-payload)). In manual mode, the fee is a flat 2pbs. + +**Fee Calculation** + +Webhooks do not need to account for fees when quoting, the fee is applied directly by the RFQ system during transaction building. + +- For example, for a quote of 1 SOL to 1,000 USDC with a fee of 100 bps +- Only 990 USDC will be transferred out of the market maker account +- While 10 USDC will be collected as a fee + + +**NOTE** + +The fee is not automatically transferred and will be accounted for asynchronously on a regular basis. + +This is subject to change in the future. + + + +### Non-standard payload + +The transaction data includes, beside the instruction data for the order-engine, 3 additional bytes that are appended to the instruction data. These bytes are not processed by the program and are only information and to be consumed by an off-chain consumer. The first 2 bytes contains the fee amount in basis points (u16) and the third byte (u8) is a bit mask where the least significant bit indicates if the swap is exact-in (0) or exact-out (1). + +### Advertising Supported Tokens + +In order to receive relevant quote requests, market makers need to advertise the tokens they support. This is done by providing a list of supported tokens in the response to the `/tokens` route. The response should be a JSON array of token addresses. The list of tokens is refreshed every 10 minutes. + +## FAQ + + + + Yes, native SOL is fully supported in the order-engine program for both the taker (user) and the maker. However, for now, we assume the maker will use WSOL (Wrapped SOL). + + + + No, the RFQ system dispatches the quote request to all registered webhooks simultaneously. All quotes received within the quote timeout are compared to select the best one. The selection prioritizes the quote value first (In the unlikely scenario where two quotes have identical values, the quote from the webhook with the faster response time will be actually prioritized). + + + + Yes, the RFQ system will verify the swap requests before forwarding them to the webhooks. However, webhooks are encouraged to verify the swap requests as well to ensure the integrity of the system. The checks that the RFQ system performs can be found in the validate_similar_fill_sanitized_message function. + + + + No, there is no penalty. It is up to the webhook to decide whether to respond with a quote (200 OK) or indicate that it cannot provide one (404 Not Found). + + For example, suppose a webhook provides quotes for USDC/SOL only within a range of 100 to 1000 USDC. If it receives a quote request for 10 USDC → SOL, it will respond with 404 Not Found, since the amount is outside its quoting range. + + In another case, a webhook may only support one-way quotes (USDC → SOL) but not SOL → USDC. If it receives a request for SOL → USDC, it will also return 404 Not Found. + + + + No. Stable to stable swaps are exempt from fees. + + diff --git a/mintlify-migration/docs/send-api.mdx b/mintlify-migration/docs/send-api.mdx new file mode 100644 index 00000000..76adc5b8 --- /dev/null +++ b/mintlify-migration/docs/send-api.mdx @@ -0,0 +1,46 @@ +--- +title: "About Send API" +description: "Send is the perfect onboarding tool to gift, pay, or onboard anyone in seconds - even if they don't have a wallet." +--- + +* Send any token - SOL, USDC or memecoins. +* Send to a new user without a wallet, existing user or anyone. +* No fees to send or claim, only network transaction fees required. +* Use Jupiter Mobile seamlessly - even if you sent non-SOL tokens, Ultra provides Gasless Support that pays for swap transaction fees. + +## About + +Send API provides more opportunities for potential users to be onboarded from other websites, apps, or any where else! + +* API only supports creating Send and Clawback transactions. +* Claiming needs to be done via Jupiter Mobile only. +* You can gamify the experience post-claim once they are onboarded! + +## Jupiter Mobile Adapter + +To maximize users experience, once your users have claimed via Jupiter Mobile, they can use the app to continue their journey on your app or other use cases. This can be done via [Jupiter Mobile Adapter](/docs/tool-kits/mobile-adapter), allowing Jupiter Mobile users to simply use the app to scan a QR code to login, they can utilize their wallets on Jupiter Mobile across any platform. + +## FAQ + + + + + +* The invite code can be in the format of a link or a QR code. + + + + + +* No, Send claims should be done in Jupiter Mobile. + + + + + +* Send is end-to-end self-custodial, where if recipient never claims, the invite code becomes invalid and your tokens are sent back to you upon expiry. +* Or use the clawback endpoint via the API to create the clawback transaction. + + + + diff --git a/mintlify-migration/docs/send-api/craft-clawback.mdx b/mintlify-migration/docs/send-api/craft-clawback.mdx new file mode 100644 index 00000000..ba78868b --- /dev/null +++ b/mintlify-migration/docs/send-api/craft-clawback.mdx @@ -0,0 +1,188 @@ +--- +title: "Craft Clawback (Beta)" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/send/v1` + * Pro URL: `https://api.jup.ag/send/v1` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +## Overview + + + + Load invite code. + + + Load public key from invite. + + + Find the [Program Derived Address (PDA)](https://solana.com/core/pda) of the invite. + * Uses `"invite"` and the public key of recipient at seed. + + + Post request to get Clawback transaction. + + + Sign with sender keypair, then send transaction and wait for confirmation. + + + + + **NOTE** + + [Please ensure that you have set up the prerequisites](/docs/send-api/invite-code#overview). + + + +```js +import { invite_code_to_priv_key } from "./utils.js"; +import { + Connection, + Keypair, + PublicKey, + VersionedTransaction, +} from "@solana/web3.js"; +import fs from "fs"; + +const connection = new Connection('insert-rpc'); +const senderPrivateKey = JSON.parse(fs.readFileSync('/Path/to/sender/id.json', 'utf8').trim()); +const sender = Keypair.fromSecretKey(new Uint8Array(senderPrivateKey)); +process.loadEnvFile('.env'); + +// STEP 1: Load invite code +const invite_code = process.env.INVITE_CODE; + +// STEP 2: Load the public key from the invite code +const secret_key = invite_code_to_priv_key(invite_code); +const pubkey = Keypair.fromSecretKey(secret_key).publicKey; + +// STEP 3: Find the Program Derived Address (PDA) for the invite +// Uses `"invite"` as seed + the public key +// PDAs are deterministic addresses owned by the program +const invite_pda = PublicKey.findProgramAddressSync( + [Buffer.from("invite"), pubkey.toBuffer()], + new PublicKey("inv1tEtSwRMtM44tbvJGNiTxMvDfPVnX9StyqXfDfks") + )[0]; + +// STEP 4: Post request for a Clawback transaction +const craftClawbackTransaction = await ( + await fetch ('https://lite-api.jup.ag/send/v1/craft-clawback', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + invitePDA: invite_pda.toBase58(), + sender: sender.publicKey.toBase58(), + }, null, 2) + }) +).json(); + +// STEP 5: Use sender keypair to sign and send to network +const transaction = VersionedTransaction.deserialize(Buffer.from(craftClawbackTransaction.tx, 'base64')); +transaction.sign([sender]); // SIGN with SENDER +const transactionBinary = transaction.serialize(); +const blockhashInfo = await connection.getLatestBlockhashAndContext({ commitment: "confirmed" }); + +const signature = await connection.sendRawTransaction(transactionBinary, { + maxRetries: 0, + skipPreflight: true, +}); + +// Log the signature immediately after sending, before confirmation +console.log(`Transaction sent: https://solscan.io/tx/${signature}`); + +try { + const confirmation = await connection.confirmTransaction({ + signature, + blockhash: blockhashInfo.value.blockhash, + lastValidBlockHeight: blockhashInfo.value.lastValidBlockHeight, + }, "confirmed"); + + if (confirmation.value.err) { + console.error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`); + console.log(`Examine the failed transaction: https://solscan.io/tx/${signature}`); + } else { + console.log(`Transaction successful: https://solscan.io/tx/${signature}`); + } +} catch (error) { + console.error(`Error confirming transaction: ${error}`); + console.log(`Examine the transaction status: https://solscan.io/tx/${signature}`); +} +``` + + +## Imports + +```js +import { invite_code_to_priv_key } from "./utils.js"; +import { + Connection, + Keypair, + PublicKey, + VersionedTransaction, +} from "@solana/web3.js"; +import fs from "fs"; + +const connection = new Connection('insert-rpc'); +const senderPrivateKey = JSON.parse(fs.readFileSync('/Path/to/sender/id.json', 'utf8').trim()); +const sender = Keypair.fromSecretKey(new Uint8Array(senderPrivateKey)); +process.loadEnvFile('.env'); +``` + +## Invite Code and Public Key + +```js +// STEP 1: Load invite code +const invite_code = process.env.INVITE_CODE; + +// STEP 2: Load the public key from the invite code +const secret_key = invite_code_to_priv_key(invite_code); // Follow the utils.js guide +const pubkey = Keypair.fromSecretKey(secret_key).publicKey; +``` + +## Invite PDA + +```js +// STEP 3: Find the Program Derived Address (PDA) for the invite +// Uses `"invite"` as seed + the public key +// PDAs are deterministic addresses owned by the program +const invite_pda = PublicKey.findProgramAddressSync( + [Buffer.from("invite"), pubkey.toBuffer()], + new PublicKey("inv1tEtSwRMtM44tbvJGNiTxMvDfPVnX9StyqXfDfks") + )[0]; +``` + +## Craft Clawback + + + **NOTE** + + The clawback will return the full amount including leftover transaction fees and/or rent back to the sender. + + +```js +// STEP 4: Post request for a Clawback transaction +const craftClawbackTransaction = await ( + await fetch ('https://lite-api.jup.ag/send/v1/craft-clawback', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + invitePDA: invite_pda.toBase58(), + sender: sender.publicKey.toBase58(), + }, null, 2) + }) +).json(); +``` diff --git a/mintlify-migration/docs/send-api/craft-send.mdx b/mintlify-migration/docs/send-api/craft-send.mdx new file mode 100644 index 00000000..21dd2501 --- /dev/null +++ b/mintlify-migration/docs/send-api/craft-send.mdx @@ -0,0 +1,178 @@ +--- +title: "Craft Send (Beta)" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/send/v1` + * Pro URL: `https://api.jup.ag/send/v1` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +## Overview + + + + Create invite code. + + + From utils, derive the secret key - a deterministic 64-byte Solana secret key (32 bytes private + 32 bytes public key). + + + Create Solana Keypair instance from the secret key. + + + Post request to get Send transaction. + + + Sign with both sender and recipient keypair, then send transaction and wait for confirmation. + + + + + **NOTE** + + [Please ensure that you have set up the prerequisites](/docs/send-api/invite-code#overview). + + + +```js +import { create_invite_code, invite_code_to_priv_key } from "./utils.js"; +import { + Connection, + Keypair, + VersionedTransaction, +} from "@solana/web3.js"; +import fs from "fs"; + +const connection = new Connection('insert-rpc'); +const senderPrivateKey = JSON.parse(fs.readFileSync('/Path/to/sender/id.json', 'utf8').trim()); +const sender = Keypair.fromSecretKey(new Uint8Array(senderPrivateKey)); + +// STEP 1: Create 12-character invite code +const invite_code = await create_invite_code(); + +// STEP 2: Derive secret key (public and private key) +const secret_key = invite_code_to_priv_key(invite_code); + +// STEP 3: Use secret key to create Solana Keypair instance +const recipient = Keypair.fromSecretKey(secret_key); + +// STEP 4: Post request for a Send transaction +const craftSendTransaction = await ( + await fetch ('https://lite-api.jup.ag/send/v1/craft-send', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + inviteSigner: recipient.publicKey.toBase58(), + sender: sender.publicKey.toBase58(), + amount: "10000000", // atomic amount before decimals + // mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // Defaults to SOL if `mint` is not provided + }, null, 2) + }) +).json(); + +// STEP 5: Use sender and receipient keypair to sign and send to network +const transaction = VersionedTransaction.deserialize(Buffer.from(craftSendTransaction.tx, 'base64')); +transaction.sign([sender, recipient]); // SIGN with both SENDER and RECIPIENT keypair +const transactionBinary = transaction.serialize(); +const blockhashInfo = await connection.getLatestBlockhashAndContext({ commitment: "confirmed" }); + +const signature = await connection.sendRawTransaction(transactionBinary, { + maxRetries: 0, + skipPreflight: true, +}); + +// Log the signature immediately after sending, before confirmation +console.log(`Transaction sent: https://solscan.io/tx/${signature}`); + +try { + const confirmation = await connection.confirmTransaction({ + signature, + blockhash: blockhashInfo.value.blockhash, + lastValidBlockHeight: blockhashInfo.value.lastValidBlockHeight, + }, "confirmed"); + + if (confirmation.value.err) { + console.error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`); + console.log(`Examine the failed transaction: https://solscan.io/tx/${signature}`); + } else { + console.log(`Transaction successful: https://solscan.io/tx/${signature}`); + }; +} catch (error) { + console.error(`Error confirming transaction: ${error}`); + console.log(`Examine the transaction status: https://solscan.io/tx/${signature}`); +}; +``` + + +## Imports + +```js +import { create_invite_code, invite_code_to_priv_key } from "./utils.js"; +import { + Connection, + Keypair, +} from "@solana/web3.js"; +import fs from "fs"; + +const connection = new Connection('insert-rpc'); +const senderPrivateKey = JSON.parse(fs.readFileSync('/Path/to/sender/id.json', 'utf8').trim()); +const sender = Keypair.fromSecretKey(new Uint8Array(senderPrivateKey)); +``` + +## Create Invite Code + +```js +// STEP 1: Create 12-character invite code +const invite_code = await create_invite_code(); + +// STEP 2: Derive secret key (public and private key) +const secret_key = invite_code_to_priv_key(invite_code); + +// STEP 3: Use secret key to create Solana Keypair instance +const recipient = Keypair.fromSecretKey(secret_key); +``` + +## Craft Send + + +**API PARAMS** + + * The `amount` is in its atomic value before applying decimals, e.g. 1 USDC is 1\_000\_000. + * The `mint` defaults to SOL if not provided, if provided it can be any token mint. + + + +**SIGNING AND SENDING** + + * After getting the transaction, you need to sign with **both sender and recipient** keypair. + * You can send the transaction to the network via any method. + + +```js +// STEP 4: Post request for a Send transaction +const craftSendTransaction = await ( + await fetch ('https://lite-api.jup.ag/send/v1/craft-send', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + inviteSigner: recipient.publicKey.toBase58(), + sender: sender.publicKey.toBase58(), + amount: "10000000", + // mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + }, null, 2) + }) +).json(); +``` diff --git a/mintlify-migration/docs/send-api/invite-code.mdx b/mintlify-migration/docs/send-api/invite-code.mdx new file mode 100644 index 00000000..703966d8 --- /dev/null +++ b/mintlify-migration/docs/send-api/invite-code.mdx @@ -0,0 +1,400 @@ +--- +title: "Invite Code (Beta)" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/send/v1` + * Pro URL: `https://api.jup.ag/send/v1` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +## Security + +The Send API is designed for **transaction building only** - it expects and exchanges parameters such as public keys, amounts, and mint addresses. The API **does not handle private keys or invite codes** for security reasons. + +**All cryptographic operations must be performed client-side:** + +* Invite code generation +* Private key derivation from invite codes +* Transaction signing + +The following sections provide the complete implementation steps required before using the API. + + + **WARNING** + + **CRITICAL SECURITY REQUIREMENTS** + + * **Never share invite codes or private keys** - treat them like passwords or seed phrases + * **Store invite codes securely** - use encrypted storage, secure vaults, or environment variables + * **Validate all inputs** - ensure invite codes meet expected format before processing + * **Implement proper error handling** - avoid exposing sensitive data in logs or error messages + + **⚠️ Loss of funds:** Any exposure of invite codes or private keys may result in permanent loss of funds. Jupiter is not liable for losses due to compromised credentials. + + +## Overview + + + + Create invite code. + + + From utils, derive the secret key - a deterministic 64-byte Solana secret key (32 bytes private + 32 bytes public key). + + + Create Solana Keypair instance from the secret key. + + + Post request to get Send transaction. + * If `craft-clawback`, requires an additional `invitePDA` to be passed in. + + + Sign with both sender and recipient keypair, then send transaction and wait for confirmation. + + + + + + +```js +import crypto from "crypto"; +import * as ed from "@noble/ed25519"; +import { sha512 } from "@noble/hashes/sha512"; +const hashFunction = (...messages) => sha512(ed.etc.concatBytes(...messages)); +ed.etc.sha512Sync = hashFunction; + +const { createHash } = await import("node:crypto"); + +// This function creates a random 12-character base58 invite code +// Uses 13 random bytes (~1.4 quintillion possible codes) +export async function create_invite_code() { + const buf = crypto.randomBytes(13); + + // 58^12 = 1.449225352 e21 + return binary_to_base58(new Uint8Array(buf)).substring(0, 12); +}; + +// This function converts an invite code to a deterministic private key +// Uses SHA256 hash of `"invite:"` + `invite_code` as the seed +// Returns a 64-byte Solana keypair (32 bytes private + 32 bytes public key) +export function invite_code_to_priv_key(invite_code) { + // Hash the invite code with a prefix + const pre_hash = "invite:" + invite_code; + const sha = createHash("sha256"); + const priv_key = crypto.createHash("sha256").update(pre_hash).digest(); + + // Use ed25519 to get the public key + const pub_key = ed.getPublicKey(new Uint8Array(priv_key)); + const solana_priv_key = new Uint8Array(64); + solana_priv_key.set(priv_key); + solana_priv_key.set(pub_key, 32); + + return solana_priv_key; +}; + +///////////////////////////////////////////////////////////////////////////////////// +// Taken from https://github.com/pur3miish/base58-js +const base58_chars = + "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; +const create_base58_map = () => { + const base58M = Array(256).fill(-1); + for (let i = 0; i < base58_chars.length; ++i) + base58M[base58_chars.charCodeAt(i)] = i; + + return base58M; +}; + +const base58Map = create_base58_map(); +export function binary_to_base58(uint8array) { + const result = []; + + for (const byte of uint8array) { + let carry = byte; + for (let j = 0; j < result.length; ++j) { + const x = (base58Map[result[j]] << 8) + carry; + result[j] = base58_chars.charCodeAt(x % 58); + carry = (x / 58) | 0; + } + while (carry) { + result.push(base58_chars.charCodeAt(carry % 58)); + carry = (carry / 58) | 0; + } + } + + for (const byte of uint8array) + if (byte) break; + else result.push("1".charCodeAt(0)); + + result.reverse(); + + return String.fromCharCode(...result); +} + +export function base58_to_binary(base58String) { + if (!base58String || typeof base58String !== "string") + throw new Error(`Expected base58 string but got “${base58String}”`); + if (base58String.match(/[IOl0]/gmu)) + throw new Error( + `Invalid base58 character “${base58String.match(/[IOl0]/gmu)}”` + ); + const lz = base58String.match(/^1+/gmu); + const psz = lz ? lz[0].length : 0; + const size = + ((base58String.length - psz) * (Math.log(58) / Math.log(256)) + 1) >>> 0; + + return new Uint8Array([ + ...new Uint8Array(psz), + ...base58String + .match(/.{1}/gmu) + .map((i) => base58_chars.indexOf(i)) + .reduce((acc, i) => { + acc = acc.map((j) => { + const x = j * 58 + i; + i = x >> 8; + return x; + }); + return acc; + }, new Uint8Array(size)) + .reverse() + .filter( + ( + (lastValue) => (value) => + (lastValue = lastValue || value) + )(false) + ), + ]); +} +///////////////////////////////////////////////////////////////////////////////////// + ``` + + + +```js +import { create_invite_code, invite_code_to_priv_key } from "./utils.js"; +import { + Connection, + Keypair, + VersionedTransaction, +} from "@solana/web3.js"; +import fs from "fs"; + +const connection = new Connection('insert-rpc'); +const senderPrivateKey = JSON.parse(fs.readFileSync('/Path/to/sender/id.json', 'utf8').trim()); +const sender = Keypair.fromSecretKey(new Uint8Array(senderPrivateKey)); + +// STEP 1: Create 12-character invite code +const invite_code = await create_invite_code(); + +// STEP 2: Derive secret key (public and private key) +const secret_key = invite_code_to_priv_key(invite_code); + +// STEP 3: Use secret key to create Solana Keypair instance +const recipient = Keypair.fromSecretKey(secret_key); + +// STEP 4: Post request for a Send transaction +const craftSendTransaction = await ( + await fetch ('https://lite-api.jup.ag/send/v1/craft-send', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + inviteSigner: recipient.publicKey.toBase58(), + sender: sender.publicKey.toBase58(), + amount: "10000000", // atomic amount before decimals + // mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // Defaults to SOL if `mint` is not provided + }, null, 2) + }) +).json(); + +// STEP 5: Use sender and receipient keypair to sign and send to network +const transaction = VersionedTransaction.deserialize(Buffer.from(craftSendTransaction.tx, 'base64')); +transaction.sign([sender, recipient]); // SIGN with both SENDER and RECIPIENT keypair +const transactionBinary = transaction.serialize(); +const blockhashInfo = await connection.getLatestBlockhashAndContext({ commitment: "confirmed" }); + +const signature = await connection.sendRawTransaction(transactionBinary, { + maxRetries: 0, + skipPreflight: true, +}); + +// Log the signature immediately after sending, before confirmation +console.log(`Transaction sent: https://solscan.io/tx/${signature}`); + +try { + const confirmation = await connection.confirmTransaction({ + signature, + blockhash: blockhashInfo.value.blockhash, + lastValidBlockHeight: blockhashInfo.value.lastValidBlockHeight, + }, "confirmed"); + + if (confirmation.value.err) { + console.error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`); + console.log(`Examine the failed transaction: https://solscan.io/tx/${signature}`); + } else { + console.log(`Transaction successful: https://solscan.io/tx/${signature}`); + }; +} catch (error) { + console.error(`Error confirming transaction: ${error}`); + console.log(`Examine the transaction status: https://solscan.io/tx/${signature}`); +}; +``` + + + +## Prerequisite + +### Dependencies + +```bash +npm install @solana/web3.js@1 # Using v1 of web3.js instead of v2 +npm install dotenv # Useful for testing and handling of invite code and private key +npm install @noble/ed25519 +npm install @noble/hashes +``` + +### Imports + +Create a utils file to add these functions + +```js +import crypto from "crypto"; +import * as ed from "@noble/ed25519"; +import { sha512 } from "@noble/hashes/sha512"; +import { PublicKey } from "@solana/web3.js"; + +// Configure the ed25519 library to use SHA-512 for internal operations +// This is REQUIRED before using any ed25519 functions like getPublicKey() +// The library needs to know which hash function to use for key derivation and signing +const hashFunction = (...messages) => sha512(ed.etc.concatBytes(...messages)); +ed.etc.sha512Sync = hashFunction; + +// Import createHash function from Node.js crypto module using dynamic import +// This allows us to use the modern 'node:crypto' protocol for better compatibility +// createHash is used for SHA-256 hashing in the invite code functions +const { createHash } = await import("node:crypto"); +``` + +## Functions + +### Create Invite Code + +```js +// This function creates a random 12-character base58 invite code +// Uses 13 random bytes (~1.4 quintillion possible codes) +export async function create_invite_code() { + const buf = crypto.randomBytes(13); + + // 58^12 = 1.449225352 e21 + return binary_to_base58(new Uint8Array(buf)).substring(0, 12); +}; +``` + +### Derive Solana Secret Key + +```js +// This function converts an invite code to a deterministic private key +// Uses SHA256 hash of `"invite:"` + `invite_code` as the seed +// Returns a 64-byte Solana secret key (32 bytes private + 32 bytes public key) +export function invite_code_to_priv_key(invite_code) { + // Hash the invite code with a prefix + const pre_hash = "invite:" + invite_code; + const sha = createHash("sha256"); + const priv_key = crypto.createHash("sha256").update(pre_hash).digest(); + + // Use ed25519 to get the public key + const pub_key = ed.getPublicKey(new Uint8Array(priv_key)); + const solana_priv_key = new Uint8Array(64); + solana_priv_key.set(priv_key); + solana_priv_key.set(pub_key, 32); + + return solana_priv_key; +}; +``` + +### Convert Binary To Base58 + +```js expandable +///////////////////////////////////////////////////////////////////////////////////// +// Taken from https://github.com/pur3miish/base58-js +const base58_chars = + "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; +const create_base58_map = () => { + const base58M = Array(256).fill(-1); + for (let i = 0; i < base58_chars.length; ++i) + base58M[base58_chars.charCodeAt(i)] = i; + + return base58M; +}; + +const base58Map = create_base58_map(); +export function binary_to_base58(uint8array) { + const result = []; + + for (const byte of uint8array) { + let carry = byte; + for (let j = 0; j < result.length; ++j) { + const x = (base58Map[result[j]] << 8) + carry; + result[j] = base58_chars.charCodeAt(x % 58); + carry = (x / 58) | 0; + } + while (carry) { + result.push(base58_chars.charCodeAt(carry % 58)); + carry = (carry / 58) | 0; + } + } + + for (const byte of uint8array) + if (byte) break; + else result.push("1".charCodeAt(0)); + + result.reverse(); + + return String.fromCharCode(...result); +} + +export function base58_to_binary(base58String) { + if (!base58String || typeof base58String !== "string") + throw new Error(`Expected base58 string but got “${base58String}”`); + if (base58String.match(/[IOl0]/gmu)) + throw new Error( + `Invalid base58 character “${base58String.match(/[IOl0]/gmu)}”` + ); + const lz = base58String.match(/^1+/gmu); + const psz = lz ? lz[0].length : 0; + const size = + ((base58String.length - psz) * (Math.log(58) / Math.log(256)) + 1) >>> 0; + + return new Uint8Array([ + ...new Uint8Array(psz), + ...base58String + .match(/.{1}/gmu) + .map((i) => base58_chars.indexOf(i)) + .reduce((acc, i) => { + acc = acc.map((j) => { + const x = j * 58 + i; + i = x >> 8; + return x; + }); + return acc; + }, new Uint8Array(size)) + .reverse() + .filter( + ( + (lastValue) => (value) => + (lastValue = lastValue || value) + )(false) + ), + ]); +} +///////////////////////////////////////////////////////////////////////////////////// +``` diff --git a/mintlify-migration/docs/send-api/manage-invites.mdx b/mintlify-migration/docs/send-api/manage-invites.mdx new file mode 100644 index 00000000..5e470917 --- /dev/null +++ b/mintlify-migration/docs/send-api/manage-invites.mdx @@ -0,0 +1,63 @@ +--- +title: "Manage Invites (Beta)" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/send/v1` + * Pro URL: `https://api.jup.ag/send/v1` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +## Overview + + + + Get pending invites. + + + Get invite history. + + + + + **NOTE** + + Both of the following endpoints only returns the invites that are set up by the sender and not from the perspective of the recipient. + + * Pending invites: Invites created by the sender that are not yet expired and can be clawback/claimed. + * Invite history: Invites created by the sender and is either claimed, clawback, or expired. (You can also pass in a Recipient pubkey to get their history) + + + + **TIP** + + Depending on how you have set up to allow connection of wallets, either via [Jupiter Mobile Adapter](/docs/tool-kits/mobile-adapter) for QR code login, wallet extensions, or any other methods, you will need to handle the passing in of their pubkey to the API to get the necessary data. + + +## Get Pending Invites + +```js +const pendingInvites = await ( + await fetch( + `https://lite-api.jup.ag/send/v1/pending-invites?address=${pubkey}` + ) +).json(); +``` + +## Get Invite History + +```js +const inviteHistory = await ( + await fetch( + `https://lite-api.jup.ag/send/v1/invite-history?address=${pubkey}` + ) +).json(); +``` diff --git a/mintlify-migration/docs/studio-api.mdx b/mintlify-migration/docs/studio-api.mdx new file mode 100644 index 00000000..5ecf9521 --- /dev/null +++ b/mintlify-migration/docs/studio-api.mdx @@ -0,0 +1,61 @@ +--- +title: "Studio API" +description: "Studio is built for culture architects who want:" +--- + +* Aggressive experimentation. +* Tools for growth and alignment. +* Collaborative and supportive vibe culture between Studio projects. + +## About + +Studio is a powerful playground equipped with a suite of tools for creators. Each feature is strategic towards how creators might want to customize to fit their needs - like flexible bonding curves, custom vesting schedules, and selectable quote mints to encode your vision. + +**Features** + +* LP Fees: 50% before AND after graduation. +* LP Locking: Optional 50% of the graduated LP unlocks after 1 year. +* Vested Tokens: 0 - 80% of token supply, with optional vesting schedule and cliff. +* Flexible parameters: Quote mint, Market cap bonding, etc. +* Other helpful tools: Anti-sniper suite, Lp Locking. + +**Dedicated Studio Token Page** + +Apart from the strategic levers, start rallying your community with the dedicated Studio page with seamless content integration with jup.ag's token page. + +* Dedicated Studio page for each token. +* Content from Studio shows up in jup.ag's token page. + + + **READINGS** + + - Design intentions: [https://x.com/9yointern/status/1940431614103937517](https://x.com/9yointern/status/1940431614103937517) + - Launch post: [https://x.com/jup\_studio/status/1940620377602011566](https://x.com/jup_studio/status/1940620377602011566) + - General FAQ: [https://support.jup.ag/hc/en-us/categories/21148110700060-Studio](https://support.jup.ag/hc/en-us/categories/21148110700060-Studio) + + +## FAQ + + + + + +* In order for us to track and store your token information, header image or token description, you **must** send your signed transaction from the `create_tx` endpoint to the `submit` endpoint. +* This will allow us to store your token into our database and reflect it as a Studio token on our frontend. +* If you submit the transaction on your own or some other way, the token will not have a dedicated Studio page. + + + + +* Those URLs are for you to upload your token's metadata and image to a static endpoint, which will be in the token's URI metadata onchain. +* You are required to make a PUT request to those endpoints, [you can refer to this section on the usage](/docs/studio-api/create-token#token-metadata). +* If you do not upload your token image and metadata to this endpoint, your token will not have any image/metadata reflected onchain. + + + + +* Lite URL: `https://lite-api.jup.ag/studio/v1`: 100 requests per 5 minutes +* Pro URL: `https://api.jup.ag/studio/v1`: 10 requests per 10 seconds (for all Tiers) + + + diff --git a/mintlify-migration/docs/studio-api/claim-fee.mdx b/mintlify-migration/docs/studio-api/claim-fee.mdx new file mode 100644 index 00000000..45ff89d8 --- /dev/null +++ b/mintlify-migration/docs/studio-api/claim-fee.mdx @@ -0,0 +1,178 @@ +--- +title: "Claim Fee (Beta)" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/studio/v1`: 100 requests per 5 minutes + * Pro URL: `https://api.jup.ag/studio/v1`: 10 requests per 10 seconds (for all Tiers) + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + + + **API REFERENCE** + + To fully utilize the Studio API, check out the [Studio API Reference](/api/studio-api). + + +## Prerequisite + + + + +```bash +npm install @solana/web3.js@1 # Using v1 of web3.js instead of v2 +npm install dotenv # If required for wallet setup +``` + + + + + **Set up RPC** + + + **NOTE** + + Solana provides a [default RPC endpoint](https://solana.com/docs/core/clusters). However, as your application grows, we recommend you to always use your own or provision a 3rd party provider’s RPC endpoint such as [Helius](https://helius.dev/) or [Triton](https://triton.one/). + + +```js +import { Connection } from '@solana/web3.js'; + +const connection = new Connection('https://api.mainnet-beta.solana.com'); +``` + + + + + **Set up Development Wallet** + + + **NOTE** + + * You can paste in your private key for testing purposes but this is not recommended for production applications. + * If you want to store your private key in the project directly, you can do it via a `.env` file. + + +To set up a development wallet via `.env` file, you can use the following script. + +```js +// index.js +import { Keypair } from '@solana/web3.js'; +import dotenv from 'dotenv'; +require('dotenv').config(); +const wallet = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY || '')); + ``` + +```bash +# .envPRIVATE_KEY='' +``` + +To set up a development wallet via a wallet generated via [Solana CLI](https://solana.com/docs/intro/installation#solana-cli-basics), you can use the following script. + +```js +import { Keypair } from '@solana/web3.js'; +import fs from 'fs'; + +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/To/.config/solana/id.json', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); +``` + + + + +```js +transaction.sign([wallet]); +const transactionBinary = transaction.serialize(); +console.log(transactionBinary); +console.log(transactionBinary.length); +const blockhashInfo = await connection.getLatestBlockhashAndContext({ commitment: 'finalized' }); + +const signature = await connection.sendRawTransaction(transactionBinary, { + maxRetries: 0, + skipPreflight: true, +}); + +console.log(`Transaction sent: https://solscan.io/tx/${signature}`); + +try { + const confirmation = await connection.confirmTransaction({ + signature, + blockhash: blockhashInfo.value.blockhash, + lastValidBlockHeight: blockhashInfo.value.lastValidBlockHeight, + }, 'confirmed'); + + if (confirmation.value.err) { + console.error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`); + console.log(`Examine the failed transaction: https://solscan.io/tx/${signature}`); + } else { + console.log(`Transaction successful: https://solscan.io/tx/${signature}`); + } +} catch (error) { + console.error(`Error confirming transaction: ${error}`); + console.log(`Examine the transaction status: https://solscan.io/tx/${signature}`); +}; +``` + + + +## Pool Address + +Your successfully created token via Jupiter Studio, should have a newly generated token mint. By using the mint, you can get the config key and pool addresses associated to it: Dynamic Bonding Curve pool and Meteora DAMM V2 pool. + +```js +const poolAddressResponse = await ( + await fetch( + `https://lite-api.jup.ag/studio/v1/dbc-pool/addresses/${mint}`, + ) +).json(); +``` + +## Fee + +Using the Pool Address, you will be able to get the total and current unclaimed fees in the Dynamic Bonding Curve pool. + +```js +const feeResponse = await ( + await fetch ( + 'https://lite-api.jup.ag/studio/v1/dbc/fee', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + poolAddress: poolAddressResponse.data.dbcPoolAddress, + }, null, 2) + }) +).json(); +``` + +## Claim Fee + +In order to claim fees from a Dynamic Bonding Curve pool, you will need to pass in the pool address into this endpoint and we will create the Claim Fee transaction for you. After receiving the transaction, you will need to sign and submit the transaction to the network on your own ([refer to Transaction Sending Example above](#prerequisite)). + +```js +const claimTransaction = await ( + await fetch ( + 'https://lite-api.jup.ag/studio/v1/dbc/fee/create-tx', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + ownerWallet: wallet.publicKey.toBase58(), + poolAddress: poolAddressResponse.data.dbcPoolAddress, + maxQuoteAmount: 1000000, // e.g. 1 USDC (depending on quote mint and decimals) + }, null, 2) + }) +).json(); +``` diff --git a/mintlify-migration/docs/studio-api/create-token.mdx b/mintlify-migration/docs/studio-api/create-token.mdx new file mode 100644 index 00000000..bb753bf7 --- /dev/null +++ b/mintlify-migration/docs/studio-api/create-token.mdx @@ -0,0 +1,296 @@ +--- +title: "Create Token (Beta)" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/studio/v1`: 100 requests per 5 minutes + * Pro URL: `https://api.jup.ag/studio/v1`: 10 requests per 10 seconds (for all Tiers) + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + + + **API REFERENCE** + + To fully utilize the Studio API, check out the [Studio API Reference](/api/studio-api). + + +## Prerequisite + + + + + +```bash +npm install @solana/web3.js@1 # Using v1 of web3.js instead of v2 +npm install dotenv # If required for wallet setup +``` + + + + + **Set up Development Wallet** + + + **NOTE** + + * You can paste in your private key for testing purposes but this is not recommended for production applications. + * If you want to store your private key in the project directly, you can do it via a `.env` file. + + + To set up a development wallet via `.env` file, you can use the following script. + +```js +// index.js +import { Keypair } from '@solana/web3.js'; +import dotenv from 'dotenv'; +require('dotenv').config(); + +const wallet = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY || '')); +``` + +```bash +# .env +PRIVATE_KEY='' +``` + + To set up a development wallet via a wallet generated via [Solana CLI](https://solana.com/docs/intro/installation#solana-cli-basics), you can use the following script. + +```js +import { Keypair } from '@solana/web3.js'; +import fs from 'fs'; + +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/To/.config/solana/id.json', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); +``` + + + +## Create Transaction + +This endpoint helps you create a few key components to launch your token on Studio. + +1. `transaction`: A base64-encoded unsigned transaction. +2. `mint`: The mint of the token that is being created. +3. `imagePresignedUrl`: A `PUT` request endpoint to upload your token image. +4. `metadataPresignedUrl`: A `PUT` request endpoint to upload your token metadata. +5. `imageUrl`: The token's static image url to be used in the metadata. + + + **PRESETS** + + On [https://jup.ag/studio](https://jup.ag/studio), you can find a few different presets to get you started. + + + + + + **Great for memes, similar profile to traditional meme launches.** + + * People begin buying your token at 16K Market Cap (MC) in USDC. + * It graduates to a Meteora pool at 69K MC. + * Your pool raises \~17.94K USDC before graduation. + +```js +buildCurveByMarketCapParam: { + quoteMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + initialMarketCap: 16000, + migrationMarketCap: 69000, + tokenQuoteDecimal: 6, + lockedVestingParam: { + totalLockedVestingAmount: 0, + cliffUnlockAmount: 0, + numberOfVestingPeriod: 0, + totalVestingDuration: 0, + cliffDurationFromMigrationTime: 0, + }, +}, +antiSniping: false, +fee: { feeBps: 100, }, +isLpLocked: true, +tokenName: '', +tokenSymbol: '', +tokenImageContentType: 'image/jpeg', +creator: wallet.publicKey.toBase58(), +``` + + + + + **For projects ready to take it up a notch. More capital required to bond, but you'll have deeper liquidity and more LP fees when you graduate.** + + * People begin buying your token at 32k Market Cap (MC) in USDC. + * It graduates to a Meteora pool at 240k MC. + * Your pool raises \~57.78K USDC before graduation. + * 10% of total supply will be vested daily over 12 months. + +```js +buildCurveByMarketCapParam: { + quoteMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', + initialMarketCap: 32000, + migrationMarketCap: 240000, + tokenQuoteDecimal: 6, + lockedVestingParam: { + totalLockedVestingAmount: 100000000, + cliffUnlockAmount: 0, + numberOfVestingPeriod: 365, + totalVestingDuration: 31536000, + cliffDurationFromMigrationTime: 0, + }, +}, +antiSniping: true, +fee: { feeBps: 100, }, +isLpLocked: true, +tokenName: '', +tokenSymbol: '', +tokenImageContentType: 'image/jpeg', +creator: wallet.publicKey.toBase58(), +``` + + + + Just pass in the parameters you need! + + + + +```js +const createTransaction = await ( + await fetch ( + 'https://lite-api.jup.ag/studio/v1/dbc-pool/create-tx', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + buildCurveByMarketCapParam: { + quoteMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // or SOL or JUP + initialMarketCap: 16000, // This means 16_000 USDC + migrationMarketCap: 69000, // This means 69_000 USDC + tokenQuoteDecimal: 6, + lockedVestingParam: { + totalLockedVestingAmount: 0, + cliffUnlockAmount: 0, + numberOfVestingPeriod: 0, + totalVestingDuration: 0, + cliffDurationFromMigrationTime: 0, + }, + }, + antiSniping: true, + fee: { feeBps: 100, }, + isLpLocked: true, + tokenName: '', + tokenSymbol: '', + tokenImageContentType: 'image/jpeg', + creator: wallet.publicKey.toBase58(), + }, null, 2) + }) +).json(); +``` + +## Token Metadata + +The following 2 steps, are to upload your token image and metadata to the **static URL**, which will be the URI in the onchain metadata of your token. + +Example + +* URI/ Off-chain Metadata: `https://static-create.jup.ag/metadata/{mint}.json` +* Image: `https://static-create.jup.ag/images/{mint}` + +You can refer to this to understand Token Metadata on Solana: [https://developers.metaplex.com/token-metadata](https://developers.metaplex.com/token-metadata) + +### Upload Image + +From the response of the `create-tx` endpoint, we will need the `imagePresignedUrl` to make a **`PUT` request** to the url provided, in order to upload the token image. + +```js +const imageResponse = await fetch(createTransaction.imagePresignedUrl, { + method: 'PUT', + headers: { + 'Content-Type': 'image/jpeg', // Adjust based on the image type passed in previously + }, + body: fs.readFileSync('./token.jpeg'), // Assuming the image file is located in the same folder +}); +``` + +### Upload Metadata + +From the response of the `create-tx` endpoint, we will need the `metadataPresignedUrl` to make a **`PUT` request** to the url provided, in order to upload the token metadata. + +```js +const metadataResponse = await fetch(createTransaction.metadataPresignedUrl, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + name: '', + symbol: '', + description: '', + image: createTransaction.imageUrl, + website: '', + twitter: '', + telegram: '', + }, null, 2), +}); +``` + +## Submit Transaction + +After you have uploaded your token image and token metadata, you can proceed to signing and making a post request to the `submit` endpoint - this will allow Jupiter Studio to complete the transaction and submit it to the network on your behalf. + + + **NOTE** + + * Do note that the endpoint expects the `requestBody`'s `content` to be in [`multipart/form-data` format](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest_API/Using_FormData_Objects). + * Ensure the file types and size of the image file is manageable. + + + + **NOTE** + + The `content` and `headerImage` refers to the Studio dedicated page's token description and header image of the page, they are not on-chain metadata. This is meant for you to customize the Studio dedicated page as you wish - to include lore, story or just a nice looking banner! + + The `content` and `headerImage` are stored off-chain for our frontend to ingest and display. + + [Do not confuse this with the uploading of token metadata, they are done separately.](#token-metadata) + + +```js +import { VersionedTransaction } from '@solana/web3.js'; +import fs from 'fs'; + +const transaction = VersionedTransaction.deserialize(Buffer.from(createTransaction.transaction, 'base64')); +transaction.sign([wallet]); +const signedTransaction = Buffer.from(transaction.serialize()).toString('base64'); + +const formData = new FormData(); +formData.append('transaction', signedTransaction); +formData.append('owner', wallet.publicKey.toBase58()); +formData.append('content', ''); +formData.append( + 'headerImage', + new File( + [fs.readFileSync('/Path/to/header.jpeg')], + 'header.jpeg', + { type: 'image/jpeg' }, + ) +); + +const result = await ( + await fetch ( + 'https://lite-api.jup.ag/studio/v1/dbc-pool/submit', + { + method: 'POST', + body: formData, + }) +).json(); +``` diff --git a/mintlify-migration/docs/swap-api.mdx b/mintlify-migration/docs/swap-api.mdx new file mode 100644 index 00000000..5eeda769 --- /dev/null +++ b/mintlify-migration/docs/swap-api.mdx @@ -0,0 +1,55 @@ +--- +title: "About Swap API" +description: "The Jupiter Swap API enables you to tap into the Jupiter Metis v1 Routing Engine, which aggregates across all liquidity available within the DEXes of Solana's DeFi ecosystem, allowing you to swap seamlessly from any token to any token." +--- + +## Features + +| Feature | Description | +| :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **Robust routing engine** | The Jupiter Metis v1 Routing Engine is a robust and battle-tested routing engine that has been in production for over 2 years with multiple DEXes integrated and trillions of dollars in volume. | +| **Best on-chain price** | Trades can split across multiple different on-chain tokens and AMMs to ensure the best possible on-chain price. | +| **Swap any token** | Swap from any token to another token. | +| **Zero platform fees** | Swaps made via the Swap API do not incur any trading fees, both for you and your users. | +| **Custom integrator fees** | Integrators can choose to charge their own custom fees. | +| **Slippage protection** | Routes are intentionally chosen to decrease the likelihood of trade failures due to price slippage. | +| **Fine-grained control** | Allows for full control of how your transaction is crafted and broadcasted. | + +## What About Ultra API? + +Ultra API is the spiritual successor to Swap API, and is much simpler to use than Swap API. If you are first starting out on your Solana development journey, using Ultra API is highly recommended over Swap API. + +However, unlike Ultra API, Swap API allows developers to: + +* Add custom instructions. +* Add Cross Program Invocation (CPI) calls. +* Choose the broadcasting strategy for the signed transaction (ie. via priority fee, Jito, etc.). +* Choose which DEXes or AMMs to route through. +* Modify the number of accounts to use in a transaction. + +If you have a highly custom need like what is described above, then Swap API may be for you. However, with Swap API, there are many more things you need to worry about that Ultra API automatically handles for: + +* **Upkeep of RPCs**: To retrieve wallet balances, broadcast and retrieve transactions, etc. +* **Deciding transaction fee**: Including, but not limited to, priority fee, Jito fee, etc. +* **Deciding slippage**: The optimal slippage to use to balance between trade success and price protection, do note that [RTSE is only available via Ultra API](/docs/ultra-api#real-time-slippage-estimator). +* **Broadcasting the transaction**: Ultra uses a proprietary transaction sending engine which dramatically improves landing rate and speed. +* **Parsing the swap results**: Polling and parsing the resulting transaction from the RPC, including handling for success and error cases. + +If the above sounds like too much work, then Ultra API will be the better choice. + +## Getting Started with Swap API + +1. [**Get Quote**](/docs/swap-api/get-quote): Request for a quote which consists of the route plan, and other params such as integrator fee, slippage, etc. + +2. [**Build Swap Transaction**](/docs/swap-api/build-swap-transaction): Post the quote to build a swap transaction. + + * You can utilize other methods to return swap instructions or use CPI rather than the default swap transaction. + * You can utilize other parameters such as priority fee, dynamic slippage, etc to customize the transaction. + +3. [**Send Swap Transaction**](/docs/swap-api/send-swap-transaction): Sign and send the swap transaction to the network via your preferred RPC or other methods. + +**Other Guides** + +* [**Adding Fees to Swap API**](/docs/swap-api/add-fees-to-swap): Add custom integrator fees to the swap transaction. +* [**Using Swap API as a payment method**](/docs/swap-api/payments-through-swap): Use Swap API as a payment method for your users. +* [**Using Jupiter Plugin**](/docs/tool-kits/plugin): Lite version of Jupiter that provides end-to-end swap with just a few lines of code. diff --git a/mintlify-migration/docs/swap-api/add-fees-to-swap.mdx b/mintlify-migration/docs/swap-api/add-fees-to-swap.mdx new file mode 100644 index 00000000..c6071f1b --- /dev/null +++ b/mintlify-migration/docs/swap-api/add-fees-to-swap.mdx @@ -0,0 +1,220 @@ +--- +title: "Add Fees To Swap" +--- + + + **INFO** + + As of January 2025, when integrating the Swap API, you no longer need to use the Referral Program to set up a `referralAccount` and `referralTokenAccount` to collect fees from the swaps you provide to the end users. + + Simply, just pass in any valid token account as the `feeAccount` parameter in the Swap API. + + However, do note that **it is still applicable to the Trigger API**. + + + + **NOTE** + + You can still find information about the Referral Program. + + The Referral Program is an open source program by Jupiter to provide referral fees for integrators who are integrating Jupiter Swap and Jupiter Limit Order. You can check out the code [here](https://github.com/TeamRaccoons/referral) to gain a better understanding of how it works. + + +## Use Case + +By default, there are **zero** protocol fees on Jupiter Swap. Integrators have the option to introduce a platform fee denoted in basis points, e.g. **20 bps** for **0.2%** of the token input or output. + +### Important Notes + +* **Input mint or the output mint** on the swap for ExactIn. +* **Input mint ONLY** on the swap for ExactOut. +* Example, if you swap JUP to USDC, you cannot take fees in SOL, it has to be part of the swap. +* It does not support Token2022 tokens. +* Referral Program is no longer required. + + + + **Important Notes** + + * The Jupiter Swap project account for the Referral Program is `45ruCyfdRkWpRNGEqWzjCiXRHkZs8WXCLQ67Pnpye7Hp`. + + * The `referralTokenAccount` can either be: + + * **Input mint or the output mint** on the swap for ExactIn. + * **Input mint ONLY** on the swap for ExactOut. + + * You can use the [Dashboard](https://referral.jup.ag/dashboard), [SDK](https://github.com/TeamRaccoons/referral/blob/main/example/src/createReferralAccount.ts) or [API](https://referral.jup.ag/api) to set up the `referralAccount` and `referralTokenAccount` in this guide. + + **Let’s Get Started** + + **1. Set up** + + You will need to complete the prerequisites and understanding of [Environment Setup](/docs/environment-setup) and [Get Quote and Swap](/docs/swap-api/get-quote) guide as this is reliant on the Swap API. + + **Obtain `referralAccount` and `referralTokenAccount`** + + There are 3 ways you can set up a referral account. + + 1. Use our [referral dashboard](https://referral.jup.ag/dashboard) to create them. After creating, remember to find your `Referral Key` on the page and the associated token accounts. + 2. Use our SDK to create them. You can use the [example scripts](https://github.com/TeamRaccoons/referral/tree/main/example/src) to create. + 3. Use our API to create them. You can use this [API reference](https://referral.jup.ag/api) to create. + + **Obtain `mintAccount`** + + As for the mint account, assuming you have an interface where a user swaps, you will know up front what are the input or output mints. For the sake of example, we will use a hardcoded mint public key. + + ```js + const referralAccount = new Publickey('ReplaceWithPubkey'); + const mintAccount = new Publickey('So11111111111111111111111111111111111111112'); + ``` + + **2. Set your referral fee in Quote** + + Setting your referral fee is simple, just add `platformFeeBps` parameter to the `/quote` endpoint. + + In this example, we set `platformFeeBps` to `20` which equates to 0.2%. + + ```js + const quoteResponse = await ( + await fetch( + 'https://lite-api.jup.ag/swap/v1/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000&slippageBps=50&restrictIntermediateTokens=true&platformFeeBps=20' + ) + ).json(); + +console.log(JSON.stringify(quoteResponse, null, 2)); + ``` + + **3. Set your referral token account in Swap** + + In order to refer and receive fees from all types of tokens, you will need to have already initialize `referralTokenAccount`s (owned by your `referralAccount`) for the mint in the swap. By calling the Swap API with the parameter `feeAccount`, which is the `referralTokenAccount`, you will receive the serialized swap transaction that will set a fee to be taken from the referred and sent to that token account. + + In this code block, we will be using the SDK to try to find the `referralTokenAccount` based on our previously defined `referralAccount` and `mintAccount`. + + * If the token account is found, it will proceed to the Swap API. + * If the token account is not found, it will send a transaction to the network to attempt to initialize one for the mint. **Do note that transactions may fail due to various reasons like Priority Fees.** + +```js +import { ReferralProvider } from "@jup-ag/referral-sdk"; + +const { tx, referralTokenAccountPubKey } = await provider.initializeReferralTokenAccount({ + payerPubKey: wallet.publicKey, + referralAccountPubKey: referralAccount, + mint: mintAccount, +}); + +const referralTokenAccount = await connection.getAccountInfo(referralTokenAccountPubKey); + +// Attempt to initialize a token account +if (!referralTokenAccount) { + const signature = await sendAndConfirmTransaction(connection, tx, [wallet]); + console.log({ signature, referralTokenAccountPubKey: referralTokenAccountPubKey.toBase58() }); + +// Since initialized, it will carry on +} else { + console.log(`referralTokenAccount ${referralTokenAccountPubKey.toBase58()} for mint ${mintAccount.toBase58()} already exists`); +}; + +const feeAccount = referralTokenAccountPubKey; +console.log(feeAccount); + ``` + + However, if you are confident that the `referralTokenAccount` for specific mints have been created, you can use this method to get it. **Do note that, even if the token account is not intialized, it will return a pubkey as it is a Program Derived Address. [Read more here.](https://solana.com/docs/core/pda#findprogramaddress)** + +```js +const [feeAccount] = PublicKey.findProgramAddressSync( + [ + Buffer.from("referral_ata"), // A string that signifies the account type, here "referral_ata." + referralAccount.toBuffer(), // The public key of the referral account converted into a buffer. + mintAccount.toBuffer(), // The mint public key, converted into a buffer. + ], + new PublicKey("REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3") // The public key of the Referral Program +); +``` + + Using the above, we will now know the `feeAccount` to be passed in as the parameter in Swap API. You can refer to the [Build Swap Transaction](/docs/swap-api/build-swap-transaction) guide to add any parameters where necessary to help transaction sending, etc. + +```js + const swapResponse = await ( + await fetch('https://lite-api.jup.ag/swap/v1/swap', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + quoteResponse, + userPublicKey: wallet.publicKey.toBase58(), // Pass in actual referred user in production + feeAccount: feeAccount, + }) + }) +).json(); +``` + + +### 1. Set up + +You will need to complete the prerequisites and understanding of [Environment Setup](/docs/environment-setup) and [Get Quote and Swap](/docs/swap-api/get-quote) guide as this is reliant on the Swap API. + +### 2. Set your fee in Quote + +Setting your fee is simple, just add `platformFeeBps` parameter to the `/quote` endpoint. + +In this example, we set `platformFeeBps` to `20` which equates to 0.2%. + +```js +const quoteResponse = await ( + await fetch( + 'https://lite-api.jup.ag/swap/v1/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000&slippageBps=50&restrictIntermediateTokens=true&platformFeeBps=20' + ) + ).json(); +``` + +### 3. Set your feeAccount in Swap + +In the `/swap` endpoint, you will need to pass in the `feeAccount` parameter. The `feeAccount` is any token account that will receive the fees from the swap. Do ensure that the token account is initialized and is the correct mint to receive the fees in. + +```js +const swapResponse = await ( + await fetch('https://api.jup.ag/swap/v1/swap', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + quoteResponse, + userPublicKey: wallet.publicKey, // Pass in actual referred user in production + feeAccount: feeAccount, + }) + }) +).json(); +``` + +### 4. Sign and send transaction + +Finally, the user can sign the transaction and it can be submitted to the network to be executed. You can refer to the [Send Swap Transaction](/docs/swap-api/send-swap-transaction) guide to complete this step. + +### Create Token Account + +To create a token account, you can use the following code or refer to [Solana Cookbook](https://solana.com/developers/cookbook/tokens/create-token-account). + +* The code creates the transaction to create the token account and handles the transaction siging and sending. +* If the token account already exists, it will not create and might throw an error such as `Provided owner is not allowed`. + +```js +import { createAssociatedTokenAccount } from "@solana/spl-token"; + +const mintPubkey = new PublicKey( + "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN", +); + +let ata = await createAssociatedTokenAccount( + connection, // connection + wallet, // fee payer + mintPubkey, // mint + wallet.publicKey, // owner of the token account + // confirmOptions, // if you need to skip simulation and send the transaction immediately + // programId, // if you need to use a different token program id such as token-2022 + // associatedTokenProgramId, + // allowOwnerOffCurve, // if you need to allow the owner to be off curve +); +console.log(`ATA: ${ata.toBase58()}`); +``` diff --git a/mintlify-migration/docs/swap-api/build-swap-transaction.mdx b/mintlify-migration/docs/swap-api/build-swap-transaction.mdx new file mode 100644 index 00000000..b8a71f86 --- /dev/null +++ b/mintlify-migration/docs/swap-api/build-swap-transaction.mdx @@ -0,0 +1,337 @@ +--- +title: "Build Swap Transaction" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/swap/v1/swap` + * Pro URL: `https://api.jup.ag/swap/v1/swap` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +The Swap API is one of the ways for you to interact with the Jupiter Swap Aggregator program. Before you send a transaction to the network, you will need to build the transaction that defines the instructions to execute and accounts to read/write to. + +It can be complex to handle this yourself, but good news! Most of our APIs and SDKs just handles it for you, so you get a response with the transaction to be prepared and sent to the network. + + + **USE SWAP API TO HANDLE IT FOR YOU OR...** + + If you are looking to interact with the Jupiter Swap Aggregator program in a different way, check out the other guides: + + **Swap Instructions** + + To compose with instructions and build your own transaction, [read how to use the `/swap-instructions` in this section](#build-your-own-transaction-with-instructions). + + **Flash Fill or Cross Program Invocation (CPI)** + + To interact with your own Solana program, [read how to use the **Flash Fill method** or **CPI** in this section](#build-your-own-transaction-with-flash-fill-or-cpi). + + +## Let’s Get Started + +In this guide, we will pick up from where [**Get Quote**](/docs/swap-api/get-quote) guide has left off. + +If you have not set up your environment to use the necessary libraries, the RPC connection to the network and successfully get a quote from the Quote API, please start at [Environment Setup](/docs/environment-setup) or [get quote](/docs/swap-api/get-quote). + + + **API REFERENCE** + + To fully utilize the Swap API, check out the [Swap API or Swap Instructions Reference](/api/swap-api/swap). + + +## Swap API + +From the previous guide on getting a quote, now using the quote response and your wallet, you can receive a **serialized swap transaction** that needs to be prepared and signed before sending to the network. + +## Get Serialized Transaction + +Using the root URL and parameters to pass in, it is as simple as the example code below! + + + **OPTIMIZING FOR TRANSACTION LANDING IS SUPER SUPER IMPORTANT!** + + This code block includes additional parameters that our Swap API supports, such as estimating compute units, priority fees and slippage, to optimize for transaction landing. + + To understand how these parameters help, the next step, [Send Swap Transaction guide](/docs/swap-api/send-swap-transaction) will discuss them. + + +```js +const swapResponse = await ( +await fetch('https://lite-api.jup.ag/swap/v1/swap', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + quoteResponse, + userPublicKey: wallet.publicKey, + + // ADDITIONAL PARAMETERS TO OPTIMIZE FOR TRANSACTION LANDING + // See next guide to optimize for transaction landing + dynamicComputeUnitLimit: true, + dynamicSlippage: true, + prioritizationFeeLamports: { + priorityLevelWithMaxLamports: { + maxLamports: 1000000, + priorityLevel: "veryHigh" + } + } + }) +}) +).json(); + +console.log(swapResponse); +``` + +From the above example, you should see this response. + +```js +{ + swapTransaction: 'AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAGDkS+3LuGTbs......+/oD9qb31dH6i0QZ2IHELXUX3Y1YeW79p9Stkqk12z4yvZFJiQ4GCQwLBwYQBgUEDggNTQ==', + lastValidBlockHeight: 279632475, + prioritizationFeeLamports: 9999, + computeUnitLimit: 388876, + prioritizationType: { + computeBudget: { + microLamports: 25715, + estimatedMicroLamports: 785154 + } + }, + dynamicSlippageReport: { + slippageBps: 50, + otherAmount: 20612318, + simulatedIncurredSlippageBps: -18, + amplificationRatio: '1.5', + categoryName: 'lst', + heuristicMaxSlippageBps: 100 + }, + simulationError: null +} +``` + +## What’s Next + +Now, you are able to get a quote and use our Swap API to build the swap transaction for you. Next steps is to proceed to prepare and sign the transaction and send the signed transaction to the network. + + + + + +## Additional Resources + +### Build Your Own Transaction With Instructions + +If you prefer to compose with instructions instead of the provided transaction that is returned from the `/swap` endpoint (like the above example). You can post to `/swap-instructions` instead, it takes the same parameters as the `/swap` endpoint but returns you the instructions rather than the serialized transaction. + + + **NOTE** + + In some cases, you may add more accounts to the transaction, which may exceed the transaction size limits. To work around this, you can use the `maxAccounts` parameter in `/quote` endpoint to limit the number of accounts in the transaction. + + [Refer to the GET /quote's `maxAccounts` guide for more details.](/docs/swap-api/get-quote#max-accounts) + + + + + Example code snippet of using `/swap-instruction` + +```js + const instructions = await ( + await fetch('https://lite-api.jup.ag/swap/v1/swap-instructions', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + quoteResponse, + userPublicKey: wallet.publicKey, + }) + }) +).json(); + +if (instructions.error) { + throw new Error("Failed to get swap instructions: " + instructions.error); +} + +const { + tokenLedgerInstruction, // If you are using `useTokenLedger = true`. + computeBudgetInstructions, // The necessary instructions to setup the compute budget. + setupInstructions, // Setup missing ATA for the users. + swapInstruction: swapInstructionPayload, // The actual swap instruction. + cleanupInstruction, // Unwrap the SOL if `wrapAndUnwrapSol = true`. + addressLookupTableAddresses, // The lookup table addresses that you can use if you are using versioned transaction. +} = instructions; + +const deserializeInstruction = (instruction) => { + return new TransactionInstruction({ + programId: new PublicKey(instruction.programId), + keys: instruction.accounts.map((key) => ({ + pubkey: new PublicKey(key.pubkey), + isSigner: key.isSigner, + isWritable: key.isWritable, + })), + data: Buffer.from(instruction.data, "base64"), + }); +}; + +const getAddressLookupTableAccounts = async ( + keys: string[] +): Promise => { + const addressLookupTableAccountInfos = + await connection.getMultipleAccountsInfo( + keys.map((key) => new PublicKey(key)) + ); + + return addressLookupTableAccountInfos.reduce((acc, accountInfo, index) => { + const addressLookupTableAddress = keys[index]; + if (accountInfo) { + const addressLookupTableAccount = new AddressLookupTableAccount({ + key: new PublicKey(addressLookupTableAddress), + state: AddressLookupTableAccount.deserialize(accountInfo.data), + }); + acc.push(addressLookupTableAccount); + } + + return acc; + }, new Array()); +}; + +const addressLookupTableAccounts: AddressLookupTableAccount[] = []; + +addressLookupTableAccounts.push( + ...(await getAddressLookupTableAccounts(addressLookupTableAddresses)) +); + +const blockhash = (await connection.getLatestBlockhash()).blockhash; +const messageV0 = new TransactionMessage({ + payerKey: payerPublicKey, + recentBlockhash: blockhash, + instructions: [ + // uncomment if needed: ...setupInstructions.map(deserializeInstruction), + deserializeInstruction(swapInstructionPayload), + // uncomment if needed: deserializeInstruction(cleanupInstruction), + ], +}).compileToV0Message(addressLookupTableAccounts); +const transaction = new VersionedTransaction(messageV0); + ``` + + +### Build Your Own Transaction With Flash Fill Or CPI + +If you prefer to interact with the Jupiter Swap Aggregator program with your own on-chain program. There are 2 ways to do it, typically on-chain program call **Cross Program Invocation (CPI)** to interact with each other, we also have another method called **Flash Fill** built by Jupiter (due to limitations of CPI in the past). + + + **CPI IS NOW RECOMMENDED!** + + As of January 2025, Jupiter Swap via CPI is recommended for most users. + + [The `Loosen CPI restriction` feature has been deployed on Solana, you can read more here](https://github.com/solana-labs/solana/issues/26641). + + + + **WHY FLASH FILL?** + + With Jupiter's complex routing, best prices comes at a cost. It often means more compute resources and accounts are required as it would route across multiple DEXes in one transaction. + + Solana transactions are limited to 1232 bytes, Jupiter is using [Address Lookup Tables (ALTs)](https://docs.solana.com/developing/lookup-tables) to include more accounts in one transaction. However, the CPI method cannot use ALTs, which means when you add more accounts to a Jupiter Swap transaction, it will likely fail if it exceeds the transaction size limits. + + **Flash Fill allows the use of Versioned Transaction and ALTs**, hence, reducing the total accounts used for a Jupiter Swap transaction. + + + + + + **A CPI transaction will be composed of these instructions:** + + 1. Borrow enough SOL from the program to open a wSOL account that the program owns. + 2. Swap X token from the user to wSOL on Jupiter via CPI. + 3. Close the wSOL account and send it to the program. + 4. The program then transfers the SOL back to the user. + + **Links and Resources:** + + * [https://github.com/jup-ag/jupiter-cpi-swap-example](https://github.com/jup-ag/jupiter-cpi-swap-example) + * [https://github.com/jup-ag/sol-swap-cpi](https://github.com/jup-ag/sol-swap-cpi) + + + + **[jupiter-cpi](https://github.com/jup-ag/jupiter-cpi)** + + To ease integration via CPI, you may add the following crate  to your program. + + In cargo.toml + + ```toml + [dependencies] + jupiter-cpi = { git = "https://github.com/jup-ag/jupiter-cpi", rev = "5eb8977" } + ``` + + In your code + +```rust + use jupiter_cpi; + ... + +let signer_seeds: &[&[&[u8]]] = &[...]; + +// Pass accounts to context one-by-one and construct accounts here +// Or in practise, it may be easier to use remaining_accounts +// https://book.anchor-lang.com/anchor_in_depth/the_program_module.html + +let accounts = jupiter_cpi::cpi::accounts::SharedAccountsRoute { + token_program: , + program_authority: , + user_transfer_authority: , + source_token_account: , + program_source_token_account: , + program_destination_token_account: , + destination_token_account: , + source_mint: , + destination_mint: , + platform_fee_account: , + token_2022_program: , +}; +let cpi_ctx = CpiContext::new_with_signer( + ctx.accounts.jup.to_account_info(), + accounts, + signer_seeds, +); + +jupiter_cpi::cpi::shared_accounts_route( + cpi_ctx, + id, + route_plan, + in_amount, + quoted_out_amount, + slippage_bps, + platform_fee_bps, +); + +... +``` + + + + + + + **A Flash Fill transaction will be composed of these instructions:** + + 1. Borrow enough SOL for opening the wSOL account from this program. + 2. Create the wSOL account for the borrower. + 3. Swap X token to wSOL. + 4. Close the wSOL account and send it to the borrower. + 5. Repay the SOL for opening the wSOL account back to this program. + + **Links and resources:** + + * [https://github.com/jup-ag/sol-swap-flash-fill](https://github.com/jup-ag/sol-swap-flash-fill) + + diff --git a/mintlify-migration/docs/swap-api/common-errors.mdx b/mintlify-migration/docs/swap-api/common-errors.mdx new file mode 100644 index 00000000..36b09fdd --- /dev/null +++ b/mintlify-migration/docs/swap-api/common-errors.mdx @@ -0,0 +1,85 @@ +--- +title: "Common Errors" +description: "In this section, you can find the list of errors that can be returned by the Jupiter Swap API, Swap Program or from other programs like DEXes, System or Token programs." +--- + +## Program Errors + +### Jupiter Swap Program Errors + + + **JUPITER SWAP PROGRAM IDL** + + You can find the full Swap Program IDL here: https://solscan.io/account/JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4#anchorProgramIdl + + + + **ABNORMAL ERROR RATES** + + If you face high or consistent amounts of errors, please reach out to [Jupiter Discord](https://discord.gg/jup). + + +| Error Code | Error Name | Debug | +| :--------- | :------------------------ | :------------------------------------------------------------------------------------------------------------------------- | +| 6001 | SlippageToleranceExceeded | Try higher fixed slippage or try [`dynamicSlippage`](/docs/swap-api/send-swap-transaction#how-jupiter-estimates-slippage) | +| 6008 | NotEnoughAccountKeys | Likely modified swap transaction causing missing account keys | +| 6014 | IncorrectTokenProgramID | Likely attempted to take platform fees on a Token2022 token (This is also 0x177e) | +| 6017 | ExactOutAmountNotMatched | Similar to slippage | + +### Solana Program Errors + +| Program | Link | +| :-------------------------------- | :---------------------------------------------------------------------------------------------------------------------- | +| Token Program | [https://github.com/solana-program/token/blob/main/program/src/error.rs](https://github.com/solana-program/token/blob/main/program/src/error.rs) | +| Token2022 Program | [https://github.com/solana-program/token-2022/blob/main/program/src/error.rs](https://github.com/solana-program/token-2022/blob/main/program/src/error.rs) | +| Associated Token Account Program | [https://github.com/solana-program/associated-token-account/blob/main/program/src/error.rs](https://github.com/solana-program/associated-token-account/blob/main/program/src/error.rs) | +| Other Solana Programs | [https://github.com/solana-program](https://github.com/solana-program) | + +### DEX Program Errors + +In the swap transaction, the DEX in routing may return errors. You can find some of their IDLs and/or error codes in an explorer. If they do not support public IDLs or open source code, you can reference the common errors below or if you need additional help, please reach out to [Jupiter Discord](https://discord.gg/jup). + +| Error | Description | +| :------------------------------------------------------- | :----------------------------------------------------------------------------------------------------- | +| Error related to tick array or bitmap extension account | Similar to slippage, the price or market has "moved out of range", hence the swap transaction failed. | + +## Routing Errors + +The common routing errors you may encounter are usually related to attempting to swap a token that is not tradable on Jupiter, for reasons such as lack of liquidity or the token is not supported. + + +| Error | Description | Debug | +| :--- | :--- | :--- | +| NO\_ROUTES\_FOUND | No routes were found for the requested swap | * Check jup.ag if it's routable
* [Check the liquidity of the token's markets](https://support.jup.ag/hc/en-us/articles/18453861473436-Why-is-this-token-not-tradable-on-Jupiter) | +| COULD\_NOT\_FIND\_ANY\_ROUTE | Unable to find any valid route for the swap | * Check jup.ag if it's routable
* [Check the liquidity of the token's markets](https://support.jup.ag/hc/en-us/articles/18453861473436-Why-is-this-token-not-tradable-on-Jupiter) | +| ROUTE\_PLAN\_DOES\_NOT\_ CONSUME\_ALL\_THE\_AMOUNT | The calculated route cannot process the entire input amount, you can get more output amount by reducing your input amount | * Try reducing your input amount | +| MARKET\_NOT\_FOUND | The specified market address was not found | * Verify the market address exists and is active | +| TOKEN\_NOT\_TRADABLE | The specified token mint is not available for trading | * Check jup.ag if it's routable
* [Check the liquidity of the token's markets](https://support.jup.ag/hc/en-us/articles/18453861473436-Why-is-this-token-not-tradable-on-Jupiter) | +| NOT\_SUPPORTED | Generic error for unsupported operations | * Check the specific error message for details | +| CIRCULAR\_ARBITRAGE\_ IS\_DISABLED | Attempted to swap a token for itself | * Input and output tokens must be different | +| CANNOT\_COMPUTE\_ OTHER\_AMOUNT\_THRESHOLD | Failed to calculate the minimum output amount based on slippage | * Verify the input amount and slippage parameters are valid | + +## Swap Transaction Composing Errors + +| Error | Description | Debug | +| :------------------------------------------------------- | :------------------------------------------------------------- | :--------------------------------------------------------------- | +| MAX\_ACCOUNT\_GREATER\_THAN\_MAX | The specified number of accounts exceeds the maximum allowed | * Reduce the number of accounts in the transaction | +| INVALID\_COMPUTE\_UNIT\_PRICE\_AND\_PRIORITIZATION\_FEE | Both compute unit price and prioritization fee were specified | - Use either compute unit price or prioritization fee, not both | +| FAILED\_TO\_GET\_SWAP\_AND\_ACCOUNT\_METAS | Failed to generate the swap transaction | * Check the error message for specific details | + +## Best Practices + +It is important to understand the error codes when your products are user facing. This will help you provide a better experience for your users, helping them make an informed decision or follow up step to help their transaction succeed. + + + **JUP.AG AS A REFERENCE** + + You can use [https://jup.ag/](https://jup.ag/) as a reference to understand how we handle errors on the UI. + + +| Error Type | Best Practice | +| :---------------------------- | :----------------------------------------------------------------------------------------------------- | +| Slippage exceeding threshold | Show the user the current slippage tolerance and the incurred slippage | +| Insufficient funds | Show the user the current balance of the account and the required balance | +| Non Jupiter Program Errors | Allow the user to retry with a different route and/or exclude the specific DEX from the quote request | +| Token not tradable | Show the user the token is not tradable and provide context on why it's not tradable | diff --git a/mintlify-migration/docs/swap-api/get-quote.mdx b/mintlify-migration/docs/swap-api/get-quote.mdx new file mode 100644 index 00000000..4224e461 --- /dev/null +++ b/mintlify-migration/docs/swap-api/get-quote.mdx @@ -0,0 +1,235 @@ +--- +title: "Get Quote" +description: "The Quote API enables you to tap into the Jupiter Metis v1 Routing Engine, which accesses the deep liquidity available within the DEXes of Solana's DeFi ecosystem. In this guide, we will walkthrough how you can get a quote for a specific token pair and other related parameters." +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/swap/v1/quote` + * Pro URL: `https://api.jup.ag/swap/v1/quote` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + + + **PLEASE USE THE SWAP API AT YOUR OWN DISCRETION.** + + The Jupiter UI at [https://jup.ag/](https://jup.ag/) contains multiple safeguards, warnings and default settings to guide our users to trade safer. Jupiter is not liable for losses incurred by users on other platforms. + + If you need clarification or support, please reach out to us in [Discord](https://discord.gg/jup). + + + + **ROUTING ENGINE** + + The quotes from Swap API are from the Jupiter Metis v1 Routing Engine. + + + + +## Let’s Get Started + +In this guide, we will be using the Solana web3.js package. + +If you have not set up your environment to use the necessary libraries and the connection to the Solana network, please head over to [Environment Setup](/docs/environment-setup). + + + **API REFERENCE** + + To fully utilize the Quote API, check out the [Quote API Reference](/api/swap-api/quote). + + +## Quote API + +The most common trading pair on Solana is SOL and USDC, to get a quote for this specific token pair, you need to pass in the required parameters such as: + +| Parameters | Description | +| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| inputMint | The pubkey or token mint address e.g. So11111111111111111111111111111111111111112 | +| outputMint | The pubkey or token mint address e.g. EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | +| amount | The number of **input** tokens before the decimal is applied, also known as the “raw amount” or “integer amount” in lamports for SOL or atomic units for all other tokens. | +| slippageBps | The number of basis points you can tolerate to lose during time of execution. e.g. 1% = 100bps | + +## Get Quote + +Using the root URL and parameters to pass in, it is as simple as the example code below! + +```js +const quoteResponse = await ( + await fetch( + 'https://lite-api.jup.ag/swap/v1/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000000&slippageBps=50&restrictIntermediateTokens=true' + ) + ).json(); + +console.log(JSON.stringify(quoteResponse, null, 2)); +``` + +Example response: + +```json expandable +{ + "inputMint": "So11111111111111111111111111111111111111112", + "inAmount": "100000000", + "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "outAmount": "16198753", + "otherAmountThreshold": "16117760", + "swapMode": "ExactIn", + "slippageBps": 50, + "platformFee": null, + "priceImpactPct": "0", + "routePlan": [ + { + "swapInfo": { + "ammKey": "5BKxfWMbmYBAEWvyPZS9esPducUba9GqyMjtLCfbaqyF", + "label": "Meteora DLMM", + "inputMint": "So11111111111111111111111111111111111111112", + "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "inAmount": "100000000", + "outAmount": "16198753", + "feeAmount": "24825", + "feeMint": "So11111111111111111111111111111111111111112" + }, + "percent": 100 + } + ], + "contextSlot": 299283763, + "timeTaken": 0.015257836 +} +``` + + + **TIP** + + `outAmount` refers to the best possible output amount based on the route at time of quote, this means that `slippageBps` does not affect. + + +## What’s Next + +Now, you are able to get a quote, next steps is to submit a transaction to execute the swap based on the quote given. Let’s go! + + +## Additional Resources + +### Restrict Intermediate Tokens + +`restrictIntermediateTokens` can be set to `true` . If your route is routed through random intermediate tokens, it will fail more frequently. With this, we make sure that your route is only routed through highly liquid intermediate tokens to give you the best price and more stable route. + +### Legacy Transactions + +All Jupiter swaps are using Versioned Transactions and [Address Lookup Tables](https://docs.solana.com/developing/lookup-tables). However, not all wallets support Versioned Transactions yet, so if you detect a wallet that does not support versioned transactions, you will need to set the `asLegacyTransaction` parameter to `true`. + +### Adding Fees + +By using the Quote API in your app, you can add a fee to charge your users. You can refer to the `platformFeeBps` parameter and to add it to your quote and in conjuction, add `feeAccount` (it can be any valid token account) to your swap request. + +### Direct Routes + +In some cases, you may want to restrict the routing to only go through 1 market. You can use the `onlyDirectRoutes` parameter to achieve this. This will ensure routing will only go through 1 market. + + + **NOTE** + + * If there are no direct routes, there will be no quote. + * If there is only 1 market but it is illiquid, it will still return the route with the illiquid market. + + + + **UNFAVORABLE TRADES** + + Please be aware that using `onlyDirectRoutes` can often yield unfavorable trades or outcomes. + + +### Max Accounts + +In some cases, you may want to add more accounts to the transaction for specific use cases, but it might exceed the transaction size limit. You can use the `maxAccounts` parameter to limit the number of accounts in the transaction. + + + **UNFAVORABLE TRADES** + + Please be aware that the misuse of `maxAccounts` can yield unfavorable trades or outcomes. + + + + **TIP** + + Refer to the [Requote with Lower Max Accounts](/docs/swap-api/requote-with-lower-max-accounts) guide for more information on how to requote and adjust the swap when using `maxAccounts`. + + + + **NOTE** + + * `maxAccounts` is an estimation and the actual number of accounts may vary. + * `maxAccounts` only applies to the total number of accounts of the inner swaps in the swap instruction and not any of the setup, cleanup or other instructions (see the example below). + * We recommend setting `maxAccounts` to 64 + * Keep `maxAccounts` as large as possible, only reduce `maxAccounts` if you exceed the transaction size limit. + * If `maxAccounts` is set too low, example to 30, the computed route may drop DEXes/AMMs like Meteora DLMM that require more than 30 accounts. + + **Jupiter has 2 types of routing instructions**, if you plan to limit `maxAccounts`, you will need to account for if the market is routable with [ALTs](https://docs.solana.com/developing/lookup-tables) or not: + + * **`Routing Instruction`** (Simple Routing): The market is still new, and we do not have ALTs set up for the market, hence the number of accounts required is higher as there are more accounts required. + * **`Shared Accounts Routing Instruction`**: The market has sufficient liquidity (and has been live for a while), and we have [ALTs](https://docs.solana.com/developing/lookup-tables) set up for the market to be used in the routing instruction, hence the number of accounts required is lower as there are less accounts required. + + + + + + [In this transaction](https://solscan.io/tx/2xpiniSn5z61hE6gB6EUaeRZCqeg8rLBEbiSnAjSD28tjVTSpBogSLfrMRaJiDzuqDyZ8v49Z7WL2TKvGQVwYbB7): + + + + Max Accounts Stabble Example + + + Max Accounts Lifinity V2 Example + + + Max Accounts Shared Accounts Route Example + + + + * You can see that there are a total of 2 inner swaps where the number of accounts respectively are + + * Stabble Stable Swap: 12 + * Lifinity Swap V2: 13 + * Total: 25 + + * The `maxAccounts` parameter is to control this value - to limit the total number of accounts in the inner swaps. + + * It doesn’t take into the consideration of a few things: + + * Each of the inner swap's program address, so 2 in this case. + * Top level routing instruction accounts where in this case Shared Accounts Route is 13 and Route is 9. + * There are also other accounts that are required to set up, clean up, etc which are not counted in the `maxAccounts` parameter + + + + + Notes: + + * Values in the table are only estimations and the actual number of accounts may vary. + * Min accounts are needed when we have already created the necessary [ALTs](https://docs.solana.com/developing/lookup-tables) for a specific pool resulting in less accounts needed in a Shared Accounts Routing context. + * Sanctum and Sanctum Infinity are unique, and their accounts are dynamic. + + | DEX | Max | Min | + | :--------------------- | :--- | :--- | + | Meteora DLMM | 47 | 19 | + | Meteora | 45 | 18 | + | Moonshot | 37 | 15 | + | Obric | 30 | 12 | + | Orca Whirlpool | 30 | 12 | + | Pumpfun AMM | 42 | 17 | + | Pumpfun Bonding Curve | 40 | 16 | + | Raydium | 45 | 18 | + | Raydium CLMM | 45 | 19 | + | Raydium CPMM | 37 | 14 | + | Sanctum | 80 | 80 | + | Sanctum Infinity | 80 | 80 | + | Solfi | 22 | 9 | + + diff --git a/mintlify-migration/docs/swap-api/payments-through-swap.mdx b/mintlify-migration/docs/swap-api/payments-through-swap.mdx new file mode 100644 index 00000000..678f5f13 --- /dev/null +++ b/mintlify-migration/docs/swap-api/payments-through-swap.mdx @@ -0,0 +1,180 @@ +--- +title: "Payments Through Swap" +description: "The Jupiter Swap API can be utilized such that you, a merchant can allow your customer to pay in any tokens while you still receive in your preferred token payment at the end of the transaction." +--- + +## Use Case + +Let’s set the stage. You are selling a **jupcake!!!** to your customer and merchant might only accept in 1 USDC, but your customer only has 1 SOL. Well, you’re at the right place! By using the Swap API, merchant can let customer pay in SOL while merchant still receive USDC in order to complete the payment for a jupcake. + +* Customer has 1,000,000 SOL. +* Merchant sells 1 jupcake for 1 USDC. +* Use the Swap API to swap exactly 1 USDC output from Customer's SOL. +* Merchant receives the 1 USDC, as planned! + +## Let’s Get Started + +### 1. Setup + +You will need slightly different imports and also remember to set up connection to an RPC. If you have not set up the other typical libraries or are familiar with the Swap API, please follow this [Environment Setup](/docs/environment-setup) and [Get Quote and Swap](/docs/swap-api/get-quote) guide. + +```bash +npm i @solana/spl-token +``` + +```js +import { PublicKey, Connection, Keypair, VersionedTransaction } from '@solana/web3.js'; +import { getAssociatedTokenAddress, TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID } from '@solana/spl-token'; +``` + +Before we start getting a quote and swap transaction, for example sake, we will need to prepare both merchant and customer accounts. In production scenario, you will need to dynamically pass this in and allow users to sign in their device interfaces. + + + **NOTE** + + Do note that you will need to have already set up: + + * **A wallet in your machine to simulate yourself as the customer as the customer is the signer of the transaction** (similar to how we set up in [Environment Setup](/docs/environment-setup)). + * `trackingAccount` is an additional Solana Account you can pass in to track only Jupiter transactions easily. + + +#### Set Up Accounts + +```js +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/to/.config/solana/id.json', 'utf8').trim()); +const customerWallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); + +const USDC_MINT = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'); // Your preferred token payment +const customerAccount = customerWallet.publicKey; +const merchantAccount = new PublicKey('ReplaceWithMerchantPubkey'); +// const trackingAccount = new PublicKey('ReplaceWithPubkey'); // If required + +console.log("USDC_MINT:", USDC_MINT.publicKey); +console.log("merchantAccount:", merchantAccount.publicKey); +// console.log("trackingAccount:", trackingAccount.publicKey); +``` + +#### Set Up `destinationTokenAccount` + +One more thing you will need to set up! Later on, you will need to pass in `destinationTokenAccount` which will be your token account for your preferred token payment mint. **Do note that it is the merchant's token account and it needs to be initialized.** + +```js +// Get the associated token account for the merchant wallet +const merchantUSDCTokenAccount = await getAssociatedTokenAddress( + USDC_MINT, + merchantAccount, + true, + TOKEN_PROGRAM_ID, + ASSOCIATED_TOKEN_PROGRAM_ID +); + +console.log("merchantUSDCTokenAccount:", merchantUSDCTokenAccount.publicKey); +``` + +### 2. Set `swapMode` to `ExactOut` in Quote + +Next, the merchant have to [Get Quote](/docs/swap-api/get-quote) for the customer. We are using the `ExactOut` mode because we know exactly how much output amount (1 USDC) the merchant want to receive but not sure how much input amount the customer should pay with. + +By getting a quote first, the customer can know upfront the specific amount of input token before they approve and sign the transaction. + + + **LIMITATIONS OF `ExactOut`** + + Currently, there are some limitations as `ExactOut` is not widely supported across all DEXes. + + * Supported DEXes are only Orca Whirlpool, Raydium CLMM, and Raydium CPMM. + * NOT ALL token pairs may be available. + + +```js +const quoteResponse = await ( + await fetch( + 'https://lite-api.jup.ag/swap/v1/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000&slippageBps=50&restrictIntermediateTokens=true&swapMode=ExactOut' + ) + ).json(); + +console.log(JSON.stringify(quoteResponse, null, 2)); +``` + +From the this quote, you should get part of the response like this, where `amount` specified in the query parameter represents the `outAmount` in the response and of course, `swapMode: ExactOut`. + +```js +{ + "inputMint": "So11111111111111111111111111111111111111112", + "inAmount": "4434914", + "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "outAmount": "1000000", + "otherAmountThreshold": "4434914", + "swapMode": "ExactOut", + ... +} +``` + +### 3. Set `destinationTokenAccount` in Swap + +The merchant then retrieves the serialized swap transaction, but the merchant need to specify the `destinationTokenAccount` in the parameters — this will build the swap transaction to swap but send to the [merchant's specified token account which we defined earlier](#set-up-destinationtokenaccount). + +The `destinationTokenAccount` should be the merchant’s token account to receive the payment in. Also do note that `customerAccount` should be accounted for. **You can refer to the [Build Swap Transaction](/docs/swap-api/build-swap-transaction) guide for other parameters to be passed in.** + +```js +const swapResponse = await ( + await fetch('https://lite-api.jup.ag/swap/v1/swap', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + quoteResponse, + userPublicKey: customerAccount.publicKey, + destinationTokenAccount: merchantUSDCTokenAccount.publicKey, + // trackingAccount: trackingAccount.publicKey, + }) + }) +).json(); +``` + +### 4. Prepare Transaction + +We have walked through the steps here and explained some of the code, you can refer to [Send Swap Transaction - Prepare Transaction](/docs/swap-api/send-swap-transaction#prepare-transaction). The main difference for payments is to ensure that the customer is the fee payer (the merchant can be generous and be the fee payer too!) and the signer. + +```js +const transactionBase64 = swapResponse.swapTransaction +const transaction = VersionedTransaction.deserialize(Buffer.from(transactionBase64, 'base64')); +transaction.feePayer = customerAccount.publicKey; +transaction.sign([customerWallet]); +const transactionBinary = transaction.serialize(); +``` + +### 5. Send Transaction + +We have walked through the steps here and explained some of the code, you can refer to [Send Swap Transaction - Send Transaction](/docs/swap-api/send-swap-transaction#send-transaction). The main difference for payments is, you might want to try adjusting `maxRetries` to a higher count as it is not time sensitive and ideally this is used with tighter slippage and ensuring the `inputMint` is not too unstable. + +Do note that more retries will cause the user to wait slightly longer, so find the balance between the two. Read more here: [https://solana.com/docs/advanced/retry](https://solana.com/docs/advanced/retry). + +```js +const signature = await connection.sendRawTransaction(transactionBinary, { + maxRetries: 10, +}); + +const confirmation = await connection.confirmTransaction({ signature }, "finalized"); + +if (confirmation.value.err) { + throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}\nhttps://solscan.io/${signature}/`); +} else console.log(`Transaction successful: https://solscan.io/tx/${signature}/`); +``` + +The succeeded Swap Transaction should show: + +* Token A swaps from the customer's token account +* Token A swap to Token B +* Token B sends to the merchant's token account + + + + + + + + + + diff --git a/mintlify-migration/docs/swap-api/requote-with-lower-max-accounts.mdx b/mintlify-migration/docs/swap-api/requote-with-lower-max-accounts.mdx new file mode 100644 index 00000000..74149878 --- /dev/null +++ b/mintlify-migration/docs/swap-api/requote-with-lower-max-accounts.mdx @@ -0,0 +1,278 @@ +--- +title: "Requote with Lower Max Accounts" +description: "In some cases where you might be limited or require strict control by adding your own instructions to the swap transaction, you might face issues with exceeding transaction size limit. In this section, we will provide some helping code to help you requote when the transaction size is too large." +--- + + + **NOTE** + + We provide a `maxAccounts` param in the `/quote` endpoint to allow you to reduce the total number of accounts used for a swap - this will allow you to add your own instructions. + + + + + + +## Example Code + +1. Request for quote and the swap transaction as per normal. + +2. Serialize the transaction. + +3. Use the conditions to check if the transaction is too large. + + 1. If too large, requote again with lower max accounts - do note that the route will change. + 2. If not, sign and send to the network. + + + **TIP** + + We recommend `maxAccounts` 64 and start as high as you can, then incrementally reduce when requoting. + + Do note that with lower max accounts, it will might yield bad routes or no route at all. + + + + **TIP** + + When you serialize the transaction, you can log the number of raw bytes being used in the transaction. + + You can either add your custom instructions before or after serializing the transaction. + + +```js expandable +import { + AddressLookupTableAccount, + Connection, + Keypair, + PublicKey, + TransactionInstruction, + TransactionMessage, + VersionedTransaction, +} from '@solana/web3.js'; + +// Set up dev environment +import fs from 'fs'; +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/to/key', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); +const connection = new Connection('your-own-rpc'); + +// Recommended +const MAX_ACCOUNTS = 64 + +async function getQuote(maxAccounts) { + const params = new URLSearchParams({ + inputMint: 'insert-mint', + outputMint: 'insert-mint', + amount: '1000000', + slippageBps: '100', + maxAccounts: maxAccounts.toString() + }); + + const url = `https://lite-api.jup.ag/swap/v1/quote?${params}`; + const response = await fetch(url); + + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`HTTP ${response.status}: ${errorText}`); + } + + const quoteResponse = await response.json(); + + if (quoteResponse.error) { + throw new Error(`Jupiter API error: ${quoteResponse.error}`); + } + + return quoteResponse; +}; + +async function getSwapInstructions(quoteResponse) { + const response = await fetch('https://lite-api.jup.ag/swap/v1/swap-instructions', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + quoteResponse: quoteResponse, + userPublicKey: wallet.publicKey.toString(), + prioritizationFeeLamports: { + priorityLevelWithMaxLamports: { + maxLamports: 10000000, + priorityLevel: "veryHigh" + } + }, + dynamicComputeUnitLimit: true, + }, null, 2) + }); + + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`HTTP ${response.status}: ${errorText}`); + } + + const swapInstructionsResponse = await response.json(); + + if (swapInstructionsResponse.error) { + throw new Error(`Jupiter API error: ${swapInstructionsResponse.error}`); + } + + return swapInstructionsResponse; +}; + +async function buildSwapTransaction(swapInstructionsResponse) { + const { + computeBudgetInstructions, + setupInstructions, + swapInstruction, + cleanupInstruction, + addressLookupTableAddresses, + } = swapInstructionsResponse; + + const deserializeInstruction = (instruction) => { + if (!instruction) return null; + return new TransactionInstruction({ + programId: new PublicKey(instruction.programId), + keys: instruction.accounts.map((key) => ({ + pubkey: new PublicKey(key.pubkey), + isSigner: key.isSigner, + isWritable: key.isWritable, + })), + data: Buffer.from(instruction.data, "base64"), + }); + }; + + const getAddressLookupTableAccounts = async ( + keys + ) => { + const addressLookupTableAccountInfos = + await connection.getMultipleAccountsInfo( + keys.map((key) => new PublicKey(key)) + ); + + return addressLookupTableAccountInfos.reduce((acc, accountInfo, index) => { + const addressLookupTableAddress = keys[index]; + if (accountInfo) { + const addressLookupTableAccount = new AddressLookupTableAccount({ + key: new PublicKey(addressLookupTableAddress), + state: AddressLookupTableAccount.deserialize(accountInfo.data), + }); + acc.push(addressLookupTableAccount); + } + + return acc; + }, []); + }; + + const addressLookupTableAccounts = []; + addressLookupTableAccounts.push( + ...(await getAddressLookupTableAccounts(addressLookupTableAddresses)) + ); + + const blockhash = (await connection.getLatestBlockhash()).blockhash; + + // Create transaction message with all instructions + const messageV0 = new TransactionMessage({ + payerKey: wallet.publicKey, + recentBlockhash: blockhash, + instructions: [ + ...(computeBudgetInstructions?.map(deserializeInstruction).filter(Boolean) || []), + ...(setupInstructions?.map(deserializeInstruction).filter(Boolean) || []), + deserializeInstruction(swapInstruction), + ...(cleanupInstruction ? [deserializeInstruction(cleanupInstruction)].filter(Boolean) : []), + ].filter(Boolean), + }).compileToV0Message(addressLookupTableAccounts); + + const transaction = new VersionedTransaction(messageV0); + + return transaction; +} + +async function checkTransactionSize(transaction) { + // Max raw bytes of a Solana transaction is 1232 raw bytes + // Using the conditions below, we can check the size of the transaction + // (or if it is too large to even serialize) + try { + const transactionUint8Array = transaction.serialize(); + console.log(transactionUint8Array.length) + + // Use 1232 assuming you have added your instructions to the transaction above + // If you have not add your instructions, you will need to know how much bytes you might use + return (transactionUint8Array.length > 1232); + + } catch (error) { + if (error instanceof RangeError) { + console.log("Transaction is too large to even serialize (RangeError)"); + + return true; + + } else { + throw error; // Re-throw if it's not a RangeError + } + } +} + +// Main execution logic with retry mechanism +let counter = 0; +let transactionTooLarge = true; +let quoteResponse, swapInstructionsResponse, transaction; + +while (transactionTooLarge && counter < MAX_ACCOUNTS) { + try { + console.log(`Attempting with maxAccounts: ${MAX_ACCOUNTS - counter}`); + + quoteResponse = await getQuote(MAX_ACCOUNTS - counter); + swapInstructionsResponse = await getSwapInstructions(quoteResponse); + transaction = await buildSwapTransaction(swapInstructionsResponse); + transactionTooLarge = await checkTransactionSize(transaction); + + if (transactionTooLarge) { + console.log(`Transaction too large (with ${MAX_ACCOUNTS - counter} maxAccounts), retrying with fewer accounts...`); + counter++; + } else { + console.log(`Transaction size OK with ${MAX_ACCOUNTS - counter} maxAccounts`); + } + + } catch (error) { + console.error('Error in attempt:', error); + counter += 2; // Incrementing by 1 account each time will be time consuming, you can use a higher counter + transactionTooLarge = true; + } +} + +if (transactionTooLarge) { + console.error('Failed to create transaction within size limits after all attempts'); +} else { + console.log('Success! Transaction is ready for signing and sending'); + + // After, you can add your transaction signing and sending logic +} +``` + +## Example Response + +```bash +Attempting with maxAccounts: 64 +Transaction is too large to even serialize (RangeError) +Transaction too large (with 64 maxAccounts), retrying with fewer accounts... + +Attempting with maxAccounts: 63 +Transaction is too large to even serialize (RangeError) +Transaction too large (with 63 maxAccounts), retrying with fewer accounts... + +... + +Attempting with maxAccounts: 57 +1244 +Transaction too large (with 57 maxAccounts), retrying with fewer accounts... + +Attempting with maxAccounts: 56 +1244 +Transaction too large (with 56 maxAccounts), retrying with fewer accounts... + +... + +Attempting with maxAccounts: 51 +1213 +Transaction size OK with 51 maxAccounts +Success! Transaction is ready for signing and sending +``` diff --git a/mintlify-migration/docs/swap-api/send-swap-transaction.mdx b/mintlify-migration/docs/swap-api/send-swap-transaction.mdx new file mode 100644 index 00000000..55aaa3a5 --- /dev/null +++ b/mintlify-migration/docs/swap-api/send-swap-transaction.mdx @@ -0,0 +1,308 @@ +--- +title: "Send Swap Transaction" +description: "Transaction sending can be very simple but optimizing for transaction landing can be challenging. This is critical in periods of network congestion when many users and especially bots are competing for block space to have their transactions processed." +--- + + + **IMPROVE TRANSACTION LANDING TIP** + + By using Jupiter Swap API, you can enable Dynamic Slippage, Priority Fee estimation and Compute Unit estimation, all supported on our backend and served directly to you through our API. + + +## Let’s Get Started + +In this guide, we will pick up from where [**Get Quote**](/docs/swap-api/get-quote) and [**Build Swap Transaction**](/docs/swap-api/build-swap-transaction) guide has left off. + +If you have not set up your environment to use the necessary libraries, the RPC connection to the network and successfully get a quote from the Quote API, please start at [Environment Setup](/docs/environment-setup) or [get quote](/docs/swap-api/get-quote). + +## Prepare Transaction + + + **WHO IS THE SIGNER?** + + The most important part of this step is to sign the transaction. For the sake of the guide, you will be using the file system wallet you have set up to sign and send yourself. + + However, for other production scenarios such as building your own program or app on top of the Swap API, you will need the user to be the signer which is often through a third party wallet provider, so do account for it. + + +In the previous guide, we are able to get the `swapTransaction` from the Swap API response. However, you will need to reformat it to sign and send the transaction, here are the formats to note of. + +| Formats | Description | +| :---------------------------- | :---------------------------------------------------------------------------------------------------- | +| Serialized Uint8array format | The correct format to send to the network. | +| Serialized base64 format | This is a text encoding of the Uint8array data, meant for transport like our Swap API or storage. You should not sign this directly. | +| Deserialized format | This is the human-readable, object-like format before serialization. This is the state you will sign the transaction. | + +Here's the code to deserialize and sign, then serialize. + +1. `swapTransaction` from the Swap API is a serialized transaction in the **base64 format**. +2. Convert it to **Uint8array (binary buffer) format**. +3. Deserialize it to a **VersionedTransaction** object to sign. +4. Finally, convert it back to **Uint8array** format to send the transaction. + +```js +const transactionBase64 = swapResponse.swapTransaction +const transaction = VersionedTransaction.deserialize(Buffer.from(transactionBase64, 'base64')); +console.log(transaction); + +transaction.sign([wallet]); + +const transactionBinary = transaction.serialize(); +console.log(transactionBinary); +``` + + + **BLOCKHASH VALIDITY** + + If you look at the response of `console.log(transaction);`, you can see that our backend has already handled the blockhash and last valid block height in your transaction. + + The validity of a blockhash typically lasts for 150 slots, but you can manipulate this to reduce the validity of a transaction, resulting in faster failures which could be useful in certain scenarios. + + + + +## Send Transaction + +### Transaction Sending Options + +Finally, there are a 2 [transaction sending options](https://solana.com/docs/advanced/retry#an-in-depth-look-at-sendtransaction) that we should take note of. Depending on your use case, these options can make a big difference to you or your users. For example, if you are using the Swap API as a payment solution, setting higher `maxRetries` allows the transaction to have more retries as it is not as critical compared to a bot that needs to catch fast moving markets. + + + + | Options | Description | + | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | [maxRetries](https://solana.com/docs/advanced/retry) | Maximum number of times for the RPC node to retry sending the transaction to the leader. If this parameter is not provided, the RPC node will retry the transaction until it is finalized or until the blockhash expires. | + | [skipPreflight](https://solana.com/docs/advanced/retry#the-cost-of-skipping-preflight) | If true, skip the preflight transaction checks (default: false). - Verify that all signatures are valid. + - Check that the referenced blockhash is within the last 150 blocks. + - Simulate the transaction against the bank slot specified by the preflightCommitment. | + + +```js +const signature = await connection.sendRawTransaction(transactionBinary, { + maxRetries: 2, + skipPreflight: true +}); +``` + +### Transaction Confirmation + +In addition, after sending the transaction, it is always a best practice to check the transaction confirmation state, and if not, log the error for debugging or communicating with your users on your interface. + + + +```js +const confirmation = await connection.confirmTransaction({signature,}, "finalized"); + +if (confirmation.value.err) { + throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}\nhttps://solscan.io/tx/${signature}/`); +} else console.log(`Transaction successful: https://solscan.io/tx/${signature}/`); +``` + +## Swap Transaction Executed! + +If you have followed the guides step by step without missing a beat, your transaction *should* theoretically land and you can view the link in console log to see the [transaction](https://solscan.io/tx/zEWGsd5tSyxUdsTn27hUzaJBadQSiFxF2X1CxVdQzdtgc3BpqyDPf5VQCFUScidhHJP5PchY33oJ3tZJLK5KXrf). + +## Oh? Transaction Not Landing? + +As the Solana network grew and increased in activity over the years, it has become more challenging to land transactions. There are several factors that can drastically affect the success of your transaction: + +* Setting competitive priority fee +* Setting accurate amount of compute units +* Managing slippage effectively +* Broadcasting transaction efficiently +* Other tips + +### How Jupiter Estimates Priority Fee? + +You can pass in `prioritizationFeeLamports` to Swap API where our backend will estimate the Priority Fee for you. + +We are using [Triton’s `getRecentPrioritizationFees`](https://docs.triton.one/chains/solana/improved-priority-fees-api) to estimate using the local fee market in writable accounts of the transaction (comparing to the global fee market), across the past 20 slots and categorizing them into different percentiles. + + + +| Parameters | Description | +| :--------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `maxLamports` | A maximum cap applied if the estimated priority fee is too high. This is helpful when you have users using your application and can be a safety measure to prevent overpaying. | +| `global` | A boolean to choose between using a global or local fee market to estimate. If `global` is set to `false`, the estimation focuses on fees relevant to the **writable accounts** involved in the instruction. | +| `priorityLevel` | A setting to choose between the different percentile levels. Higher percentile will have better transaction landing but also incur higher fees. - `medium`: 25th percentile +- `high`: 50th percentile +- `veryHigh`: 75th percentile | + +```js +const swapResponse = await ( + await fetch('https://lite-api.jup.ag/swap/v1/swap', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + quoteResponse, + userPublicKey: wallet.publicKey, + prioritizationFeeLamports: { + priorityLevelWithMaxLamports: { + maxLamports: 10000000, + global: false, + priorityLevel: "veryHigh" + } + } + }) + }) +).json(); +``` + +### How Jupiter Estimates Compute Unit Limit? + +You can pass in `dynamicComputeUnitLimit` to Swap API where our backend will estimate the Compute Unit Limit for you. + +When `true`, it allows the transaction to utilize a dynamic compute unit rather than using incorrect compute units which can be detrimental to transaction prioritization. Additionally, the amount of compute unit used and the compute unit limit requested to be used are correlated to the amount of priority fees you pay. + + + +```js +const swapTransaction = await ( + await fetch('https://lite-api.jup.ag/swap/v1/swap', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + quoteResponse, + userPublicKey: wallet.publicKey, + dynamicComputeUnitLimit: true + }) + }) +).json(); +``` + +### How Jupiter Estimates Slippage? + +Slippage is an unavoidable aspect of trading on decentralized exchanges (DEXes). + +#### About Slippage + +* **Token Pair:** The same fixed slippage setting can have very different effects depending on the tokens involved. For example, swapping between two stablecoins is much less volatile than swapping between two meme coins. +* **Timing:** The time between when you receive a quote and when you actually send the swap transaction matters. Any delay can result in the price moving outside your slippage threshold. +* **Transaction Landing:** How efficiently your transaction lands on-chain also affects slippage. Poorly optimized transactions may experience more slippage. + + + **USE ULTRA API!** + + - If you use the Swap API: + + * You are limited to fixed and dynamic slippage settings. + * You are responsible for handling slippage and optimizing transaction landing yourself. + + - [Alternatively, consider using the Ultra API](/docs/ultra-api): + + * All of these optimizations are handled for you - without any RPC from you. + * Additional routing is available to RFQ (Request for Quote) systems like Jupiterz where slippage is not an issue because the market maker fills your order exactly as quoted. + + +#### Dynamic Slippage + +Apart from the fixed slippage setting, you can use Dynamic Slippage: During swap transaction building, we will simulate the transaction and estimate a slippage value, which we then factor in the token categories heuristics to get the final slippage value. + + + **DYNAMIC SLIPPAGE VS REAL TIME SLIPPAGE ESTIMATOR (RTSE)** + + RTSE is very different from Dynamic Slippage and has provided a much better user experience and results. RTSE is able to intelligently estimate the best possible slippage to use at the time of execution, balancing between trade success and price protection. RTSE uses a variety of heuristics, algorithms and monitoring to ensure the best user experience: + + * **Heuristics**: Token categories, historical and real-time slippage data, and more. + * **Algorithms**: Exponential Moving Average (EMA) on slippage data, and more. + * **Monitoring**: Real-time monitoring of failure rates to ensure reactiveness to increase slippage when necessary. + + + + + + **WARNING** + + To use Dynamic Slippage, you will need to pass in `dynamicSlippage=true` to both the `/swap/v1/quote` and `/swap/v1/swap` endpoints. + + Do note that we have discontinued development on Dynamic Slippage. + + +```js +const quoteResponse = await ( + await fetch( + 'https://lite-api.jup.ag/swap/v1/quote?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000000&slippageBps=50&restrictIntermediateTokens=true&dynamicSlippage=true' + ) +).json(); + +const swapTransaction = await ( + await fetch('https://lite-api.jup.ag/swap/v1/swap', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + quoteResponse, + userPublicKey: wallet.publicKey, + dynamicSlippage: true, + }) + }) +).json(); +``` + +### How Jupiter Broadcast Transactions? + +Transaction broadcasting is the process of submitting a signed transaction to the network so that validators can verify, process, and include it in a block. + +#### Broadcasting Through RPCs + +After you’ve built and signed your transaction, the signed transaction is serialized into a binary format and sent to the network via a Solana RPC node. The RPC node will verify and relay the transaction to the leader validator responsible for producing the next block. + + + +This is the most typical method to send transactions to the network to get executed. It is simple but you need to make sure the transactions are: + +* Send in the serialized transaction format. + +* Use fresh blockhash and last valid blockheight. + +* Use optimal amount of priority fees and compute unit limit. + +* Free of error. + +* Utilize retries. + +* Configure your RPCs + + * Optional but you can send your transaction to a staked RPC endpoint also known as [Stake-Weighted Quality of Service (SWQoS)](https://solana.com/developers/guides/advanced/stake-weighted-qos). + * Used dedicated RPC services versus free or shared, depending on how critical your usage is. + * Propagate to multiple RPC rather than reliant on one. + +#### Broadcasting Through Jito + +To include Jito Tips in your Swap transaction, you can do specify in the Swap API parameters. However, please take note of these when sending your transaction to Jito and [you can find thsese information in their documentation](https://docs.jito.wtf/): + +* You need to submit to a Jito RPC endpoint for it to work. +* You need to send an appropriate amount of Jito Tip to be included to be processed. + + + **MORE ABOUT JITO** + + You can leverage [Jito](https://www.jito.wtf/) to send transactions via tips for faster inclusion and better outcomes. Similar to Priority Fees, Jito Tips incentivize the inclusion of transaction bundles during block production, enhancing users' chances of securing critical transactions in competitive scenarios. + + Additionally, Jito enables bundling transactions to ensure they execute together or not at all, helping protect against front-running and other MEV risks through “revert protection” if any part of the sequence fails, all while reducing transaction latency for timely execution. + + + + +```js +const swapTransaction = await ( + await fetch('https://lite-api.jup.ag/swap/v1/swap', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + quoteResponse, + userPublicKey: wallet.publicKey, + prioritizationFeeLamports: { + jitoTipLamports: 1000000 // note that this is FIXED LAMPORTS not a max cap + } + }) + }) +).json(); +``` diff --git a/mintlify-migration/docs/swap-api/solana-unity-sdk.mdx b/mintlify-migration/docs/swap-api/solana-unity-sdk.mdx new file mode 100644 index 00000000..ad340ed8 --- /dev/null +++ b/mintlify-migration/docs/swap-api/solana-unity-sdk.mdx @@ -0,0 +1,18 @@ +--- +title: "Swap In Solana Unity SDK (C#)" +description: "Jupiter is fully supported within the [Solana.Unity-SDK](https://github.com/magicblock-labs/Solana.Unity-Core/tree/master/src/Solana.Unity.Dex). The core library is independent of Unity and can be incorporated into Unreal Engine using the UnrealCLR library or in a C# backend." +sidebarTitle: "Swap In Solana Unity SDK" +--- + +Using the Solana.Unity-SDK, game developers can effortlessly incorporate Jupiter swaps into their games and achieve cross-platform compatibility without the need to modify a single line of code. + +Within the SDK, the Jupiter Swap API can also be used as a [payment method](/docs/swap-api/payments-through-swap), enabling you to utilize Jupiter + SolanaPay for facilitating user payments with any SPL token, allowing pricing in USDC or other tokens. + +## Documentation + +For the detailed documentation, please visit: [Solana Unity SDK Jupiter Documentation](https://solana.unity-sdk.gg/docs/jupiter) + +## Demos + +* Watch this demo video showcasing an in-game swap powered by the Jupiter integration: [Watch Demo Video](https://youtu.be/nCceV53thjY) +* Explore a live game demo here: [Live Demo](https://magicblock-labs.github.io/Solana.Unity-SDK/) diff --git a/mintlify-migration/docs/token-api.mdx b/mintlify-migration/docs/token-api.mdx new file mode 100644 index 00000000..9d385d29 --- /dev/null +++ b/mintlify-migration/docs/token-api.mdx @@ -0,0 +1,31 @@ +--- +title: "Token API" +description: "The Jupiter Token API and verification system aims to provide a way to validate mint addresses and provide integrators a simply way to get mint information." +--- + + + **DEPRECATED** + + [Token API V1](/docs/token-api/v1) will be/is deprecated by 1 August 2025. + + Please migrate to [Token API V2](/docs/token-api/v2) which consists of breaking changes. + + + +## About + +As Solana grew and exploded with tens of thousands of newly minted tokens a day, the Jupiter Token API and verification system has evolved to meet the demands of token verification and provide an ecosystem-wide source of truth to rely on. + +A historical breakdown of the evolutions of the Token API and verification system. + +* [Solana Token Registry](https://github.com/solana-labs/token-list) was deprecated in 2022. +* [Ecosystem Token List V1: Github](https://github.com/jup-ag/token-list): Maintained via Github with 4.8k Pull Requests verified manually. +* [Ecosystem Token List V2: Catdet List](https://catdetlist.jup.ag): Maintained by Catdets and community with simple metrics to aid review. +* [Ecosystem Token List V3: Verify](https://verify.jup.ag): Using a variety of trading, social metrics and [Organic Score](/docs/token-api/organic-score) to aid verification. + + + **MORE READING MATERIALS** + + - [Introducing a new token verification method](https://x.com/9yointern/status/1907425355071197347) at [https://verify.jup.ag](https://verify.jup.ag) + - [Background and History of the Ecosystem Token List V2](https://www.jupresear.ch/t/ecosystem-master-token-list/19786) + diff --git a/mintlify-migration/docs/token-api/organic-score.mdx b/mintlify-migration/docs/token-api/organic-score.mdx new file mode 100644 index 00000000..7aaf20dc --- /dev/null +++ b/mintlify-migration/docs/token-api/organic-score.mdx @@ -0,0 +1,18 @@ +--- +title: "Organic Score" +description: "Organic Score is a metric designed to measure the genuine activity and health of a token. Unlike traditional metrics that can be easily manipulated by artificial trading or bot activity, the Organic Score focuses on real user participation and authentic market metrics. This helps users, developers, and projects better understand the context of similar tokens and find the signal within the noise." +--- + +## How Organic Score is Derived + +Organic Score is derived from a set of core metrics, such as holder count, trading volume and liquidity. In order to ensure the authenticity and reliability of the score, we track the metrics participated by real user wallets (not bots, etc) in real time to derive the Organic Score. + + + **ORGANIC SCORE** + + This is a high level depiction of how Organic Score is dervied, there are other heuristics and data involved to measure and derive it. + + + Organic Score + + diff --git a/mintlify-migration/docs/token-api/token-tag-standard.mdx b/mintlify-migration/docs/token-api/token-tag-standard.mdx new file mode 100644 index 00000000..193a01d3 --- /dev/null +++ b/mintlify-migration/docs/token-api/token-tag-standard.mdx @@ -0,0 +1,19 @@ +--- +title: "Token Tag Standard" +description: "The Token API is built with a tagging system such as Verified, LSTs and more. In this section, we will be going through how you can get your tokens tagged for better visibility on Jupiter UI or via the Token API." +--- + +## Requirements + +* [An endpoint that points to a .csv file with a mint address per row](https://raw.githubusercontent.com/jup-ag/token-list/main/examples/sample_tags.csv). +* A preferred word or acronym for your tag - one that's short and mobile friendly. +* A set interval for us to poll. + +The endpoint should be public, with our IP whitelisted for rate limits where necessary. + +## How to get your tokens tagged + +After you have completed the requirements, please reach out to us via [Discord](https://discord.gg/jup). + +Once we start ingesting your list, the tokens will be tagged automatically. + diff --git a/mintlify-migration/docs/token-api/v1.mdx b/mintlify-migration/docs/token-api/v1.mdx new file mode 100644 index 00000000..10f024dd --- /dev/null +++ b/mintlify-migration/docs/token-api/v1.mdx @@ -0,0 +1,280 @@ +--- +title: "Token API V1 (Deprecated)" +description: "In this guide, we will be going through a few examples of what Token API endpoints you can call to get the information you need." +sidebarTitle: "V1 (Deprecated)" +--- + + + **DEPRECATED** + + [Token API V1](/docs/token-api/v1) will be/is deprecated by 30th September 2025. + + Please migrate to [Token API V2](/docs/token-api/v2) which consists of breaking changes. + + + + + + **NOTE** + + Base URL: `https://lite-api.jup.ag/tokens/v1` + + For higher rate limits, [refer to the API Key Setup doc](/docs/api-setup). + + +## Get Token Information + +Using this endpoint, you can get the token information of the specific mint address. In the following example, we are looking at getting the token information of the JUP token. + + + **USEFUL MINT INFORMATION** + + In the response, you can see that we have identified the `tags`, [`freeze_authority`](https://spl.solana.com/token#freezing-accounts) and [`permanent_delegate`](https://spl.solana.com/token#authority-delegation) to help you or your users make informed decisions. + + +```js +const tokenInfoResponse = await ( + await fetch('https://lite-api.jup.ag/tokens/v1/token/JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN') +).json(); + +console.log(tokenInfoResponse); +``` + +From the above example, you should see this response. + +```js +{ + address: 'JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN', + name: 'Jupiter', + symbol: 'JUP', + decimals: 6, + logoURI: 'https://static.jup.ag/jup/icon.png', + tags: [ 'verified', 'strict', 'community', 'birdeye-trending' ], + daily_volume: 79535977.0513354, + created_at: '2024-04-26T10:56:58.893768Z', + freeze_authority: null, + mint_authority: null, + permanent_delegate: null, + minted_at: '2024-01-25T08:54:23Z', + extensions: { coingeckoId: 'jupiter-exchange-solana' } +} +``` + +## Get Tokens In Market + +Using this endpoint, you can get a list of token mints that belong to a market/pool address. In the following example, we use a [Meteora SOL-USDC market](https://solscan.io/account/BVRbyLjjfSBcoyiYFuxbgKYnWuiFaF9CSXEa5vdSZ9Hh). + +```js +const marketTokensResponse = await ( + await fetch('https://lite-api.jup.ag/tokens/v1/market/BVRbyLjjfSBcoyiYFuxbgKYnWuiFaF9CSXEa5vdSZ9Hh/mints') +).json(); + +console.log(marketTokensResponse); +``` + +From the above example, you should see this response. + +```js +[ + 'So11111111111111111111111111111111111111112', + 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' +] +``` + +## Get All Tradable Tokens + +Using this endpoint, you can get a list of all token mints that are tradable on Jupiter. + +* A new token (before market liquidity checks) +* Or tokens that has past the market liquidity checks +* These tokens should return a quote from the `/quote` endpoint and is able to swap. + +```js +const allTradableResponse = await ( + await fetch('https://lite-api.jup.ag/tokens/v1/mints/tradable') +).json(); + +console.log(allTradableResponse); +``` + +From the above example, you should see this response. + +```js +[ + ... + + 'So11111111111111111111111111111111111111112', + 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' + 'jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v', + 'JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN', + '27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4', + + ... +] +``` + +## Get Tagged Tokens + +Using this endpoint, you can get a list of token mints (with information) that are tagged according to the tag you pass in. In the following example, we use the `lst` tag. + + + **TIP** + + A list of useful tags are: + + | **Token List Name** | **Description** | + | :------------------- | :-------------------------------------------------------------------------------------------------- | + | **verified** | A list of verified tokens, consisting of community-verified tokens via [catdetlist.jup.ag](https://catdetlist.jup.ag) and the previous standard of Jupiter Strict. | + | **lst** | A list of liquid staked tokens, maintained with Sanctum. | + | **token-2022** | A list of all token-2022 tokens. | + + You can pass in multiple tags using a comma separated list, refer to the API Reference for more details. + + +```js +const lstTaggedResponse = await ( + await fetch('https://lite-api.jup.ag/tokens/v1/tagged/lst') +).json(); + +console.log(lstTaggedResponse); +``` + +From the above example, you should see this response. + +```js +... + +{ + address: 'jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v', + name: 'Jupiter Staked SOL', + symbol: 'JupSOL', + decimals: 9, + logoURI: 'https://static.jup.ag/jupSOL/icon.png', + tags: [ 'verified', 'community', 'strict', 'lst' ], + daily_volume: 24017778.687489692, + created_at: '2024-04-26T10:57:45.759228Z', + freeze_authority: null, + mint_authority: 'EMjuABxELpYWYEwjkKmQKBNCwdaFAy4QYAs6W9bDQDNw', + permanent_delegate: null, + minted_at: '2024-03-25T09:28:04Z', + extensions: { coingeckoId: 'jupiter-staked-sol' } +}, + +... +``` + +## Get New Tokens + +Using this endpoint, you can get a list of token mints (with information) **sorted by `created_at` their timestamps**. + + + **PAGINATE LARGE RESPONSE** + + The `/new` endpoint will return a large sized payload as response, you can utilize the `limit` and `offset` query parameters to help paginate the responses. + + * `limit`: Refers to how many counts of data to be in the output. + * `offset`: Refers to how many counts of data to offset into the result set. + * Used in conjunction with `limit` to page through the data. + + +```js +const newTokensReponse = await ( + await fetch('https://lite-api.jup.ag/tokens/v1/new') +).json(); + +console.log(newTokensReponse); +``` + +From the above example, you should see this response. + +```js +{ + mint: 'penguin', + created_at: '1733481083', + metadata_updated_at: 1733481087, + name: 'cool penguin', + symbol: 'penguin', + decimals: 6, + logo_uri: 'https://jup.ag', + known_markets: [ 'market' ], + mint_authority: null, + freeze_authority: null +}, +{ + mint: 'cat', + created_at: '1733481083', + metadata_updated_at: 1733481087, + name: 'cat moon', + symbol: 'cat', + decimals: 6, + logo_uri: 'https://jup.ag', + known_markets: [ 'market' ], + mint_authority: null, + freeze_authority: null +}, +``` + +## Get All Tokens + +Using the endpoint, you can simply query with the `all` resource to get all tokens that Jupiter has indexed through our infrastructure. + + + **WARNING** + + Do note that calling this endpoint's resource will return **a large payload of 300+MB**, which would introduce some latency in the call. Please use carefully and intentionally, else utilize the other endpoints. + + This endpoint does not support `limit` or `offset`. + + + + **TIP** + + To index your own tokens, you can use RPC APIs such as the [Metaplex Digital Asset Standard (DAS)](https://developers.metaplex.com/das-api). Major RPC providers like [Helius](https://docs.helius.dev/compression-and-das-api/digital-asset-standard-das-api) and [Triton One](https://docs.triton.one/digital-assets-api/introduction) offer access to this API. + + +```js +const allResponse = await ( + await fetch("https://lite-api.jup.ag/tokens/v1/all") +).json(); + +console.log(allResponse); +``` + +From the above example, you should see this response. + +```js +... + +{ + address: 'So11111111111111111111111111111111111111112', + name: 'Wrapped SOL', + symbol: 'SOL', + decimals: 9, + logoURI: 'https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png', + tags: [ 'verified', 'community', 'strict' ], + daily_volume: 2873455332.377303, + created_at: '2024-04-26T10:56:58.893768Z', + freeze_authority: null, + mint_authority: null, + permanent_delegate: null, + minted_at: null, + extensions: { coingeckoId: 'wrapped-solana' } +}, +{ + address: 'JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN', + name: 'Jupiter', + symbol: 'JUP', + decimals: 6, + logoURI: 'https://static.jup.ag/jup/icon.png', + tags: [ 'verified', 'strict', 'community', 'birdeye-trending' ], + daily_volume: 79535977.0513354, + created_at: '2024-04-26T10:56:58.893768Z', + freeze_authority: null, + mint_authority: null, + permanent_delegate: null, + minted_at: '2024-01-25T08:54:23Z', + extensions: { coingeckoId: 'jupiter-exchange-solana' } +}, + +... +``` diff --git a/mintlify-migration/docs/token-api/v2.mdx b/mintlify-migration/docs/token-api/v2.mdx new file mode 100644 index 00000000..a6d91ae9 --- /dev/null +++ b/mintlify-migration/docs/token-api/v2.mdx @@ -0,0 +1,211 @@ +--- +title: "Token API V2 (Beta)" +sidebarTitle: "V2 (Beta)" +description: "The Token API V2 provides different endpoints to query for mint information in specific searches, tags or categories." +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/tokens/v2` + * Pro URL: `https://api.jup.ag/tokens/v2` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + + + **USEFUL MINT INFORMATION** + + * Token Metadata like name, symbol, icon to display token information to users + * [Organic Score](/docs/token-api/organic-score), Holder count, Market cap, etc can be useful to help make a better trading decision + * And much more! + + Do note that the response is subject to changes as we continue to improve. + + Refer to [Example Response](#example-response) or [Token API V2 Reference](/api/token-api/v2) for full schema. + + +## Query by Mint + +The Token API V2 provides an endpoint to search tokens in the background for you and returns you the search results, along with the mint information. + +This is useful in most user applications, as users need to choose which tokens they want to swap. This also provides a seamless developer experience as integrating this allows us to handle and abstract the token search mechanism, allowing you to focus on other user features. + + + **SEARCH** + + * Search for a token and its information by its **symbol, name or mint address**. + * Comma-separate to search for multiple. + * Limit to 100 mint addresses in query. + * Default to 20 mints in response when searching via symbol or name. + + +```js +const searchResponse = await ( + await fetch(`https://lite-api.jup.ag/tokens/v2/search?query=So11111111111111111111111111111111111111112`) +).json(); +``` + +## Query by Tag + +The Token API V2 provides an endpoint to query by tags. This is useful to help users distinguish between verified vs non-verified or specific groups of tokens like liquid-staked tokens (LSTs). + + + **TAGS** + + * Only `lst` or `verified` tag. + * Note that this will return the entire array of existing mints that belongs to the tag. + + +```js +const tagResponse = await ( + await fetch(`https://lite-api.jup.ag/tokens/v2/tag?query=verified`) +).json(); +``` + +## Get Category + +The Token API V2 provides an endpoint to get mints and their mint information by categories. These categories are useful for identifying tokens in specific trading scenarios, providing users with more information to trade with. + + + **CATEGORY** + + * Only `toporganicscore`, `toptraded` or `toptrending` category. + * Added query by interval for more accuracy, using `5m`, `1h`, `6h`, `24h`. + * The result filters out generic top tokens like SOL, USDC, etc (since those tokens are likely always top of the categories). + * Default to 50 mints in response (use `limit` to increase or decrease number of results). + + +```js +const categoryResponse = await ( + await fetch(`https://lite-api.jup.ag/tokens/v2/toporganicscore/5m?limit=100`) +).json(); +``` + +## Get Recent + +The Token API V2 provides an endpoint to get mints and their mint information by their recency. This is helpful to display to users a list of tokens that just had their first pool created, providing more information to trade with. + + + **RECENT** + + * Do note that the definition of RECENT is the **token's first pool creation time** (and not token's mint/creation timestamp). + * Default to 30 mints in response. + + +```js +const recentResponse = await ( + await fetch(`https://lite-api.jup.ag/tokens/v2/recent`) +).json(); +``` + +## Example Response + +All endpoints will return an array of mints, along with their information. + +**Successful example response:** + +```js expandable +[ + { + id: 'So11111111111111111111111111111111111111112', + name: 'Wrapped SOL', + symbol: 'SOL', + icon: 'https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png', + decimals: 9, + circSupply: 531207433.3986673, + totalSupply: 603724547.3627878, + tokenProgram: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', + firstPool: { + id: '58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2', + createdAt: '2021-03-29T10:05:48Z' + }, + holderCount: 2342610, + audit: { + mintAuthorityDisabled: true, + freezeAuthorityDisabled: true, + topHoldersPercentage: 1.2422471238911812 + }, + organicScore: 98.92390784896082, + organicScoreLabel: 'high', + isVerified: true, + cexes: [ + 'Binance', 'Bybit', + 'OKX', 'Upbit', + 'Bitget', 'Kraken', + 'KuCoin', 'MEXC', + 'Gate.io' + ], + tags: [ 'community', 'strict', 'verified' ], + fdv: 87824499429.22047, + mcap: 77275352037.79674, + usdPrice: 145.47114211747515, + priceBlockId: 349038717, + liquidity: 89970631.83880953, + stats5m: { + priceChange: 0.021175445311831707, + liquidityChange: -0.01230267453174984, + volumeChange: 4.855149318222242, + buyVolume: 14644327.188370818, + sellVolume: 14743625.023908526, + buyOrganicVolume: 269570.2345543641, + sellOrganicVolume: 204114.37436445671, + numBuys: 49281, + numSells: 54483, + numTraders: 18155, + numOrganicBuyers: 981, + numNetBuyers: 3503 + }, + stats1h: { + priceChange: -0.145099593531635, + liquidityChange: -0.13450589635262783, + volumeChange: -15.928930753985316, + buyVolume: 171520842.22567528, + sellVolume: 174057197.5207193, + buyOrganicVolume: 3099405.8562825476, + sellOrganicVolume: 2975660.0383528043, + numBuys: 586069, + numSells: 649275, + numTraders: 78145, + numOrganicBuyers: 2716, + numNetBuyers: 14442 + }, + stats6h: { + priceChange: 0.3790495974473589, + liquidityChange: 0.1659230330014905, + volumeChange: 14.571340846647542, + buyVolume: 1084625651.9256022, + sellVolume: 1094488293.656417, + buyOrganicVolume: 31145072.655369382, + sellOrganicVolume: 31647431.25353508, + numBuys: 3789847, + numSells: 4363909, + numTraders: 272131, + numOrganicBuyers: 10849, + numNetBuyers: 37155 + }, + stats24h: { + priceChange: 1.5076363979360274, + liquidityChange: 2.417364079880319, + volumeChange: -2.1516094834673254, + buyVolume: 4273248565.256824, + sellVolume: 4306065610.69747, + buyOrganicVolume: 109007133.8196669, + sellOrganicVolume: 118085567.17983335, + numBuys: 15125444, + numSells: 17582713, + numTraders: 754618, + numOrganicBuyers: 28590, + numNetBuyers: 80961 + }, + ctLikes: 4232, + smartCtLikes: 522, + updatedAt: '2025-06-25T05:02:21.034234634Z' + } +] +``` diff --git a/mintlify-migration/docs/tool-kits.mdx b/mintlify-migration/docs/tool-kits.mdx new file mode 100644 index 00000000..e0a95e52 --- /dev/null +++ b/mintlify-migration/docs/tool-kits.mdx @@ -0,0 +1,32 @@ +--- +title: "About Tool Kits" +sidebarTitle: "About Tool Kits" +description: "Jupiter Tool Kits are a collection of developer tools and SDKs that help you integrate Jupiter's powerful swap infrastructure into your applications. These tools are designed to make it easy to build on top of Solana and Jupiter." +--- + +## Why Use Jupiter Tool Kits? + +- **Accelerate Development**: Get your applications to market faster with our pre-built components and SDKs. +- **Open Source**: All our tools are open source, allowing you to inspect, modify and contribute to the codebase. +- **Low Code Solutions**: Many of our tools require minimal coding, making integration quick and straightforward. +- **Community Driven**: Join a vibrant community of developers building and improving these tools. + +## Jupiter Tool Kits + +- [**Jupiter Plugin**](/docs/tool-kits/plugin/): A ready-to-use swap interface that can be embedded into any website. +- [**Jupiter Mobile Adapter**](/docs/tool-kits/mobile-adapter): A wallet interface to allow Jupiter Mobile QR code login. +- [**Unified Wallet Kit**](/docs/tool-kits/wallet-kit/): A wallet interface that can be embedded into any website. + +## Community Contributions + +- [**Jupiverse Kit**](https://jupiversekit.xyz/): A ready-to-use React components for building with Jupiter Plugin and Unified Wallet Kit. +- [**DevRel Examples**](https://github.com/Jupiter-DevRel): A wealth of scripts and examples for building with Solana and Jupiter. + +## How to Contribute + +We welcome contributions from the anyone! Here's how you can help: + +1. Submit pull requests to our repositories. +2. Submit issues to our repositories. +3. If you're a vibe coder or non-technical, join our [Discord](https://discord.gg/jup) to discuss any ideas you have. +4. Help us by spreading the word about the tool kits. diff --git a/mintlify-migration/docs/tool-kits/mobile-adapter.mdx b/mintlify-migration/docs/tool-kits/mobile-adapter.mdx new file mode 100644 index 00000000..a089ad5f --- /dev/null +++ b/mintlify-migration/docs/tool-kits/mobile-adapter.mdx @@ -0,0 +1,69 @@ +--- +title: "Jupiter Mobile Adapter" +description: "The Jupiter Mobile Adapter allows you to integrate Jupiter Mobile login functionality into your app! By allowing Jupiter Mobile users to simply use the app to scan a QR code to login, they can utilize their wallets on Jupiter Mobile across any platform." +sidebarTitle: "Getting Started" +--- + + + + Install [@jup-ag/jup-mobile-adapter](https://www.npmjs.com/package/@jup-ag/jup-mobile-adapter) + + + Use `useWrappedReownAdapter` (Prerequisite to create an app id on [https://dashboard.reown.com/](https://dashboard.reown.com/)) + + + Add the `jupiterAdapter` within the wrapped adapter + + + + + +**TIP** + +[Example code reference from Jupiverse Kit](https://github.com/dannweeeee/jupiverse-kit/blob/36b0ed1e51ae7c4150355d1dd70205525ed9f305/src/provider/hooks/useAllWallets.ts#L10) + + +```js expandable +import { WalletProvider } from '@solana/wallet-adapter-react'; +import { useWrappedReownAdapter } from "@jup-ag/jup-mobile-adapter"; + +const WalletConnectionProvider: React.FC = ({ + children, +}) => { + // Refer to https://reown.com/appkit + const { reownAdapter, jupiterAdapter } = useWrappedReownAdapter({ + appKitOptions: { + metadata: { + name: "", + description: ``, + url: "", // origin must match your domain & subdomain + icons: [ + // add icons here + ], + }, + projectId: "", + features: { + analytics: false, + socials: ["google", "x", "apple"], + email: false, + }, + enableWallets: false, + }, + }); + + const wallets = useMemo( + () => [ + reownAdapter, + jupiterAdapter, + // add more wallets here + ], + [] + ); + + return ( + + {children} + + ); +}; +``` diff --git a/mintlify-migration/docs/tool-kits/plugin.mdx b/mintlify-migration/docs/tool-kits/plugin.mdx new file mode 100644 index 00000000..d0ab9fa5 --- /dev/null +++ b/mintlify-migration/docs/tool-kits/plugin.mdx @@ -0,0 +1,84 @@ +--- +title: "Integrate Jupiter Plugin" +description: "Seamlessly integrate end-to-end Ultra swap functionality into any application with just a few lines of code." +--- + +Jupiter Plugin is an open-source, lightweight, plug-and-play version of Jupiter Ultra Swap, allowing you to bring the exact jup.ag swap experience to any application. + +Try out the [Plugin Playground](https://plugin.jup.ag/) to experience the entire suite of customizations. + +To view the open-source code, visit the [GitHub repository](https://github.com/jup-ag/plugin). + + + + Plugin Playground { + e.target.style.opacity = '1'; + e.target.style.border = '2px solid #C8F284'; + }} + onMouseLeave={(e) => { + e.target.style.opacity = '1'; + e.target.style.border = '2px solid transparent'; + }} + /> + + + + +**QUICK START** + +To quick start your integration, check out the [Next.js](/docs/tool-kits/plugin/nextjs-app-example), [React](/docs/tool-kits/plugin/react-app-example) or [HTML](/docs/tool-kits/plugin/html-app-example) app examples. + +Refer to [Customization](/docs/tool-kits/plugin/customization) and [FAQ](/docs/tool-kits/plugin/faq) for more information. + + +## Key Features + +- **Seamless Integration**: Embed Jupiter's swap functionality directly into your application without redirects. +- **Multiple Display Options**: Choose between integrated, widget, or modal display modes. +- **Customizable Options**: Configure the swap form to match your application's needs. +- **RPC-less**: Integrate Plugin without any RPCs, Ultra handles transaction sending, wallet balances and token information. +- **Ultra Mode**: Access to all features of Ultra Mode, read more about it in the [Ultra API docs](/docs/ultra-api/). + +## Getting Started + +When integrating Plugin, there are a few integration methods to think about, and choose the one that best fits your application's architecture and requirements. + +### Integration Methods + +- **Using Window Object** - Simplest way to add and initialize Plugin. +- [**Using NPM Package**](https://www.npmjs.com/package/@jup-ag/plugin) - Install via `npm install @jup-ag/plugin` and initialize as a module (will require you to maintain its dependencies). + +### Wallet Integration + +- **Wallet Standard Support**: For applications without existing wallet provider, Plugin will provide a wallet adapter and connection - powered by [Unified Wallet Kit](/docs/tool-kits/wallet-kit/). +- **Passthrough Wallet**: For applications with existing wallet provider(s), set `enableWalletPassthrough=true` with context, and Plugin will allow the application to pass through the existing wallet provider's connection to Plugin. + +### Adding Fees to plugin + +- **Referral Account**: You can create a referral account via [scripts](/docs/ultra-api/add-fees-to-ultra) or [Referral Dashboard](https://referral.jup.ag/). +- **Referral Fee**: You can set the referral fee and account in the `formProps` interface when you initialize the Plugin. + +### Quick Start Guides + +In the next sections, we'll walk you through the steps to integrate Jupiter Plugin into different types of web applications from scratch. + + + + + + + + + + +By integrating Jupiter Plugin into your application, you can seamlessly integrate a fully functional swap interface into your application with minimal effort, while staying at the forefront of Solana DeFi innovation. diff --git a/mintlify-migration/docs/tool-kits/plugin/customization.mdx b/mintlify-migration/docs/tool-kits/plugin/customization.mdx new file mode 100644 index 00000000..378ce962 --- /dev/null +++ b/mintlify-migration/docs/tool-kits/plugin/customization.mdx @@ -0,0 +1,268 @@ +--- +title: "Customizing Plugin" +description: "Try out the [Plugin Playground](https://plugin.jup.ag/) to experience the full swap features and see the different customization options with code snippets." +--- + +For the full customization options, you can refer to the [repository](https://github.com/jup-ag/plugin/blob/main/src/types/index.d.ts). + +If you are using TypeScript, you can use the type declaration file to get the full type definitions for the Plugin. + + +```js + declare global { + interface Window { + Jupiter: JupiterPlugin; + } +} + +export type WidgetPosition = 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'; +export type WidgetSize = 'sm' | 'default'; +export type SwapMode = "ExactInOrOut" | "ExactIn" | "ExactOut"; +export type DEFAULT_EXPLORER = 'Solana Explorer' | 'Solscan' | 'Solana Beach' | 'SolanaFM'; + +export interface FormProps { + swapMode?: SwapMode; + initialAmount?: string; + initialInputMint?: string; + initialOutputMint?: string; + fixedAmount?: boolean; + fixedMint?: string; + referralAccount?: string; + referralFee?: number; +} + +export interface IInit { + localStoragePrefix?: string; + formProps?: FormProps; + defaultExplorer?: DEFAULT_EXPLORER; + autoConnect?: boolean; + displayMode?: 'modal' | 'integrated' | 'widget'; + integratedTargetId?: string; + widgetStyle?: { + position?: WidgetPosition; + size?: WidgetSize; + }; + containerStyles?: CSSProperties; + containerClassName?: string; + enableWalletPassthrough?: boolean; + passthroughWalletContextState?: WalletContextState; + onRequestConnectWallet?: () => void | Promise; + onSwapError?: ({ + error, + quoteResponseMeta, + }: { + error?: TransactionError; + quoteResponseMeta: QuoteResponse | null; + }) => void; + onSuccess?: ({ + txid, + swapResult, + quoteResponseMeta, + }: { + txid: string; + swapResult: SwapResult; + quoteResponseMeta: QuoteResponse | null; + }) => void; + onFormUpdate?: (form: IForm) => void; + onScreenUpdate?: (screen: IScreen) => void; +} + +export interface JupiterPlugin { + _instance: JSX.Element | null; + init: (props: IInit) => void; + resume: () => void; + close: () => void; + root: Root | null; + enableWalletPassthrough: boolean; + onRequestConnectWallet: IInit['onRequestConnectWallet']; + store: ReturnType; + syncProps: (props: { passthroughWalletContextState?: IInit['passthroughWalletContextState'] }) => void; + onSwapError: IInit['onSwapError']; + onSuccess: IInit['onSuccess']; + onFormUpdate: IInit['onFormUpdate']; + onScreenUpdate: IInit['onScreenUpdate']; + localStoragePrefix: string; +} + +export { }; +``` + + +## Display Modes + +Jupiter Plugin offers three distinct display modes to suit different use cases: + +### 1. Integrated Mode + +The integrated mode embeds the swap form directly into your application's layout. This is ideal for creating a seamless swap experience within your dApp. + +```js +{ + displayMode: "integrated"; + integratedTargetId: string; // Required: ID of the container element + containerStyles?: { + width?: string; + height?: string; + borderRadius?: string; + overflow?: string; + }; + containerClassName?: string; +} +``` + +### 2. Widget Mode + +The widget mode creates a floating swap form that can be positioned in different corners of the screen. Perfect for quick access to swaps without taking up too much space. + +```js +{ + displayMode: "widget"; + widgetStyle?: { + position?: "top-left" | "top-right" | "bottom-left" | "bottom-right"; + size?: "sm" | "default"; + }; +} +``` + +### 3. Modal Mode + +The modal mode displays the swap form in a popup overlay. This is useful when you want to keep the swap form hidden until needed. + +```js +{ + displayMode: "modal"; +} +``` + +## Form Props Configuration + +The `formProps` object allows you to customize the initial state and behavior of the swap form! This can be useful for use cases like fixed token swaps for memecoin communities or fixed amount payments. + +```js +{ + displayMode: "modal"; + formProps?: { + swapMode?: SwapMode; // Set the swap mode to "ExactIn", "ExactOut", or default to "ExactInOrOut" + + initialAmount?: string; // Pre-fill the swap amount (e.g. "100") + initialInputMint?: string; // Pre-select the input token by its mint address + initialOutputMint?: string; // Pre-select the output token by its mint address + + fixedAmount?: boolean; // When true, users cannot change the swap amount + fixedMint?: string; // Lock one side of the swap to a specific token by its mint address + + referralAccount?: string; // Set the referral account for the swap + referralFee?: number; // Set the referral fee for the swap + } +} +``` + +## Wallet Integration + +Jupiter Plugin supports third-party wallet integration through the `enableWalletPassthrough` prop. This allows your application to pass through an existing wallet provider's connection in your application to Plugin. If you do not have an existing wallet provider, Plugin will provide a wallet adapter and connection - powered by [Unified Wallet Kit](/docs/tool-kits/wallet-kit/). + +```js +{ + // When true, wallet connection are handled by your dApp, + // and use `syncProps()` to syncronise wallet state with Plugin. + enableWalletPassthrough?: boolean; + + // Optional, if wallet state is ready, + // you can pass it in here, or just use `syncProps()` + passthroughWalletContextState?: WalletContextState; + + // When enableWalletPassthrough is true, this allows Plugin + // to callback your app's wallet connection flow + onRequestConnectWallet?: () => void | Promise; +} +``` + +## Event Handling + +Jupiter Plugin provides event handlers to track swap operations: + +```js +{ + onSuccess: ({ txid, swapResult, quoteResponseMeta }) => { + // Handle successful swap + console.log("Swap successful:", txid); + }; + onSwapError: ({ error, quoteResponseMeta }) => { + // Handle swap errors + console.error("Swap failed:", error); + } +} +``` + +## Branding + +Jupiter Plugin supports branding through the `branding` prop. This allows you to customize the Plugin's logo and name to include your own branding. + +```js +{ + branding?: { + logoUri?: string; + name?: string; + }; +} +``` + +## Color Theme + +Jupiter Plugin supports a simplified way to customize the color theme. This allows you to match the appearance of the Plugin to your brand. + +```js +/* In your global CSS file */ +:root { + --jupiter-plugin-primary: 199, 242, 132; + --jupiter-plugin-background: 0, 0, 0; + --jupiter-plugin-primaryText: 232, 249, 255; + --jupiter-plugin-warning: 251, 191, 36; + --jupiter-plugin-interactive: 33, 42, 54; + --jupiter-plugin-module: 16, 23, 31; +} +``` + +## Examples + +### Fixed SOL Swap + +```js +window.Jupiter.init({ + displayMode: "integrated"; + integratedTargetId: "jupiter-plugin"; + formProps: { + initialInputMint: "So11111111111111111111111111111111111111112"; // SOL + initialOutputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; // USDC + fixedMint: "So11111111111111111111111111111111111111112"; + }; +}); +``` + +### Payment Integration + +```js +window.Jupiter.init({ + displayMode: "modal"; + formProps: { + swapMode: "ExactOut"; + initialAmount: "10"; + fixedAmount: true; + initialOutputMint: "YOUR_TOKEN_MINT"; + fixedMint: "YOUR_TOKEN_MINT"; + }; +}); +``` + +### Floating Widget + +```js +window.Jupiter.init({ + displayMode: "widget"; + widgetStyle: { + position: "bottom-right"; + size: "sm"; + }; +}); +``` + diff --git a/mintlify-migration/docs/tool-kits/plugin/faq.mdx b/mintlify-migration/docs/tool-kits/plugin/faq.mdx new file mode 100644 index 00000000..f3560a0e --- /dev/null +++ b/mintlify-migration/docs/tool-kits/plugin/faq.mdx @@ -0,0 +1,59 @@ +--- +title: "FAQ" +--- + + + * For feature requests, please open an issue on the [GitHub repository](https://github.com/jup-ag/plugin/issues) and tag us on Discord. + * For support, please join the [Discord server](https://discord.gg/jup) and get help in the developer channels. + + + + + * **Creating Referral Account and Token Accounts**: You can create via [scripts](/docs/ultra-api/add-fees-to-ultra) or [Referral Dashboard](https://referral.jup.ag). + * **Adding to FormProps**: You can set the referral account and fee in the [`formProps` interface](/docs/tool-kits/plugin/customization#form-props-configuration) when you initialize the Plugin. + + + + + * Ensure you establish a fixed height for the swap form container under `containerStyles` + +```js +{ + displayMode: "integrated", + integratedTargetId: "jupiter-plugin", + containerStyles: { + height: "500px", + }, +} +``` + + + + + + +## Best Practices for Customization + + + * Use percentage-based widths for container styles + * Test on different screen sizes + * Consider mobile-first design + + + + + * Position widgets in easily accessible locations + * Consider fixed token pairs for specific use cases + * Implement proper error handling and prompts + + + + + * Use environment variables for sensitive data + * Implement proper error boundaries + * Validate user inputs + + + + + diff --git a/mintlify-migration/docs/tool-kits/plugin/html-app-example.mdx b/mintlify-migration/docs/tool-kits/plugin/html-app-example.mdx new file mode 100644 index 00000000..cbdd3a12 --- /dev/null +++ b/mintlify-migration/docs/tool-kits/plugin/html-app-example.mdx @@ -0,0 +1,74 @@ +--- +title: "HTML App Example" +description: "In this guide, we'll walk you through from scratch the steps to integrate Jupiter Plugin into a HTML application." +--- + +## Prerequisites + +Before you begin, make sure you have the following installed on your system. + +**Node.js and npm**: Download and install from [nodejs.org](https://nodejs.org) **http-server**: Download and install [http-server from npm](https://www.npmjs.com/package/http-server) + +## Step 1: Create a New HTML Project + + Head to your preferred directory and create a new folder for your project: + +```bash +mkdir plugin-democd +plugin-demotouch +index.html +``` + +## Step 2: Add the Plugin Script + +Add the Plugin script to your project: + +```bash expandable + + + + + + Jupiter Plugin Demo + + + + +
+

Jupiter Plugin Demo

+
+
+ + + + +``` + +## Step 3: Run the Project + +Run the project using `http-server`: + +```bash +http-server +``` + +There you have it! You've successfully integrated Jupiter Plugin into your HTML application. + * Please test the swap functionality and check the transaction. + * If you require more customizations, check out the [Plugin Playground](https://plugin.jup.ag) or the [Customization](/docs/tool-kits/plugin/customization) documentation. + * If you have any questions or issues, please refer to the [FAQ](/docs/tool-kits/plugin/faq) or contact us on [Discord](https://discord.gg/jup). + diff --git a/mintlify-migration/docs/tool-kits/plugin/nextjs-app-example.mdx b/mintlify-migration/docs/tool-kits/plugin/nextjs-app-example.mdx new file mode 100644 index 00000000..08eb545b --- /dev/null +++ b/mintlify-migration/docs/tool-kits/plugin/nextjs-app-example.mdx @@ -0,0 +1,273 @@ +--- +title: "Next.js App Example" +description: "In this guide, we'll walk you through from scratch the steps to integrate Jupiter Plugin into a Next.js application." +--- + +## Prerequisites + +Before you begin, make sure you have the following installed on your system. + +**Node.js and npm**: Download and install from [nodejs.org](https://nodejs.org) + +## Step 1: Create a New Next.js Project + +Head to your preferred directory and create a new Next.js project using `create-next-app` with TypeScript template (you can use other templates or methods to start your project too): + +```bash +npx create-next-app@latest plugin-demo --typescript +cd plugin-demo +npm run dev +``` + +## Step 2: Add TypeScript Support + +Create a type declaration file `plugin.d.ts` in your project's `/src/types` folder: + +```js +declare global { + interface Window { + Jupiter: JupiterPlugin; + } +}; +export {}; +``` + + +```js + declare global { + interface Window { + Jupiter: JupiterPlugin; + } +} + +export type WidgetPosition = 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'; +export type WidgetSize = 'sm' | 'default'; +export type SwapMode = "ExactInOrOut" | "ExactIn" | "ExactOut"; +export type DEFAULT_EXPLORER = 'Solana Explorer' | 'Solscan' | 'Solana Beach' | 'SolanaFM'; + +export interface FormProps { + swapMode?: SwapMode; + initialAmount?: string; + initialInputMint?: string; + initialOutputMint?: string; + fixedAmount?: boolean; + fixedMint?: string; + referralAccount?: string; + referralFee?: number; +} + +export interface IInit { + localStoragePrefix?: string; + formProps?: FormProps; + defaultExplorer?: DEFAULT_EXPLORER; + autoConnect?: boolean; + displayMode?: 'modal' | 'integrated' | 'widget'; + integratedTargetId?: string; + widgetStyle?: { + position?: WidgetPosition; + size?: WidgetSize; + }; + containerStyles?: CSSProperties; + containerClassName?: string; + enableWalletPassthrough?: boolean; + passthroughWalletContextState?: WalletContextState; + onRequestConnectWallet?: () => void | Promise; + onSwapError?: ({ + error, + quoteResponseMeta, + }: { + error?: TransactionError; + quoteResponseMeta: QuoteResponse | null; + }) => void; + onSuccess?: ({ + txid, + swapResult, + quoteResponseMeta, + }: { + txid: string; + swapResult: SwapResult; + quoteResponseMeta: QuoteResponse | null; + }) => void; + onFormUpdate?: (form: IForm) => void; + onScreenUpdate?: (screen: IScreen) => void; +} + +export interface JupiterPlugin { + _instance: JSX.Element | null; + init: (props: IInit) => void; + resume: () => void; + close: () => void; + root: Root | null; + enableWalletPassthrough: boolean; + onRequestConnectWallet: IInit['onRequestConnectWallet']; + store: ReturnType; + syncProps: (props: { passthroughWalletContextState?: IInit['passthroughWalletContextState'] }) => void; + onSwapError: IInit['onSwapError']; + onSuccess: IInit['onSuccess']; + onFormUpdate: IInit['onFormUpdate']; + onScreenUpdate: IInit['onScreenUpdate']; + localStoragePrefix: string; +} + +export { }; +``` + + +## Step 3: Embed the Plugin Script + +For Next.js applications, you can add the script in two ways: + +### Using App Router (Next.js 13+) + +In your `app/layout.tsx`: + +```js +import Script from "next/script"; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + +``` + +## Step 4: Initialize Plugin + +There are two ways to initialize Jupiter Plugin in a React application: + +### Method 1: Using Window Object + +In your `/src/App.tsx`, use the following code to initialize the plugin. + +```bash +import React, { useEffect } from 'react'; +import './App.css'; +import './types/plugin.d'; + +export default function App() { + useEffect(() => { + // Initialize plugin + window.Jupiter.init({ + displayMode: "widget", + integratedTargetId: "jupiter-plugin", + }); + }, []); + + return ( +
+

Jupiter Plugin Demo

+
+
+ ); +} +``` + +### Method 2: Using @jup-ag/plugin Package + + +**WARNING** + +Do note that using this method will require you to maintain its dependencies. + + + + + + Install the package: + +```bash +npm install @jup-ag/plugin +``` + + + +Initialize the plugin: + +```bash +import React, { useEffect } from "react"; +import "@jup-ag/plugin/css"; +import "./App.css"; +import "./types/plugin.d"; + +export default function App() { + useEffect(() => { + import("@jup-ag/plugin").then((mod) => { + const { init } = mod; + init({ + displayMode: "widget", + integratedTargetId: "jupiter-plugin", + }); + }); + }, []); + + return ( +
+

Jupiter Plugin Demo

+
+
+ ); +} +``` + + + +There you have it! You've successfully integrated Jupiter Plugin into your Next.js application. + - Please test the swap functionality and check the transaction. + - If you require more customizations, check out the [Plugin Playground](https://plugin.jup.ag) or the [Customization](/docs/tool-kits/plugin/customization) documentation. + - If you have any questions or issues, please refer to the [FAQ](/docs/tool-kits/plugin/faq) or contact us on [Discord](https://discord.gg/jup). diff --git a/mintlify-migration/docs/tool-kits/referral-program.mdx b/mintlify-migration/docs/tool-kits/referral-program.mdx new file mode 100644 index 00000000..3c1b5c48 --- /dev/null +++ b/mintlify-migration/docs/tool-kits/referral-program.mdx @@ -0,0 +1,40 @@ +--- +title: "Referral Program" +sidebarTitle: "Introduction" +description: "The Referral Program is an open-source program used by Jupiter Programs (or any other programs) to enable developers to earn fees." +--- + + +**REFERRAL PROGRAM SOURCE CODE** + +[Open Source Repository](https://github.com/TeamRaccoons/referral): To understand and make use of the referral program better. + + +## Jupiter API Integrators + +The Jupiter Programs use the Referral Program to allow developers to earn fees when integrating with Jupiter. Below are some resources to help you quickly get started. There are a different ways to setup such as via the Jupiter Referral Dashboard or using the provided scripts. + +- [Jupiter Referral Dashboard](https://referral.jup.ag/): To view and manage your referral accounts used with Jupiter APIs. +- [Add Fees to Ultra API](/docs/ultra-api/add-fees-to-ultra): To add fees to your Ultra API integration. +- [Add Fees to Swap and Trigger API](/docs/swap-api/add-fees-to-swap): To add fees to your Swap and Trigger API integration. +- [Add Fees to Jupiter Plugin](/docs/tool-kits/plugin#adding-fees-to-plugin): To add fees to your Plugin integration. + +## Other Program Integrators + +### Project Usage + +If you have a project/product that runs a program on the Solana blockchain, you can integrate the Referral Program to allow/share revenue with the integrators of your program. + +Similar to how Jupiter Programs uses the Referral Program to help developers earn fees and/or share the revenue with Jupiter. For example, Jupiter Ultra uses the Jupiter Swap program which relies on the Referral Program. + +- Create a `Project` by calling `initialize_project` with your chosen `base` key and a project `name` (`base` key refers to a key identifier of your project). +- Set a `default_share_bps` to share the fees with your referrers (or integrators). +- An example of a `Project` account: [Jupiter Ultra Project](https://solscan.io/account/DkiqsTrw1u1bYFumumC7sCG2S8K25qc2vemJFHyW2wJc) + +### Referrer Usage + +If you are a referrer such as a developer or integrator of a project that runs a program on the Solana blockchain, you can create the necessary accounts via the Referral Program to earn fees. + +- The program must be integrated with the Referral Program. +- Create a `Referral` account by calling `initialize_referral_account` with the correct `Project` account, the `Referral` account, and your own `Partner` account (`Partner` account is the admin of this referral account). +- Create the necessary `Referral` token accounts for the `Referral` account to receive fees in. diff --git a/mintlify-migration/docs/tool-kits/wallet-kit.mdx b/mintlify-migration/docs/tool-kits/wallet-kit.mdx new file mode 100644 index 00000000..29827327 --- /dev/null +++ b/mintlify-migration/docs/tool-kits/wallet-kit.mdx @@ -0,0 +1,112 @@ +--- +title: "Unified Wallet Kit" +description: "The Unified Wallet Kit is an open-source, Swiss Army Knife wallet adapter designed to streamline your development on Solana." +sidebarTitle: "Getting Started" +--- + +Integrating multiple wallets into a single interface can be cumbersome, the Unified Wallet Kit aims to eliminates redundancies by providing these building blocks in a simple, plug-and-play package. This allows developers to focus on what matters most: building innovative features for your users. + +The Unified Wallet Kit will help you reduce repetitive tasks within your development process, including: + - Creating a wallet notification system. + - Managing wallet states (connected, disconnected, etc.). + - Implementing a mobile-friendly wallet connector . + + +**UNIFIED WALLET KIT REFERENCES** + + - [Wallet Kit Playground](https://unified.jup.ag/): To play with different settings,features and styling. + - [Open Source Repository](https://github.com/TeamRaccoons/Unified-Wallet-Kit): To understand and make use of the wallet adapter better. + - [Quick Examples](https://github.com/TeamRaccoons/Unified-Wallet-Kit/tree/main/src/components/examples): To reference code snippets and examples. + + +## Core Features + +| Feature | Description | +| :--- | :--- | +| **Compact Bundle** | Main ESM bundle is a lightweight 94KB (20KB gzipped). | +| **Built-in Support** | Comes with Wallet Standard and Mobile Wallet Adapter support. | +| **Abstracted Wallet Adapter** | Use the Bring Your Own Wallet (BYOW) approach to select custom and legacy wallets. | +| **Mobile Responsive** | Designed to be mobile-first. | +| **Smart Notification System** | Integrates seamlessly with your existing notification system or can be used independently. | +| **Internationalization** | Supports multiple languages including English, Chinese, Vietnamese, French, Japanese, Bahasa Indonesia, and Russian. | +| **Theming Options** | Choose from light, dark, and Jupiter modes, with more customization options coming soon. | +| **New User Onboarding** | Simplifies the onboarding process for new users. | + + +## Let's Get Started + +#### TLDR Steps + + + + Adjust the Theme Selector to your desired version. + + + Select your appropriate Language + + + Expand the 'Show Snippet' box for the wallet configuration you would like in your app and + + + Select the `Copy to Clipboard` button for easy code insertion into your app. + + + Install the Unified Wallet Kit to your project dependencies. + + + + + + +**Install the wallet adapter depenency** + +```bash +npm i @jup-ag/wallet-adapter +``` + +**Wrap your app with ``** + +```js expandable +const ExampleBaseOnly = () => { + return ( + + + + ); +}; + +export default ExampleBaseOnly; +``` + + +**INFO** + +This kit also supports the attachment of custom elements to specific wallets + + +```js +config={{ + walletAttachments: { + 'Phantom': { + attachment:
Auto Confirm
+ } + } +}} + +``` diff --git a/mintlify-migration/docs/trigger-api.mdx b/mintlify-migration/docs/trigger-api.mdx new file mode 100644 index 00000000..362649a3 --- /dev/null +++ b/mintlify-migration/docs/trigger-api.mdx @@ -0,0 +1,55 @@ +--- +title: "About Trigger API" +description: "The Jupiter Trigger API enables you to create limit orders on Solana, allowing users to set target prices for token swaps that execute automatically when market conditions are met." +--- + +The Trigger API is ideal for: + +* DeFi applications that want to offer users more advanced trading options +* Wallets looking to expand their trading features +* Automated systems that need to execute at specific price points + +## Features + +| Feature | Description | +| :-------------------------- | :----------------------------------------------------------------------------------------------------------- | +| **Custom integrator fees** | Integrators can choose to charge their own custom fees (on top of Jupiter's fees). | +| **Any token pair** | Create trigger orders between any token pairs supported on Jupiter's Metis Routing Engine. | +| **Best execution** | Orders are executed through Jupiter's Metis Routing Engine to get the best possible price across all DEXes. | +| **Price monitoring** | Our infrastructure continuously monitors prices to execute trigger orders as soon as conditions are met. | +| **Order expiry** | Trigger orders can be set to expire after a certain period of time. | +| **Slippage addition** | Add slippage to the target price, ideal for users who want to prioritize success rate over price. | + +## Getting Started with Trigger API + +1. [**Create Order**](/docs/trigger-api/create-order): Create a new trigger order with your desired parameters. +2. [**Execute Order**](/docs/trigger-api/execute-order): Execute a trigger order. +3. [**Cancel Order**](/docs/trigger-api/cancel-order): Cancel an existing trigger order. +4. [**Get Trigger Orders**](/docs/trigger-api/get-trigger-orders): Retrieve active/historical trigger orders for a specific wallet address +5. [**Best Practices**](/docs/trigger-api/best-practices): Best practices for using Trigger API. + +## FAQ + + + + + +Trigger API takes 0.03% for stable pairs and 0.1% for every other pairs. + + + + + +Yes, integrators can take fees on top of Jupiter's fees. + + + + +When using trigger orders on the jup.ag frontend, you'll see two execution modes: + +| jup.ag UI Mode | API Implementation | Description | +| :-------------- | :----------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **Exact** | `slippageBps: 0` (default) | Orders execute with 0 slippage for precise price execution

By default, trigger orders execute with 0 slippage (you can omit the `slippageBps` parameter) | +| **Ultra** | `slippageBps: ` | Orders execute with custom slippage for higher success rates On the jup.ag UI, Ultra denotes that Jupiter sets the slippage for the user, however, in API implementation, you will need to evaluate and set it yourself. | +
+
diff --git a/mintlify-migration/docs/trigger-api/best-practices.mdx b/mintlify-migration/docs/trigger-api/best-practices.mdx new file mode 100644 index 00000000..24167f5f --- /dev/null +++ b/mintlify-migration/docs/trigger-api/best-practices.mdx @@ -0,0 +1,12 @@ +--- +title: "Best Practices" +description: "Some best practices when using the Trigger API." +--- + +| Item | Recommendation | +| :---------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| The program will accept any value to create an order. | On jup.ag, our frontend enforces a minimum of 5 USD per order to be created, this will ensure our keepers can accommodate for no loss in transaction fees coverage. However, programmatically, if you do not enforce this, the user can still create an order. | +| The program does not check the price or rate of the order, and the keeper will execute as instructed. | On our frontend, when user attempts to set the rate to buy above market price, we provide warnings and disable the execution if above 5%. If the order is created with such rates, the keeper will execute as instructed. For example, if user sets to Sell 1000 USDC to Buy 1 SOL at the rate of 1000 SOL/USDC, the keeper will execute as instructed and the additional funds will be lost. | +| Tokens with transfer tax extension are disabled. | Our frontend informs the user if the token has transfer tax. | +| Token2022 tokens with transfer tax extension are disabled. | Our frontend informs the user if the token has transfer tax. | +| Trigger orders with slippage. | By nature, trigger orders execute with 0 slippage. However, you can add slippage to the order to ensure the order is filled but at the cost of slippage. | diff --git a/mintlify-migration/docs/trigger-api/cancel-order.mdx b/mintlify-migration/docs/trigger-api/cancel-order.mdx new file mode 100644 index 00000000..452779d8 --- /dev/null +++ b/mintlify-migration/docs/trigger-api/cancel-order.mdx @@ -0,0 +1,124 @@ +--- +title: "Cancel Order" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/trigger/v1/cancelOrder` + * Pro URL: `https://api.jup.ag/trigger/v1/cancelOrder` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +If you want to cancel order(s), you need to do these steps: + +1. Get a list of the order accounts you want to cancel via `/getTriggerOrders` endpoint. +2. Use the list of order accounts to make a post request to the `/cancelOrder` endpoint to get the transaction to cancel one or multiple orders. +3. Sign then send the transaction to the network either via `/execute` endpoint or by yourself. + + + **GET TRIGGER ORDERS** + + [Refer to the `/getTriggerOrders` section](/docs/trigger-api/get-trigger-orders) to prepare the list of order accounts you want to cancel. + + + + **INFO** + + To cancel multiple orders, you can use the [`/cancelOrders` endpoint](#cancel-orders) to pass in a list of order accounts and it will build the transaction for multiple cancellations. + + +## Cancel Order + +```js +const cancelOrderResponse = await ( + await fetch('https://lite-api.jup.ag/trigger/v1/cancelOrder', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + maker: "jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3", + computeUnitPrice: "auto", + order: "3g2jF8txqXPp6GUStwtXMrWydeYWxU4qoBA8UDLoTnK7", + }) + }) +).json(); +``` + +## Cancel Order Response + +**Success Example Response** + +```json +{ + "transaction": "AQAAAAAAAAAAAAAAAAAAAAAA......QYHAwUIX4Ht8Agx34Q=", + "requestId": "370100dd-1a85-421b-9278-27f0961ae5f4", +} +``` + +**Failed Example Response** + +```json +{ + "error": "no matching orders found", + "code": 400 +} +``` + +## Cancel Orders + + + **WARNING** + + If no orders are specified, the API will return the transaction to cancel **ALL** open orders, batched in groups of 5 orders. + + + + **TIP** + + Orders are batched in groups of 5, if you have 6 orders to cancel, you will receive 2 transactions. + + Do note that you will receive a list of transactions, so you will need to access each transaction in it to sign and send individually. + + If using `/execute` endpoint, you should pass in the same `requestId` for the different transactions. + + +```js +const cancelOrdersResponse = await ( + await fetch('https://lite-api.jup.ag/trigger/v1/cancelOrders', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + maker: "jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3", + computeUnitPrice: "auto", + orders: [ + "6fe8ByaiFHisjnYnH5qdpyiNtkn89mMBQUemRkVmKhro", + "9jwzPKHxcrSozdrTYzPnTqy7psRvNGxaYUAiiyxwZKjj" + ] + }) + }) +).json(); +``` + +## Cancel Orders Response + +**Success Example Response** + +```json +{ + "transactions": [ + "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA......DHfhA0JAAAJBQ0ODwsNCF+B7fAIMd+EDQkAAAMCDQ4PCw0IX4Ht8Agx34Q=", + "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA......a8lAwQABQLAqAAABAAJAy48AAAAAAAABQkAAAIBBQYHAwUIX4Ht8Agx34Q=" + ], + "requestId": "370100dd-1a85-421b-9278-27f0961ae5f4", +} +``` diff --git a/mintlify-migration/docs/trigger-api/create-order.mdx b/mintlify-migration/docs/trigger-api/create-order.mdx new file mode 100644 index 00000000..320c7227 --- /dev/null +++ b/mintlify-migration/docs/trigger-api/create-order.mdx @@ -0,0 +1,104 @@ +--- +title: "Create Order" +--- + + + **NEW PATHS** + + The `/limit/v2` path will be deprecated soon, please update your API calls to use the `/trigger/v1` path immediately. + + When updating to the new path, please refer to the documentation as there are some breaking changes. + + * `/execute` endpoint is introduced. + * `/createOrder` endpoint now includes an additional `requestId` parameter to be used with the `/execute` endpoint. + * `/cancelOrder` endpoint only builds the transaction for 1 order, while `/cancelOrders` endpoint builds the transaction for multiple orders. + * The `tx` field in the responses are now `transaction` or `transactions`. + * `/getTriggerOrders` endpoint is introduced to get either active or historical orders (based on the query parameters) in a new format. + + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/trigger/v1/createOrder` + * Pro URL: `https://api.jup.ag/trigger/v1/createOrder` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +## Create Order + +This is a POST request to `/createOrder` endpoint, where you pass in the necessary parameters and our backend will create the transaction for you to sign and send to the network seamlessly. + + + **OPTIONAL PARAMETERS** + + Do note that there are a few optional parameters that you can use, such as: + + * Adding slippage to the order: This corresponds to the "Ultra" mode on jup.ag frontend. Higher slippage increases execution success rate but may result in less favorable prices. Omitting this parameter (or setting it to 0) corresponds to "Exact" mode. [Learn more about UI modes vs API implementation](/docs/trigger-api#faq). + * Setting an expiry date on the order. + * Adding fees through our referral program, please ensure that your `feeAccount` has the necessary `referralTokenAccount`s of the output mint of the limit order for it to work, you can learn more about creating them dynamically in the [Add Fees To Swap](/docs/swap-api/add-fees-to-swap) guide. (Note that the fees are transferred only after the trigger order has been executed.) + + +**Create a POST request to the `/createOrder` endpoint.** + +```js +const createOrderResponse = await ( + await fetch('https://api.jup.ag/trigger/v1/createOrder', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + inputMint: inputMint.toString(), + outputMint: outputMint.toString(), + maker: "jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3", + payer: "jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3", + params: { + makingAmount: "1000000", + takingAmount: "300000", + // slippageBps: "", // Optional, by nature, trigger orders execute with 0 slippage + // expiredAt: "", // In unix seconds (e.g. Date.now()/1_000) or optional + // feeBps: "", // Requires referral account or optional + }, + computeUnitPrice: "auto", + // feeAccount: "", // Optional but if specified it is the referral token account of the output mint + // wrapAndUnwrapSol: true, // Default true or optional + }) + }) +).json(); + +console.log(createOrderResponse); +``` + +Now that you have the order transaction, you can sign and send to the network. There are 2 methods, after signing the transaction, you can either send it to the network yourself or use the Trigger API's `/execute` endpoint to do it for you. + + + + + +## Create Order Response + +**Success Example Response** + +```json +{ + "order": "CFG9Bmppz7eZbna96UizACJPYT3UgVgps3KkMNNo6P4k", + "transaction": "AQAAAAAAAAAAAAAAAAAAAAAA......AgAKCAkBAQsPAAADBAEMCwcKCQkIBg0LIoVuSq9wn/WfdskdmHlfUulAQg8AAAAAAICpAwAAAAAAAAAJAwEAAAEJAA==", + "requestId": "370100dd-1a85-421b-9278-27f0961ae5f4" +} +``` + +**Failed Example Response** + +```json +{ + "error": "invalid create order request", + "cause": "input mint making amount must be at least 5 USD, received: 2", + "code": 400 +} +``` diff --git a/mintlify-migration/docs/trigger-api/execute-order.mdx b/mintlify-migration/docs/trigger-api/execute-order.mdx new file mode 100644 index 00000000..2e59066a --- /dev/null +++ b/mintlify-migration/docs/trigger-api/execute-order.mdx @@ -0,0 +1,112 @@ +--- +title: "Execute Order" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/trigger/v1/execute` + * Pro URL: `https://api.jup.ag/trigger/v1/execute` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +After getting the order transaction, you can sign and send to the network yourself or use the Trigger API's `/execute` endpoint to do it for you. + +## Sign Transaction + +Using the Solana `web3.js` v1 library, you can sign the transaction as follows: + +```js +// ... GET /order's response + +// Extract the transaction from the order response +const transactionBase64 = orderResponse.tx + +// Deserialize the transaction +const transaction = VersionedTransaction.deserialize(Buffer.from(transactionBase64, 'base64')); + +// Sign the transaction +transaction.sign([wallet]); + +// Serialize the transaction to base64 format +const signedTransaction = Buffer.from(transaction.serialize()).toString('base64'); +``` + +## Execute Order + +By making a post request to the `/execute` endpoint, Jupiter executes the order transaction on behalf of you/your users. This includes handling of transaction handling, priority fees, RPC connection, etc. + +```js +const executeResponse = await ( + await fetch('https://lite-api.jup.ag/trigger/v1/execute', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + signedTransaction: signedTransaction, + requestId: "370100dd-1a85-421b-9278-27f0961ae5f4", + }), + }) +).json(); +``` + +## Execute Order Response + +After making the post request to the `/execute` endpoint, you will receive a response with the status of the order. + +**Example response of successful order:** + +```json +{ + "signature": "...", + "status": "Success" +} +``` + +**Example response of failed order:** + +```json +{ + "error": "custom program error code: 1", + "code": 500, + "signature": "...", + "status": "Failed" +} +``` + +## Send Transaction Yourself + +If you want to handle the transaction, you can sign and send the transaction to the network yourself. + +```js expandable +const transactionBase64 = createOrderResponse.transaction +const transaction = VersionedTransaction.deserialize(Buffer.from(transactionBase64, 'base64')); + +transaction.sign([wallet]); + +const transactionBinary = transaction.serialize(); + +const blockhashInfo = await connection.getLatestBlockhashAndContext({ commitment: "finalized" }); + +const signature = await connection.sendRawTransaction(transactionBinary, { + maxRetries: 1, + skipPreflight: true +}); + +const confirmation = await connection.confirmTransaction({ +signature, +blockhash: blockhashInfo.value.blockhash, +lastValidBlockHeight: blockhashInfo.value.lastValidBlockHeight, +}, "finalized"); + +if (confirmation.value.err) { + throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}\n\nhttps://solscan.io/tx/${signature}`); +} else console.log(`Transaction successful: https://solscan.io/tx/${signature}`); +``` diff --git a/mintlify-migration/docs/trigger-api/get-trigger-orders.mdx b/mintlify-migration/docs/trigger-api/get-trigger-orders.mdx new file mode 100644 index 00000000..2e115fd9 --- /dev/null +++ b/mintlify-migration/docs/trigger-api/get-trigger-orders.mdx @@ -0,0 +1,55 @@ +--- +title: "Get Trigger Orders" +--- + + + **NOTE** + + * Lite URL: `https://lite-api.jup.ag/trigger/v1/getTriggerOrders` + * Pro URL: `https://api.jup.ag/trigger/v1/getTriggerOrders` + + To upgrade to Pro or understand our rate limiting, please refer to this section. + + + + + + + +This is a GET request to `/getTriggerOrders` endpoint. + +The response is paginated for every 10 orders and you can view different pages using the `page` parameter. The `hasMoreData` boolean will indicate if you have more data in the next page. + + + **CHANGE OF RESPONSE FORMAT** + + The `/getTriggerOrders` endpoint does not provide the same data format as the old `orderHistory` or `openOrders` endpoint. + + +## Active Orders + +To get the active orders, you can pass in the `orderStatus` parameter as `active`. + + + You can optionally pass in the input and output token mint addresses to filter the open orders. + + +```js +const openOrdersResponse = await ( + await fetch( + 'https://lite-api.jup.ag/trigger/v1/getTriggerOrders?user=jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3&orderStatus=active' + ) +).json(); +``` + +## Order History + +To get the order history, you can pass in the `orderStatus` parameter as `history`. + +```js +const orderHistoryResponse = await ( + await fetch( + 'https://lite-api.jup.ag/trigger/v1/getTriggerOrders?user=ErJKdNoarixqGGQTHbBtvHtg2nkcCqcKtYjGbVKUxY7D&orderStatus=history' + ) +).json(); +``` diff --git a/mintlify-migration/docs/ultra-api.mdx b/mintlify-migration/docs/ultra-api.mdx new file mode 100644 index 00000000..518ed476 --- /dev/null +++ b/mintlify-migration/docs/ultra-api.mdx @@ -0,0 +1,125 @@ +--- +title: "About Ultra API" +description: "The Jupiter Ultra API is the API *you* ever need to experience or build the best trading experience on Solana." +--- + +## Features + +Ultra API is a holistic solution for developers to build all types of applications, without having to worry about the complexities of the underlying infrastructure: + +| Feature | Description | +| :--------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Best Trading Experience** | Ultra is the best trading experience in crypto, it handles all the complexities and headaches such as slippage protection, transaction landing and more. | +| **RPC-less** | You do not need to provide a RPC endpoint to send transactions, get token information, or get user balances - we handle everything for you. | +| **Holistic Coverage** | Ultra API covers all the necessary features for you to build your application, including the features mentioned below and useful information such as user wallet balances, token information, and more. | +| **Integrator Fees** | Ultra API allows you to add custom integrator fees to your transactions, on top of Jupiter's fees. Refer to the [Add Fees To Ultra](/docs/ultra-api/add-fees-to-ultra) guide for more information. | +| **Developer Support** | Get the [best developer support in our Discord](https://discord.gg/jup), the DevRel Working Group is here to help you with any issues you may face when using Ultra API. | +| **World Class Support** | Ultra is the best trading experience in crypto, it handles all the complexities such as slippage protection and transaction landing, and if you ever face any issues or need help when using Ultra, our support team is here to assist you 24/7. Read more about [Ultra customer support](/misc/integrator-guidelines#customer-support). | + +### Juno Liquidity Engine + +Ultra utilizes the latest [Juno Liquidity Engine](/docs/routing) which aggregates across multiple liquidity sources, including Jupiter's proprietary routing engines both Metis and Jupiter Z (RFQ), and third-party liquidity sources, for the best possible price. It also includes self-learning capabilities (to detect and sideline low-quality liquidity sources) which creates a competitive environment for all liquidity sources to continously optimize their performance and price. + +### Transaction Sending + +Over the years of experiment and development, we have optimized and continues to better our transaction sending service. Using various strategies involving multiple RPCs, priority fees/Jito tips estimation, and more, we are able to send transactions at a blazing fast speed with a high success rate (while still being [MEV-protected](#mev-protection)). + + + **INFO** + + 95% of all swaps are executed under 2 seconds via our proprietary transaction sending engine. + + For more information on latencies, [refer to the latency section](#latency). + + +### MEV Protection + +According to both our internal monitoring system and external resources such as [Sandwiched.me](https://sandwiched.me/sandwiches), Ultra has the lowest incidence of MEV attacks across all existing applications, by far. Comparing using the ratio of volume to the amount of value extracted, Ultra has the highest volume yet the lowest value extracted. + +### Real Time Slippage Estimator + +Building on top of our previous versions of slippage estimation/optimization engines, we have developed a new Real Time Slippage Estimator (RTSE), that is able to intelligently estimate the best possible slippage to use at the time of execution, balancing between trade success and price protection. RTSE uses a variety of heuristics, algorithms and monitoring to ensure the best user experience: + +* **Heuristics**: Token categories, historical and real-time slippage data, and more. +* **Algorithms**: Exponential Moving Average (EMA) on slippage data, and more. +* **Monitoring**: Real-time monitoring of failure rates to ensure reactiveness to increase slippage when necessary. + + + **RTSE VS DYNAMIC SLIPPAGE** + + | API | Ultra API | Swap API | + | :----------- | :-------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- | + | Types | Real Time Slippage Estimator (RTSE) | Dynamic Slippage | + | Description | Comprehensive data, heuristics and algorithms, and real-time reactiveness to increase slippage when necessary. | Only uses transaction simulations, though shares token categories heuristics. (Do note that we have discontinued development on Dynamic Slippage.) | + + +### Gasless + +Ultra provides different gasless mechanisms for different scenarios. + +* **Gasless via Jupiter Z (RFQ)**: All swaps routed via Jupiter Z are gasless, as the market maker is the fee payer for the transaction. +* **Gasless via Gasless Support**: Depending on the tokens and trade sizes of your swap, Ultra will automatically determine if it can provide gasless support to your swap by helping you pay for the transaction fee of your swap - you can identify this via the secondary signer in the transaction. + +### Latency + +95% of all swaps are executed under 2 seconds via our proprietary transaction sending engine. + +| Endpoint | Description | Latency (P90 Average) | +| :----------- | :----------------------------------------------------------------------------------------------------- | :----------------------- | +| `/order` | Aggregating across multiple liquidity sources and selecting the best price. | 500ms | +| `/execute` | Broadcasting the transaction to the network and polling for the status and result of the transaction. | Metis: 1.5sJupiterZ: 5s | +| `/balances` | Retrieving the user's balances. | 200ms | +| `/shield` | Enhanced token security feature to provide critical token information. | 400ms | + +## What About Swap API? + +Ultra API is the spiritual successor to Swap API, and is much simpler to use than Swap API. If you are first starting out on your Solana development journey, using Ultra API is highly recommended over Swap API. + +However, unlike Ultra API, Swap API allows developers to: + +* Add custom instructions. +* Add Cross Program Invocation (CPI) calls. +* Choose the broadcasting strategy for the signed transaction (ie. via priority fee, Jito, etc.). +* Choose which DEXes or AMMs to route through. +* Modify the number of accounts to use in a transaction. + +If you have a highly custom need like what is described above, then Swap API may be for you. However, with Swap API, there are many more things you need to worry about that Ultra API automatically handles for: + +* **Upkeep of RPCs**: To retrieve wallet balances, broadcast and retrieve transactions, etc. +* **Deciding transaction fee**: Including, but not limited to, priority fee, Jito fee, etc. +* **Deciding slippage**: The optimal slippage to use to balance between trade success and price protection. +* **Broadcasting the transaction**: Ultra uses a proprietary transaction sending engine which dramatically improves landing rate and speed. +* **Parsing the swap results**: Polling and parsing the resulting transaction from the RPC, including handling for success and error cases. + +If the above sounds like too much work, then Ultra API will be the better choice. + +## Getting Started with Ultra API + +1. [**Get Order**](/docs/ultra-api/get-order): Request for a swap transaction then sign it. +2. [**Execute Order**](/docs/ultra-api/execute-order): Execute the swap transaction and get the execution status. + +* [**Get Balances**](/docs/ultra-api/get-balances): Additionally, you can request for token balances of an account from `/ultra/v1/balances`. +* [**Get Shield**](/docs/ultra-api/get-shield): Enhanced security feature via Shield API to provide critical token information, to help provide an informed trading decision. + +**Other Guides** + +* [**Add Fees To Ultra**](/docs/ultra-api/add-fees-to-ultra): Add custom integrator fees to your Ultra transaction, on top of Jupiter's fees. + +## FAQ + + + + +* **Integrator without custom fees**: Do note that when your users swap using Ultra, we take 0.1% (or 0.05% depending on the tokens) of the swap amount as a fee. +* **Integrator with custom fees**: If you are an integrator, you can add custom integrator fees via Ultra API and Jupiter will take 20% of the integrator fees. Please refer to the [Add Fees To Ultra](/docs/ultra-api/add-fees-to-ultra) guide for more information. + + + +* Dynamic Rate Limits are now applied to Ultra API. + + * No Pro plans or payment needed. + * Simply generate the universal API Key via [Portal](https://portal.jup.ag) + * Rate limits scale together with your swap volume. + * [Read more about Ultra API Dynamic Rate Limit](/docs/api-rate-limit). + + diff --git a/mintlify-migration/docs/ultra-api/add-fees-to-ultra.mdx b/mintlify-migration/docs/ultra-api/add-fees-to-ultra.mdx new file mode 100644 index 00000000..01327c30 --- /dev/null +++ b/mintlify-migration/docs/ultra-api/add-fees-to-ultra.mdx @@ -0,0 +1,358 @@ +--- +title: "Add Fees To Ultra" +description: "In this guide, we will be walking through the steps to create the necessary accounts for adding fees to your Ultra transaction." +--- + +## Important Notes + +| Note | Description | +| :------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Referral Dashboard UI** | Use the [Referral Dashboard](https://referral.jup.ag/) to create referral accounts through a user-friendly interface. This is the recommended approach for most users before proceeding with the SDK setup below. | +| **Additional required accounts** | It is required to have a valid **referral account** and **referral token accounts** for the specific token mints. These accounts are initalized with the Referral Program under the ["Jupiter Ultra" Referral Project](https://solscan.io/account/DkiqsTrw1u1bYFumumC7sCG2S8K25qc2vemJFHyW2wJc). | +| **Fee mint** | In the `/order` response, you will see the `feeMint` field which is the token mint we will collect the fees in for that particular order. Since Jupiter will always dictate which token mint to collect the fees in, you must ensure that you have the valid referral token account created for the specific fee mint. If it is not initialized, the order will still return and can be executed without your fees. This is to ensure success rates and the best experience with Jupiter Ultra. | +| **Jupiter fees** | By default, Jupiter Ultra incurs a 0.05% or 0.1% fee based on token mint. When you add a referral fee, Jupiter will take a flat 20% of your integrator fees, for example, if you plan to take 100bps, Jupiter will take 20bps from it. | +| **Integrator fees** | You can configure `referralFee` to be between 50bps to 255bps. The `/order` response will show the total fee in `feeBps` field which should be exactly what you specified in `referralFee`. Do note that, the referral token account has to be created before calling `/order` because during the request, we will check if the token account is initialized before applying your referral fee (if it is not applied, we will only apply our default fees). | +| **Limitations** | * Currently, we do not support fees for Token2022 tokens.* Setting up the referral accounts and token accounts can only be done via the SDK (the scripts provided in this guide), and not via the Referral Dashboard. | + +## Step-by-step + + + + Install additional dependencies. + + +Create `referralTokenAccount` for each token mint. + + + Create `referralAccount`. + + + Create `referralTokenAccount` for each token mint. + + + Add `referralAccount` and `referralFee` to Ultra `/order` endpoint. + + + Sign and send the transaction via Ultra `/execute` endpoint. + + + Verify transaction and fees. + + + + +```js +import { ReferralProvider } from "@jup-ag/referral-sdk"; +import { Connection, Keypair, PublicKey, sendAndConfirmTransaction, sendAndConfirmRawTransaction } from "@solana/web3.js"; +import fs from 'fs'; + +const connection = new Connection("https://api.mainnet-beta.solana.com"); +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/to/.config/solana/id.json', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); + +const provider = new ReferralProvider(connection); +const projectPubKey = new PublicKey('DkiqsTrw1u1bYFumumC7sCG2S8K25qc2vemJFHyW2wJc'); + +async function initReferralAccount() { + const transaction = await provider.initializeReferralAccountWithName({ + payerPubKey: wallet.publicKey, + partnerPubKey: wallet.publicKey, + projectPubKey: projectPubKey, + name: "insert-name-here", + }); + + const referralAccount = await connection.getAccountInfo( + transaction.referralAccountPubKey, + ); + + if (!referralAccount) { + const signature = await sendAndConfirmTransaction(connection, transaction.tx, [wallet]); + console.log('signature:', `https://solscan.io/tx/${signature}`); + console.log('created referralAccountPubkey:', transaction.referralAccountPubKey.toBase58()); + } else { + console.log( + `referralAccount ${transaction.referralAccountPubKey.toBase58()} already exists`, + ); + } +} + +async function initReferralTokenAccount() { + const mint = new PublicKey("So11111111111111111111111111111111111111112"); // the token mint you want to collect fees in + + const transaction = await provider.initializeReferralTokenAccountV2({ + payerPubKey: wallet.publicKey, + referralAccountPubKey: new PublicKey("insert-referral-account-pubkey-here"), // you get this from the initReferralAccount function + mint, + }); + + const referralTokenAccount = await connection.getAccountInfo( + transaction.tokenAccount, + ); + + if (!referralTokenAccount) { + const signature = await sendAndConfirmTransaction(connection, transaction.tx, [wallet]); + console.log('signature:', `https://solscan.io/tx/${signature}`); + console.log('created referralTokenAccountPubKey:', transaction.tokenAccount.toBase58()); + console.log('mint:', mint.toBase58()); + } else { + console.log( + `referralTokenAccount ${transaction.tokenAccount.toBase58()} for mint ${mint.toBase58()} already exists`, + ); + } +} + +async function claimAllTokens() { + const transactions = await provider.claimAllV2({ + payerPubKey: wallet.publicKey, + referralAccountPubKey: new PublicKey("insert-referral-account-pubkey-here"), + }) + + // Send each claim transaction one by one. + for (const transaction of transactions) { + transaction.sign([wallet]); + + const signature = await sendAndConfirmRawTransaction(connection, transaction.serialize(), [wallet]); + console.log('signature:', `https://solscan.io/tx/${signature}`); + } +} + +// initReferralAccount(); // you should only run this once +// initReferralTokenAccount(); +// claimAllTokens(); + ``` + + +### Dependencies + +```bash +npm install @jup-ag/referral-sdk +npm install @solana/web3.js@1 # Using v1 of web3.js instead of v2 +npm install bs58 +npm install dotenv # if required for wallet setup +``` + + + **Set up RPC Connection** + + + **NOTE** + + Solana provides a [default RPC endpoint](https://solana.com/docs/core/clusters). However, as your application grows, we recommend you to always use your own or provision a 3rd party provider’s RPC endpoint such as [Helius](https://helius.dev/) or [Triton](https://triton.one/). + + +```js +import { Connection } from "@solana/web3.js"; + +const connection = new Connection('https://api.mainnet-beta.solana.com'); +``` + + **Set up Development Wallet** + + + + **NOTE** + + * You can paste in your private key for testing purposes but this is not recommended for production applications. + * If you want to store your private key in the project directly, you can do it via a `.env` file. + + + +To set up a development wallet via `.env` file, you can use the following script. + +```js +// index.js +import { Keypair } from '@solana/web3.js'; +import dotenv from 'dotenv'; +require('dotenv').config(); + +const wallet = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY || '')); + ``` + + ```bash + # .envPRIVATE_KEY="" + ``` + + To set up a development wallet via a wallet generated via [Solana CLI](https://solana.com/docs/intro/installation#solana-cli-basics), you can use the following script. + +```js +import { Keypair } from '@solana/web3.js'; +import fs from 'fs'; + +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/To/.config/solana/id.json', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); + ``` + + +### Create `referralAccount` + +* You should only need to create the referral account once. +* After this step, you need to [create the referral token accounts for each token mint](#create-referraltokenaccount). + +```js expandable +import { ReferralProvider } from "@jup-ag/referral-sdk"; +import { Connection, Keypair, PublicKey, sendAndConfirmTransaction } from "@solana/web3.js"; + +const connection = new Connection("https://api.mainnet-beta.solana.com"); +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/to/.config/solana/id.json', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); +const provider = new ReferralProvider(connection); +const projectPubKey = new PublicKey('DkiqsTrw1u1bYFumumC7sCG2S8K25qc2vemJFHyW2wJc'); // Jupiter Ultra Referral Project + +async function initReferralAccount() { + const transaction = await provider.initializeReferralAccountWithName({ + payerPubKey: wallet.publicKey, + partnerPubKey: wallet.publicKey, + projectPubKey: projectPubKey, + name: "insert-name-here", + }); + + const referralAccount = await connection.getAccountInfo( + transaction.referralAccountPubKey, + ); + + if (!referralAccount) { + const signature = await sendAndConfirmTransaction(connection, transaction.tx, [wallet]); + console.log('signature:', `https://solscan.io/tx/${signature}`); + console.log('created referralAccountPubkey:', transaction.referralAccountPubKey.toBase58()); + } else { + console.log( + `referralAccount ${transaction.referralAccountPubKey.toBase58()} already exists`, + ); + } +} +``` + +### Create `referralTokenAccount` + +* You need to [create the `referralAccount` first](#create-referralaccount). +* You need to create a `referralTokenAccount` for each token mint you want to collect fees in. +* We don't recommend creating a token account for **every** token mint, as it costs rent and most tokens might not be valuable, instead created token accounts for top mints to begin with (you can always add more later). + +```js expandable +import { ReferralProvider } from "@jup-ag/referral-sdk"; +import { Connection, Keypair, PublicKey, sendAndConfirmTransaction } from "@solana/web3.js"; + +const connection = new Connection("https://api.mainnet-beta.solana.com"); +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/to/.config/solana/id.json', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); +const provider = new ReferralProvider(connection); + +async function initReferralTokenAccount() { + const mint = new PublicKey("So11111111111111111111111111111111111111112"); // the token mint you want to collect fees in + + const transaction = await provider.initializeReferralTokenAccountV2({ + payerPubKey: wallet.publicKey, + referralAccountPubKey: new PublicKey("insert-referral-account-pubkey-here"), + mint, + }); + + const referralTokenAccount = await connection.getAccountInfo( + transaction.tokenAccount, + ); + + if (!referralTokenAccount) { + const signature = await sendAndConfirmTransaction(connection, transaction.tx, [wallet]); + console.log('signature:', `https://solscan.io/tx/${signature}`); + console.log('created referralTokenAccountPubKey:', transaction.tokenAccount.toBase58()); + console.log('mint:', mint.toBase58()); + } else { + console.log( + `referralTokenAccount ${transaction.tokenAccount.toBase58()} for mint ${mint.toBase58()} already exists`, + ); + } +} +``` + +### Usage in Ultra + +* After creating the necessary accounts, you can now add the `referralAccount` and `referralFee` to the Ultra `/order` endpoint. +* From the order response, you should see the `feeMint` field, which is the token mint we will collect the fees in for that particular order. +* From the order response, you should see the `feeBps` field, which is the total fee in bps, which should be exactly what you specified in `referralFee`. +* Then, you can sign and send the transaction via the Ultra `/execute` endpoint. + + + **DANGER** + + Do note that, during your request to `/order`, we will check if the specific fee mint's referral token account is initialized. If it is not, the order will still return and can be executed without your fees. This is to ensure success rates and the best experience with Jupiter Ultra. + + Hence, please verify the transaction when testing with a new referral token account, and always create the referral token account before calling `/order`. + + +```js expandable +import { Keypair, VersionedTransaction } from "@solana/web3.js"; +import fs from 'fs'; + +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/to/.config/solana/id.json', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); + +const orderResponse = await ( + await fetch( + 'https://lite-api.jup.ag/ultra/v1/order?' + + 'inputMint=So11111111111111111111111111111111111111112&' + + 'outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&' + + 'amount=100000000&' + + 'taker=jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3&' + + 'referralAccount=&' + // insert referral account public key here + 'referralFee=50' // insert referral fee in basis points (bps) + ) +).json(); + +console.log(JSON.stringify(orderResponse, null, 2)); + +const transactionBase64 = orderResponse.transaction // Extract the transaction from the order response +const transaction = VersionedTransaction.deserialize(Buffer.from(transactionBase64, 'base64')); // Deserialize the transaction +transaction.sign([wallet]); // Sign the transaction +const signedTransaction = Buffer.from(transaction.serialize()).toString('base64'); // Serialize the transaction to base64 format + +const executeResponse = await ( + await fetch('https://lite-api.jup.ag/ultra/v1/execute', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + signedTransaction: signedTransaction, + requestId: orderResponse.requestId, + }), + }) +).json(); + +if (executeResponse.status === "Success") { + console.log('Swap successful:', JSON.stringify(executeResponse, null, 2)); + console.log(`https://solscan.io/tx/${executeResponse.signature}`); +} else { + console.error('Swap failed:', JSON.stringify(executeResponse, null, 2)); + console.log(`https://solscan.io/tx/${executeResponse.signature}`); +} +``` + +## Claim All Fees + +* The `claimAllV2` method will return a list of transactions to claim all fees and are batched by 5 claims for each transaction. +* The code signs and sends the transactions one by one - you can also Jito Bundle to send multiple at once, if preferred. +* When claiming fees, the transaction will include the transfer of the fees to both your referral account and Jupiter's (20% of your integrator fees). + +```js expandable +import { ReferralProvider } from "@jup-ag/referral-sdk"; +import { Connection, Keypair, PublicKey, sendAndConfirmRawTransaction } from "@solana/web3.js"; + +const connection = new Connection("https://api.mainnet-beta.solana.com"); +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/to/.config/solana/id.json', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); +const provider = new ReferralProvider(connection); + +async function claimAllTokens() { + const transactions = await provider.claimAllV2({ + payerPubKey: wallet.publicKey, + referralAccountPubKey: new PublicKey("insert-referral-account-pubkey-here"), + }) + + // Send each claim transaction one by one. + for (const transaction of transactions) { + transaction.sign([wallet]); + + const signature = await sendAndConfirmRawTransaction(connection, transaction.serialize(), [wallet]); + console.log('signature:', `https://solscan.io/tx/${signature}`); + } +} +``` diff --git a/mintlify-migration/docs/ultra-api/execute-order.mdx b/mintlify-migration/docs/ultra-api/execute-order.mdx new file mode 100644 index 00000000..6a4739ad --- /dev/null +++ b/mintlify-migration/docs/ultra-api/execute-order.mdx @@ -0,0 +1,198 @@ +--- +title: "Execute Order" +--- + + + **NOTE** + + Lite URL: `https://lite-api.jup.ag/ultra/v1/execute` + + Dynamic URL: `https://api.jup.ag/ultra/v1/execute` + + Dynamic Rate Limits are now applied to Ultra API. + + * No Pro plans or payment needed. + * Simply generate the universal API Key via [Portal](https://portal.jup.ag) + * Rate limits scale together with your swap volume. + + + + + + + + **API REFERENCE** + + To fully utilize the Ultra API, check out the [Ultra API Reference](/api/ultra-api/execute). + + +## Sign Transaction + +Using the Solana `web3.js` **v1** library, you can sign the transaction as follows: + + +```bash +npm install @solana/web3.js@1 # Using v1 of web3.js instead of v2 +npm install bs58 +npm install dotenv # if required for wallet setup +``` + + + **NOTE** + + * You can paste in your private key for testing purposes but this is not recommended for production applications. + * If you want to store your private key in the project directly, you can do it via a `.env` file. + + + To set up a development wallet via `.env` file, you can use the following script. + +```js +// index.js +import { Keypair } from '@solana/web3.js'; +import dotenv from 'dotenv'; +require('dotenv').config(); + +const wallet = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY || '')); +``` + +```bash +# .env +PRIVATE_KEY="" +``` + + To set up a development wallet via a wallet generated via [Solana CLI](https://solana.com/docs/intro/installation#solana-cli-basics), you can use the following script. + +```js +import { Keypair } from '@solana/web3.js'; +import fs from 'fs'; + +const privateKeyArray = JSON.parse(fs.readFileSync('/Path/To/.config/solana/id.json', 'utf8').trim()); +const wallet = Keypair.fromSecretKey(new Uint8Array(privateKeyArray)); +``` + + +```js +// ... GET /order's response + +// Extract the transaction from the order response +const transactionBase64 = orderResponse.transaction + +// Deserialize the transaction +const transaction = VersionedTransaction.deserialize(Buffer.from(transactionBase64, 'base64')); + +// Sign the transaction +transaction.sign([wallet]); + +// Serialize the transaction to base64 format +const signedTransaction = Buffer.from(transaction.serialize()).toString('base64'); +``` + +## Execute Order + +By making a post request to the `/execute` endpoint, Jupiter executes the swap transaction on behalf of you/your users. This includes handling of slippage, priority fees, transaction landing and more. + +To make a post request to execute a swap order, you need to pass in the required parameters: + +* `signedTransaction`: The signed transaction +* `requestId`: The order response's request ID + + + **`/execute` PARAMETERS** + + Both required parameters are found in the [order response](/docs/ultra-api/get-order#order-response), do note that the `transaction` field is the base64 encoded transaction that [you need to sign](#sign-transaction) before submitting to the network. + + +```js +const executeResponse = await ( + await fetch('https://lite-api.jup.ag/ultra/v1/execute', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + signedTransaction: signedTransaction, + requestId: orderResponse.requestId, + }), + }) +).json(); +``` + +## Execute Response + +After making the post request to the `/execute` endpoint, you will receive a response with the status of the swap. + +```js +if (executeResponse.status === "Success") { + console.log('Swap successful:', JSON.stringify(executeResponse, null, 2)); + console.log(`https://solscan.io/tx/${executeResponse.signature}`); +} else { + console.error('Swap failed:', JSON.stringify(executeResponse, null, 2)); + console.log(`https://solscan.io/tx/${executeResponse.signature}`); +} +``` + +**Example response of successful swap:** + +```json +{ + "status": "Success", + "signature": "transaction signature", + "slot": "323598314", + "code": 0, + "inputAmountResult": "9995000", + "outputAmountResult": "1274698", + "swapEvents": [ + { + "inputMint": "So11111111111111111111111111111111111111112", + "inputAmount": "9995000", + "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "outputAmount": "1274698" + } + ] +} +``` + +**Example response of failed swap:** + +```json +{ + "status": "Failed", + "signature": "transaction signature", + "error": "custom program error: #6023", + "code": 4615026, + "slot": "323597963" +} +``` + +## Response Codes + +The following is a list of error codes that can be returned by the `/execute` endpoint. + +### Ultra Endpoint Codes + +| Code | Description | Debugging | +| :---- | :-------------------------- | :---------------------------------------------------------------------------------------------------------- | +| 0 | Success | - | +| -1 | Missing cached order | `requestId` not found in cache, likely expired or not found | +| -2 | Invalid signed transaction | `signedTransaction` is invalid, likely failed to sign the transaction correctly | +| -3 | Invalid message bytes | `signedTransaction` is invalid, likely due to incorrect usage of `transaction` field in the order response | + +### Aggregator Swap Type Codes + +| Code | Description | Debugging | +| :---- | :--------------------------- | :---------------------------------------- | +| -1000 | Failed to land | Transaction failed to land on the network | +| -1001 | Unknown error | - | +| -1002 | Invalid transaction | - | +| -1003 | Transaction not fully signed | - | +| -1004 | Invalid block height | - | + +### RFQ Swap Type Codes + +| Code | Description | Debugging | +| :---- | :--------------- | :-------------------------------------------------------------------- | +| -2000 | Failed to land | - | +| -2001 | Unknown error | - | +| -2002 | Invalid payload | - | +| -2003 | Quote expired | User did not respond in time or RFQ provider did not execute in time | +| -2004 | Swap rejected | User or RFQ provider rejected the swap | diff --git a/mintlify-migration/docs/ultra-api/get-balances.mdx b/mintlify-migration/docs/ultra-api/get-balances.mdx new file mode 100644 index 00000000..9013bb67 --- /dev/null +++ b/mintlify-migration/docs/ultra-api/get-balances.mdx @@ -0,0 +1,64 @@ +--- +title: "Get Balances" +--- + + + **NOTE** + + - Lite URL: `https://lite-api.jup.ag/ultra/v1/balances` + + - Dynamic URL: `https://api.jup.ag/ultra/v1/balances` + + Dynamic Rate Limits are now applied to Ultra API. + + * No Pro plans or payment needed. + * Simply generate the universal API Key via [Portal](https://portal.jup.ag) + * Rate limits scale together with your swap volume. + + + + + + + + **API REFERENCE** + + To fully utilize the Ultra API, check out the [Ultra API Reference](/api/ultra-api/balances). + + +## Get Balances + +The Ultra API supports a simple endpoint to get the token balances of an account, you just need to pass in the required parameter of the user's wallet address. + +```js +const balancesResponse = await ( + await fetch(`https://lite-api.jup.ag/ultra/v1/balances/3X2LFoTQecbpqCR7G5tL1kczqBKurjKPHhKSZrJ4wgWc`) +).json(); + +console.log(JSON.stringify(balancesResponse, null, 2)); +``` + +## Balances Response + +The balances response will return a list of token balances for the user's wallet address. + +**Successful example response:** + +```json +{ + "SOL": { + "amount": "0", + "uiAmount": 0, + "slot": 324307186, + "isFrozen": false + } +} +``` + +**Failed example response:** + +```json +{ + "error": "Invalid address" +} +``` diff --git a/mintlify-migration/docs/ultra-api/get-order.mdx b/mintlify-migration/docs/ultra-api/get-order.mdx new file mode 100644 index 00000000..211407fa --- /dev/null +++ b/mintlify-migration/docs/ultra-api/get-order.mdx @@ -0,0 +1,213 @@ +--- +title: "Get Order" +--- + + + **NOTE** + + - Lite URL: `https://lite-api.jup.ag/ultra/v1/order` + + - Dynamic URL: `https://api.jup.ag/ultra/v1/order` + + Dynamic Rate Limits are now applied to Ultra API. + + * No Pro plans or payment needed. + * Simply generate the universal API Key via [Portal](https://portal.jup.ag) + * Rate limits scale together with your swap volume. + + + + + + + + **API REFERENCE** + + To fully utilize the Ultra API, check out the [Ultra API Reference](/api/ultra-api/order). + + +## Get Order + +To get a swap order, you need to pass in the required parameters such as: + +* `inputMint`: The input token mint address +* `outputMint`: The output token mint address +* `amount`: The amount of input token to swap +* `taker`: The user's wallet address + * Note: If the `taker` is not provided, there will still be an Order Response with no `transaction` field. +* `referralAccount`: The referral account address - refer to the [Add Fees To Ultra](/docs/ultra-api/add-fees-to-ultra) guide for the step by step process. +* `referralFee`: The referral fee in basis points (bps) + +```js +const orderResponse = await ( + await fetch( + 'https://lite-api.jup.ag/ultra/v1/order?inputMint=So11111111111111111111111111111111111111112&outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000000&taker=jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3' + ) + ).json(); + +console.log(JSON.stringify(orderResponse, null, 2)); +``` + +## Order Response + +In the order response, you will receive a number of fields that are important to note of, such as the `swapType`, `slippageBps`, etc. + +The main fields you should need: + +* `transaction`: The base64 encoded transaction that you need to sign before submitting to the network. +* `requestId`: The request ID of the order to be used in the `Execute Order` endpoint. + +Now, you are able to get a swap order, next steps is to make a post request to the `Execute Order` endpoint. [Let's go](/docs/ultra-api/execute-order)! + +**Example response of Aggregator Swap:** + +```json expandable +{ + "mode": "ultra", + "swapType": "aggregator", + "router": "metis", + "requestId": "5421e18f-9d12-4709-8f5a-6c79c1032203", + "inAmount": "1000000", + "outAmount": "6652914", + "otherAmountThreshold": "6644643", + "swapMode": "ExactIn", + "slippageBps": 15, + "priceImpactPct": "0", + "routePlan": [ + { + "swapInfo": { + "ammKey": "4bg8UDLXEm4T6pCyoW7iUizAz9HMoxhTAtMquSXigFZu", + "label": "Meteora DLMM", + "inputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "outputMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", + "inAmount": "90000", + "outAmount": "89991", + "feeAmount": "9", + "feeMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" + }, + "percent": 9, + "bps": 900 + }, + { + "swapInfo": { + "ammKey": "5M7McNWX7yBBGrZGB6XhmHYhFwWwwB2ckrA1HEpkf3SA", + "label": "Perena", + "inputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "outputMint": "2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH", + "inAmount": "50000", + "outAmount": "50007", + "feeAmount": "5", + "feeMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" + }, + "percent": 5, + "bps": 500 + }, + { + "swapInfo": { + "ammKey": "6dB49iS94RnwUhQwJwjnE7mEqPedZDtU7XBZXaLBbfbt", + "label": "Stabble Stable Swap", + "inputMint": "2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH", + "outputMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", + "inAmount": "50007", + "outAmount": "49995", + "feeAmount": "0", + "feeMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB" + }, + "percent": 100, + "bps": 10000 + }, + { + "swapInfo": { + "ammKey": "BWBHrYqfcjAh5dSiRwzPnY4656cApXVXmkeDmAfwBKQG", + "label": "Obric V2", + "inputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "outputMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", + "inAmount": "860000", + "outAmount": "859910", + "feeAmount": "6", + "feeMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB" + }, + "percent": 86, + "bps": 8600 + }, + { + "swapInfo": { + "ammKey": "D94tFiBfJzdZmcH6GtV39iXexWyVpNfwEH3CxEbqvsvr", + "label": "Obric V2", + "inputMint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", + "outputMint": "So11111111111111111111111111111111111111112", + "inAmount": "999896", + "outAmount": "6654624", + "feeAmount": "343", + "feeMint": "So11111111111111111111111111111111111111112" + }, + "percent": 100, + "bps": 10000 + } + ], + "inputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "outputMint": "So11111111111111111111111111111111111111112", + "feeMint": "So11111111111111111111111111111111111111112", + "feeBps": 2, + "taker": "5dMXLJ8GYQxcHe2fjpttVkEpRrxcajRXZqJHCiCbWS4H", + "gasless": false, + "transaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAFCkS+3LuGTbsYdcCPVuxlVEcq9wNOnR9+PBw6SEM3ACeKd1R4MYi595YUO8ViNwpWb17+Q9DxkVcz5fWpSqjtDyi/by2TOVyTUuu9HYAIH+8AvsAiyyBVh4I4Fsd9iyTJyeC0vJINbsjyglaB0IKJCaka7Xs7bD5H1KusZLVDh/7A+PTko52VL0CIM2xtl0WkvNslD6Wawxr7yd9HYllN4LxSYdFKrMW8DuxjXahwWh9wo57jWprPC/jyLMbOSQGdegMGRm/lIRcy/+ytunLDm+e8jOW7xfcSayxDmzpAAAAA50rZbONln9MTUQAoS/d4BFuFEKjzTkmMki7ub8MF+GkEedVb8jHAbu50xW7OaBUH/bGy3qP0jlECsc2iVrwTjwbd9uHXZaGT2cvhRs7reawctIXtX1s3kTqM9YV+/wCpPSwt5ThewuTEP350DNuqyKwGVEa4lpMRw26ckG/cO10EBgAFApE/CQAGAAkDSbc4AAAAAAAIVwkkAAEOEAIPJg0IIwguGi4bHg4EDzEcLiQJCS0uHRkIMyAPHw4DISIyJAknKyQfMQMEFBMREikqKCwJJy8LBwUMCg4EFhYWJAkvFQcFGBcQBBYWMCQJJTjBIJszQdacgQAFAAAAJgkABEcAAQUAAk9kAgQ6AVYABDoAZAQFQEIPAAAAAABthWUAAAAAAA8AAgkDAgAAAQkGFvHsWcITjSSy666/XikzqLiO11a0SwY8rT5d3C+q84sDvr+7ACm/lQcqT78E33F1k+c4vMwhJygVwkcagNn59VWw1IQlBBopKBgFAAMBFxV9wMcXAhzLZucTPtF6MmZ80NPWq9GD13dumGAXjalsagR49HT7BfFveXXzwVdRxcH4wwx5hrqgGgkua/Gonv4pzAZz/LU35B3ySlkEeHl2dwQsLXV6xTf8OXe5zg55RN15dUirCc2NlTbGZ63YLmpuzcw8rqYGaGqFaW1mAWfiYdGuN3McD0TMhBYpTLog607/NBju6DG/v6eBEjRZCQSVk5fMApSW", + "prioritizationFeeLamports": 2252824, + "inUsdValue": 0.999901896351375, + "outUsdValue": 1.0004190022848067, + "priceImpact": 0.05171566683877625, + "swapUsdValue": 0.999901896351375, + "totalTime": 735 +} +``` + +**Example response of RFQ Swap:** + +```json expandable +{ + "mode": "ultra", + "inputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "outputMint": "So11111111111111111111111111111111111111112", + "inAmount": "1000000", + "outAmount": "6643102", + "otherAmountThreshold": "6643102", + "swapMode": "ExactIn", + "slippageBps": 0, + "priceImpactPct": "0", + "routePlan": [ + { + "swapInfo": { + "ammKey": "CifhTfrKeMfSpTRLjJnXLXEALS37dKH3ziC8gjTLe5dD", + "label": "JupiterZ", + "inputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + "outputMint": "So11111111111111111111111111111111111111112", + "inAmount": "1000000", + "outAmount": "6643102", + "feeAmount": "0", + "feeMint": "11111111111111111111111111111111" + }, + "percent": 100 + } + ], + "feeBps": 2, + "transaction": "AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAIABgyuHR/2vkxfzU7FGy7oIwST/eu3qKGcgDNLQXNZqjhf/ES+3LuGTbsYdcCPVuxlVEcq9wNOnR9+PBw6SEM3ACeKLG4Kt0ZV/x7L9RaG1rdUmMMOr+NV9iN2t63tTwAhJqt3VHgxiLn3lhQ7xWI3ClZvXv5D0PGRVzPl9alKqO0PKK8uUfxZ6umAKD8aFHv43B/XRa4GxCNft1fWnLOBGKhCvT1zZhVaaLZKp6kLnLekwgoP5noPGw80QSK/+q5KDAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMGRm/lIRcy/+ytunLDm+e8jOW7xfcSayxDmzpAAAAABpuIV/6rgYT7aH9jRhjANdrEOdwa6ztVmKDwAAAAAAEG3fbh12Whk9nL4UbO63msHLSF7V9bN5E6jPWFfv8AqUpYSftyo7vpH9xbDmpX9jxaHLRbIGem7Qys02OVyKECxvp6877brTo9ZfNqq8l0MbG75MLS9uDkfKYCA0UvXWFUzz6zfmKnWYJxn4RVu8Gf4g/6x2CmlkWSbSUO82C+2wMHAAkDiQQAAAAAAAAHAAUCMa0AAAoMAQADAgoECwkICQYFI6hgt6NcCiigQEIPAAAAAACeXWUAAAAAAELqbGgAAAAAAgAAAA==", + "gasless": true, + "prioritizationFeeLamports": 0, + "requestId": "9e39b39a-4e6d-2c03-3a4e-df0564d98531", + "swapType": "rfq", + "router": "jupiterz", + "quoteId": "b8f818b8-4651-5d3b-ba57-1f921c6b0f62", + "maker": "CifhTfrKeMfSpTRLjJnXLXEALS37dKH3ziC8gjTLe5dD", + "taker": "jdocuPgEAjMfihABsPgKEvYtsmMzjUHeq9LX4Hvs7f3", + "expireAt": "1751968322", + "platformFee": { + "amount": "1328", + "feeBps": 2 + }, + "inUsdValue": 0.999901896351375, + "outUsdValue": 0.9993827964401991, + "priceImpact": -0.05191508417676995, + "swapUsdValue": 0.999901896351375, + "totalTime": 721 +} +``` diff --git a/mintlify-migration/docs/ultra-api/get-shield.mdx b/mintlify-migration/docs/ultra-api/get-shield.mdx new file mode 100644 index 00000000..8040ed93 --- /dev/null +++ b/mintlify-migration/docs/ultra-api/get-shield.mdx @@ -0,0 +1,86 @@ +--- +title: "Get Shield" +--- + + + **NOTE** + + - Lite URL: `https://lite-api.jup.ag/ultra/v1/shield` + + - Dynamic URL: `https://api.jup.ag/ultra/v1/shield` + + Dynamic Rate Limits are now applied to Ultra API. + + * No Pro plans or payment needed. + * Simply generate the universal API Key via [Portal](https://portal.jup.ag) + * Rate limits scale together with your swap volume. + + + + + + + + **API REFERENCE** + + To fully utilize the Ultra API, check out the [Ultra API Reference](/api/ultra-api/shield). + + +## Get Shield + +The Ultra API provides an endpoint to retrieve token information and associated warnings for the specified mint addresses. To use this endpoint, provide one or more mint addresses for the required query parameter named mints. + +This is useful when integrating with Jupiter Ultra or any other APIs, allowing you or your user to be informed of any potential malicious mints before conducting your transaction. + +```js +const shieldResponse = await ( + await fetch(`https://lite-api.jup.ag/ultra/v1/shield?mints=So11111111111111111111111111111111111111112,EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v,someTokenAddressForEducationalPurposes`) +).json(); +``` + +## Shield Response + +The shield response will return a list of objects, containing the token information and warnings of the mints passed in. + +Do note that this is subject to changes, and we will be adding more warnings and improving the accuracy of the warnings over time. + +For the full list of potential warnings, refer to the [Shield API Reference](/api/ultra-api/shield). + +**Successful example response:** + +```json expandable +{ + "warnings": { + "someTokenAddressForEducationalPurposes": [ + { + "type": "NOT_VERIFIED", + "message": "This token is not verified, make sure the mint address is correct before trading", + "severity": "info" + }, + { + "type": "LOW_ORGANIC_ACTIVITY", + "message": "This token has low organic activity", + "severity": "info" + }, + { + "type": "NEW_LISTING", + "message": "This token is newly listed", + "severity": "info" + } + ], + "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v": [ + { + "type": "HAS_FREEZE_AUTHORITY", + "message": "The authority's owner has the ability to freeze your token account, preventing you from further trading", + "severity": "warning" + }, + { + "type": "HAS_MINT_AUTHORITY", + "message": "The authority's owner has the ability to mint more tokens", + "severity": "info" + } + ], + "So11111111111111111111111111111111111111112": [] + } +} +``` diff --git a/mintlify-migration/docs/ultra-api/plugin-integration.mdx b/mintlify-migration/docs/ultra-api/plugin-integration.mdx new file mode 100644 index 00000000..c8f072bc --- /dev/null +++ b/mintlify-migration/docs/ultra-api/plugin-integration.mdx @@ -0,0 +1,86 @@ +--- +title: "Integrate Jupiter Plugin" +description: "Jupiter Plugin is an open-source, lightweight, plug-and-play version of Jupiter that allows you to seamlessly integrate end-to-end swap functionality into your application with minimal effort - with just a few lines of code, you can embed a fully functional swap interface directly into your website while providing the same powerful Ultra Mode swap experience found on [https://jup.ag](https://jup.ag/)." +--- + + + + Plugin Playground { + e.target.style.opacity = '1'; + e.target.style.border = '2px solid #C8F284'; + }} + onMouseLeave={(e) => { + e.target.style.opacity = '1'; + e.target.style.border = '2px solid transparent'; + }} + /> + + + + +**PLUGIN PLAYGROUND** + +Try out the [Plugin Playground](https://plugin.jup.ag/) to experience the full swap features and see the different customization options with code snippets. + +To view the open-source code, visit the [GitHub repository](https://github.com/jup-ag/plugin). + + + +**QUICK START** + +To quick start your integration, check out the [Next.js](/docs/tool-kits/plugin/nextjs-app-example), [React](/docs/tool-kits/plugin/react-app-example) or [HTML](/docs/tool-kits/plugin/html-app-example) app examples. + +Refer to [Customization](/docs/tool-kits/plugin/customization) and [FAQ](/docs/tool-kits/plugin/faq) for more information. + + +## Key Features + +- **Seamless Integration**: Embed Jupiter's swap functionality directly into your application without redirects. +- **Multiple Display Options**: Choose between integrated, widget, or modal display modes. +- **Customizable Options**: Configure the swap form to match your application's needs. +- **RPC-less**: Integrate Plugin without any RPCs, Ultra handles transaction sending, wallet balances and token information. +- **Ultra Mode**: Access to all features of Ultra Mode, read more about it in the [Ultra API docs](/docs/ultra-api/). + +## Getting Started + +When integrating Plugin, there are a few integration methods to think about, and choose the one that best fits your application's architecture and requirements. + +### Integration Methods + +- **Using Window Object** - Simplest way to add and initialize Plugin. +- [**Using NPM Package**](https://www.npmjs.com/package/@jup-ag/plugin) - Install via `npm install @jup-ag/plugin` and initialize as a module (will require you to maintain its dependencies). + +### Wallet Integration + +- **Wallet Standard Support**: For applications without existing wallet provider, Plugin will provide a wallet adapter and connection - powered by [Unified Wallet Kit](/docs/tool-kits/wallet-kit/). +- **Passthrough Wallet**: For applications with existing wallet provider(s), set `enableWalletPassthrough=true` with context, and Plugin will allow the application to pass through the existing wallet provider's connection to Plugin. + +### Adding Fees to plugin + +- **Referral Account**: You can create a referral account via [scripts](/docs/ultra-api/add-fees-to-ultra) or [Referral Dashboard](https://referral.jup.ag/). +- **Referral Fee**: You can set the referral fee and account in the `formProps` interface when you initialize the Plugin. + +### Quick Start Guides + +In the next sections, we'll walk you through the steps to integrate Jupiter Plugin into different types of web applications from scratch. + + + + + + + + + + +By integrating Jupiter Plugin into your application, you can seamlessly integrate a fully functional swap interface into your application with minimal effort, while staying at the forefront of Solana DeFi innovation. diff --git a/mintlify-migration/docs/ultra-api/search-token.mdx b/mintlify-migration/docs/ultra-api/search-token.mdx new file mode 100644 index 00000000..dedbda5c --- /dev/null +++ b/mintlify-migration/docs/ultra-api/search-token.mdx @@ -0,0 +1,166 @@ +--- +title: "Search Token" +--- + + + **NOTE** + + - Lite URL: `https://lite-api.jup.ag/ultra/v1/search` + + - Dynamic URL: `https://api.jup.ag/ultra/v1/search` + + Dynamic Rate Limits are now applied to Ultra API. + + * No Pro plans or payment needed. + * Simply generate the universal API Key via [Portal](https://portal.jup.ag) + * Rate limits scale together with your swap volume. + + + + + + + + **API REFERENCE** + + To fully utilize the Ultra API, check out the [Ultra API Reference](/api/ultra-api/search). + + +## Search Token + +The Ultra API provides an endpoint to search tokens in the background for you and returns you the search results, along with the mint information. + +This is useful in most user applications, as users need to choose which tokens they want to swap. This also provides a seamless developer experience as integrating this allows us to handle and abstract the token search mechanism, allowing you to focus on other user features. + + + **SEARCH** + + * Search for a token and its information by its **symbol, name or mint address**. + * Comma-separate to search for multiple. + * Limit to 100 mint addresses in query. + * Default to 20 mints in response when searching via symbol or name. + + +```js +const searchResponse = await ( + await fetch(`https://lite-api.jup.ag/ultra/v1/search?query=So11111111111111111111111111111111111111112`) +).json(); +``` + +## Search Response + +The search response will return an array of mints, along with their information. + + + **USEFUL MINT INFORMATION** + + * Token Metadata like name, symbol, icon to display token information to users + * [Organic Score](/docs/token-api/organic-score), Holder count, Market cap, etc can be useful to help make a better trading decision + * And much more! + + Do note that the response is subject to changes as we continue to improve. + + Refer to [Ultra API Reference](/api/ultra-api/search) for full schema. + + +**Successful example response:** + +```js expandable +[ + { + id: 'So11111111111111111111111111111111111111112', + name: 'Wrapped SOL', + symbol: 'SOL', + icon: 'https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png', + decimals: 9, + circSupply: 531207433.3986673, + totalSupply: 603724547.3627878, + tokenProgram: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', + firstPool: { + id: '58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2', + createdAt: '2021-03-29T10:05:48Z' + }, + holderCount: 2342610, + audit: { + mintAuthorityDisabled: true, + freezeAuthorityDisabled: true, + topHoldersPercentage: 1.2422471238911812 + }, + organicScore: 98.92390784896082, + organicScoreLabel: 'high', + isVerified: true, + cexes: [ + 'Binance', 'Bybit', + 'OKX', 'Upbit', + 'Bitget', 'Kraken', + 'KuCoin', 'MEXC', + 'Gate.io' + ], + tags: [ 'community', 'strict', 'verified' ], + fdv: 87824499429.22047, + mcap: 77275352037.79674, + usdPrice: 145.47114211747515, + priceBlockId: 349038717, + liquidity: 89970631.83880953, + stats5m: { + priceChange: 0.021175445311831707, + liquidityChange: -0.01230267453174984, + volumeChange: 4.855149318222242, + buyVolume: 14644327.188370818, + sellVolume: 14743625.023908526, + buyOrganicVolume: 269570.2345543641, + sellOrganicVolume: 204114.37436445671, + numBuys: 49281, + numSells: 54483, + numTraders: 18155, + numOrganicBuyers: 981, + numNetBuyers: 3503 + }, + stats1h: { + priceChange: -0.145099593531635, + liquidityChange: -0.13450589635262783, + volumeChange: -15.928930753985316, + buyVolume: 171520842.22567528, + sellVolume: 174057197.5207193, + buyOrganicVolume: 3099405.8562825476, + sellOrganicVolume: 2975660.0383528043, + numBuys: 586069, + numSells: 649275, + numTraders: 78145, + numOrganicBuyers: 2716, + numNetBuyers: 14442 + }, + stats6h: { + priceChange: 0.3790495974473589, + liquidityChange: 0.1659230330014905, + volumeChange: 14.571340846647542, + buyVolume: 1084625651.9256022, + sellVolume: 1094488293.656417, + buyOrganicVolume: 31145072.655369382, + sellOrganicVolume: 31647431.25353508, + numBuys: 3789847, + numSells: 4363909, + numTraders: 272131, + numOrganicBuyers: 10849, + numNetBuyers: 37155 + }, + stats24h: { + priceChange: 1.5076363979360274, + liquidityChange: 2.417364079880319, + volumeChange: -2.1516094834673254, + buyVolume: 4273248565.256824, + sellVolume: 4306065610.69747, + buyOrganicVolume: 109007133.8196669, + sellOrganicVolume: 118085567.17983335, + numBuys: 15125444, + numSells: 17582713, + numTraders: 754618, + numOrganicBuyers: 28590, + numNetBuyers: 80961 + }, + ctLikes: 4232, + smartCtLikes: 522, + updatedAt: '2025-06-25T05:02:21.034234634Z' + } +] +``` diff --git a/mintlify-migration/favicon.png b/mintlify-migration/favicon.png new file mode 100644 index 00000000..1d90abf0 Binary files /dev/null and b/mintlify-migration/favicon.png differ diff --git a/mintlify-migration/index.mdx b/mintlify-migration/index.mdx new file mode 100644 index 00000000..7d28ce85 --- /dev/null +++ b/mintlify-migration/index.mdx @@ -0,0 +1,429 @@ +--- +mode: "custom" +title: "Jupiter Developer Docs" +--- + +
+
+ +
+ +
+
+ Jupiter Developer Docs +
+ +

+ How can we help you today? +

+
+ +
+
+
+ +
+ + + + +Develop with the most comprehensive set of APIs offering a full range of Jupiter Products like [Ultra](/docs/ultra-api/), [Swap](/docs/swap-api/), [Trigger](/docs/trigger-api/), [Recurring](/docs/recurring-api/), [Lend](/docs/lend-api/), and more. + + + + + + + + For those looking for low-code solutions, we provide a customizable tools like Jupiter Plugin for you to develop faster and smoother. + + + + If you are a decentralized exchange or market maker and have an interest to be part of our routing engines, refer to the routing integration guides. + + + + + + + Explore our ecosystem of projects and protocols that are part of our routing engine, or utilize Jupiter's developer tools to build their applications. + + + + +
+

+ Browse by API + +

+

+ Most comprehensive set of endpoints to integrate Jupiter Products into your + applications +

+
+ + + + + + Docs + + + Schemas + + + + + Docs + + + Schemas + + + + + + Docs + + + Schemas + + + + + + Docs + + + Schemas + + + + + + Docs + + + Schemas + + + + + + Docs + + + Schemas + + + + + + Docs + + + Schemas + + + + + + Docs + + + Schemas + + + + + + Docs + + + Schemas + + + + + +
+

+ Browse by Tool Kits +

+

+ Ready-to-use components and libraries to accelerate your development +

+
+ + + + Playground + Docs + + + + + NPM + + + Docs + + + + + + Playground + + + Docs + + + + + + NPM + + + Example + + + + + +
+

+ Developed by DevRel Working Group +

+

+ Community-driven resources and examples to help you build with Jupiter +

+
+ + + + Typescript + Python + + + + + Playground + + + GitHub + + + + + +
+

+ We'd love to hear from you! +

+

+ Join our community and share your feedback to help us improve +

+
+ + + + +Join our Discord Community + + +Share your suggestions on GitHub + + + +
diff --git a/mintlify-migration/logo/dark.svg b/mintlify-migration/logo/dark.svg new file mode 100644 index 00000000..8b343cd6 --- /dev/null +++ b/mintlify-migration/logo/dark.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/mintlify-migration/logo/light.svg b/mintlify-migration/logo/light.svg new file mode 100644 index 00000000..03e62bf1 --- /dev/null +++ b/mintlify-migration/logo/light.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/mintlify-migration/logo/logo.png b/mintlify-migration/logo/logo.png new file mode 100644 index 00000000..a404c4a7 Binary files /dev/null and b/mintlify-migration/logo/logo.png differ diff --git a/mintlify-migration/misc.mdx b/mintlify-migration/misc.mdx new file mode 100644 index 00000000..5b2158f7 --- /dev/null +++ b/mintlify-migration/misc.mdx @@ -0,0 +1,54 @@ +--- +title: "Legal & Guidelines" +sidebarTitle: "Overview" +--- + + + + IMPORTANT//portal.jup.ag (collectively the "Service"). The Service + includes a... + + + Jupiter, https://jup.ag, a website-hosted user interface (the "Interface") made... + + + + Jupiter, accessible at//jup.ag, one of its main priorities is the privacy of partici... + + + + Guidelines for integrations with Jupiter. + + + + Audits for Jupiter protocols. + + + + + diff --git a/mintlify-migration/misc/audits.mdx b/mintlify-migration/misc/audits.mdx new file mode 100644 index 00000000..b308feba --- /dev/null +++ b/mintlify-migration/misc/audits.mdx @@ -0,0 +1,31 @@ +--- +title: "Audits" +description: "Audits of Jupiter protocols." +--- + +Jupiter protocols are audited by reputable security firms to ensure the highest level of security and reliability. The following section provides the audits of Jupiter's protocols. + +## Jupiter Swap + +- [Offside Labs](/static/files/audits/swap-v6-offside.pdf) (v6) +- [Sec3](/static/files/audits/swap-v3-sec3.pdf) (v3) + +## Jupiter Limit Order + +- [Offside Labs](/static/files/audits/limit-v2-offside.pdf) (v2) + +## Jupiter DAO + +- [Offside Labs](/static/files/audits/dao-offside.pdf) + +## Jupiter Perpetuals + +- [Offside Labs](/static/files/audits/perpetual-offside.pdf) +- [OtterSec](/static/files/audits/perpetual-ottersec.pdf) +- [Sec3](/static/files/audits/perpetual-sec3.pdf) + +## Jupiter Lend + +- [Zenith Report: June 24th, 2025 - July 31, 2025](/static/files/audits/lend-zenith.pdf) +- [Offside Labs Liquidity report: July 10th, 2025 - July 18, 2025](/static/files/audits/lend-liquidity-offside.pdf) +- [Offside Labs Vaults report: July 23rd, 2025 - August 4th, 2025](/static/files/audits/lend-vault-offside.pdf) \ No newline at end of file diff --git a/mintlify-migration/misc/integrator-guidelines.mdx b/mintlify-migration/misc/integrator-guidelines.mdx new file mode 100644 index 00000000..e163b427 --- /dev/null +++ b/mintlify-migration/misc/integrator-guidelines.mdx @@ -0,0 +1,52 @@ +--- +title: "Integrator Guidelines" +description: "Jupiter provides developer tools and resources to help you integrate with Jupiter. The following section provides the guidelines when integrating with Jupiter." +--- + +## Branding and Marketing + +When integrating with Jupiter, you can use the following assets to help you brand and market your product: [Jupiter Brand Assets](https://github.com/jup-ag/docs/tree/main/static/files). + + + **LABELLING ROUTING PROVIDER** + +Do note that, if you are using our routing engine (such as getting quotes from the Swap API), you are to label the routing provider as **"Jupiter Metis v1"**, and not "Jupiter". + + + +## Developer Support + +There are currently 2 ways to get technical support: + + + +Public Developer Support Channel in Discord + + + Portal Enquiry + + + + +**WARNING** + + Please use the Discord channel for your technical questions, as it is a public channel, more people can help you and it promotes discovery/discussion. + +If you open a ticket via the link that **does not relate** to Portal Enquiries, we will redirect you to the Discord channel. + + + +## Customer Support + +The Jupiter UI contains multiple safeguards, warnings and default settings to guide our users to trade safer. However, when you integrate with Jupiter, we cannot control these elements despite sharing best practices, hence, Jupiter is not liable for any losses incurred on your UI/platform. + +The only exception is for Jupiter Ultra API, where you can use our ticketing system to provide support to your users. + + +**WARNING** + + We are still in the process of finalizing the Ultra API customer support process. + +Reach out to [us](https://t.me/Yankee0x) to discuss what is the best way to support your users. + + diff --git a/mintlify-migration/misc/privacy-policy.mdx b/mintlify-migration/misc/privacy-policy.mdx new file mode 100644 index 00000000..4f637188 --- /dev/null +++ b/mintlify-migration/misc/privacy-policy.mdx @@ -0,0 +1,138 @@ +--- +title: "Privacy Policy" +--- + +Jupiter, accessible at: [https://jup.ag](https://jup.ag), one of its main priorities is the privacy of participants who are visitors of [https://jup.ag](https://jup.ag) and its dApps . + +Jupiter does it best to collect as minimum Personal Data as possible. This Privacy Policy document contains types of data that are collected, used, and recorded by Jupiter. + +The Jupiter Interface backed by Block Raccoon S.A., a company incorporated in Panama, which is the controller for your Personal Data within the scope of this Privacy Policy. Jupiter decides “why” and “how” your Personal Data is processed in connection with the Interface. If you have additional questions or require more information about this Privacy Policy, do not hesitate to contact `privacy@jup.ag`. + +This Privacy Policy applies only to the Interface activities and is valid for participants who are visitors to the Interface with regards to the Personal Data that they share and/or which is collected within Jupiter Interface. This Privacy Policy is not applicable to any Personal Data collected offline or via channels other than the Interface. Please read this Privacy Policy carefully to understand our policies and practices regarding your data and how it will be treated by the Interface. + +IF YOU DO NOT HAVE THE RIGHT, POWER AND AUTHORITY TO ACT ON BEHALF OF AND BIND THE BUSINESS, ORGANIZATION, OR OTHER ENTITY YOU REPRESENT, PLEASE DO NOT ACCESS OR OTHERWISE USE THE INTERFACE. IF YOU ARE INTERESTED IN HOW WE USE COOKIES AND YOU CAN CHANGE YOUR COOKIE CHOICE, PLEASE SEE SECTION 5 “COOKIES AND AUTOMATICALLY-COLLECTED DATA” + +### 1. Changes to this Agreement + +If our data processing practices change, we will update this Privacy Policy accordingly to let you know of them upfront and give you a possibility to either provide your consent, object to a particular processing, or undertake other action you are entitled to under the Regulation. Please keep track of any changes we may introduce to this Privacy Policy. Your continued access to and use of the Interface constitutes your awareness of all amendments made to this Privacy Policy as of the date of your accessing and use of the Interface. Therefore, we encourage you to review this Privacy Policy regularly as you shall be bound by it. If, for some reason, you are not satisfied with our personal data processing practices, your immediate recourse is to stop using the Interface. You do not have to inform us of this decision unless you intend to exercise some of the data protection rights stipulated by GDPR and defined below in this Privacy Policy. + +### 2. Eligibility + +Age. By accessing our using the Interface, you represent and warrant that you are at least eighteen (18) years of age. If you are under the age of eighteen (18), you may not, under any circumstances or for any reason, use the Interface. Please report to us any instances involving the use of the Interface by individuals under the age of 18, should they come to your knowledge. + +### 3. Applicability + +This Privacy Policy applies to all your interactions with us via the Interface and your interactions with us in connection therewith. + +Below are the categories of our processors used on the Interface due to an internal data processing roadmap providing a brief grasp of our data processing activities with regard to each piece of the Personal Data we may collect through the Interface, as well as your place in every data processing event. It can be requested at `[privacy@jup.ag]`. Below are the categories of our processors which can access and process your Personal Data through the Interface: + +1. Technical maintenance vendors; +2. Project and team management vendors; +3. Communication vendors; +4. Analytics, statistics, performance, marketing vendors. + +### 4. Data processing in connection with the interface + +**Types of Data Collected** + +To the maximum extent possible, Jupiter tries to collect as minimum Personal Data from you as possible. Personal Data we collect: + +* IP address, MAC address, log files, domain server, data related to usage, performance, website security, traffic patterns, location information, browser and device information – only when you are using the Interface; +* Wallet addresses (public blockchain addresses), transaction, and balance information (blockchain data) that is accessible when interacting with the Interface; We use public Blockchain addresses to identify a user’s journey through our product. We group and analyze these user journeys collectively in order to improve our product user experience. We do not use this data for any purpose at an individual user level. The legal basis for this processing is our legitimate interests, such as monitoring and improving the Interface, the proper protection of the Interface against risks, and partly the contract performance basis to provide you the Interface. Note that we are not responsible for your use of any of the blockchain and your data processed in these decentralized and permissionless networks; +* Log Files. Jupiter follows a standard procedure of using log files. These files log visitors when they visit websites. All hosting companies do this and this kind of Personal Data may also be collected as a part of hosting services' analytics. The data collected by log files include internet protocol (IP) addresses, browser type, Internet Service Provider (ISP), date and time stamp, referring/exit pages, and possibly the number of clicks. These kinds of data may be linked to data that is personally identifiable. The purpose of the data collection and processing is for analyzing trends, administering the website, tracking users' movement on the website, and gathering demographic information; + +Jupiter may also engage third-parties advertising platforms that are triggered only when their technical features (so-called “pixels”) are enabled through the Interface. The mentioned third-parties advertising platforms may collect Personal Data of Interface's visitors only with the purpose to optimize their advertising possibilities through their platforms, target you with their advertisements, and possibly share your data with other advertising platforms and agencies for further use. Jupiter may engage with the mentioned Personal Data of Interfaces visitors. + +In no event, are we going to ask you to share your private keys or wallet seed. Never trust anyone or any website that asks you to enter your private keys or wallet seed. + +**How and Why we use your Personal Data** + +We may use your Personal Data listed above only for: + +* Our internal and operational purposes, when: ensuring security, identifying irregular website behavior, preventing fraudulent activity, and improving security at all possible levels; +* Assessing and improving the performance of the Interface; +* Analyzing our website visitors’ actions to improve our Interface (section “Cookies and Automatically Collected Data”); +* Analyzing the Interface behavior, including via: Google Analytics (please refer to Google's Analytics Policy for more information); +* Find and prevent fraud. + +To clear any doubts, we may use Personal Data described above or any other Personal Data: + +* on the basis of contract performance or necessity to enter into a contract (where the Personal Data is required for us to perform our undertakings and obligations in accordance with a contract we are entering into when you use our services, or where we are at the negotiations phase); +* on the basis of our or our processors’ legitimate interests to protect the Interface, prevent any malicious and harmful activities to the Interface, maintain our technical systems healthily and secure, improve services and products by using aggregate statistics; +* to respond to legal requests of authorities, provide information upon court orders and judgments, or if we have a good-faith belief that such disclosure is necessary in order to comply with official investigations or legal proceedings initiated by governmental and/or law enforcement officials, or private parties, including but not limited to: in response to subpoenas, search warrants or court orders, and including other similar statutory obligations we or our processors are subjected to; +* on the basis of your consent; and +* on other legal bases set forth in the personal data protection laws. + +**Disclosure of Data** + +In continuation of legal bases for collecting and processing the Personal Data, We may disclose any Personal Data about you: + +* in connection with a merger, division, restructuring, or other association change; or +* to our subsidiaries or affiliates (if any) only if necessary for operational purposes. If we must disclose any of your Personal Data in order to comply with official investigations or legal proceedings initiated by governmental and/or law enforcement officials, we may not be able to ensure that such recipients of your Personal Data will maintain the privacy or security of your Personal Data. + +**Data Retention Period** + +Jupiter maintains Personal Data exclusively within the time needed to follow prescribed herein legal purposes. When we no longer need Personal Data, the limitation period for storage of such Personal Data has expired, you have withdrawn your consent or objected to our or our processors’ legitimate interests, we securely delete or destroy it unless the statutory requirements we, our processors or other controllers are subjected to stipulate otherwise. Aggregated data, which cannot directly identify a device/browser (or individual) and is used for purposes of reporting and analysis, is maintained for as long as commercially necessary till you object to the processing of such data or withdraw your consent. + +Sometimes legal requirements oblige us to retain certain data, for specific purposes, for an extended period of time. Reasons we might retain some data for longer periods of time include: + +* Security, fraud & abuse prevention; +* Financial monitoring and record-keeping; +* Complying with legal or regulatory requirements; +* Ensuring the continuity of your interaction with the Interface. + +**Your Inquiries** + +You may contact us by email at the following email address: `[privacy@jup.ag]`; We use the data that you provide in an email to us, which you may give voluntarily, only in order to answer your question or to reply to your email in the best possible manner. + +### 5. Cookies and Automatically Collected Data + +As you navigate through and interact with our Interface, we may ask your consent to use cookies, which are small files placed on the hard drive/browser of your computer or mobile device, and web beacons, which are small electronic files located on pages of the Interface, to collect certain information about devices you use, browsing actions, and patterns. + +The data automatically collected from cookies and web beacons may include information about your web browser (such as browser type and browser language) and details of your visits to the Interface, including traffic data, location data and logs, page views, length of visit, and website navigation paths as well as information about your device and internet connection, including your IP address and how you interact with the Interface. We collect this data in order to help us improve the Interface and interaction with it. + +The information we collect automatically may also include statistical and performance information arising from your use of the Interface. This type of data will only be used by us in an aggregated and pseudonymized manner. + +You can choose to disable cookies through your individual browser options. To get more detailed information about cookie management with specific web browsers, please find it on the browsers' respective websites: + +* For Google Chrome browser please refer to these instructions: [https://support.google.com/accounts/answer/32050?co=GENIE.Platform%3DDesktop\&hl=en](https://support.google.com/accounts/answer/32050?co=GENIE.Platform%3DDesktop\&hl=en); +* For Firefox browser please look up here: [https://support.mozilla.org/en-US/kb/clear-cookies-and-site-data-firefox](https://support.mozilla.org/en-US/kb/clear-cookies-and-site-data-firefox) +* For Safari browser please visit: [https://support.apple.com/ru-ru/guide/safari/sfri11471/mac](https://support.apple.com/ru-ru/guide/safari/sfri11471/mac) +* For Internet Explorer browser please refer to: [https://support.microsoft.com/en-us/windows/delete-and-manage-cookies-168dab11-0753-043d-7c16-ede5947fc64d](https://support.microsoft.com/en-us/windows/delete-and-manage-cookies-168dab11-0753-043d-7c16-ede5947fc64d) + +### 6. Your rights under GDPR + +Under certain circumstances, you may have a number of privacy rights concerning the use, storage, and processing of your Personal Data (e.g., the right to delete your data). Here is a list of privacy rights: + +* right to be informed - we are publishing this Privacy Policy to keep you informed as to what we do with your Personal Data. You can ask us for Personal Data regarding you that we keep at any time. This information concerns, among other things, the data categories we process, for what purposes we process them, the origin of the data if we did not acquire them directly from you and, if applicable, the recipients to who we have sent your data. +* right of access – You may ask us whether we process your Personal Data and you have the right to request a copy of the data we hold about you. +* right of rectification – You have the right to correct inaccurate or incomplete data about you. +* right to be forgotten – You can ask for the Personal Data that we hold about you to be erased from our system and we will comply with this request unless we have a legitimate reason, legal requirement, and other statutory basis not to do so. Even if we can delete (erase) the Personal Data subject to our active (ongoing) processing activities and cease its processing, we will nevertheless retain this particular Personal Data in our backup and archive storages to fulfill our statutory and other requirements. +* right to restriction of processing – where certain conditions apply, you can ask us to ‘block’ the processing of your Personal Data. +* right to data portability – You have the right to have the data we hold about you transferred to another organization and to receive Personal Data in a structured, commonly used format. Please apply to: `[privacy@jup.ag]` to find out whether we currently support the provision of the portable file containing Personal Data we process about you. +* right to object - You can object to the processing of your data by applying to: `[privacy@jup.ag]` at any time for reasons that arise from your special situation provided the data processing is based on our legitimate interest or that of a third party, or where we carry out profiling, use machine learning or automated decision-making algorithms. In this case, we will no longer process your Personal Data. The latter does not apply if we are able to prove there are compelling, defensible reasons for the processing that outweigh your interests or we require your data to assert, exercise, or defend legal claims. +* right to withdraw consent - withdraw the consent you gave us with regard to the processing of your Personal Data for certain purposes. +* right to complain - we take your rights very seriously. However, if you are of the opinion that we have not dealt with your complaints adequately, you have the right to submit a complaint to the data privacy protection authorities responsible. You can send your complaints to the EEA supervisory authority of your country of residence. + +Please email: `[privacy@jup.ag]` with any questions about exercising any of the above rights. If You wish to learn more about the GDPR and Your rights, the Information Commissioner’s Office website is a reliable source. + +### 7. Privacy of children + +Our Interface is not directed to collect any data from people under the age of 18. We do not knowingly allow anyone under 18 years old to submit any data to our Interface. If you believe your child may have provided us with their data, you can contact us using the information in this Policy and we will delete the data from our Interface. + +### 8. Transfer of Personal Data + +Transfers to third countries shall be made subject to appropriate safeguards, namely Standard Contractual Clauses adopted by the supervisory authority and approved by the Commission. Copy of the foregoing appropriate safeguards may be obtained by you upon a prior written request sent. We may instruct you on further steps to be taken with the purpose of obtaining such a copy, including your obligation to assume confidentiality commitments in connection with being disclosed the Jupiter proprietary and personal information of third parties as well as terms of their relationships with Jupiter. + +Keep in mind that the use of the Interface based on public blockchains is intended to immutably record transactions across wide networks of computer systems. Many blockchains are open to forensic analysis which can lead to deanonymization and the unintentional revelation of Personal Data, in particular when blockchain data is combined with other data. Because blockchains are decentralized or third-party networks that are not controlled or operated by us, we are not able to erase, modify, or alter Personal Data from such networks. + +### 9. Data Integrity & Security of Processing + +We take data security very seriously. We work hard to protect the Personal Data you provide us from loss, misuse, or unauthorized access. We utilize a variety of safeguards such as encryption, digital and physical access controls, non-disclosure agreements, and other technical and organizational measures to protect the Personal Data submitted to us, both during transmission and once it is at rest. + +Please note that no electronic transmission, storage, or processing of Personal Data can be entirely secure. We cannot guarantee that the security measures we have in place to safeguard Personal Data will never be defeated or fail, or that those measures will always be sufficient or effective. Therefore, although we are committed to protecting your privacy, we do not promise, and you should not expect that your Personal Data will always remain private or secure. + +### 10. Supervisory authority oversight + +If you are a data subject whose data we process, you may also have the right to lodge a complaint with a data protection regulator in one or more of the European Union member states. Here you can find a list of data protection authorities in Europe: ​​[https://edpb.europa.eu/about-edpb/about-edpb/members\_en](https://edpb.europa.eu/about-edpb/about-edpb/members_en) + diff --git a/mintlify-migration/misc/sdk-api-license-agreement.mdx b/mintlify-migration/misc/sdk-api-license-agreement.mdx new file mode 100644 index 00000000..1f85c5ee --- /dev/null +++ b/mintlify-migration/misc/sdk-api-license-agreement.mdx @@ -0,0 +1,202 @@ +--- +title: "SDK & API License Agreement" +--- + +**IMPORTANT**: This Jupiter API & SDK License Agreement (\"Agreement\") is a legally binding contract between you, as Licensee (\"You\", \"Your\" or \"Licensee\") and Block Raccoon S.A., an entity incorporated in Panama (\"Jupiter,\" \"we\" or \"our\") and applies to your use of the Jupiter API or SDK, as defined herein, available through (collectively the \"Service\"). + +The Service includes an Application Programming Interface (\"API\") and a Software Development Kit (“SDK”), which is further discussed and defined below. If you do not agree to be bound by the terms and conditions of this Agreement, please do not proceed with the use of Service, the API, or the SDK. + +This Agreement becomes effective as of the date you first access, download, copy or otherwise use the API or SDK ("Effective Date"). This Agreement shall continue until terminated either by us or by you. Even after termination of this Agreement, certain provisions will survive, as discussed herein. This Agreement also incorporates Jupiter\`s Terms of Service link and Privacy Policy link which terms shall also govern your use of the Service. In the event of any conflict between this Agreement and the Terms of Service or Privacy Policy, the provisions of this Agreement shall prevail. + +YOU ARE ENTERING A LEGALLY BINDING CONTRACT: BY COPYING, DOWNLOADING, OR OTHERWISE USING THE JUPITER API OR SDK YOU ARE EXPRESSLY AGREEING TO BE BOUND BY ALL TERMS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO ALL OF THE TERMS OF THIS AGREEMENT, YOU ARE NOT AUTHORIZED TO COPY, DOWNLOAD, INSTALL OR OTHERWISE USE THE JUPITER API or SDK. + +The API and SDK are protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. The API and SDK is licensed to you, and its use is subject to the terms of this Agreement. + +**1. Definitions​** + +1.1 **"Application Programming Interfaces"** or **"API"** or **"Jupiter API"** means the back-end smart routing algorithm which facilitates the user's efficient swapping of digital assets at a variety of third party trading venues, which may include object code, software libraries, software tools, sample source code, published specifications and Documentation. Jupiter API shall include any future, updated or otherwise modified version(s) thereof furnished by Jupiter (in its sole discretion) to Licensee. + +1.2 **"Software Development Kit"** or **"SDK"** or **"Jupiter SDK"** means the ancillary tools and resources that allow the user to utilise or integrate the API. Jupiter SDK shall include any future, updated or otherwise modified version(s) thereof furnished by Jupiter (in its sole discretion) to Licensee. + +1.3 **"Documentation"** includes, but is not limited to programmer guides, manuals, materials, and information appropriate or necessary for use in connection with the API, and in particular shall include the Integrator Guidelines available at [/misc/integrator-guidelines](/misc/integrator-guidelines). + +**2. Grant of License​** + +2.1 Subject to the terms of this Agreement, Jupiter hereby grants Licensee a limited, non-exclusive, fee-bearing, non-transferable, non-sublicensable licence to use the API or SDK during the term of this Agreement solely for the purpose of Licensee's internal development efforts to develop products or services integrating the API and/or SDK in any manner, including without limitation for any informational, comparison, or testing purpose (the **Licensee's Product**). + +2.2 Licensee shall have no right to distribute, license (whether or not through multiple tiers) or otherwise transfer the API or SDK to any third party. + +2.3 Notwithstanding any of the provisions herein, where the Licensee uses the API or SDK (including without limitation for any informational, comparison, or testing purpose), it shall be required to strictly label/name/characterise the API and any output of the API as “Jupiter Metis v1" and not utilise any other label, name or characteristic, in particular where the same is visible to end users of the Licensee’s Product. The Licensee accepts that it is misleading and unethical to label/name/characterise the API and any output of the API as “Jupiter” or otherwise suggest it is the same product as the service available at [https://jup.ag/](https://jup.ag/). + +2.4 In case of potential other API or SDK use that is not prescribed by this Agreement, please write to [legal@jup.ag](mailto:legal@jup.ag) to seek written consent. + +2.5 Representations. Both Parties to this Agreement are duly organized and validly existing in good standing with all requisite power and authority to enter into this Agreement and conduct its business as is now being conducted. The Licensee is not identified on, or engages in any transactions with any party listed on, any sanctions list maintained by the U.S. Department of the Treasury’s Office of Foreign Asset Control (“OFAC”). + +2.6 By providing access to the API and the SDK, Jupiter is solely providing a back-end technical service to the Licensee which allows the Licensee to provide swap-related services to end users of the Licensee's products or services. Jupiter is not a party to any agreement for swap-related services between the Licensee, its end users, any counterparty or trading venue where swaps are performed, nor any trustee, custodian, bailee, manager, administrator or service provider in respect of any digital asset or otherwise. + +2.7 Independent Contractor Relationship. The relationship between the Parties is that of independent contractors. Nothing in this Agreement shall be construed to create anything like the relationship of an employer and employee, joint venture, partnership, or joint association. + +**3. Other Rights and Limitations​** + +3.1 Copies. Licensee may copy the API or SDK only as necessary for the purpose of the licence hereunder. + +3.2 Except as expressly authorised under this Agreement or by Jupiter in writing, the Licensee agrees it shall not (and shall not permit or authorise any other person to): + +a. use the API or SDK in any manner that is not expressly authorised by this Agreement; + +b. use the API or SDK or develop or use the Licensee's Product (i) for any illegal, unauthorised or otherwise improper purposes or (ii) in any manner which would violate this Agreement or the Documentation, breach any laws, regulations, rules or orders (including those relating to virtual assets, intellectual property, data privacy, data transfer, international communications or the export of technical or personal data) or violate the rights of third parties (including rights of privacy or publicity); + +c. remove any legal, copyright, trademark or other proprietary rights notices contained in or on materials it receives or is given access to pursuant to this Agreement, including the API, the SDK and the Documentation; + +d. sell, lease, share, transfer or sublicense the API, SDK or any content obtained through the API, directly or indirectly, to any third party; + +e. use the API or SDK in a manner that, as determined by Jupiter in its sole discretion, exceeds reasonable request volume, constitutes excessive or abusive usage, or otherwise fails to comply or is inconsistent with any part of the Documentation; + +f. access the API or SDK for competitive analysis or disseminate performance information (including uptime, response time and/or benchmarks) relating to the API; + +g. use the API in conjunction with, or combine content from the API with, content obtained through scraping or any other means outside the API; + +h. (i) interfere with, disrupt, degrade, impair, overburden or compromise the integrity of the API, Jupiter's systems or any networks connected to the API or Jupiter's systems (including by probing, scanning or testing their vulnerability), (ii) disobey any requirements, procedures, policies or regulations of networks connected to the API or Jupiter's systems, (iii) attempt to gain unauthorised access to the API, Jupiter's systems or any information not permitted by this Agreement or circumvent any access or usage limits imposed by Jupiter or (iv) transmit through the Licensee's Product or the use of the API or SDK any (A) content that is illegal, tortious, defamatory, vulgar, obscene, racist, ethnically insensitive, or invasive of another person's privacy, (B) content that promotes illegal or harmful activity, or gambling or adult content, (C) viruses, worms, defects, Trojan horses, or any other malicious programs or code or items of a destructive nature or (D) materials that could harm minors in any way; + +i. copy, adapt, reformat, reverse-engineer, disassemble, decompile, download, translate or otherwise modify or create derivative works of the API, the SDK or the Documentation, Jupiter's website, or any of Jupiter's other content, products or services, through automated or other means; + +j. interfere with Jupiter's business practices or the way in which it licenses or distributes the API or SDK; + +k. make any representations, warranties or commitments (i) regarding the API or SDK or (ii) on behalf of Jupiter; or + +l. take any action that would subject the API or SDK to any third-party terms, including without limitation any open source software licence terms. + +3.3 Without prejudice of the generality of the foregoing, where the Licensee's Product is competitive (whether wholly or partially) with the API or the Service, Jupiter shall have the right to access the Licensee's Product and/or request the Licensee for information regarding the Licensee's Product. Jupiter shall be granted a non-exclusive, royalty-free, non-transferable, non-sublicensable licence to use the Licensee's Product (including without limitation any application programming interface, software development kit, logos, brand information, technical information or data or information in connection with any aspect of the Licensee's Product) for any purpose. + +3.4 Third Party Software. Licensee acknowledges that effective utilization of the API and SDK may require the use of a development tool, compiler and other software and technology of third parties ("Third Party Software"). Licensee is solely responsible for procuring such Third-Party Software and technology and the necessary licenses for the use thereof. Jupiter makes no representation or warranty concerning Third Party Software and shall have no obligation or liability with respect to Third Party Software. + +3.5 No right is granted to Licensee to sublicense its rights hereunder. All rights not expressly granted are reserved by Jupiter and, except as expressly set forth herein, no license is granted by Jupiter under this Agreement directly, by implication, estoppel or otherwise, under any patent, copyright, trade secret or trademark or other intellectual property rights of Jupiter. Nothing herein shall be deemed to authorize Licensee to use Jupiter\`s trademarks or trade names in Licensee's advertising, marketing, promotional, sales or related materials. Jupiter reserves all rights not otherwise expressly granted in this Agreement. + +3.6 No assertion by Licensee. Licensee agrees not to assert any patent rights related to the API/SDK or applications developed using the API/SDK against Jupiter, Jupiter's participants, or other licensees of the API/SDK for making, using, selling, offering for sale, or importing any products or technology developed using the API/SDK. + +3.7 Jupiter may from time to time provide updates or upgrades to the API or SDK. Any such updates and upgrades will be performed according to Jupiter's then-current operational policies, which may include automatic updating or upgrading of API or SDK currently in use at that time. Where the Licensee fails to accept such updates or upgrades, Jupiter shall be entitled to withhold access to the API, SDK and/or Service, and the same shall not constitute any breach of the terms of this Agreement. + +**4. Intellectual Property and proprietary rights** + +4.1 As between Jupiter and Licensee, Jupiter and/or its licensors shall own and retain all proprietary rights, including all patent, copyright, trade secret, trademark and other intellectual property rights, in and to the API and SDK and any corrections, bug fixes, enhancements, updates, improvements, or modifications thereto and (to the extent such rights accrue to the Licensee), the Licensee hereby irrevocably transfers, conveys and assigns to Jupiter all of its right, title, and interest therein. + +4.2 Jupiter shall have the exclusive right to apply for or register any patents, mask work rights, copyrights, and such other proprietary protections with respect thereto. + +4.3 The Licensee acknowledges that the license granted under this Agreement does not provide Licensee with title or ownership to the API or SDK, but only a right of limited use under the terms and conditions of this Agreement. + +4.4 The Parties acknowledge that Jupiter does not store, send, or receive digital assets. Digital assets exist only by virtue of the ownership record maintained on the relevant blockchain network. Any creation or transfer of title that might occur in respect of any digital asset occurs on the relevant blockchain network (on the relevant contractual terms applicable to such creation and/or transfer) and is performed by the Licensee's Product, and Jupiter does not have any role or responsibility in such transactions. Jupiter cannot guarantee that the Licensee's Product, or any party can effect the transfer of such title or right to any digital asset. Accordingly, Jupiter cannot provide any guarantee, warranty or assurance regarding the authenticity, uniqueness, originality, quality, marketability, legality or value of any digital assets utilised in connection with the API and the Services. + +**5. No Obligation to Support​** + +5.1 Subject to payment of fees as described herein, Jupiter would issue to the Licensee certain unique API keys, tokens, passwords and/or other credentials (collectively, **"Keys"**), for accessing the API and/or SDK and managing the Licensee's access to the API. The Licensee may only access the API with the Keys issued to the Licensee by Jupiter. The Licensee acknowledges that access to the API may not always be available. The Licensee may not sell, transfer, sublicense or otherwise disclose its Keys to any other party or use them for any other purpose other than that expressly permitted by Jupiter. The Licensee is responsible for maintaining the secrecy and security of the Keys. The Licensee is fully responsible for all activities that occur using the Keys, regardless of whether such activities are undertaken by the Licensee or a third party. The Licensee is responsible for maintaining up-to-date and accurate information (including a current email address and other required contact information) for the Licensee's access to the API and SFK. Jupiter may discontinue the Licensee's access to the API and SDK if such contact information is not up-to-date and/or the Licensee does not respond to communications directed to such coordinates. + +5.2 Jupiter makes no guarantees with respect to the performance, availability or uptime of the API or the SDK. Jupiter may conduct maintenance on or stop providing any of the API or the SDK at any time with or without written notice to the Licensee. In addition, Jupiter may change the method of access to the API, SDK and Documentation at any time. + +5.3 Jupiter does not guarantee any support for the API or SDK under this Agreement. Nothing herein shall be construed to require Jupiter to provide consultations, support services or updates, upgrades, bug fixes or modifications to the API or SDK. In the event of degradation or instability of Jupiter's system or an emergency, Jupiter may, in its sole discretion, suspend access to the API and/or SDK. + +5.4 Jupiter reserves the right to change the method of access to the API or SDK at any time to ensure the safety and security of its environment. In the event of degradation or instability of Jupiter\`s systems or in an emergency, you acknowledge and agree that Jupiter may, in its sole and absolute discretion, temporarily suspend your access to the API or SDK in order to minimize threats to and protect the operational stability and security of the Jupiter system. + +**6. Fees & Payment​** + +6.1 Jupiter shall charge a subscription fee for usage of the Jupiter API and/or SDK. This may be a fixed fee, infrastructure fee and/or a variable fee based on revenue earned by the Licensee in respect of the Licensee's Product. + +6.2 The details of the level of fees charged shall be notified to you via the API portal at [https://portal.jup.ag](https://portal.jup.ag). By accessing, downloading, copying or otherwise using the API or SDK, you shall be deemed to have consented to said fees. + +6.3 The Fees may be reviewed by Jupiter at any time commencing from three (3) months after the Effective Date. Any updated fees shall be notified to you via the API portal and your continued usage of the API or SDK shall be deemed consent to such updated fees. + +**7. Licensee's Obligations** + +7.1 The Licensee agrees to report to Jupiter any errors or difficulties discovered related to the API or SDK, and the characteristic conditions and symptoms of such errors and difficulties. + +7.2 The Licensee shall perform such sanity testing, cybersecurity testing or other technical checks in respect of the API or SDK as may be reasonably requested by Licensor from time to time. + +7.3 The Licensee shall ensure that the offering/provision of the Licensee's Product complies with all applicable laws and regulations, including without limitation all consumer protection, Know Your Customer (KYC) or Anti-money Laundering (AML) due diligence laws, sanctions, anti-money laundering or terrorist financing laws, securities laws, payment provider laws, or virtual assets regulations. Without prejudice to the generality of the foregoing, the Licensee shall obtain and maintain in force (or as applicable procure the obtaining and maintenance in force of) all necessary licenses, permissions, authorisations, consents and permits which may be necessary or desirable for the offering/provision of the Licensee's Product and (b) perform transaction screening and monitoring of all digital wallets interacting with the Client’s Product, including blocking of sanctioned, blacklisted, prohibited, restricted, flagged, illicit, suspicious or crime-associated digital wallets, in accordance with prevailing best market practice. The Licensee shall be solely responsible for any failure to comply with the foregoing. + +7.4 The Licensee acknowledges and agrees that all reporting, information gathering and other obligations under applicable Know Your Customer (KYC) or Anti-money Laundering (AML) due diligence laws, sanctions, anti-money laundering or terrorist financing laws, securities laws, payment provider laws, or virtual assets regulations with respect to the Licensee's end-users are the responsibility of the Licensee; and Jupiter shall not be responsible or have any liability for any of the foregoing. The Licensee agrees to provide such information to Jupiter if reasonably requested by Jupiter. + +7.5 Without prejudice to the foregoing, upon written request from Jupiter, the Licensee shall use all efforts to block any specific digital wallet or address from accessing the Licensee's Product and/or the API integration. + +7.6 The Licensee agrees to immediately notify Jupiter if (i) the Licensee becomes aware of any security event, including any cybersecurity breach, attack or economic exploit relating to the Licensee's Product or (ii) the Licensee's Product, API, SDK or the Service becomes subject to any legal or regulatory investigation or action. + +7.7 The Licensee shall be responsible for all customer service for all its products and services (including the Licensee's Product). + +**8. Confidentiality​ and Publicity** + +8.1 The API and SDK contains valuable proprietary information and trade secrets of Jupiter and its suppliers that remain the property of Jupiter. You shall protect the confidentiality of, and avoid disclosure and unauthorized use of, the API or SDK. + +8.2 Without prejudice to the generality of the foregoing, you agree not to disparage Jupiter, any of its affiliates, or any of their directors, shareholders, employees, servants, contractors, or agents in any manner, or otherwise make any false, misleading or negative statements to any party about Jupiter or any of its affiliates, the Service (or any output of the Service), or any other product(s) or service(s) of Jupiter or any of its affiliates. + +8.3 Jupiter may disclose and publicise the existence of the business relationship between Jupiter and you on its website and in promotional and marketing materials without requiring any further consent from you. + +8.4 You shall ensure that the Licensee's Product shall prominently display to end users of such product or service the message "Powered by Jupiter". + +**9. No Warranty​** + +9.1 The API, SDK, and Documentation are provided "AS-IS" without any warranty whatsoever. To the full extent allowed by law, the foregoing warranties and remedies are exclusive and are in lieu of all other warranties, terms, or conditions, express or implied, either in fact or by operation of law, statutory or otherwise, including warranties, terms, or conditions of merchantability, fitness for a particular purpose, satisfactory quality, correspondence with description, and non-infringement, all of which are expressly disclaimed. + +9.2 No advice or information, whether oral or written, obtained by you from Jupiter or through or from the API/SDK shall create any warranty not expressly stated in this agreement. Jupiter does not warrant that the API, SDK and Documentation are suitable for Licensee's use, that the API, SDK or Documentation are without defect or error, that operation will be uninterrupted, or that defects will be corrected. Further, Jupiter makes no warranty regarding the results of the use of the API, SDK, and Documentation. + +**10. Limitation of Liability​** + +JUPITER WILL NOT BE LIABLE FOR ANY DAMAGES OF ANY KIND ARISING OUT OF OR RELATING TO THE USE OR THE INABILITY TO USE THE API, SDK AND ITS USE OR THE INABILITY TO USE WITH ANY THIRD PARTY SOFTWARE, ITS CONTENT OR FUNCTIONALITY, INCLUDING BUT NOT LIMITED TO DAMAGES FOR LOSS OF BUSINESS PROFITS OR REVENUE; BUSINESS INTERRUPTION OR WORK STOPPAGE; COMPUTER FAILURE OR MALFUNCTION; LOSS OF BUSINESS INFORMATION, DATA OR DATA USE; LOSS OF GOODWILL; DAMAGES CAUSED BY OR RELATED TO ERRORS, OMISSIONS, INTERRUPTIONS, DEFECTS, DELAY IN OPERATION OR TRANSMISSION, COMPUTER VIRUS, FAILURE TO CONNECT, NETWORK CHARGES, AND ALL OTHER DIRECT, INDIRECT, SPECIAL, INCIDENTAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES EVEN IF JUPITER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE ABOVE EXCLUSIONS OR LIMITATIONS MAY NOT APPLY TO YOU. NOTWITHSTANDING THE FOREGOING, JUPITER TOTAL LIABILITY TO LICENSEE FOR ALL LOSSES, DAMAGES, CAUSES OF ACTION, INCLUDING BUT NOT LIMITED TO THOSE BASED ON CONTRACT, TORT, OR OTHERWISE, ARISING OUT OF YOUR USE OF THE API/SDK AND/OR INTELLECTUAL PROPERTY ON THIS TECHNOLOGY PLATFORM OR API/SDK, OR ANY OTHER PROVISION OF THIS AGREEMENT, SHALL NOT EXCEED THE AMOUNT OF 100 USD. THE FOREGOING LIMITATIONS, EXCLUSIONS, AND DISCLAIMERS SHALL APPLY TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, EVEN IF ANY REMEDY FAILS ITS ESSENTIAL PURPOSE. + +**11. Indemnity​** + +You agree to indemnify and hold harmless Jupiter and its contributors, subsidiaries, affiliates, officers, agents, Intellectual Property service providers, co-branders, customers, suppliers or other partners, and employees, from any loss, claim or demand, including reasonable attorneys' fees, made by any third party due to or arising out of your negligence, error, omissions, or failure to perform relating to your use of the API/SDK, your connection to the API, or your violation of the Agreement. + +**12. Disclaimers** + +12.1 UNLESS SEPARATELY STATED IN A WRITTEN EXPRESS LIMITED WARRANTY, THE API AND SDK PROVIDED BY JUPITER IS PROVIDED "AS IS" AND ON AN "AS AVAILABLE" BASIS, WITHOUT WARRANTIES OF ANY KIND FROM JUPITER, EITHER EXPRESS OR IMPLIED. TO THE FULLEST EXTENT POSSIBLE PURSUANT TO APPLICABLE LAW, JUPITER DISCLAIMS ALL WARRANTIES EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY OR WORKMANSHIP LIKE EFFORT, FITNESS FOR A PARTICULAR PURPOSE, RELIABILITY OR AVAILABILITY, ACCURACY, LACK OF VIRUSES, QUIET ENJOYMENT, NON- INFRINGEMENT OF THIRD-PARTY RIGHTS OR OTHER VIOLATIONS OF RIGHTS. SOME JURISDICTIONS DO NOT ALLOW EXCLUSIONS OR LIMITATIONS OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSIONS OR LIMITATIONS MAY NOT APPLY TO YOU. NO ADVICE OR INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED BY YOU FROM JUPITER OR ITS AFFILIATES SHALL BE DEEMED TO ALTER THIS DISCLAIMER BY JUPITER OF WARRANTY REGARDING THE API OR SDK OR THE AGREEMENT, OR TO CREATE ANY WARRANTY OF ANY SORT FROM JUPITER. + +12.2 NEITHER JUPITER NOR THE API PROVIDES ANY DIGITAL ASSET EXCHANGE OR PORTFOLIO/FUND MANAGEMENT SERVICE. WHERE THE LICENSEE OR ANY END USER OF THE LICENSEE'S PRODUCT MAKES THE DECISION TO TRANSACT UTILISING THE API OR THE SERVICE, THEN SUCH DECISIONS AND TRANSACTIONS AND ANY CONSEQUENCES FLOWING THEREFROM ARE SUCH TRANSACTING PARTY'S SOLE RESPONSIBILITY. + +12.3 THE API FUNCTIONS SOLELY AS A BACK-END SUPPORTING TECHNICAL SERVICE FOR A SMART ROUTING ALGORITHM FOR DIGITAL ASSET SWAPS ONLY; IN NO CIRCUMSTANCES SHALL JUPITER, THE API OR THE SDK BE CONSTRUED AS A DIGITAL ASSET EXCHANGE, BROKER, DEALER, FUND MANAGER, FINANCIAL INSTITUTION, EXCHANGE, CUSTODIAN, ROBO-ADVISOR, INTERMEDIARY, OR CREDITOR. + +12.4 THE API DOES NOT FACILITATE OR ARRANGE DIGITAL ASSET TRANSACTIONS BETWEEN COUNTERPARTIES, INCLUDING WITH RESPECT TO ANY TRANSACTIONS THAT OCCUR IN CONNECTION WITH ANY DECENTRALISED EXCHANGE, LIQUIDITY POOL OR OTHER CENTRALISED OR DECENTALISED FINANCE PRODUCT / FACILITY, WHICH TRANSACTIONS OCCUR ON SUCH PLATFORM, PROTOCOL AND/OR THE RELEVANT BLOCKCHAIN NETWORK. JUPITER IS NOT A COUNTERPARTY TO ANY DIGITAL ASSET TRANSACTION FACILITATED BY THE API OR THE LICENSEE'S PRODUCT. + +12.5 There may be various vulnerabilities, failures or abnormal behaviour of software relating to digital assets (e.g., token contract, wallet, smart contract), or relating to the relevant blockchain network, and Jupiter cannot be responsible for any losses in connection with the same, including without limitation any losses in connection with (i) user error, such as forgotten passwords or incorrectly construed smart contracts or other transactions, (ii) server failure or data loss, (iii) corrupted wallet files, or (iv) unauthorised access or activities by third parties, including but not limited to the use of viruses, phishing, brute-forcing or other means of attack against the API or SDK, the relevant blockchain network, or the Licensee's or any end user's digital wallet. + +12.6 Jupiter disclaims any responsibility for any disclosure of information or any other practices of any third-party API provider. Jupiter expressly disclaims any warranty regarding whether your personal information is captured by any third-party API provider or the use to which such personal information may be put by such third-party API provider. + +**13. Term and Termination​** + +13.1 The effective date of this Agreement is the start of use of the API or SDK by the Licensee. There shall be a minimum term of 30 days for usage of the API to be paid for in advance (or such other minimum term as notified to you via the API portal at [https://portal.jup.ag](https://portal.jup.ag)). + +13.2 This Agreement will terminate automatically if you fail to comply with any of the terms and conditions of this Agreement and you will be liable to Jupiter and its suppliers for damages or losses caused by your non-compliance. The waiver by Jupiter of a specific breach or default shall not constitute the waiver of any subsequent breach or default. + +13.3 Either party shall have the right to terminate the Agreement (for any reason), by written notice to the other party and refunding a pro-rata portion of any unutilised fee paid (in the case of termination by Jupiter). For the purpose of the Licensee's service of notice, it may contact [legal@jup.ag](mailto:legal@jup.ag). + +13.4 Upon termination of this Agreement, Licensee will immediately cease using the API and the SDK, and Licensee agrees to destroy all adaptations or copies of the API, SDK, and Documentation or return them to Jupiter upon the termination of this License. + +13.5 Jupiter shall have the right to review/audit your use of the API or SDK in conjunction with this Agreement, and you will provide reasonable assistance for this purpose. + +13.6 The rights of Jupiter and your obligations contained in this Agreement survive any expiration or termination of this Agreement. + +**14. Applicable Law; Arbitration​** + +14.1 Licensee and Jupiter agree to arbitrate any dispute arising from this Agreement, except for disputes in which either party seeks equitable and other relief for the alleged unlawful use of copyrights, trademarks, trade names, logos, trade secrets or patents. ARBITRATION PREVENTS LICENSEE FROM SUING IN COURT OR FROM HAVING A JURY TRIAL. + +14.2 Licensee and Jupiter agree to notify each other in writing of any dispute within thirty (30) days of when it arises. Notice to Jupiter shall be sent to [legal@jup.ag](mailto:legal@jup.ag). + +14.3 The Licensee and Jupiter shall cooperate in good faith to resolve any dispute, controversy or claim arising out of, relating to, or in connection with this Agreement, including with respect to the formation, applicability, breach, termination, validity or enforceability thereof (a "Dispute") shall be settled in accordance with the laws of Panama. The parties undertake to carry out any award without delay and waive their right to any form of recourse insofar as such waiver can validly be made. Judgment upon the award may be entered by any court having jurisdiction thereof or having jurisdiction over the relevant party or its assets. Jupiter and the Licensee will each pay their respective attorneys' fees and expenses. Any dispute arising out of or related to this Agreement is personal to the Licensee and Jupiter and will not be brought as a class arbitration, class action, or any other type of representative proceeding. There will be no class arbitration or arbitration in which a person attempts to resolve a dispute as a representative of another person or group of persons. Further, a dispute cannot be brought as a class or other type of representative action, whether within or outside of arbitration, or on behalf of any other person or group of persons. + +14.4 Any dispute between the parties will be governed by this Agreement and the laws of Panama, without giving effect to any conflict of laws principles that may provide for the application of the law of another jurisdiction. Whether the dispute is heard in arbitration or in court, Licensee and Jupiter will not commence against the other a class action, class arbitration or representative action or proceeding. + +**15. Changes to this Agreement​** + +We may amend any portion of this Agreement at any time by posting the revised version of this Agreement on [https://portal.jup.ag](https://portal.jup.ag) with an updated revision date. The changes will become effective and shall be deemed accepted by you, the first time you use or access the SDK or API after the initial posting of the revised Agreement and shall apply on a going-forward basis with respect to your use of the SDK and/or API. In the event that you do not agree with any such modification, your sole and exclusive remedy is to terminate your use of the SDK and/or API. + +**16. Miscellaneous​** + +16.1 Assignment. Licensee may not assign this Agreement or any interest or rights granted hereunder to any third party without the prior written consent of Jupiter. A change of control or reorganization of Licensee pursuant to a merger, sale of assets or stock shall be deemed to be an assignment under this Agreement. This Agreement shall terminate immediately upon the occurrence of any prohibited assignment. + +16.2 Waiver. No failure by either party to exercise or enforce any of its rights under this Agreement will act as a waiver of such rights and no waiver of a breach in a particular situation shall be held to be a waiver of any other or subsequent breach. + +16.3 Severability. If any provision of this Agreement is found invalid or unenforceable, that provision will be enforced to the maximum extent possible and the other provisions of this Agreement will remain in force. + +16.4 Entire agreement. This Agreement represents the complete agreement concerning the API, SDK and oral amendments are void. If any provision of this Agreement is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. + +16.5 Neither Party hereto shall be responsible for any failure to perform its obligations under this Agreement if such failure is caused by acts of God, war, strikes, revolutions, lack or failure of transportation facilities, laws or governmental regulations or other causes that are beyond the reasonable control of such Party. Obligations hereunder, however, shall in no event be excused but shall be suspended only until the cessation of any cause of such failure. + +16.6 By installing, copying, or otherwise using this API or SDK, you acknowledge that you have read, understand and agree to be bound by the terms and conditions indicated above. + diff --git a/mintlify-migration/misc/terms-of-use.mdx b/mintlify-migration/misc/terms-of-use.mdx new file mode 100644 index 00000000..a9dde904 --- /dev/null +++ b/mintlify-migration/misc/terms-of-use.mdx @@ -0,0 +1,153 @@ +--- +title: "Terms of Use" +--- + +**Jupiter**, [https://jup.ag](https://jup.ag), a website-hosted user interface (the \"Interface\") made available by Block Raccoon S.A. + +The Interface is a visual representation of Jupiter protocol (the "Protocol") which comprises open source software deployed in a permissionless manner by Block Raccoon S.A. The Interface provides an interface which allows users to view and administer their interactions with the Protocol. + +These Terms of Use and any terms and conditions incorporated herein by reference (collectively, the "Terms") govern your access to and use of the Interface. You must read the Terms carefully. + +To make these Terms easier to read: + +* Block Raccoon S.A.is referred to as "Jupiter", "we", "us", "our" or "the Company". +* "You", "your" and "user(s)" refers to anybody who accesses or uses, in any way, the Interface. If you are accessing or using the Interface on behalf of a company (such as your employer) or other legal entity, you represent and warrant that you have the authority to bind that entity to these Terms and, in that case, "you", "your" or "user(s)" will refer to that entity. + +By accessing, browsing, or otherwise using the Interface, or by acknowledging agreement to the Terms on the Interface, you agree that you have read, understood, and accepted all of the Terms and our Privacy Policy (the "Privacy Policy"), which is incorporated by reference into the Terms. + +IMPORTANT NOTE REGARDING ARBITRATION: WHEN YOU AGREE TO THESE TERMS BY USING OR ACCESSING THE INTERFACE, YOU ARE AGREEING TO RESOLVE ANY DISPUTE BETWEEN YOU AND JUPITER THROUGH BINDING, INDIVIDUAL ARBITRATION RATHER THAN IN COURT. AND YOU AGREE TO A CLASS ACTION WAIVER, BOTH OF WHICH IMPACT YOUR RIGHTS AS TO HOW DISPUTES ARE RESOLVED. + +If you come up with any further questions, please, dont be shy and feel free to contact us at `legal@jup.ag`. + +### 1. Eligibility + +*General*. You may not use the Interface if you are otherwise barred from using the Interface under applicable law. + +*Legality*. You are solely responsible for adhering to all laws and regulations applicable to you and your use or access to the Interface. Your use of the Interface is prohibited by and otherwise violate or facilitate the violation of any applicable laws or regulations, or contribute to or facilitate any illegal activity. + +The Interface and each of the Company's services does not constitute, and may not be used for the purposes of, an offer or solicitation to anyone in any jurisdiction in which such offer or solicitation is not authorised, or to any person to whom it is unlawful to make such an offer or solicitation. + +By using or accessing the Interface, you represent to us that you are not subject to sanctions or otherwise designated on any list of prohibited or restricted parties or excluded or denied persons, including but not limited to the lists maintained by the United Nations Security Council, the European Union or its Member States, or any other government authority. + +We make no representations or warranties that the information, products, or services provided through our Interface, are appropriate for access or use in other jurisdictions. You are not permitted to access or use our Interface in any jurisdiction or country if it would be contrary to the law or regulation of that jurisdiction or if it would subject us to the laws of, or any registration requirement with, such jurisdiction. We reserve the right to limit the availability of our Interface to any person, geographic area, or jurisdiction, at any time and at our sole and absolute discretion. + +*Prohibited Localities*. Jupiter does not interact with digital wallets located in, established in, or a resident of the United States, the Republic of China, Singapore, Myanmar (Burma), Cote D'Ivoire (Ivory Coast), Cuba, Crimea and Sevastopol, Democratic Republic of Congo, Iran, Iraq, Libya, Mali, Nicaragua, Democratic People’s Republic of Korea (North Korea), Somalia, Sudan, Syria, Yemen, Zimbabwe or any other state, country or region that is subject to sanctions enforced by the United States, the United Kingdom or the European Union. You must not use any software or networking techniques, including use of a Virtual Private Network (VPN) to modify your internet protocol address or otherwise circumvent or attempt to circumvent this prohibition. + +*Non-Circumvention*. You agree not to access the Interface using any technology for the purposes of circumventing these Terms. + +### 2. Compliance Obligations + +The Interface may not be available or appropriate for use in all jurisdictions. By accessing or using the Interface, you agree that you are solely and entirely responsible for compliance with all laws and regulations that may apply to you. You further agree that we have no obligation to inform you of any potential liabilities or violations of law or regulation that may arise in connection with your access and use of the Interface and that we are not liable in any respect for any failure by you to comply with any applicable laws or regulations. + +### 3. Access to the Interface + +We reserve the right to disable access to the Interface at any time in the event of any breach of the Terms, including without limitation, if we, in our sole discretion, believe that you, at any time, fail to satisfy the eligibility requirements set forth in the Terms. Further, we reserve the right to limit or restrict access to the Interface by any person or entity, or within any geographic area or legal jurisdiction, at any time and at our sole discretion. We will not be liable to you for any losses or damages you may suffer as a result of or in connection with the Interface being inaccessible to you at any time or for any reason. + +The Interface and the Protocol may rely on or utilise a variety of external third party services or software, including without limitation oracles, decentralised cloud storage services, analytics tools, hence the Interface or the Protocol may be adversely affected by any number of risks related to these third party services/software. These may include technical interruptions, network congestion/failure, security vulnerabilities, cyberattacks, or malicious activity. Access to the Interface or the Protocol may become degraded or unavailable during times of significant volatility or volume. This could result in the inability to interact with third-party services for periods of time and may also lead to support response time delays. The Company cannot guarantee that the Interface or the Protocol will be available without interruption and neither does it guarantee that requests to interact with third-party services will be successful. You agree that you shall not hold the Company responsible for any losses which occur due to any of the foregoing. + +### 4. Your Use of Interface + +By using or accessing the Interface, you represent and warrant that you understand that there are inherent risks associated with virtual currency, and the underlying technologies including, without limitation, cryptography and blockchain, and you agree that Jupiter is not responsible for any losses or damages associated with these risks. You specifically acknowledge and agree that the Interface facilitates your interaction with decentralized networks and technology and, as such, we have no control over any blockchain or virtual currencies and cannot and do not ensure that any of your interactions will be confirmed on the relevant blockchain and do not have the ability to effectuate any cancellation or modification requests regarding any of your interactions. + +Without limiting the foregoing, you specifically understand and hereby represent your acknowledgment of the following: + +* The pricing information data provided through the Interface does not represent an offer, a solicitation of an offer, or any advice regarding, or recommendation to enter into, a transaction with the Interface. +* The Interface does not act as an agent for any of the users. +* The Interface does not own or control any of the underlying software through which blockchain networks are formed, and therefore is not responsible for them and their operation. +* You are solely responsible for reporting and paying any taxes applicable to your use of the Interface. +* Although it is intended to provide accurate and timely information on the Interface, the Interface or relevant tools may not always be entirely accurate, complete, or current and may also include technical inaccuracies or typographical errors. Accordingly, you should verify all information before relying on it, and all decisions based on information contained on the Interface or relevant tools are your sole responsibility. + +In order to allow other users to have a full and positive experience of using the Interface you agree that you will not use the Interface in a manner that: + +* Breaches the Terms; +* Infringes on or violates any copyright, trademark, service mark, patent, right of publicity, right of privacy, or other proprietary or intellectual property rights under the law; +* Seeks to interfere with or compromise the integrity, security, or proper functioning of any computer, server, network, personal device, or other information technology system, including, but not limited to, the deployment of viruses and denial of service attacks; +* Attempts, in any manner, to obtain the private key, password, account, or other security information from any other user, including such information about the digital wallet; +* Decompiles, reverse engineer, or otherwise attempt to obtain the source code or underlying ideas or information of or relating to the Interface; +* Seeks to defraud us or any other person or entity, including, but not limited to, providing any false, inaccurate, or misleading information in order to unlawfully obtain the property of another; +* Violates any applicable law, rule, or regulation concerning the integrity of trading markets, including, but not limited to, the manipulative tactics commonly known as spoofing and wash trading; +* Violates any applicable law, rule, or regulation of the United States or another relevant jurisdiction, including, but not limited to, the restrictions and regulatory requirements imposed by U.S. law; +* Disguises or interferes in any way with the IP address of the computer you are using to access or use the Interface or that otherwise prevents us from correctly identifying the IP address of the computer you are using to access the Interface; +* Transmits, exchanges, or is otherwise supported by the direct or indirect proceeds of criminal or fraudulent activity; +* Contributes to or facilitates any of the foregoing activities. + +As it has been already stated, we only provide you with the relevant interface and software and neither has control over your interactions with the blockchain nor encourages you to perform any. Any interaction performed by you via the Interface remains your sole responsibility. + +All information provided in connection with your access and use of the Interface is for informational purposes only and should not be construed as professional advice. You should not take, or refrain from taking, any action based on any information contained in the Interface or any other information that we make available at any time, including, without limitation, blog posts, articles, links to third-party content, news feeds, tutorials, tweets, and videos. Before you make any financial, legal, or other decisions involving the Interface, you should seek independent professional advice from an individual who is licensed and qualified in the area for which such advice would be appropriate. + +The Terms are not intended to, and do not, create or impose any fiduciary duties on us. To the fullest extent permitted by law, you acknowledge and agree that we owe no fiduciary duties or liabilities to you or any other party and that to the extent any such duties or liabilities may exist at law or in equity, those duties and liabilities are hereby irrevocably disclaimed, waived, and eliminated. You further agree that the only duties and obligations that we owe you are those set forth expressly in the Terms. + +You understand that smart contract protocols such as the Protocol simply comprise a set of autonomous blockchain-based smart contracts deployed on the relevant blockchain network, operated directly by users calling functions on it (which allows them to interact with other users in a multi-party peer-to-peer manner). There is no further control by or interaction with the original entity which had deployed the smart contract, which entity solely functions as a provider of technical tools for users, and is not offering any sort of securities product or regulated service nor does it hold any user assets on custody. Any rewards earned by user interactions arise solely out of their involvement in the protocol by taking on the risk of interacting with other users and the ecosystem. + +### 5. Non-custodial nature of Interface and Protocol + +The Interface and Protocol are non-custodial in nature, therefore neither holds or controls your digital assets. Any digital assets which you may acquire through the usage of the Interface or the Protocol will be held and administered solely by you through your selected electronic wallet, and we shall have no access to or responsibility in regard to such electronic wallet or digital asset held therein. It is solely your responsibility to select the wallet service provider to use, and your use of such electronic wallet will be subject to the governing terms of use or privacy policy of the provider of such wallet. We neither own nor control your selected electronic wallet service, the relevant blockchain network, or any other third party site, product, or service that you might access, visit, or use for the purpose of enabling you to utilise the Interface or the Protocol. We will not be liable for the acts or omissions of any such third parties, nor will we be liable for any damage that you may suffer as a result of your transactions or any other interaction with any such third parties. + +We will not create any hosted wallet for you or otherwise custody digital assets on your behalf, and it is your sole responsibility to maintain the security of your selected electronic wallet. You hereby irrevocably waive, release and discharge all claims, whether known or unknown to you, against us, our affiliates and their respective shareholders, members, directors, officers, employees, agents and representatives related to your use of any wallet software, associated loss of digital assets, transaction failures, or any other defects that arise in the course of your use of your electronic wallet, including any losses that may obtain as a result of any failure of the Interface or the Protocol. + +Neither the Company, the Interface nor the Protocol provides any digital asset exchange or portfolio/fund management services. If you choose to engage in transactions with other users via the Interface or the Protocol, then such decisions and transactions and any consequences flowing therefrom are your sole responsibility. In no event shall the Company, its affiliates or their respective directors or employees be responsible or liable to you or anyone else, directly or indirectly, for any damage or loss arising from or relating to any interaction or continued interaction with the Interface or the Protocol or in reliance on any information provided on the Interface (including, without limitation, directly or indirectly resulting from errors in, omissions of or alterations to any such information). + +"Know Your Customer" and "Anti-Money Laundering" checks We reserve the right to conduct "Know Your Customer" and "Anti-Money Laundering" checks on you if deemed necessary by us (at our sole discretion) or such checks become required under applicable laws in any jurisdiction. Upon our request, you shall immediately provide us with information and documents that we, in our sole discretion, deem necessary or appropriate to conduct "Know Your Customer" and "Anti-Money Laundering" checks. Such documents may include, but are not limited to, passports, driver's licenses, utility bills, photographs of associated individuals, government identification cards or sworn statements before notaries or other equivalent professionals. Notwithstanding anything herein, we may, in its sole discretion, refuse to provide access to the Interface to you until such requested information is provided, or in the event that, based on information available to us, you are suspected of using the Interface or the Protocol in connection with any money laundering, terrorism financing, or any other illegal activity. In addition, we shall be entitled to use any possible efforts for preventing money laundering, terrorism financing or any other illegal activity, including without limitation blocking of your access to the Interface or the Protocol, or providing your information to any regulatory authority. + +### 6. Disclaimers + +You understand and agree that the Interface enables access to an online, decentralized, and autonomous protocol and environment, and associated decentralized networks, that are not controlled by Jupiter. We do not have access to your private key and cannot initiate an interaction with your virtual currency or otherwise access your virtual currency. We are not responsible for any activities that you engage in when using your wallet, or the Interface. + +Jupiter cannot and does not represent or guarantee that any of the information available through the Interface is accurate, reliable, current, complete or appropriate for your needs. The information displayed through the Interface including information about prices is provided by third parties and/or calculated for informational purposes. Your use of any third-party scripts, indicators, ideas, and other content is at your sole risk. + +You expressly understand and agree that your use of the Interface is at your sole risk. We make and expressly disclaim all representations and warranties, express, implied or statutory, and with respect to the Interface and the code proprietary or open-source, we specifically do not represent and warrant and expressly disclaim any representation or warranty, express, implied or statutory, including without limitation, any representations or warranties of title, non-infringement, merchantability, usage, security, suitability or fitness for any particular purpose, or as to the workmanship or technical coding thereof, or the absence of any defects therein, whether latent or patent. We do not represent or warrant that the Interface, code, and any related information are accurate, complete, reliable, current, or error-free. The Interface is provided on an "as is" and "as available" basis, without warranties of any kind, either express or implied, including, without limitation, implied warranties of merchantability, fitness for a particular purpose, or non-infringement. + +You acknowledge that no advice, information, or statement that we make should be treated as creating any warranty concerning the Interface. We do not endorse, guarantee, or assume responsibility for any advertisements, offers, or statements made by third parties concerning the Interface. You acknowledge that Jupiter is not responsible for transferring, safeguarding, or maintaining your private keys or any virtual currency associated therewith. If you lose, mishandle, or have stolen associated virtual currency private keys, you acknowledge that you may not be able to recover associated virtual currency and that Jupiter is not responsible for such loss. You acknowledge that Jupiter is not responsible for any loss, damage, or liability arising from your failure to comply with the terms hereunder. + +By accessing and using the Interface, you represent that you understand (a) the Interface facilitates access to the Protocol, the use of which has many inherent risks, and (b) the cryptographic and blockchain-based systems have inherent risks to which you are exposed when using the Interface. You further represent that you have a working knowledge of the usage and intricacies of blockchain-based digital assets, including, without limitation, SPL token standard available on the Solana blockchain. You further understand that the markets for these blockchain-based digital assets are highly volatile due to factors that include, but are not limited to, adoption, speculation, technology, security, and regulation. You acknowledge that the cost and speed of transacting with blockchain-based systems, such as Solana, are variable and may increase or decrease, respectively, drastically at any time. You hereby acknowledge and agree that we are not responsible for any of these variables or risks associated with the Protocol and cannot be held liable for any resulting losses that you experience while accessing or using the Interface. Accordingly, you understand and agree to assume full responsibility for all of the risks of accessing and using the Interface to interact with the Protocol. + +The Interface may contain references or links to third-party resources, including, but not limited to, information, materials, products, or services, that we do not own or control. In addition, third parties may offer promotions related to your access and use of the Interface. We do not endorse or assume any responsibility for any such resources or promotions. If you access any such resources or participate in any such promotions, you do so at your own risk, and you understand that the Terms do not apply to your dealings or relationships with any third parties. You expressly relieve us of any and all liability arising from your use of any such resources or participation in any such promotions. + +### 7. Intellectual Proprietary Rights + +We own all intellectual property and other rights in the Interface and its contents, including, but not limited to, software, text, images, trademarks, service marks, copyrights, patents, and designs. Unless expressly authorized by us, you may not copy, modify, adapt, rent, license, sell, publish, distribute, or otherwise permit any third party to access or use the Interface or any of its contents. Accessing or using the Interface does not constitute a grant to you of any proprietary intellectual property or other rights in the Interface or its contents. + +You will retain ownership of all intellectual property and other rights in any information and materials you submit through the Interface. However, by uploading such information or materials, you grant us a worldwide, royalty-free, irrevocable license to use, copy, distribute, publish and send this data in any manner in accordance with applicable laws and regulations. + +You may choose to submit comments, bug reports, ideas, or other feedback about the Interface, including, without limitation, about how to improve the Interface (collectively, "Feedback"). By submitting any Feedback, you agree that we are free to use such Feedback at our discretion and without additional compensation to you, and to disclose such Feedback to third parties (whether on a non-confidential basis or otherwise). If necessary under applicable law, then you hereby grant us a perpetual, irrevocable, non-exclusive, transferable, worldwide license under all rights necessary for us to incorporate and use your Feedback for any purpose. + +If (i) you satisfy all of the eligibility requirements set forth in the Terms, and (ii) your access to and use of the Interface complies with the Terms, you hereby are granted a single, personal, limited license to access and use the Interface. This license is non-exclusive, non-transferable, and freely revocable by us at any time without notice or cause in our sole discretion. Use of the Interface for any purpose not expressly permitted by the Terms is strictly prohibited. + +In the event that you utilise any intellectual property in any manner which infringes on the rights of any party (including by unauthorised incorporation of the same in any project, protocol, code or any digital token), the Company reserves the sole discretion to effectuate the takedown of any such project, protocol, code or any digital token (or underlying intellectual property) at any time, without notice, compensation or payment to you. In addition, and without prejudice to the Company's other remedies under this Agreement, you shall indemnify the Company and its officers, directors, employees, contractors, agents, affiliates, and subsidiaries from and against all claims, damages, obligations, losses, liabilities, costs, and expenses arising from your aforesaid infringement of intellectual rights. + +### 8. Indemnification + +You agree to hold harmless, release, defend, and indemnify us and our officers, directors, employees, contractors, agents, affiliates, and subsidiaries from and against all claims, damages, obligations, losses, liabilities, costs, and expenses arising from (a) your access to and use of the Interface; (b) your violation of these Terms, the right of any third party, or any other applicable law, rule, or regulation; and (c) any other party’s access and use of the Interface with your assistance or using any device or account that you own or control. + +### 9. Limitation of Liability + +Under no circumstances shall we or any of our officers, directors, employees, contractors, agents, affiliates, or subsidiaries be liable to you for any indirect, punitive, incidental, special, consequential, or exemplary damages, including (but not limited to) damages for loss of profits, goodwill, use, data, or other intangible property, arising out of or relating to any access to or use of the Interface, nor will we be responsible for any damage, loss, or injury resulting from hacking, tampering, or other unauthorized access to or use of the Interface, or from any access to or use of any information obtained by any unauthorized access to or use of the Interface. We assume no liability or responsibility for any: (a) errors, mistakes, or inaccuracies of content; (b) personal injury or property damage, of any nature whatsoever, resulting from any access to or use of the Interface; (c) unauthorized access to or use of any secure server or database in our control or the use of any information or data stored therein; (d) interruption or cessation of function related to the Interface; (e) bugs, viruses, trojan horses, or the like that may be transmitted to or through the Interface; (f) errors or omissions in, or loss or damage incurred as a result of, the use of any content made available through the Interface; and (g) the defamatory, offensive, or illegal conduct of any third party. Under no circumstances shall we or any of our officers, directors, employees, contractors, agents, affiliates, or subsidiaries be liable to you for any claims, proceedings, liabilities, obligations, damages, losses, or costs in an amount exceeding the greater of (i) the amount you paid to us in exchange for access to and use of the Interface, or (ii) $100.00. This limitation of liability applies regardless of whether the alleged liability is based on contract, tort, negligence, strict liability, or any other basis, and even if we have been advised of the possibility of such liability. Some jurisdictions do not allow the exclusion of certain warranties or the limitation or exclusion of certain liabilities and damages. Accordingly, some of the disclaimers and limitations set forth in the Terms may not apply to you. This limitation of liability shall apply to the fullest extent permitted by law. + +### 10. Arbitration and Class Action Waiver​ + +*Binding Arbitration*. Except for disputes in which either party seeks to bring an individual action in small claims court or seeks injunctive or other equitable relief for the alleged unlawful use of copyrights, trademarks, trade names, logos, trade secrets or patents, you and the Jupiter: (a) waive the right to have any and all disputes or claims arising from these Terms, your use or access to the Interface or any other disputes with the Jupiter *(collectively, "Disputes")* resolved in a court; and (b) waive any right to a jury trial. Instead, you and the Jupiter agree to arbitrate Disputes that are not resolved informally (as described below) through binding arbitration (i.e. the referral of a Dispute to one or more persons charged with reviewing the Dispute and making a final and binding determination to resolve it) instead of having the Dispute decided by a judge or jury in court). + +*No Class Arbitrations, Class Actions or Representative Actions*. You and Jupiter agree that any dispute is personal to you and Jupiter and that any such dispute will be resolved solely through individual arbitration and will not be brought as a class arbitration, class action, or any other type of representative proceeding. Neither party agrees to class arbitration or to an arbitration in which an individual attempts to resolve a dispute as a representative of another individual or group of individuals. Further, you and the Jupiter agree that a dispute cannot be brought as a class, or other types of representative action, whether within or outside of arbitration, or on behalf of any other individual or group of individuals. + +*Process*. You and the Jupiter agree that each will notify the other, in writing, of any Dispute within thirty (30) days of when it arises so that the parties can attempt, in good faith, to resolve the Dispute informally. Notice to Jupiter shall be provided by sending an email to [legal@jup.ag](mailto:legal@jup.ag). Your notice must include (1) your name, postal address, and email address; (2) a description of the nature or basis of the Dispute; and (3) the specific action that you are seeking. If you and the Jupiter cannot resolve the Dispute within thirty (30) days of the Jupiter receiving the notice, either you or Jupiter may, as appropriate pursuant to this Section 12, commence an arbitration proceeding. You and Jupiter agree that any arbitration or claim must be commenced or filed within one (1) year after the Dispute arose; otherwise, you and the Jupiter agree that the claim is permanently barred (which means that you will no longer have the right to assert a claim regarding the Dispute). + +*Choice of Law*. These Terms are governed by and will be construed under the laws of Panama, without regard to principles of conflict of laws, govern the Terms and any Dispute between you and us. Any Dispute under these Terms shall be finally settled by Binding Arbitration (as defined below). Any unresolved Dispute arising out of or in connection with these Terms shall be referred to and finally resolved by arbitration under the rules of the London Court of International Arbitration (LCIA), which rules are deemed to be incorporated by reference into this Section 12 to the extent they are consistent with it. Any dispute arising from or relating to the subject matter of these Terms shall be finally settled in London, United Kingdom, in English, in accordance with the LCIA Arbitration Rules. Unless we agree otherwise, the arbitrator may not consolidate your claims with those of any other party. Any judgment on the award rendered by the arbitrator may be entered in any court of competent jurisdiction, to the extent a court therein would be deemed to be a court of competent jurisdiction other than any court located in the United States of America. You further agree that the Interface shall be deemed to be based solely in Panama and that, although the Interface may be available in other jurisdictions, its availability does not give rise to general or specific personal jurisdiction in any forum outside Panama. + +*Authority of Arbitrator*. As limited by these Terms and applicable arbitration rules, the arbitrator will have: (a) the exclusive authority and jurisdiction to make all procedural and substantive decisions regarding a Dispute; and (b) the authority to grant any remedy that would otherwise be available in court. The arbitrator may only conduct an individual arbitration and may not consolidate more than one individual s claims, preside over any type of class or representative proceeding or preside over any proceeding involving more than one individual. + +### 11. Miscellaneous + +*Changes*. We may amend any portion of these Terms at any time by posting the revised version of these Terms with an updated revision date. The changes will become effective and shall be deemed accepted by you, the first time you use or access the Interface after the initial posting of the revised Terms and shall apply on a going-forward basis with respect to your use of the Interface including any transactions initiated after the posting date. In the event that you do not agree with any such modification, your sole and exclusive remedy are to terminate your use of the Interface. + +*Entire Agreement*. These Terms (and any additional terms, rules, and conditions of participation that may be posted on the website of Jupiter) including the Privacy Policy constitute the entire agreement with respect to the Interface and supersedes any prior agreements, oral or written. + +*Privacy Policy*. The Privacy Policy describes the ways we collect, use, store and disclose your personal information. You agree to the collection, use, storage, and disclosure of your data in accordance with the Privacy Policy. + +*Severability*. If any provision of these Terms shall be determined to be invalid or unenforceable under any rule, law, or regulation of any local, state, or federal government agency, such provision will be changed and interpreted to accomplish the objectives of the provision to the greatest extent possible under any applicable law and the validity or enforceability of any other provision of these Terms shall not be affected. If such construction is not possible, the invalid or unenforceable portion will be severed from these Terms but the rest of these Terms will remain in full force and effect. + +*Survival*. Upon termination of these Terms for any reason, all rights and obligations of the parties that by their nature are continuing will survive such termination. + +*English language*. Notwithstanding any other provision of these Terms, any translation of these Terms is provided for your convenience. The meanings of terms, conditions, and representations herein are subject to their definitions and interpretations in the English language. In the event of conflict or ambiguity between the English language version and translated versions of these terms, the English language version shall prevail. You acknowledge that you have read and understood the English language version of these Terms. + +If you have any questions, claims, complaints, or suggestions, please, contact us at `legal@jup.ag`. + diff --git a/mintlify-migration/static/files/audits/dao-offside.pdf b/mintlify-migration/static/files/audits/dao-offside.pdf new file mode 100644 index 00000000..76705192 Binary files /dev/null and b/mintlify-migration/static/files/audits/dao-offside.pdf differ diff --git a/mintlify-migration/static/files/audits/lend-liquidity-offside.pdf b/mintlify-migration/static/files/audits/lend-liquidity-offside.pdf new file mode 100644 index 00000000..a29b5338 Binary files /dev/null and b/mintlify-migration/static/files/audits/lend-liquidity-offside.pdf differ diff --git a/mintlify-migration/static/files/audits/lend-vault-offside.pdf b/mintlify-migration/static/files/audits/lend-vault-offside.pdf new file mode 100644 index 00000000..ea021511 Binary files /dev/null and b/mintlify-migration/static/files/audits/lend-vault-offside.pdf differ diff --git a/mintlify-migration/static/files/audits/lend-zenith.pdf b/mintlify-migration/static/files/audits/lend-zenith.pdf new file mode 100644 index 00000000..529aed3f Binary files /dev/null and b/mintlify-migration/static/files/audits/lend-zenith.pdf differ diff --git a/mintlify-migration/static/files/audits/limit-v2-offside.pdf b/mintlify-migration/static/files/audits/limit-v2-offside.pdf new file mode 100644 index 00000000..116ab3e2 Binary files /dev/null and b/mintlify-migration/static/files/audits/limit-v2-offside.pdf differ diff --git a/mintlify-migration/static/files/audits/lock-ottersec.pdf b/mintlify-migration/static/files/audits/lock-ottersec.pdf new file mode 100644 index 00000000..8e60d7bc Binary files /dev/null and b/mintlify-migration/static/files/audits/lock-ottersec.pdf differ diff --git a/mintlify-migration/static/files/audits/perpetual-offside.pdf b/mintlify-migration/static/files/audits/perpetual-offside.pdf new file mode 100644 index 00000000..bc377992 Binary files /dev/null and b/mintlify-migration/static/files/audits/perpetual-offside.pdf differ diff --git a/mintlify-migration/static/files/audits/perpetual-ottersec.pdf b/mintlify-migration/static/files/audits/perpetual-ottersec.pdf new file mode 100644 index 00000000..618f81d2 Binary files /dev/null and b/mintlify-migration/static/files/audits/perpetual-ottersec.pdf differ diff --git a/mintlify-migration/static/files/audits/perpetual-sec3.pdf b/mintlify-migration/static/files/audits/perpetual-sec3.pdf new file mode 100644 index 00000000..a94eb36b Binary files /dev/null and b/mintlify-migration/static/files/audits/perpetual-sec3.pdf differ diff --git a/mintlify-migration/static/files/audits/swap-v3-sec3.pdf b/mintlify-migration/static/files/audits/swap-v3-sec3.pdf new file mode 100644 index 00000000..bcb1bc6f Binary files /dev/null and b/mintlify-migration/static/files/audits/swap-v3-sec3.pdf differ diff --git a/mintlify-migration/static/files/audits/swap-v6-offside.pdf b/mintlify-migration/static/files/audits/swap-v6-offside.pdf new file mode 100644 index 00000000..1d22f9f8 Binary files /dev/null and b/mintlify-migration/static/files/audits/swap-v6-offside.pdf differ diff --git a/mintlify-migration/static/images/max_accounts_lifinity_v2.png b/mintlify-migration/static/images/max_accounts_lifinity_v2.png new file mode 100644 index 00000000..966797f4 Binary files /dev/null and b/mintlify-migration/static/images/max_accounts_lifinity_v2.png differ diff --git a/mintlify-migration/static/images/max_accounts_shared_accounts_route.png b/mintlify-migration/static/images/max_accounts_shared_accounts_route.png new file mode 100644 index 00000000..f803efda Binary files /dev/null and b/mintlify-migration/static/images/max_accounts_shared_accounts_route.png differ diff --git a/mintlify-migration/static/images/max_accounts_stabble.png b/mintlify-migration/static/images/max_accounts_stabble.png new file mode 100644 index 00000000..0f401086 Binary files /dev/null and b/mintlify-migration/static/images/max_accounts_stabble.png differ diff --git a/mintlify-migration/static/images/organic-score-diagram.png b/mintlify-migration/static/images/organic-score-diagram.png new file mode 100644 index 00000000..7b21bea2 Binary files /dev/null and b/mintlify-migration/static/images/organic-score-diagram.png differ diff --git a/mintlify-migration/static/images/plugin-playground.png b/mintlify-migration/static/images/plugin-playground.png new file mode 100644 index 00000000..981572ea Binary files /dev/null and b/mintlify-migration/static/images/plugin-playground.png differ diff --git a/mintlify-migration/static/images/rfq-flow.png b/mintlify-migration/static/images/rfq-flow.png new file mode 100644 index 00000000..ccf076e4 Binary files /dev/null and b/mintlify-migration/static/images/rfq-flow.png differ diff --git a/mintlify-migration/updates.mdx b/mintlify-migration/updates.mdx new file mode 100644 index 00000000..56abf736 --- /dev/null +++ b/mintlify-migration/updates.mdx @@ -0,0 +1,117 @@ +--- +title: "Updates" +description: "Product updates and announcements" +--- + + +**SUNSETTING LEGACY ENDPOINTS** + +We’re sunsetting several legacy endpoints over the next few weeks by gradually reducing access/rate limits. Please migrate to the latest versions ASAP. + + +**Action Required** +* Old Quote API V6: `http://quote-api.jup.ag/v6/` +* Old Tokens API: `http://tokens.jup.ag` +* Old Price API: `http://price.jup.ag` +* Token V1: `http://lite-api.jup.ag/tokens/v1` +* Price V2: `http://lite-api.jup.ag/price/v2` + + + + +**DEPRECATION OF PRICE API V2 AND TOKEN API V1** + +[**Price API upgrades to V3**](/docs/price-api/v3) to support more reliable and timely pricing data - derived by the last swap price (across all transactions) and a set of heuristics to ensure the accuracy of the price and eliminate any outliers. + +[**Token API upgrades to V2**](/docs/token-api/v2) to support an easier and reliable usage with new data addition such as [Organic Score](/docs/token-api/organic-score), more trading categories like toporganicscore, and more. + + +**Action Required** +* If you are using **Price API V2** and **Token API V1** +* Please migrate to their new versions respectively +* The older versions will be deprecated by 30 September 2025 + + + + +**API GATEWAY: IMPROVEMENTS** + +**Improved API Gateway!** + +For those that have been using the new hostnames at `api.jup.ag/**`, we have made improvements to the infrastructure + +* Reduced latency in responses and much more consistent now +* Infrastructure costs reduction (will help us look into reducing costs of the plans with higher rate limits) + +**Dual endpoint moving forward.** + +We will be deploying 2 different endpoints, 1 for free usage and 1 for plans with higher rate limits via [https://portal.jup.ag/](https://portal.jup.ag/) + +* `api.jup.ag` will serve only pro/paid users +* `lite-api.jup.ag` will be the endpoint to provide free usage + + +**Action Required (Free plan)** + +* Migrate to `lite-api.jup.ag` **BY 1 MAY 2025** +* The paths remain unchanged, only domain/hostname changes +* The same rate limits still apply +* You do not need an API Key to use the APIs for free +* If you are still on `api.jup.ag` without an API key, you will get a 401 response + +**NO Action Required (Pro plan)** + +* Your usage on `api.jup.ag` remains unchanged +* You can only use `api.jup.ag` with an API Key + + + + +**TRIGGER API: NEW HOSTNAME AND BREAKING CHANGES** + +* The `/limit/v2` path will be deprecated soon, please update your API calls to use the `/trigger/v1` path immediately. +* `/execute` endpoint is introduced. +* `/createOrder` endpoint now includes an additional `requestId` parameter to be used with the `/execute` endpoint. +* `/cancelOrder` endpoint only builds the transaction for 1 order, while `/cancelOrders` endpoint builds the transaction for multiple orders. +* The `tx` field in the responses are now `transaction` or `transactions`. +* `/getTriggerOrders` endpoint is introduces a new format to get either active or historical orders (based on the query parameters). +* [Please refer to the documentation for usage](/docs/trigger-api/create-order). + + +| Old Paths | New Paths | +| :--- | :--- | +| `/limit/v2/createOrder` | `/trigger/v1/createOrder` | +| `/limit/v2/executeOrder` | `/trigger/v1/executeOrder` | +| `/limit/v2/cancelOrder` | `/trigger/v1/cancelOrder` `/trigger/v1/cancelOrders` | +| `/limit/v2/openOrders` `/limit/v2/orderHistory` | `/trigger/v1/getTriggerOrders` | + + + + +**API GATEWAY: NEW HOSTNAMES AND API KEYS** + +* API will now be served through new hostnames. +* API will now be served through API keys. +* API Keys will be distributed via [https://portal.jup.ag](https://portal.jup.ag) (Refer to [API Setup](/docs/api-setup) to get started). +* Old hostnames will be slowly phased out. +* Old hostnames during this period will have reduced rate limits to facilitate migration to the new API. + +| Service Types | Description | +| :---------------------- | :-------------------------------------------------------- | +| Free with no API key | Decreased rate limits to only accommodate for testing. | +| Paid plan with API key | Fixed rate limits, self served through an API dashboard. | + + + +| Old Hostnames | New Hostnames | +| :------------------------------------------------- | :----------------------------------------------------- | +| `quote-api.jup.ag/v6/quote` | `lite-api.jup.ag/swap/v1/quote` | +| `quote-api.jup.ag/v6/swap` | `lite-api.jup.ag/swap/v1/swap` | +| `quote-api.jup.ag/v6/swap-instructions` | `lite-api.jup.ag/swap/v1/swap-instructions` | +| `quote-api.jup.ag/v6/program-id-to-label` | `lite-api.jup.ag/swap/v1/program-id-to-label` | +| `price.jup.ag/v6` | `lite-api.jup.ag/price/v2` | +| `tokens.jup.ag/token/:mint` | `lite-api.jup.ag/tokens/v1/token/:mint` | +| `tokens.jup.ag/tokens?tags=:tags` | `lite-api.jup.ag/tokens/v1/tagged/:tag` | +| `tokens.jup.ag/tokens_with_markets` | `lite-api.jup.ag/tokens/v1/mints/tradable` | + +