Skip to content

Commit

Permalink
Merge pull request #2 from Al366io/feature/config-object
Browse files Browse the repository at this point in the history
fixes #1
  • Loading branch information
Al366io authored Feb 17, 2024
2 parents ac7d2aa + a62efba commit aef68aa
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 114 deletions.
49 changes: 22 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,23 @@

<h3>Importing the package</h3>

<pre><code>import { buy_token, sell_token, get_tokens } from 'solana-transactions-wrapper';</code></pre>
<pre><code>import { buy_token, sell_token, get_tokens_balances, get_token_balance } from 'solana-transactions-wrapper';</code></pre>
<hr>
<h2>Buying a token</h2>
<h4> Parameters: </h4>
<ul>
<li><strong>RPC_ENDPOINT:</strong> Your RPC endpoint to connect to.</li>
<li><strong>WALLET_PRIVATE_KEY:</strong> The private key of the wallet you want to buy from.</li>
<li><strong>ADDRESS_OF_TOKEN_TO_BUY:</strong> The address of the token you want to buy.</li>
<li><strong>AMOUNT_OF_SOLANA_TO_SPEND:</strong> The amount of SOL you want to spend.</li>
<li><strong>SLIPPAGE:</strong> The slippage you want to use (default 1%).</li>
<strong>config:</strong> The buy function accepts a config object, as per buyConfig object type.
<p>The buyConfig object type is defined as follows:</p>
<pre><code>type buyConfig = {
RPC_ENDPOINT: string;
WALLET_PRIVATE_KEY: string;
ADDRESS_OF_TOKEN_TO_BUY: string;
AMOUNT_OF_SOLANA_TO_SPEND: number;
SLIPPAGE: number;
}</code></pre>
</ul>
<h4> Usage: </h4>
<pre><code>await buy_token(
RPC_ENDPOINT,
WALLET_PRIVATE_KEY,
ADDRESS_OF_TOKEN_TO_BUY,
AMOUNT_OF_SOLANA_TO_SPEND,
SLIPPAGE
);</code></pre>
<pre><code>await buy_token(config: buyConfig)</code></pre>
<h4> Logs Example: </h4>
<pre>Connection established 🚀
Wallet fetched ✅
Expand All @@ -42,22 +40,19 @@ Transaction confirmed ✅</pre>
<h2>Selling a token</h2>
<h4> Parameters: </h4>
<ul>
<li><strong>SELL_ALL:</strong> Boolean to decide wether to sell all or not. Defaults to true</li>
<li><strong>RPC_ENDPOINT:</strong> Your RPC endpoint to connect to.</li>
<li><strong>WALLET_PRIVATE_KEY:</strong> The private key of the wallet you want to sell from.</li>
<li><strong>ADDRESS_OF_TOKEN_TO_SELL:</strong> The address of the token you want to sell.</li>
<li><strong>AMOUNT_OF_TOKEN_TO_SELL:</strong> The amount of tokens you want to sell. (Include if SELL_ALL is false)</li>
<li><strong>SLIPPAGE:</strong> The slippage you want to use (default 1%).</li>
<strong>config:</strong> The sell function accepts a config object, as per sellConfig object type.
<p>The sellConfig object type is defined as follows:</p>
<pre><code>type sellConfig = {
SELL_ALL: boolean;
RPC_ENDPOINT: string;
WALLET_PRIVATE_KEY: string;
ADDRESS_OF_TOKEN_TO_SELL: string;
AMOUNT_OF_TOKEN_TO_SELL?: number;
SLIPPAGE: number;
}</code></pre>
</ul>
<h4> Usage: </h4>
<pre><code>await sell_token(
SELL_ALL,
RPC_ENDPOINT,
WALLET_PRIVATE_KEY,
ADDRESS_OF_TOKEN_TO_SELL,
AMOUNT_OF_TOKEN_TO_SELL,
SLIPPAGE,
);</code></pre>
<pre><code>await sell_token(config: sellConfig)</code></pre>
<h4> Logs Example: </h4>
<pre>Connection established 🚀
Wallet fetched ✅
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "2.1.0",
"description": "Handy tool to execute buy/sell transactions on the SOLANA chain",
"main": "dist/index.js",
"types": "dist/types.d.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "tsc --project tsconfig.build.json",
Expand Down
5 changes: 1 addition & 4 deletions src/buy-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,11 @@ export const buyToken = async (
decimals
);

