Skip to content

Commit 2dc1e5e

Browse files
committed
let user fill dcaconfig with ticker
1 parent c8de534 commit 2dc1e5e

File tree

3 files changed

+70
-54
lines changed

3 files changed

+70
-54
lines changed

src/constants/index.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ export const WALLET_PRIVATE_KEY =
1919
export const USER_PRIVATE_KEY = bs58.decode(WALLET_PRIVATE_KEY);
2020
export const USER_KEYPAIR = Keypair.fromSecretKey(USER_PRIVATE_KEY);
2121

22+
// mainnet-beta mints only
23+
// for list, see: https://solscan.io/tokens
24+
export const MINT_ADDRESSES: { [key: string]: string } = {
25+
"SOL": "So11111111111111111111111111111111111111112",
26+
"USDC": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
27+
"USDT": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
28+
};
29+
2230
// Interface
2331
export interface Token {
2432
chainId: number; // 101,
@@ -32,8 +40,8 @@ export interface Token {
3240

3341
export interface DcaConfig {
3442
name?: string;
35-
inputMint: string;
36-
outputMint: string;
43+
inputToken: string;
44+
outputToken: string;
3745
amount: number;
3846
slippage: number;
3947
cron: string;

src/dcaconfig-example.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,31 @@ import { DcaConfig } from './constants';
22

33
export const dcaconfig: DcaConfig[] = [
44
{
5-
name: "USDC to USDT",
6-
inputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC
7-
outputMint: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", // USDT
5+
inputToken: "USDC",
6+
outputToken: "USDT",
87
amount: 0.01,
98
slippage: 1,
10-
cron: "*/1 * * * *"
9+
cron: "*/* * * * *" // every minute
1110
},
1211
{
13-
name: "0.01 USDT -> USDC",
14-
inputMint: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", // USDT
15-
outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC
12+
inputToken: "USDT",
13+
outputToken: "USDC",
1614
amount: 0.01,
1715
slippage: 1,
18-
cron: "*/1 * * * *"
16+
cron: "*/2 * * * *" // every t2 minutes
17+
},
18+
{
19+
inputToken: "USDC",
20+
outputToken: "SOL",
21+
amount: 0.01,
22+
slippage: 1,
23+
cron: "*0 8 * * 0-6" // 8 AM everyday
24+
},
25+
{
26+
inputToken: "REKT", // invalid mint
27+
outputToken: "USDT",
28+
amount: 0.01,
29+
slippage: 1,
30+
cron: "* * * * *"
1931
},
2032
];

src/index.ts

Lines changed: 40 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { PublicKey, Connection } from "@solana/web3.js";
44
import * as cron from "node-cron";
55
import {
66
ENV,
7+
MINT_ADDRESSES,
78
SOLANA_RPC_ENDPOINT,
89
Token,
910
USER_KEYPAIR,
@@ -28,30 +29,20 @@ const jupiterSwap = async ({
2829
return null;
2930
}
3031

31-
console.log(
32-
`Getting routes for ${inputAmount} ${inputToken.symbol} -> ${outputToken.symbol}...`
33-
);
34-
const inputAmountInSmallestUnits = inputToken
35-
? Math.round(inputAmount * 10 ** inputToken.decimals)
36-
: 0;
37-
const routes =
38-
inputToken && outputToken
39-
? await jupiter.computeRoutes({
40-
inputMint: new PublicKey(inputToken.address),
41-
outputMint: new PublicKey(outputToken.address),
42-
inputAmount: inputAmountInSmallestUnits, // raw input amount of tokens
43-
slippage,
44-
forceFetch: true,
45-
})
46-
: null;
32+
const inputAmountInSmallestUnits = inputToken
33+
? Math.round(inputAmount * 10 ** inputToken.decimals)
34+
: 0;
35+
const routes = inputToken && outputToken
36+
? await jupiter.computeRoutes({
37+
inputMint: new PublicKey(inputToken.address),
38+
outputMint: new PublicKey(outputToken.address),
39+
inputAmount: inputAmountInSmallestUnits, // raw input amount of tokens
40+
slippage,
41+
forceFetch: true,
42+
})
43+
: null;
4744

4845
if (routes && routes.routesInfos) {
49-
console.log("Possible number of routes:", routes.routesInfos.length);
50-
console.log(
51-
"Best quote: ",
52-
routes.routesInfos[0].outAmount / 10 ** outputToken.decimals,
53-
`(${outputToken.symbol})`
54-
);
5546
// Prepare execute exchange
5647
const { execute } = await jupiter.exchange({
5748
routeInfo: routes!.routesInfos[0],
@@ -61,15 +52,14 @@ const jupiterSwap = async ({
6152
const swapResult: any = await execute();
6253
if (swapResult.error) {
6354
console.log(swapResult.error);
64-
return null;
6555
} else {
66-
console.log(`https://explorer.solana.com/tx/${swapResult.txid}`);
6756
console.log(
68-
`inputAmount=${swapResult.inputAmount} outputAmount=${swapResult.outputAmount}`
69-
);
57+
`${
58+
swapResult.inputAmount / (10 ** inputToken.decimals)} ${inputToken.symbol} -> ${swapResult.outputAmount / (10 ** inputToken.decimals)} ${outputToken.symbol} - https://solscan.io/tx/${swapResult.txid}`
59+
);
7060
}
7161
} else {
72-
return null;
62+
console.log("Error: Jupiter couldn't route.");
7363
}
7464
} catch (error) {
7565
throw error;
@@ -88,31 +78,37 @@ const main = async () => {
8878
// Fetch token list from Jupiter API
8979
const tokens: Token[] = await (await fetch(TOKEN_LIST_URL[ENV])).json();
9080

91-
const filteredJobs = dcaconfig.filter(dcajob => {
92-
return cron.validate(dcajob.cron);
81+
console.log("Validating dcaconfig. Jobs may not be included if the cron expression is invalid or chosen token strings do not exist in the MINT_ADDRESSES object.");
82+
const filteredJobs = dcaconfig.filter(job => {
83+
return (cron.validate(job.cron)
84+
&& job.inputToken in MINT_ADDRESSES
85+
&& job.outputToken in MINT_ADDRESSES
86+
);
9387
});
88+
89+
console.log("Scheduling the following jobs: ");
90+
filteredJobs.map(job => {
91+
console.log(`${job.amount} ${job.inputToken} -> ${job.outputToken}. cron: ${job.cron}`);
92+
});
93+
94+
const scheduledJobs = filteredJobs.map(job => {
95+
const inputToken = tokens.find((t) =>
96+
t.address == MINT_ADDRESSES[job.inputToken]
97+
);
98+
const outputToken = tokens.find((t) =>
99+
t.address == MINT_ADDRESSES[job.outputToken]
100+
);
94101

95-
console.log("Valid jobs to be scheduled: ", filteredJobs.map(job => {
96-
return job.name;
97-
}));
98-
99-
const scheduledJobs = filteredJobs.map(dcajob => {
100-
const inputToken = tokens.find((t) => t.address == dcajob.inputMint);
101-
const outputToken = tokens.find((t) => t.address == dcajob.outputMint);
102-
103-
return cron.schedule(dcajob.cron, async () => {
104-
console.log('SWAPPING @!!!!!');
105-
const routes = await jupiterSwap({
102+
return cron.schedule(job.cron, async () => {
103+
await jupiterSwap({
106104
jupiter,
107105
inputToken,
108106
outputToken,
109-
inputAmount: dcajob.amount,
110-
slippage: dcajob.slippage, // % slippage
107+
inputAmount: job.amount,
108+
slippage: job.slippage, // % slippage
111109
});
112110
});
113111
});
114-
115-
console.log('started!!!');
116112
} catch (error) {
117113
console.log({ error });
118114
}

0 commit comments

Comments
 (0)