diff --git a/.gitignore b/.gitignore index 0125458..e44913f 100644 --- a/.gitignore +++ b/.gitignore @@ -116,3 +116,5 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* + +.idea/ diff --git a/run_swap.py b/run_swap.py new file mode 100644 index 0000000..efe56ff --- /dev/null +++ b/run_swap.py @@ -0,0 +1,31 @@ +PRIVATE = 'https://go.getblock.io/d287cc6e8eec4374891f369c333ca7a2' +MAIN = 'https://api.mainnet-beta.solana.com' + +import subprocess +import os, sys +from src.conf.tokens import * + +def Buy(base_token=SOL, token_address=USDC, amount=0.01, fee=0.0005, slippageRate=5, liquideFile='trimmed_mainnet.json', + useVersionedTransaction=True, fixSIde='in', executeSwap=False, maxRetries=3): + + env = os.environ.copy() + env['TokenAAddress'] = base_token + env['TokenAAmount'] = str(amount) + env['TokenBAddress'] = token_address + env['LiquidityFile'] = liquideFile + env['Fee'] = str(fee) + env['UseVersionedTransaction'] = str(useVersionedTransaction) + env['FIXED_SIDE'] = fixSIde + env['ExecuteSwap'] = str(executeSwap) + env['MaxRetries'] = str(maxRetries) + + # 执行命令 + cmd = ['yarn', 'swap'] + result = subprocess.run(cmd, env=env) + + print(result.stdout) + print(result.stderr) + + +if __name__ == '__main__': + Buy(executeSwap=True) diff --git a/src/RaydiumSwap.ts b/src/RaydiumSwap.ts index 3625be1..310b2a7 100644 --- a/src/RaydiumSwap.ts +++ b/src/RaydiumSwap.ts @@ -105,10 +105,11 @@ class RaydiumSwap { poolKeys: LiquidityPoolKeys, maxLamports: number = 100000, useVersionedTransaction = true, - fixedSide: 'in' | 'out' = 'in' + fixedSide: 'in' | 'out' = 'in', + slippageRate: number = 5 ): Promise { const directionIn = poolKeys.quoteMint.toString() == toToken - const { minAmountOut, amountIn } = await this.calcAmountOut(poolKeys, amount, directionIn) + const { minAmountOut, amountIn } = await this.calcAmountOut(poolKeys, amount, directionIn, slippageRate) console.log({ minAmountOut, amountIn }); const userTokenAccounts = await this.getOwnerTokenAccounts() const swapTransaction = await Liquidity.makeSwapInstructionSimple({ @@ -238,7 +239,7 @@ class RaydiumSwap { * @param {boolean} swapInDirection - The direction of the swap (true for in, false for out). * @returns {Promise} The swap calculation result. */ - async calcAmountOut(poolKeys: LiquidityPoolKeys, rawAmountIn: number, swapInDirection: boolean) { + async calcAmountOut(poolKeys: LiquidityPoolKeys, rawAmountIn: number, swapInDirection: boolean, slippageRate: number) { const poolInfo = await Liquidity.fetchInfo({ connection: this.connection, poolKeys }) let currencyInMint = poolKeys.baseMint @@ -256,7 +257,7 @@ class RaydiumSwap { const currencyIn = new Token(TOKEN_PROGRAM_ID, currencyInMint, currencyInDecimals) const amountIn = new TokenAmount(currencyIn, rawAmountIn, false) const currencyOut = new Token(TOKEN_PROGRAM_ID, currencyOutMint, currencyOutDecimals) - const slippage = new Percent(5, 100) // 5% slippage + const slippage = new Percent(slippageRate, 100) // 5% slippage const { amountOut, minAmountOut, currentPrice, executionPrice, priceImpact, fee } = Liquidity.computeAmountOut({ poolKeys, diff --git a/src/conf/tokens.py b/src/conf/tokens.py new file mode 100644 index 0000000..4b3264e --- /dev/null +++ b/src/conf/tokens.py @@ -0,0 +1,3 @@ +USDC = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' +USDT = 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB' +SOL = 'So11111111111111111111111111111111111111112' \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 41bbbd4..cb83ada 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,6 @@ import RaydiumSwap from './RaydiumSwap'; -import { Transaction, VersionedTransaction } from '@solana/web3.js'; +import { Transaction, VersionedTransaction, LAMPORTS_PER_SOL } from '@solana/web3.js'; import 'dotenv/config'; -import { swapConfig } from './swapConfig'; // Import the configuration /** * Performs a token swap on the Raydium protocol. @@ -11,20 +10,20 @@ const swap = async () => { /** * The RaydiumSwap instance for handling swaps. */ - const raydiumSwap = new RaydiumSwap(process.env.RPC_URL, process.env.WALLET_PRIVATE_KEY); + const raydiumSwap = new RaydiumSwap(process.env.PrivateURL, process.env.SubPraviteKey); console.log(`Raydium swap initialized`); - console.log(`Swapping ${swapConfig.tokenAAmount} of ${swapConfig.tokenAAddress} for ${swapConfig.tokenBAddress}...`) + console.log(`Swapping ${process.env.TokenAAmount} of ${process.env.TokenAAddress} for ${process.env.TokenBAddress}...`) /** * Load pool keys from the Raydium API to enable finding pool information. */ - await raydiumSwap.loadPoolKeys(swapConfig.liquidityFile); + await raydiumSwap.loadPoolKeys(process.env.LiquidityFile); console.log(`Loaded pool keys`); /** * Find pool information for the given token pair. */ - const poolInfo = raydiumSwap.findPoolInfoForTokens(swapConfig.tokenAAddress, swapConfig.tokenBAddress); + const poolInfo = raydiumSwap.findPoolInfoForTokens(process.env.TokenAAddress, process.env.TokenBAddress); if (!poolInfo) { console.error('Pool info not found'); return 'Pool info not found'; @@ -35,25 +34,35 @@ const swap = async () => { /** * Prepare the swap transaction with the given parameters. */ + + const tokenAAmount: number = Number(process.env.TokenAAmount); + const useVersionedTransaction: boolean = Boolean(process.env.UseVersionedTransaction); + const fixedSide = process.env.FIXED_SIDE === 'in' ? 'in' : 'out'; + const slippageRate: number = Number(process.env.SlippageRate) + const fee: number = Number(process.env.Fee) + const tx = await raydiumSwap.getSwapTransaction( - swapConfig.tokenBAddress, - swapConfig.tokenAAmount, + process.env.TokenBAddress, + tokenAAmount, poolInfo, - swapConfig.maxLamports, - swapConfig.useVersionedTransaction, - swapConfig.direction + fee * LAMPORTS_PER_SOL, + useVersionedTransaction, + fixedSide, + slippageRate ); + const executeSwap: boolean = Boolean(process.env.ExecuteSwap); + const maxRetries: number = Number(process.env.MaxRetries); /** * Depending on the configuration, execute or simulate the swap. */ - if (swapConfig.executeSwap) { + if (executeSwap) { /** * Send the transaction to the network and log the transaction ID. */ - const txid = swapConfig.useVersionedTransaction - ? await raydiumSwap.sendVersionedTransaction(tx as VersionedTransaction, swapConfig.maxRetries) - : await raydiumSwap.sendLegacyTransaction(tx as Transaction, swapConfig.maxRetries); + const txid = useVersionedTransaction + ? await raydiumSwap.sendVersionedTransaction(tx as VersionedTransaction, maxRetries) + : await raydiumSwap.sendLegacyTransaction(tx as Transaction, maxRetries); console.log(`https://solscan.io/tx/${txid}`); @@ -61,7 +70,7 @@ const swap = async () => { /** * Simulate the transaction and log the result. */ - const simRes = swapConfig.useVersionedTransaction + const simRes = useVersionedTransaction ? await raydiumSwap.simulateVersionedTransaction(tx as VersionedTransaction) : await raydiumSwap.simulateLegacyTransaction(tx as Transaction);