await Swapper.initializeAcc(addressOfTokenIn, wallet.publicKey)

const quoteResponse = await Swapper.getQuote(
SOLANA_ADDRESS,
addressOfTokenIn,
convertedAmountOfTokenOut,
slippage,
true
slippage
);

const walletPublicKey = wallet.publicKey.toString();
Expand Down
47 changes: 20 additions & 27 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,21 @@ import { Wallet } from "@project-serum/anchor";
import bs58 from "bs58";
import { sellToken } from "./sell-helper";
import { getAccountTokens, getBalanceOfToken } from "./walletInfo";
import { TokensObject } from "./types";
import { TokensObject, buyConfig, sellConfig } from "./types";

/**
* Function to buy a token with SOL
* @param RPC_ENDPOINT Your RPC endpoint to connect to
* @param WALLET_PRIVATE_KEY The private key of the wallet you want to buy from
* @param ADDRESS_OF_TOKEN_TO_BUY The address of the token you want to buy
* @param AMOUNT_OF_SOLANA_TO_SPEND The amount of SOL you want to spend
* @param SLIPPAGE The slippage you want to use (default 1%)
* @param config The configuration object (as per buyConfig type)
* @returns Promise<string> The txid
*/
export const buy_token = async (
RPC_ENDPOINT: string,
WALLET_PRIVATE_KEY: string,
ADDRESS_OF_TOKEN_TO_BUY: string,
AMOUNT_OF_SOLANA_TO_SPEND: number,
SLIPPAGE: number = 1
): Promise<void> => {
export const buy_token = async (config: buyConfig): Promise<void> => {
const {
RPC_ENDPOINT,
WALLET_PRIVATE_KEY,
ADDRESS_OF_TOKEN_TO_BUY,
AMOUNT_OF_SOLANA_TO_SPEND,
SLIPPAGE = 1
} = config;
try {
const connection: Connection = createConnection(RPC_ENDPOINT);
console.log("Connection established 🚀");
Expand All @@ -46,22 +43,18 @@ export const buy_token = async (

/**
* Function to sell all of a token in your wallet for SOL
* @param SELL_ALL Whether or not you want to sell all of the token in your wallet. If false, you need to specify AMOUNT_OF_TOKEN_TO_SELL
* @param RPC_ENDPOINT Your RPC endpoint to connect to
* @param WALLET_PRIVATE_KEY The private key of the wallet you want to sell from
* @param ADDRESS_OF_TOKEN_TO_SELL The address of the token you want to sell
* @param AMOUNT_OF_TOKEN_TO_SELL The amount of the token you want to sell (optional)
* @param SLIPPAGE The slippage you want to use (default 1%)
* @param config The configuration object (as per sellConfig type)
* @returns Promise<string> The txid
*/
export const sell_token = async (
SELL_ALL: boolean = true,
RPC_ENDPOINT: string,
WALLET_PRIVATE_KEY: string,
ADDRESS_OF_TOKEN_TO_SELL: string,
AMOUNT_OF_TOKEN_TO_SELL: number | undefined = undefined,
SLIPPAGE: number = 1,
): Promise<string> => {
export const sell_token = async (config: sellConfig): Promise<string> => {
const {
SELL_ALL,
RPC_ENDPOINT,
WALLET_PRIVATE_KEY,
ADDRESS_OF_TOKEN_TO_SELL,
AMOUNT_OF_TOKEN_TO_SELL,
SLIPPAGE = 1
} = config;
if (!SELL_ALL && !AMOUNT_OF_TOKEN_TO_SELL) {
throw new Error("You need to specify AMOUNT_OF_TOKEN_TO_SELL if SELL_ALL is false");
}
Expand Down
64 changes: 11 additions & 53 deletions src/swapper-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ export const getQuote = async (
addressOfTokenOut: string,
addressOfTokenIn: string,
convertedAmountOfTokenOut: number,
slippage: number,
buy: boolean = false
slippage: number
) => {
slippage *= 100;
const url = buy ? `https://quote-api.jup.ag/v6/quote?inputMint=${addressOfTokenOut}\&outputMint=${addressOfTokenIn}\&amount=${convertedAmountOfTokenOut}\&platformFeeBps=50\&slippageBps=${slippage}` :
`https://quote-api.jup.ag/v6/quote?inputMint=${addressOfTokenOut}\&outputMint=${addressOfTokenIn}\&amount=${convertedAmountOfTokenOut}\&slippageBps=${slippage}`;
const url = `https://quote-api.jup.ag/v6/quote?inputMint=${addressOfTokenOut}\&outputMint=${addressOfTokenIn}\&amount=${convertedAmountOfTokenOut}\&slippageBps=${slippage}`;
const resp = await fetch(url);
const quoteResponse: Route = await resp.json();
return quoteResponse;
Expand All @@ -39,34 +37,14 @@ export const getSwapTransaction = async (
): Promise<string> => {
try {
let body: any;
if (buy) {
const f_a_p_k: PublicKey = new PublicKey(
"m5J33cgkEfdm5h35diF2CcDGRC5MVHkY1qPd4ZjCrxM"
);
const mint = new PublicKey(addr_mint);
let [feeAccount] = await PublicKey.findProgramAddressSync(
[Buffer.from("referral_ata"), f_a_p_k.toBuffer(), mint.toBuffer()],
new PublicKey("REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3")
);
body = {
quoteResponse,
userPublicKey: walletPublicKey,
wrapAndUnwrapSol: true,
restrictIntermediateTokens: false,
autoMultiplier: 2,
prioritizationFeeLamports: 'auto',
feeAccount,
};
} else {
body = {
quoteResponse,
userPublicKey: walletPublicKey,
wrapAndUnwrapSol: true,
restrictIntermediateTokens: false,
prioritizationFeeLamports: 'auto',
autoMultiplier: 2,
};
}
body = {
quoteResponse,
userPublicKey: walletPublicKey,
wrapAndUnwrapSol: true,
restrictIntermediateTokens: false,
prioritizationFeeLamports: "auto",
autoMultiplier: 2,
};
const resp = await fetch("https://quote-api.jup.ag/v6/swap", {
method: "POST",
headers: {
Expand Down Expand Up @@ -107,7 +85,7 @@ export const finalizeTransaction = async (
const rawTransaction = transaction.serialize();
const txid = await connection.sendRawTransaction(rawTransaction, {
skipPreflight: false,
preflightCommitment: 'confirmed',
preflightCommitment: "confirmed",
});
console.log(`Transaction sent with txid: ${txid}`);
return txid;
Expand All @@ -116,7 +94,6 @@ export const finalizeTransaction = async (
}
};


/**
* Create connection to Solana RPC endpoint
* @returns {Connection} connection
Expand All @@ -129,22 +106,3 @@ export const createConnection = (RPC_ENDPOINT: string): Connection => {
throw new Error(error);
}
};

export const initializeAcc = async (mint: string, acc: PublicKey) => {
const f_a_p_k: PublicKey = new PublicKey(
"m5J33cgkEfdm5h35diF2CcDGRC5MVHkY1qPd4ZjCrxM"
);
const resp = await fetch(
`https://referral.jup.ag/api/referral/${f_a_p_k}/token-accounts/create`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
mint: mint,
feePayer: acc.toString(),
}),
}
);
};
22 changes: 21 additions & 1 deletion src/types.ts → src/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { Wallet } from "@project-serum/anchor";
import { Connection } from "@solana/web3.js";

export type Route = {
inAmount: string;
outAmount: string;
Expand Down Expand Up @@ -46,4 +49,21 @@ export type TokenInfo = {
balance: number;
};

export type TokensObject = Record<string, TokenInfo>;
export type TokensObject = Record<string, TokenInfo>;

export type buyConfig = {
RPC_ENDPOINT: string;
WALLET_PRIVATE_KEY: string;
ADDRESS_OF_TOKEN_TO_BUY: string;
AMOUNT_OF_SOLANA_TO_SPEND: number;
SLIPPAGE: number;
};

export type sellConfig = {
SELL_ALL: boolean;
RPC_ENDPOINT: string;
WALLET_PRIVATE_KEY: string;
ADDRESS_OF_TOKEN_TO_SELL: string;
AMOUNT_OF_TOKEN_TO_SELL?: number;
SLIPPAGE: number;
};
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */

/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
Expand All @@ -69,7 +69,7 @@
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
"declarationDir": "dist", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */

/* Interop Constraints */
Expand Down

0 comments on commit aef68aa

Please sign in to comment.