Skip to content

Commit e3f30b1

Browse files
Merge pull request #1 from cryptopavelsan/cryptopavelsan-jupv3
Cryptopavelsan jupv3
2 parents 437658d + 57433b1 commit e3f30b1

File tree

5 files changed

+62
-20
lines changed

5 files changed

+62
-20
lines changed

.env-example

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
RPC_ENDPOINT="https://ssc-dao.genesysgo.net"
2-
WALLET_PRIVATE_KEY=abc123def456
1+
RPC_ENDPOINT="https://solana.public-rpc.com"
2+
WALLET_PRIVATE_KEY="changethistotheprivatekey"
3+
TRADING_ENABLED=true
4+
WRAP_UNWRAP_SOL=false
5+
NODE_ENV=production
6+
DEBUG=false

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Jup DCA Bot
1+
# Jup V3 DCA Bot
22
This bot runs a simple dollar cost averaging strategy to buy assets over a period of time. It utilizes [Jupiter Aggregator](https://jup.ag), a swap aggregator on Solana.
33

44
This code was made to experiment and learn. It has not been thoroughly tested and is unaudited. Please use at your own risk!
@@ -24,4 +24,4 @@ yarn start
2424
```
2525
## Improvements
2626
- transaction retries. Not great to fail on swaps that may occur once-a-week or biweekly.
27-
- start and end dates.
27+
- start and end dates.

package.json

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
11
{
2-
"name": "jup-dca-bot",
3-
"version": "0.1.0",
2+
"name": "jupv3-dca-bot",
3+
"version": "0.2.0",
44
"description": "Dollar cost averaging bot on Solana",
55
"source": "src/index.ts",
66
"main": "src/index.ts",
77
"module": "dist/module.js",
88
"types": "dist/types.d.ts",
99
"scripts": {
10-
"start": "ts-node ./src/index.ts"
10+
"start": "ts-node ./src/index.ts",
11+
"trade": "ts-node ./src/index.ts"
1112
},
1213
"keywords": [],
1314
"author": "",
1415
"license": "ISC",
1516
"dependencies": {
16-
"@jup-ag/core": "^1.0.0-beta.16",
17+
"@jup-ag/core": "^3.0.0-beta.8",
1718
"@solana/wallet-adapter-base": "^0.7.1",
18-
"@solana/web3.js": "^1.36.0",
19+
"@solana/web3.js": "^1.66.1",
1920
"@types/bs58": "^4.0.1",
2021
"@types/isomorphic-fetch": "^0.0.35",
2122
"bs58": "^4.0.1",
2223
"cronstrue": "^1.125.0",
23-
"dotenv": "^10.0.0",
2424
"isomorphic-fetch": "^3.0.0",
25+
"jsbi": "^4.3.0",
2526
"node-cron": "^3.0.0",
26-
"node-fetch": "^3.1.0"
27+
"node-fetch": "^2.6.6"
28+
"circular-json": "^0.5.9"
2729
},
2830
"devDependencies": {
2931
"@types/node-cron": "^3.0.1",

src/constants/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import bs58 from "bs58";
33
import 'dotenv/config'
44

55
export const SOLANA_RPC_ENDPOINT: string = process.env.RPC_ENDPOINT!;
6+
export const WRAP_UNWRAP_SOL: boolean = process.env.WRAP_UNWRAP_SOL === undefined ? true : process.env.WRAP_UNWRAP_SOL === "true";
67

78
// Wallets
89
export const WALLET_PRIVATE_KEY =

src/index.ts

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
require("dotenv").config();
2+
13
import fetch from "isomorphic-fetch";
2-
import { Jupiter, TOKEN_LIST_URL } from "@jup-ag/core";
4+
import { Jupiter, TOKEN_LIST_URL, SwapMode } from "@jup-ag/core";
35
import { PublicKey, Connection } from "@solana/web3.js";
46
import * as cron from "node-cron";
57
import cronstrue from "cronstrue";
6-
import {Token, MINT_ADDRESSES, USER_KEYPAIR, SOLANA_RPC_ENDPOINT} from "./constants";
8+
import {Token, MINT_ADDRESSES, USER_KEYPAIR, SOLANA_RPC_ENDPOINT, WRAP_UNWRAP_SOL} from "./constants";
79
import { dcaconfig } from './dcaconfig'
10+
import JSBI from 'jsbi';
811

912
const jupiterSwap = async ({
1013
jupiter,
@@ -24,16 +27,22 @@ const jupiterSwap = async ({
2427
return null;
2528
}
2629

27-
const inputAmountInSmallestUnits = inputToken
28-
? Math.round(inputAmount * 10 ** inputToken.decimals)
29-
: 0;
30+
const inputAmountInSmallestUnits = inputToken
31+
? JSBI.BigInt(Math.round(inputAmount * 10 ** inputToken.decimals))
32+
: JSBI.BigInt(0);
33+
3034
const routes = inputToken && outputToken
3135
? await jupiter.computeRoutes({
3236
inputMint: new PublicKey(inputToken.address),
3337
outputMint: new PublicKey(outputToken.address),
34-
inputAmount: inputAmountInSmallestUnits, // raw input amount of tokens
35-
slippage,
38+
amount: inputAmountInSmallestUnits,
39+
slippageBps: slippage,
40+
feeBps: 0,
3641
forceFetch: true,
42+
onlyDirectRoutes: false,
43+
filterTopNResult: 2,
44+
enforceSingleTx: false,
45+
swapMode: SwapMode.ExactIn,
3746
})
3847
: null;
3948

@@ -54,7 +63,7 @@ const jupiterSwap = async ({
5463
);
5564
process.stdout.write(`${inputToken.symbol} -> `);
5665
process.stdout.write(
57-
`${swapResult.outputAmount / (10 ** inputToken.decimals)} `
66+
`${swapResult.outputAmount / (10 ** outputToken.decimals)} `
5867
);
5968
process.stdout.write(`${outputToken.symbol}: `);
6069
console.log(`https://solscan.io/tx/${swapResult.txid}`);
@@ -77,12 +86,38 @@ const main = async () => {
7786
connection,
7887
cluster: cluster,
7988
user: USER_KEYPAIR,
89+
restrictIntermediateTokens: true,
90+
shouldLoadSerumOpenOrders: false,
91+
wrapUnwrapSOL: WRAP_UNWRAP_SOL,
92+
ammsToExclude: {
93+
Lifinity: false,
94+
GooseFX: true,
95+
'Raydium CLMM': false,
96+
Serum: true,
97+
Cropper: false,
98+
Cykura: false,
99+
Invariant: false,
100+
'Marco Polo': false,
101+
Openbook: false,
102+
Balansol: false,
103+
DeltaFi: false,
104+
Meteora: false,
105+
Crema: true,
106+
Step: false,
107+
Saber: false,
108+
Sencha: false,
109+
Raydium: false,
110+
Mercurial: false,
111+
Aldrin: false,
112+
Dradex: true,
113+
'Lifinity V2': false,
114+
}
80115
});
81116

82117
// Fetch token list from Jupiter API
83118
const tokens: Token[] = await (await fetch(TOKEN_LIST_URL[cluster])).json();
84119

85-
console.log("Warning! dcaconfig entries may be excluded due to:");
120+
console.log("Warning! dcaconfig entries may be excluded if there are errors with the:");
86121
console.log("- invalid cron expression");
87122
console.log("- inputToken or outputToken does not exist in MINT_ADDRESSES");
88123
console.log("Validating dcaconfig.ts ...");

0 commit comments

Comments
 (0)