forked from firefly-sol/jupiter-arb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
161 lines (144 loc) · 4.29 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
require('dotenv').config();
import {Connection, Keypair, PublicKey} from '@solana/web3.js';
import fetch from 'isomorphic-fetch';
import bs58 from 'bs58';
import {Jupiter, RouteInfo, TOKEN_LIST_URL} from '@jup-ag/core';
const RPC_ENDPOINT = 'https://solana-api.projectserum.com';
// Interface
interface Token {
chainId: number; // 101,
address: string; // '8f9s1sUmzUbVZMoMh6bufMueYH1u4BJSM57RCEvuVmFp',
symbol: string; // 'TRUE',
name: string; // 'TrueSight',
decimals: number; // 9,
logoURI: string; // 'https://i.ibb.co/pKTWrwP/true.jpg',
tags: string[]; // [ 'utility-token', 'capital-token' ]
}
const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
const secretKey = process.env.SECRET_KEY!;
const decodedSecretKey = bs58.decode(secretKey);
const kp = Keypair.fromSecretKey(decodedSecretKey);
const getRoutes = async ({
jupiter,
inputToken,
outputToken,
inputAmount,
slippage,
}: {
jupiter: Jupiter;
inputToken?: Token;
outputToken?: Token;
inputAmount: number;
slippage: number;
}) => {
try {
if (!inputToken || !outputToken) {
return null;
}
console.log(
`Getting routes for ${inputAmount} ${inputToken.symbol} -> ${outputToken.symbol}...`,
);
const inputAmountInSmallestUnits = inputToken
? Math.round(inputAmount * 10 ** inputToken.decimals)
: 0;
const routes =
inputToken && outputToken
? await jupiter.computeRoutes({
inputMint: new PublicKey(inputToken.address),
outputMint: new PublicKey(outputToken.address),
inputAmount: inputAmountInSmallestUnits, // raw input amount of tokens
slippage,
forceFetch: true,
})
: null;
if (routes && routes.routesInfos) {
console.log('Possible number of routes:', routes.routesInfos.length);
console.log(
'Best quote: ',
routes.routesInfos[0].outAmount / 10 ** outputToken.decimals,
`(${outputToken.symbol})`,
);
return routes;
} else {
return null;
}
} catch (error) {
throw error;
}
};
const executeSwap = async ({
jupiter,
routeInfo,
}: {
jupiter: Jupiter;
routeInfo: RouteInfo;
}) => {
try {
// Prepare execute exchange
const {execute} = await jupiter.exchange({
routeInfo,
});
// Execute swap
const swapResult: any = await execute(); // Force any to ignore TS misidentifying SwapResult type
if (swapResult.error) {
console.log(swapResult.error);
} else {
console.log(`https://explorer.solana.com/tx/${swapResult.txid}`);
console.log(
`inputAddress=${swapResult.inputAddress.toString()} outputAddress=${swapResult.outputAddress.toString()}`,
);
console.log(
`inputAmount=${swapResult.inputAmount} outputAmount=${swapResult.outputAmount}`,
);
}
} catch (error) {
throw error;
}
};
async function getBestRouteToSelf(
amount: number,
token: Token,
jupiter: Jupiter,
) {
const routes = await getRoutes({
jupiter,
inputToken: token, // input token
outputToken: token, // output token
inputAmount: amount, // 1 unit in UI
slippage: 1, // 1% slippage
});
return routes?.routesInfos[0];
}
async function tryToExecuteSwap(
amount: number,
token: Token,
jupiter: Jupiter,
) {
const bestRoute = await getBestRouteToSelf(amount, token, jupiter);
const bestOutAmountWithSlippage = bestRoute?.outAmountWithSlippage ?? 0;
const inputUSDCWithDecimals = amount * 10 ** 6;
console.log('bestRoute', bestRoute);
if (bestOutAmountWithSlippage > inputUSDCWithDecimals) {
await executeSwap({jupiter, routeInfo: bestRoute!});
}
}
const main = async () => {
const connection = new Connection(RPC_ENDPOINT); // Setup Solana RPC connection
const tokens: Token[] = await (
await fetch(TOKEN_LIST_URL['mainnet-beta'])
).json();
// Load Jupiter
const jupiter = await Jupiter.load({
connection,
cluster: 'mainnet-beta',
user: kp, // or public key
});
const usdcToken = tokens.find((t) => t.address === USDC_MINT)!;
const amount = 1000; // arbitrary small amount
console.log('running');
for (let i = 0; i < 1000; ++i) {
tryToExecuteSwap(amount, usdcToken, jupiter);
await new Promise((resolve) => setTimeout(resolve, 10000)); // Timed in miliseconds so this is ten seconds
}
};
main();