Skip to main content

Build a Limit Order Bot With Javascript

Jupiter Limit Order provides users with the simplest way to place limit orders on Solana and receive tokens directly in your wallet when the order is filled!

limit

Create Limit Order

1. Install the libraries

Running this example requires a minimum of NodeJS 16. In your command line terminal, install the libraries.

npm i @solana/web3.js
npm i cross-fetch
npm i @project-serum/anchor
npm i bs58

2. Import from libraries and setup connection

Next you can copy the following code snippets to a javascript file jupiter-api-example.js. And when you are ready to run the code, just type: node jupiter-api-example.js

import { Connection, Keypair, VersionedTransaction } from "@solana/web3.js";
import fetch from "cross-fetch";
import { Wallet } from "@project-serum/anchor";
import bs58 from "bs58";

// It is recommended that you use your own RPC endpoint.
// This RPC endpoint is only for demonstration purposes so that this example will run.
const connection = new Connection(
"https://neat-hidden-sanctuary.solana-mainnet.discover.quiknode.pro/2af5315d336f9ae920028bbb90a73b724dc1bbed/"
);
info

Always make sure that you are using your own RPC endpoint. The RPC endpoint used by the connection object in the above example may not work anymore.

3. Setup your wallet

In this example, you can paste in your private key for testing purposes but this is not recommended for production applications.

const wallet = new Wallet(
Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY || ""))
);
const referral = new Wallet(
Keypair.fromSecretKey(bs58.decode(process.env.REFERRAL_PRIVATE_KEY || ""))
);

4. Get the serialized transactions to perform the swap

// Base key are used to generate a unique order id
const base = Keypair.generate();

// get serialized transactions
const transactions = await (
await fetch('https://jup.ag/api/limit/v1/createOrder', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
owner: wallet.publicKey.toString(),
inAmount: 100000, // 1000000 => 1 USDC if inputToken.address is USDC mint
outAmount: 100000,
inputMint: inputMint.toString(),
outputMint: outputMint.toString(),
expiredAt: null, // new Date().valueOf() / 1000,
base: base.publicKey.toString(),
// referralAccount and name are both optional
// provide both to get referral fees
// more details in the section below
referralAccount: referral.publicKey.toString(),
referralName: "Referral Name"
})
})
).json();

const { tx } = transactions;

expiredAt - Can be either null or Unix timestamp in seconds.

Execute transaction

5. Deserialize and sign the transaction

// deserialize the transaction
const transactionBuf = Buffer.from(tx, "base64");
var transaction = VersionedTransaction.deserialize(transactionBuf);

// sign the transaction using the required key
// for create order, wallet and base key are required.
transaction.sign([wallet.payer, base]);

6. Execute the transaction

// Execute the transaction
const rawTransaction = transaction.serialize();
const txid = await connection.sendRawTransaction(rawTransaction, {
skipPreflight: true,
maxRetries: 2,
});
await connection.confirmTransaction(txid);
console.log(`https://solscan.io/tx/${txid}`);

Query user open order, order history and trade history

GET

https://jup.ag/api/limit/v1/openOrders

Parameters

QueryTypeRequired
walletstringNo
inputMintstringNo
outputMintstringNo

Response

200: OKSuccess Response
[
{
"publicKey": "string",
"account": {
"maker": "string",
"inputMint": "string",
"outputMint": "string",
"oriInAmount": 0,
"oriOutAmount": 0,
"inAmount": 0,
"outAmount": 0,
"expiredAt": 0,
"base": "string"
}
}
]
default Error Response
{
"message": "string",
"code": "string",
"issues": [
{
"message": "string"
}
]
}
GET

https://jup.ag/api/limit/v1/orderHistory

Parameters

QueryTypeRequired
walletstringYes
cursornumberNo
skipnumberNo
takenumberNo

Response

200: OKSuccess Response
[
{
"id": 0,
"orderKey": "string",
"maker": "string",
"inputMint": "string",
"outputMint": "string",
"inAmount": 0,
"oriInAmount": 0,
"outAmount": 0,
"oriOutAmount": 0,
"expiredAt": 0,
"state": "Waiting",
"createTxid": "string",
"cancelTxid": "string",
"updatedAt": "2023-05-05T07:48:36.390Z",
"createdAt": "2023-05-05T07:48:36.390Z"
}
]
default Error Response
{
"message": "string",
"code": "string",
"issues": [
{
"message": "string"
}
]
}
GET

https://jup.ag/api/limit/v1/tradeHistory

Parameters

QueryTypeRequired
walletstringNo
inputMintstringNo
outputMintstringNo
cursornumberNo
skipnumberNo
takenumberNo

Response

200: OKSuccess Response
[
{
"id": 0,
"outAmount": 0,
"txid": "string",
"updatedAt": "2023-05-05T07:48:36.390Z",
"createdAt": "2023-05-05T07:48:36.390Z",
"order": {
"id": 0,
"orderKey": "string",
"inputMint": "string",
"outputMint": "string"
}
}
]
default Error Response
{
"message": "string",
"code": "string",
"issues": [
{
"message": "string"
}
]
}

Cancel order

POST

https://jup.ag/api/limit/v1/cancelOrders

Body

{
"owner": "string",
"feePayer": "string",
"orders": [
"string"
]
}

Response

200: OKSuccess Response
{ "tx": "string"}
default Error Response
{
"message": "string",
"code": "string",
"issues": [
{
"message": "string"
}
]
}

Deserialize, sign and execute the transaction from the response like here.

info

Due to the transaction size limit, the maximum cancellation order in a batch is 10.

Referral

Check out the referral program for Limit Order.