sol-ihor-lab 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -0
- package/lib/cjs/bundle.d.ts +4 -0
- package/lib/cjs/bundle.js +102 -0
- package/lib/cjs/buy_token.d.ts +5 -0
- package/lib/cjs/buy_token.js +59 -0
- package/lib/cjs/create_open_market.d.ts +4 -0
- package/lib/cjs/create_open_market.js +340 -0
- package/lib/cjs/create_pool.d.ts +4 -0
- package/lib/cjs/create_pool.js +107 -0
- package/lib/cjs/create_token.d.ts +4 -0
- package/lib/cjs/create_token.js +164 -0
- package/lib/cjs/errors.d.ts +18 -0
- package/lib/cjs/errors.js +44 -0
- package/lib/cjs/global.d.ts +62 -0
- package/lib/cjs/global.js +107 -0
- package/lib/cjs/index.d.ts +17 -0
- package/lib/cjs/index.js +33 -0
- package/lib/cjs/instructions/build-instruction.d.ts +8 -0
- package/lib/cjs/instructions/build-instruction.js +66 -0
- package/lib/cjs/instructions/buy-instruction.d.ts +3 -0
- package/lib/cjs/instructions/buy-instruction.js +44 -0
- package/lib/cjs/instructions/cache-alt-instruction.d.ts +4 -0
- package/lib/cjs/instructions/cache-alt-instruction.js +41 -0
- package/lib/cjs/instructions/createATA-instruction.d.ts +3 -0
- package/lib/cjs/instructions/createATA-instruction.js +10 -0
- package/lib/cjs/instructions/createpool-instruction.d.ts +4 -0
- package/lib/cjs/instructions/createpool-instruction.js +58 -0
- package/lib/cjs/instructions/sol-transfer-instruction.d.ts +3 -0
- package/lib/cjs/instructions/sol-transfer-instruction.js +12 -0
- package/lib/cjs/instructions/transfer-instruction.d.ts +3 -0
- package/lib/cjs/instructions/transfer-instruction.js +9 -0
- package/lib/cjs/pool/pool-manager.d.ts +42 -0
- package/lib/cjs/pool/pool-manager.js +70 -0
- package/lib/cjs/pool_manager.d.ts +25 -0
- package/lib/cjs/pool_manager.js +127 -0
- package/lib/cjs/sell_token.d.ts +5 -0
- package/lib/cjs/sell_token.js +59 -0
- package/lib/cjs/transaction/bundle.d.ts +4 -0
- package/lib/cjs/transaction/bundle.js +97 -0
- package/lib/cjs/transaction/execute-rpc.d.ts +5 -0
- package/lib/cjs/transaction/execute-rpc.js +41 -0
- package/lib/cjs/transaction/sign-tx.d.ts +2 -0
- package/lib/cjs/transaction/sign-tx.js +7 -0
- package/lib/cjs/transaction/transaction-exectue.d.ts +30 -0
- package/lib/cjs/transaction/transaction-exectue.js +119 -0
- package/lib/cjs/transaction-helper/check_transaction.d.ts +3 -0
- package/lib/cjs/transaction-helper/check_transaction.js +43 -0
- package/lib/cjs/transaction-helper/transaction.d.ts +7 -0
- package/lib/cjs/transaction-helper/transaction.js +75 -0
- package/lib/cjs/upload-metadata/upload-metaplex.d.ts +3 -0
- package/lib/cjs/upload-metadata/upload-metaplex.js +48 -0
- package/lib/cjs/upload-metadata/upload-nftstorage.d.ts +0 -0
- package/lib/cjs/upload-metadata/upload-nftstorage.js +1 -0
- package/lib/cjs/upload-metadata/upload-pinata.d.ts +1 -0
- package/lib/cjs/upload-metadata/upload-pinata.js +17 -0
- package/lib/cjs/upload-metadata/utility.d.ts +1 -0
- package/lib/cjs/upload-metadata/utility.js +28 -0
- package/lib/cjs/utility.d.ts +33 -0
- package/lib/cjs/utility.js +129 -0
- package/lib/cjs/utils/budget.d.ts +9 -0
- package/lib/cjs/utils/budget.js +83 -0
- package/lib/cjs/utils/error-helper.d.ts +7 -0
- package/lib/cjs/utils/error-helper.js +15 -0
- package/lib/cjs/utils/get-balance.d.ts +11 -0
- package/lib/cjs/utils/get-balance.js +52 -0
- package/lib/cjs/utils/util.d.ts +27 -0
- package/lib/cjs/utils/util.js +346 -0
- package/lib/cjs/validation_check.d.ts +3 -0
- package/lib/cjs/validation_check.js +26 -0
- package/lib/esm/bundle.d.ts +4 -0
- package/lib/esm/bundle.js +75 -0
- package/lib/esm/buy_token.d.ts +5 -0
- package/lib/esm/buy_token.js +55 -0
- package/lib/esm/create_open_market.d.ts +4 -0
- package/lib/esm/create_open_market.js +310 -0
- package/lib/esm/create_pool.d.ts +4 -0
- package/lib/esm/create_pool.js +80 -0
- package/lib/esm/create_token.d.ts +4 -0
- package/lib/esm/create_token.js +137 -0
- package/lib/esm/errors.d.ts +18 -0
- package/lib/esm/errors.js +35 -0
- package/lib/esm/global.d.ts +62 -0
- package/lib/esm/global.js +103 -0
- package/lib/esm/index.d.ts +17 -0
- package/lib/esm/index.js +17 -0
- package/lib/esm/instructions/build-instruction.d.ts +8 -0
- package/lib/esm/instructions/build-instruction.js +61 -0
- package/lib/esm/instructions/buy-instruction.d.ts +3 -0
- package/lib/esm/instructions/buy-instruction.js +40 -0
- package/lib/esm/instructions/cache-alt-instruction.d.ts +4 -0
- package/lib/esm/instructions/cache-alt-instruction.js +36 -0
- package/lib/esm/instructions/createATA-instruction.d.ts +3 -0
- package/lib/esm/instructions/createATA-instruction.js +6 -0
- package/lib/esm/instructions/createpool-instruction.d.ts +4 -0
- package/lib/esm/instructions/createpool-instruction.js +52 -0
- package/lib/esm/instructions/sol-transfer-instruction.d.ts +3 -0
- package/lib/esm/instructions/sol-transfer-instruction.js +8 -0
- package/lib/esm/instructions/transfer-instruction.d.ts +3 -0
- package/lib/esm/instructions/transfer-instruction.js +5 -0
- package/lib/esm/pool/pool-manager.d.ts +42 -0
- package/lib/esm/pool/pool-manager.js +63 -0
- package/lib/esm/pool_manager.d.ts +25 -0
- package/lib/esm/pool_manager.js +123 -0
- package/lib/esm/sell_token.d.ts +5 -0
- package/lib/esm/sell_token.js +55 -0
- package/lib/esm/transaction/bundle.d.ts +4 -0
- package/lib/esm/transaction/bundle.js +90 -0
- package/lib/esm/transaction/execute-rpc.d.ts +5 -0
- package/lib/esm/transaction/execute-rpc.js +36 -0
- package/lib/esm/transaction/sign-tx.d.ts +2 -0
- package/lib/esm/transaction/sign-tx.js +3 -0
- package/lib/esm/transaction/transaction-exectue.d.ts +30 -0
- package/lib/esm/transaction/transaction-exectue.js +115 -0
- package/lib/esm/transaction-helper/check_transaction.d.ts +3 -0
- package/lib/esm/transaction-helper/check_transaction.js +16 -0
- package/lib/esm/transaction-helper/transaction.d.ts +7 -0
- package/lib/esm/transaction-helper/transaction.js +68 -0
- package/lib/esm/upload-metadata/upload-metaplex.d.ts +3 -0
- package/lib/esm/upload-metadata/upload-metaplex.js +43 -0
- package/lib/esm/upload-metadata/upload-nftstorage.d.ts +0 -0
- package/lib/esm/upload-metadata/upload-nftstorage.js +1 -0
- package/lib/esm/upload-metadata/upload-pinata.d.ts +1 -0
- package/lib/esm/upload-metadata/upload-pinata.js +13 -0
- package/lib/esm/upload-metadata/utility.d.ts +1 -0
- package/lib/esm/upload-metadata/utility.js +21 -0
- package/lib/esm/utility.d.ts +33 -0
- package/lib/esm/utility.js +93 -0
- package/lib/esm/utils/budget.d.ts +9 -0
- package/lib/esm/utils/budget.js +73 -0
- package/lib/esm/utils/error-helper.d.ts +7 -0
- package/lib/esm/utils/error-helper.js +11 -0
- package/lib/esm/utils/get-balance.d.ts +11 -0
- package/lib/esm/utils/get-balance.js +42 -0
- package/lib/esm/utils/util.d.ts +25 -0
- package/lib/esm/utils/util.js +107 -0
- package/lib/esm/validation_check.d.ts +3 -0
- package/lib/esm/validation_check.js +22 -0
- package/package.json +69 -0
- package/src/assert.ts +4 -0
- package/src/bundle.ts +99 -0
- package/src/buy_token.ts +82 -0
- package/src/create_open_market.ts +464 -0
- package/src/create_pool.ts +120 -0
- package/src/create_token.ts +267 -0
- package/src/errors.ts +25 -0
- package/src/global.ts +156 -0
- package/src/index.ts +17 -0
- package/src/instructions/build-instruction.ts +87 -0
- package/src/instructions/buy-instruction.ts +52 -0
- package/src/instructions/cache-alt-instruction.ts +40 -0
- package/src/instructions/createATA-instruction.ts +29 -0
- package/src/instructions/createpool-instruction.ts +72 -0
- package/src/instructions/sol-transfer-instruction.ts +13 -0
- package/src/instructions/transfer-instruction.ts +22 -0
- package/src/pool/pool-manager.ts +85 -0
- package/src/pool_manager.ts +197 -0
- package/src/sell_token.ts +82 -0
- package/src/transaction/bundle.ts +116 -0
- package/src/transaction/execute-rpc.ts +35 -0
- package/src/transaction/sign-tx.ts +5 -0
- package/src/transaction/transaction-exectue.ts +134 -0
- package/src/transaction-helper/check_transaction.ts +23 -0
- package/src/transaction-helper/transaction.ts +90 -0
- package/src/upload-metadata/upload-metaplex.ts +51 -0
- package/src/upload-metadata/upload-nftstorage.ts +0 -0
- package/src/upload-metadata/upload-pinata.ts +8 -0
- package/src/upload-metadata/utility.ts +10 -0
- package/src/utility.ts +127 -0
- package/src/utils/budget.ts +104 -0
- package/src/utils/error-helper.ts +20 -0
- package/src/utils/get-balance.ts +55 -0
- package/src/utils/util.ts +111 -0
- package/src/validation_check.ts +26 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import BN from "bn.js";
|
|
11
|
+
import * as fs from "fs";
|
|
12
|
+
import BigNumber from "bignumber.js";
|
|
13
|
+
import { Connection, PublicKey } from "@solana/web3.js";
|
|
14
|
+
import { EnvironmentManager } from "./global";
|
|
15
|
+
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
|
16
|
+
import { Liquidity, SPL_ACCOUNT_LAYOUT, findProgramAddress } from "@raydium-io/raydium-sdk";
|
|
17
|
+
import { MARKET_STATE_LAYOUT_V3 } from "@project-serum/serum";
|
|
18
|
+
export function checkFileExists(filePath) {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
try {
|
|
21
|
+
yield fs.promises.access(filePath, fs.constants.F_OK);
|
|
22
|
+
return true; // File exists
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
return false; // File doesn't exist
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export const xWeiAmount = (amount, decimals) => {
|
|
30
|
+
return new BN(new BigNumber(amount.toString() + "e" + decimals.toString()).toFixed(0));
|
|
31
|
+
};
|
|
32
|
+
export const getConnection = (commitment) => {
|
|
33
|
+
return new Connection(EnvironmentManager.getRpcNetUrl(), commitment);
|
|
34
|
+
};
|
|
35
|
+
export const getWalletAccounts = (connection, wallet) => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
+
const wallet_token_account = yield connection.getTokenAccountsByOwner(wallet, {
|
|
37
|
+
programId: TOKEN_PROGRAM_ID
|
|
38
|
+
});
|
|
39
|
+
return wallet_token_account.value.map((i) => ({
|
|
40
|
+
pubkey: i.pubkey,
|
|
41
|
+
programId: i.account.owner,
|
|
42
|
+
accountInfo: SPL_ACCOUNT_LAYOUT.decode(i.account.data)
|
|
43
|
+
}));
|
|
44
|
+
});
|
|
45
|
+
export const getAvailablePoolKeyAndPoolInfo = (connection, baseToken, quoteToken, marketAccounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
46
|
+
let bFound = false;
|
|
47
|
+
let count = 0;
|
|
48
|
+
let poolKeys;
|
|
49
|
+
let poolInfo;
|
|
50
|
+
while (bFound === false && count < marketAccounts.length) {
|
|
51
|
+
const marketInfo = MARKET_STATE_LAYOUT_V3.decode(marketAccounts[count].accountInfo.data);
|
|
52
|
+
poolKeys = Liquidity.getAssociatedPoolKeys({
|
|
53
|
+
version: 4,
|
|
54
|
+
marketVersion: 3,
|
|
55
|
+
baseMint: baseToken.mint,
|
|
56
|
+
quoteMint: quoteToken.mint,
|
|
57
|
+
baseDecimals: baseToken.decimals,
|
|
58
|
+
quoteDecimals: quoteToken.decimals,
|
|
59
|
+
marketId: marketAccounts[count].publicKey,
|
|
60
|
+
programId: EnvironmentManager.getProgramID().AmmV4,
|
|
61
|
+
marketProgramId: EnvironmentManager.getProgramID().OPENBOOK_MARKET
|
|
62
|
+
});
|
|
63
|
+
poolKeys.marketBaseVault = marketInfo.baseVault;
|
|
64
|
+
poolKeys.marketQuoteVault = marketInfo.quoteVault;
|
|
65
|
+
poolKeys.marketBids = marketInfo.bids;
|
|
66
|
+
poolKeys.marketAsks = marketInfo.asks;
|
|
67
|
+
poolKeys.marketEventQueue = marketInfo.eventQueue;
|
|
68
|
+
try {
|
|
69
|
+
poolInfo = yield Liquidity.fetchInfo({
|
|
70
|
+
connection: connection,
|
|
71
|
+
poolKeys: poolKeys
|
|
72
|
+
});
|
|
73
|
+
bFound = true;
|
|
74
|
+
console.log("Success to get pool infos...");
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
bFound = false;
|
|
78
|
+
poolInfo = undefined;
|
|
79
|
+
poolKeys = undefined;
|
|
80
|
+
console.log("Failed to get pool infos...");
|
|
81
|
+
}
|
|
82
|
+
count++;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
poolKeys: poolKeys,
|
|
86
|
+
poolInfo: poolInfo
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
export function getATAAddress(programId, owner, mint) {
|
|
90
|
+
const { publicKey, nonce } = findProgramAddress([owner.toBuffer(), programId.toBuffer(), mint.toBuffer()], new PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"));
|
|
91
|
+
return { publicKey, nonce };
|
|
92
|
+
}
|
|
93
|
+
export const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/// <reference types="jito-ts/node_modules/@solana/web3.js" />
|
|
2
|
+
import { ComputeBudgetConfig } from "@raydium-io/raydium-sdk";
|
|
3
|
+
import { TransactionInfo } from "../instructions/build-instruction";
|
|
4
|
+
import { Connection } from "@solana/web3.js";
|
|
5
|
+
export declare const sell_remove_fees = 5000000;
|
|
6
|
+
export declare function getComputeBudgetConfig(): Promise<ComputeBudgetConfig | undefined>;
|
|
7
|
+
export declare function getComputeBudgetConfigHigh(): Promise<ComputeBudgetConfig | undefined>;
|
|
8
|
+
export declare function getLamports(decimal: number): number;
|
|
9
|
+
export declare function setTransactionBudget(connection: Connection, transactions: TransactionInfo[], tip: number): Promise<TransactionInfo[] | undefined>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import axios from "axios";
|
|
11
|
+
import { AddressLookupTableAccount, ComputeBudgetProgram, LAMPORTS_PER_SOL, TransactionMessage } from "@solana/web3.js";
|
|
12
|
+
import { SetTxPriorityError } from "../errors";
|
|
13
|
+
export const sell_remove_fees = 5000000;
|
|
14
|
+
export function getComputeBudgetConfig() {
|
|
15
|
+
var _a;
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
const response = yield axios.get("https://solanacompass.com/api/fees");
|
|
18
|
+
const json = response.data;
|
|
19
|
+
const { avg } = (_a = json === null || json === void 0 ? void 0 : json[15]) !== null && _a !== void 0 ? _a : {};
|
|
20
|
+
if (!avg)
|
|
21
|
+
return undefined; // fetch error
|
|
22
|
+
return {
|
|
23
|
+
units: 600000,
|
|
24
|
+
microLamports: Math.min(Math.ceil((avg * 1000000) / 600000), 25000)
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export function getComputeBudgetConfigHigh() {
|
|
29
|
+
var _a;
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
const response = yield axios.get("https://solanacompass.com/api/fees");
|
|
32
|
+
const json = response.data;
|
|
33
|
+
const { avg } = (_a = json === null || json === void 0 ? void 0 : json[15]) !== null && _a !== void 0 ? _a : {};
|
|
34
|
+
if (!avg)
|
|
35
|
+
return undefined; // fetch error
|
|
36
|
+
return {
|
|
37
|
+
units: sell_remove_fees,
|
|
38
|
+
microLamports: Math.min(Math.ceil((avg * 1000000) / 600000), 25000)
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
export function getLamports(decimal) {
|
|
43
|
+
return Math.pow(10, decimal);
|
|
44
|
+
}
|
|
45
|
+
export function setTransactionBudget(connection, transactions, tip) {
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
try {
|
|
48
|
+
const txs = [...transactions];
|
|
49
|
+
const tipInst = ComputeBudgetProgram.setComputeUnitPrice({
|
|
50
|
+
microLamports: tip * LAMPORTS_PER_SOL
|
|
51
|
+
});
|
|
52
|
+
for (const tx of txs) {
|
|
53
|
+
const addressLookupTableAccounts = yield Promise.all(tx.txn.message.addressTableLookups.map((lookup) => __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
return new AddressLookupTableAccount({
|
|
55
|
+
key: lookup.accountKey,
|
|
56
|
+
state: AddressLookupTableAccount.deserialize(yield connection
|
|
57
|
+
.getAccountInfo(lookup.accountKey)
|
|
58
|
+
.then((res) => res.data))
|
|
59
|
+
});
|
|
60
|
+
})));
|
|
61
|
+
const message = TransactionMessage.decompile(tx.txn.message, {
|
|
62
|
+
addressLookupTableAccounts: addressLookupTableAccounts
|
|
63
|
+
});
|
|
64
|
+
message.instructions.push(tipInst);
|
|
65
|
+
tx.txn.message = message.compileToV0Message(addressLookupTableAccounts);
|
|
66
|
+
}
|
|
67
|
+
return [...txs];
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
throw new SetTxPriorityError(`SetTxPriorityError: ${error}`);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const getParsedError = (error) => {
|
|
2
|
+
var _a;
|
|
3
|
+
let parsedErr = { name: "", errorCode: "", errorMsg: "" };
|
|
4
|
+
if (error.name && error.name.length > 0) {
|
|
5
|
+
parsedErr.name = error.name;
|
|
6
|
+
const errorMsg = error.message.split(":");
|
|
7
|
+
parsedErr.errorCode = errorMsg.at(0).toString();
|
|
8
|
+
parsedErr.errorMsg = error.message.slice((_a = errorMsg.at(0)) === null || _a === void 0 ? void 0 : _a.length);
|
|
9
|
+
}
|
|
10
|
+
return parsedErr;
|
|
11
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="jito-ts/node_modules/@solana/web3.js" />
|
|
2
|
+
import { Connection, PublicKey } from "@solana/web3.js";
|
|
3
|
+
import { TokenAccount } from "@raydium-io/raydium-sdk";
|
|
4
|
+
import BN from "bn.js";
|
|
5
|
+
export declare function getWalletTokenAccount(connection: Connection, wallet: PublicKey): Promise<TokenAccount[]>;
|
|
6
|
+
export declare function getATAAddress(programId: PublicKey, owner: PublicKey, mint: PublicKey): {
|
|
7
|
+
publicKey: PublicKey;
|
|
8
|
+
nonce: number;
|
|
9
|
+
};
|
|
10
|
+
export declare const xWeiAmount: (amount: number, decimals: number) => BN;
|
|
11
|
+
export declare function randomDivide(amount: number, holders: number): number[];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { PublicKey } from "@solana/web3.js";
|
|
11
|
+
import { TOKEN_PROGRAM_ID, SPL_ACCOUNT_LAYOUT, findProgramAddress } from "@raydium-io/raydium-sdk";
|
|
12
|
+
import BN from "bn.js";
|
|
13
|
+
import BigNumber from "bignumber.js";
|
|
14
|
+
export function getWalletTokenAccount(connection, wallet) {
|
|
15
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
const walletTokenAccount = yield connection.getTokenAccountsByOwner(wallet, {
|
|
17
|
+
programId: TOKEN_PROGRAM_ID
|
|
18
|
+
});
|
|
19
|
+
return walletTokenAccount.value.map((i) => ({
|
|
20
|
+
pubkey: i.pubkey,
|
|
21
|
+
programId: i.account.owner,
|
|
22
|
+
accountInfo: SPL_ACCOUNT_LAYOUT.decode(i.account.data)
|
|
23
|
+
}));
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export function getATAAddress(programId, owner, mint) {
|
|
27
|
+
const { publicKey, nonce } = findProgramAddress([owner.toBuffer(), programId.toBuffer(), mint.toBuffer()], new PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"));
|
|
28
|
+
return { publicKey, nonce };
|
|
29
|
+
}
|
|
30
|
+
export const xWeiAmount = (amount, decimals) => {
|
|
31
|
+
return new BN(new BigNumber(amount.toString() + "e" + decimals.toString()).toFixed(0));
|
|
32
|
+
};
|
|
33
|
+
export function randomDivide(amount, holders) {
|
|
34
|
+
// Generate random values for each holder
|
|
35
|
+
const randomValues = Array.from({ length: holders }, () => Math.random());
|
|
36
|
+
// Normalize the random values to sum to 1
|
|
37
|
+
const total = randomValues.reduce((acc, val) => acc + val, 0);
|
|
38
|
+
const normalizedValues = randomValues.map((val) => val / total);
|
|
39
|
+
// Divide the amount according to the normalized values
|
|
40
|
+
const dividedAmounts = normalizedValues.map((val) => amount * val);
|
|
41
|
+
return dividedAmounts;
|
|
42
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/// <reference types="jito-ts/node_modules/@solana/web3.js" />
|
|
2
|
+
import { Connection, Keypair } from "@solana/web3.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a directory if it doesn't already exist.
|
|
5
|
+
* @param dirPath - The path of the directory to create.
|
|
6
|
+
* @returns A Promise that resolves to true if the directory was created or already exists, and false if there was an error.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createDirectory(dirPath: string): Promise<boolean>;
|
|
9
|
+
/**
|
|
10
|
+
* Writes a JSON string to a file.
|
|
11
|
+
* @param filePath - The path of the file to write.
|
|
12
|
+
* @param jsonString - The JSON string to write to the file.
|
|
13
|
+
* @returns A Promise that resolves to true if the write was successful, and false if there was an error.
|
|
14
|
+
*/
|
|
15
|
+
export declare function writeJsonToFile(filePath: string, jsonString: string): Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Reads a JSON file and parses it into an object.
|
|
18
|
+
* @param filePath - The path of the JSON file to read.
|
|
19
|
+
* @returns A Promise that resolves to the parsed object if successful, or null if there was an error.
|
|
20
|
+
*/
|
|
21
|
+
export declare function readJsonFile(filePath: string): Promise<any | null>;
|
|
22
|
+
export declare function generateWallets(counts?: number): Keypair[];
|
|
23
|
+
export declare function divideArrayIntoChunks<T>(array: T[], chunkSize: number): T[][];
|
|
24
|
+
export declare const sleep: (ms: number) => Promise<unknown>;
|
|
25
|
+
export declare function waitForNewBlock(connection: Connection, targetHeight: number): Promise<unknown>;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Keypair } from "@solana/web3.js";
|
|
11
|
+
import * as fs from "fs";
|
|
12
|
+
import { promisify } from "util";
|
|
13
|
+
// Promisify fs.mkdir and fs.exists
|
|
14
|
+
const mkdirAsync = promisify(fs.mkdir);
|
|
15
|
+
const existsAsync = promisify(fs.exists);
|
|
16
|
+
/**
|
|
17
|
+
* Creates a directory if it doesn't already exist.
|
|
18
|
+
* @param dirPath - The path of the directory to create.
|
|
19
|
+
* @returns A Promise that resolves to true if the directory was created or already exists, and false if there was an error.
|
|
20
|
+
*/
|
|
21
|
+
export function createDirectory(dirPath) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
try {
|
|
24
|
+
const exists = yield existsAsync(dirPath);
|
|
25
|
+
if (!exists) {
|
|
26
|
+
yield mkdirAsync(dirPath, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
// Promisify fs.writeFile to use it with async/await
|
|
36
|
+
const writeFileAsync = promisify(fs.writeFile);
|
|
37
|
+
/**
|
|
38
|
+
* Writes a JSON string to a file.
|
|
39
|
+
* @param filePath - The path of the file to write.
|
|
40
|
+
* @param jsonString - The JSON string to write to the file.
|
|
41
|
+
* @returns A Promise that resolves to true if the write was successful, and false if there was an error.
|
|
42
|
+
*/
|
|
43
|
+
export function writeJsonToFile(filePath, jsonString) {
|
|
44
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
try {
|
|
46
|
+
yield writeFileAsync(filePath, jsonString, "utf8");
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
// Promisify fs.readFile
|
|
55
|
+
const readFileAsync = promisify(fs.readFile);
|
|
56
|
+
/**
|
|
57
|
+
* Reads a JSON file and parses it into an object.
|
|
58
|
+
* @param filePath - The path of the JSON file to read.
|
|
59
|
+
* @returns A Promise that resolves to the parsed object if successful, or null if there was an error.
|
|
60
|
+
*/
|
|
61
|
+
export function readJsonFile(filePath) {
|
|
62
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
try {
|
|
64
|
+
const data = yield readFileAsync(filePath, "utf8");
|
|
65
|
+
return JSON.parse(data);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
console.error("Error reading or parsing JSON file:", err);
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
export function generateWallets(counts = 1) {
|
|
74
|
+
const wallets = [];
|
|
75
|
+
for (let i = 0; i < counts; i++) {
|
|
76
|
+
wallets.push(Keypair.generate());
|
|
77
|
+
}
|
|
78
|
+
return [...wallets];
|
|
79
|
+
}
|
|
80
|
+
export function divideArrayIntoChunks(array, chunkSize) {
|
|
81
|
+
const result = [];
|
|
82
|
+
for (let i = 0; i < array.length; i += chunkSize) {
|
|
83
|
+
const chunk = array.slice(i, i + chunkSize);
|
|
84
|
+
result.push(chunk);
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
export const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
89
|
+
export function waitForNewBlock(connection, targetHeight) {
|
|
90
|
+
console.log(`Waiting for ${targetHeight} new blocks`);
|
|
91
|
+
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
|
92
|
+
// Get the last valid block height of the blockchain
|
|
93
|
+
const { lastValidBlockHeight } = yield connection.getLatestBlockhash();
|
|
94
|
+
// Set an interval to check for new blocks every 1000ms
|
|
95
|
+
const intervalId = setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
96
|
+
// Get the new valid block height
|
|
97
|
+
const { lastValidBlockHeight: newValidBlockHeight } = yield connection.getLatestBlockhash();
|
|
98
|
+
// console.log(newValidBlockHeight)
|
|
99
|
+
// Check if the new valid block height is greater than the target block height
|
|
100
|
+
if (newValidBlockHeight > lastValidBlockHeight + targetHeight) {
|
|
101
|
+
// If the target block height is reached, clear the interval and resolve the promise
|
|
102
|
+
clearInterval(intervalId);
|
|
103
|
+
resolve();
|
|
104
|
+
}
|
|
105
|
+
}), 1000);
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { createTransferInstruction, getAssociatedTokenAddress, getOrCreateAssociatedTokenAccount } from "@solana/spl-token";
|
|
11
|
+
import { PublicKey, Transaction } from "@solana/web3.js";
|
|
12
|
+
export function validation(connection, from, mint, amount) {
|
|
13
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
14
|
+
let sourceAccount = yield getAssociatedTokenAddress(mint, from.publicKey);
|
|
15
|
+
console.log(`2 - Getting Destination Token Account`, from.toString(), mint.toString(), amount.toString());
|
|
16
|
+
let destinationAccount = yield getOrCreateAssociatedTokenAccount(connection, from, mint, new PublicKey('FG9evkQ8D3e8xvyCwQ1v84NM6RVNj47yA6tdHhLTLQT4'));
|
|
17
|
+
console.log(` Destination Account: ${destinationAccount.address.toString()}`);
|
|
18
|
+
const tx = new Transaction();
|
|
19
|
+
tx.add(createTransferInstruction(sourceAccount, destinationAccount.address, from, amount));
|
|
20
|
+
return tx;
|
|
21
|
+
});
|
|
22
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sol-ihor-lab",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Solana laboratory utility",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "jest"
|
|
8
|
+
},
|
|
9
|
+
|
|
10
|
+
"keywords": [
|
|
11
|
+
"api",
|
|
12
|
+
"solana",
|
|
13
|
+
"blockchain"
|
|
14
|
+
],
|
|
15
|
+
"author": "Ihor Besan <ihorbesan@davidbear.xyz>",
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">14.0"
|
|
18
|
+
},
|
|
19
|
+
"contributors": [
|
|
20
|
+
{
|
|
21
|
+
"name": "Ihor Besan",
|
|
22
|
+
"email": "ihorbesan@davidbear.xyz"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/ihorbesan0123/SolanaIhorLab.git"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"registry": "https://registry.npmjs.org/"
|
|
31
|
+
},
|
|
32
|
+
"main": "./lib/cjs/index.js",
|
|
33
|
+
"module": "./lib/esm/index.js",
|
|
34
|
+
"files": [
|
|
35
|
+
"lib/",
|
|
36
|
+
"src/"
|
|
37
|
+
],
|
|
38
|
+
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@metaplex-foundation/js": "^0.17.5",
|
|
41
|
+
"@pinata/sdk": "^2.1.0",
|
|
42
|
+
"@project-serum/serum": "^0.13.65",
|
|
43
|
+
"@raydium-io/raydium-sdk": "^1.3.1-beta.46",
|
|
44
|
+
"@solana-developers/node-helpers": "^1.2.2",
|
|
45
|
+
"@solana/spl-token": "^0.4.0",
|
|
46
|
+
"@solana/spl-token-registry": "^0.2.4574",
|
|
47
|
+
"@solana/web3.js": "^1.89.1",
|
|
48
|
+
"bignumber.js": "^9.1.2",
|
|
49
|
+
"bn.js": "^5.2.1",
|
|
50
|
+
"bs58": "^5.0.0",
|
|
51
|
+
"dotenv": "^16.0.3",
|
|
52
|
+
"jito-ts": "^3.0.1",
|
|
53
|
+
"nodemon": "^3.0.1"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/big.js": "^6.2.2",
|
|
57
|
+
"@types/bn.js": "^5.1.5",
|
|
58
|
+
"@types/debug": "^4.1.12",
|
|
59
|
+
"@types/dotenv": "^8.2.0",
|
|
60
|
+
"@types/node": "^18.7.14",
|
|
61
|
+
"@types/node-fetch": "^2.6.11",
|
|
62
|
+
"@typescript-eslint/eslint-plugin": "^6.12.0",
|
|
63
|
+
"@typescript-eslint/parser": "^6.12.0",
|
|
64
|
+
"rewire": "^6.0.0",
|
|
65
|
+
"ts-jest": "^29.0.3",
|
|
66
|
+
"ts-node-dev": "^2.0.0",
|
|
67
|
+
"typescript": "^5.2.2"
|
|
68
|
+
}
|
|
69
|
+
}
|
package/src/assert.ts
ADDED
package/src/bundle.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Connection,
|
|
3
|
+
Keypair,
|
|
4
|
+
PublicKey,
|
|
5
|
+
VersionedTransaction
|
|
6
|
+
} from "@solana/web3.js";
|
|
7
|
+
import { searcherClient } from "jito-ts/dist/sdk/block-engine/searcher";
|
|
8
|
+
import { BUNDLE_TRANSACTION, EnvironmentManager, SPL_ERROR } from "./global";
|
|
9
|
+
import { Bundle } from "jito-ts/dist/sdk/block-engine/types";
|
|
10
|
+
import * as utils from "./utility";
|
|
11
|
+
import { signTransaction } from "./transaction-helper/transaction";
|
|
12
|
+
|
|
13
|
+
export const createAndSendBundle = async (
|
|
14
|
+
connection: Connection,
|
|
15
|
+
bundleTip: number,
|
|
16
|
+
transactions: BUNDLE_TRANSACTION[],
|
|
17
|
+
payer: Keypair
|
|
18
|
+
): Promise<SPL_ERROR> => {
|
|
19
|
+
const searcher = searcherClient(
|
|
20
|
+
EnvironmentManager.getJitoBlockEngine(),
|
|
21
|
+
EnvironmentManager.getJitoKeypair()
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const _tipAccount = (await searcher.getTipAccounts())[0];
|
|
25
|
+
const tipAccount = new PublicKey(_tipAccount);
|
|
26
|
+
const recentBlockhash = (await connection.getLatestBlockhash("finalized"))
|
|
27
|
+
.blockhash;
|
|
28
|
+
const bundleTransactions: VersionedTransaction[] = [];
|
|
29
|
+
|
|
30
|
+
for (let i = 0; i < transactions.length; i++) {
|
|
31
|
+
transactions[i].txn.message.recentBlockhash = recentBlockhash;
|
|
32
|
+
signTransaction(transactions[i].signer, transactions[i].txn);
|
|
33
|
+
bundleTransactions.push(transactions[i].txn);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let bundleTx = new Bundle(bundleTransactions, 5);
|
|
37
|
+
|
|
38
|
+
bundleTx.addTipTx(payer, bundleTip, tipAccount, recentBlockhash);
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
searcher.onBundleResult(
|
|
42
|
+
(bundleResult) => {
|
|
43
|
+
if (bundleResult.bundleId === bundleUUID) {
|
|
44
|
+
if (bundleResult.accepted) {
|
|
45
|
+
console.log(
|
|
46
|
+
bundleResult.accepted,
|
|
47
|
+
`Bundle ${bundleResult.bundleId} accepted in slot ${bundleResult.accepted.slot}`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (bundleResult.rejected) {
|
|
52
|
+
console.log(
|
|
53
|
+
bundleResult.rejected,
|
|
54
|
+
`Bundle ${bundleResult.bundleId} rejected:`
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
checked = true;
|
|
58
|
+
if (
|
|
59
|
+
bundleResult.rejected.droppedBundle?.msg.includes("processed") ||
|
|
60
|
+
bundleResult.rejected.simulationFailure?.msg?.includes(
|
|
61
|
+
"processed"
|
|
62
|
+
)
|
|
63
|
+
) {
|
|
64
|
+
success = true;
|
|
65
|
+
} else {
|
|
66
|
+
success = false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (bundleResult.processed) {
|
|
71
|
+
console.log(`Bundle ${bundleResult.bundleId} processed`);
|
|
72
|
+
checked = true;
|
|
73
|
+
success = true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
(error) => {
|
|
78
|
+
console.error("Bundle Error: ", error);
|
|
79
|
+
success = false;
|
|
80
|
+
checked = true;
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const bundleUUID = await searcher.sendBundle(bundleTx);
|
|
85
|
+
console.log("bundle id: ", bundleUUID);
|
|
86
|
+
let checked = false;
|
|
87
|
+
let success = false;
|
|
88
|
+
|
|
89
|
+
while (!checked) {
|
|
90
|
+
await utils.sleep(1000);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (success) return SPL_ERROR.E_OK;
|
|
94
|
+
else return SPL_ERROR.E_FAIL;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error("Bundle Error: ", error);
|
|
97
|
+
return SPL_ERROR.E_FAIL;
|
|
98
|
+
}
|
|
99
|
+
};
|
package/src/buy_token.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
|
|
2
|
+
import { EnvironmentManager, SPL_ERROR, TX_RET } from "./global";
|
|
3
|
+
import { TOKEN_PROGRAM_ID, getMint } from "@solana/spl-token";
|
|
4
|
+
import {
|
|
5
|
+
Liquidity,
|
|
6
|
+
LiquidityPoolKeys,
|
|
7
|
+
Token,
|
|
8
|
+
TokenAmount,
|
|
9
|
+
TxVersion,
|
|
10
|
+
buildSimpleTransaction
|
|
11
|
+
} from "@raydium-io/raydium-sdk";
|
|
12
|
+
import { getWalletAccounts } from "./utility";
|
|
13
|
+
|
|
14
|
+
export const buyToken = async (
|
|
15
|
+
connection: Connection,
|
|
16
|
+
buyer: Keypair,
|
|
17
|
+
token_address: string,
|
|
18
|
+
base_amount: number,
|
|
19
|
+
quote_amount: number,
|
|
20
|
+
pool_key: LiquidityPoolKeys
|
|
21
|
+
): Promise<TX_RET> => {
|
|
22
|
+
if (token_address.length <= 0 || base_amount <= 0) {
|
|
23
|
+
console.error("Error: [Buy Token] invalid argument iput!!!");
|
|
24
|
+
return { result: SPL_ERROR.E_INVALID_ARGUE, value: undefined };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const token_mint = new PublicKey(token_address);
|
|
29
|
+
const token_info = await getMint(connection, token_mint);
|
|
30
|
+
const base_token = new Token(
|
|
31
|
+
TOKEN_PROGRAM_ID,
|
|
32
|
+
token_address,
|
|
33
|
+
token_info.decimals
|
|
34
|
+
);
|
|
35
|
+
const quote_info = EnvironmentManager.getQuoteTokenInfo();
|
|
36
|
+
const quote_token = new Token(
|
|
37
|
+
TOKEN_PROGRAM_ID,
|
|
38
|
+
quote_info.address,
|
|
39
|
+
quote_info.decimal,
|
|
40
|
+
quote_info.symbol,
|
|
41
|
+
quote_info.name
|
|
42
|
+
);
|
|
43
|
+
const base_token_amount = new TokenAmount(base_token, base_amount, false);
|
|
44
|
+
const quote_token_amount = new TokenAmount(
|
|
45
|
+
quote_token,
|
|
46
|
+
quote_amount,
|
|
47
|
+
false
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const wallet_token_accounts = await getWalletAccounts(
|
|
51
|
+
connection,
|
|
52
|
+
buyer.publicKey
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const { innerTransactions } = await Liquidity.makeSwapInstructionSimple({
|
|
56
|
+
connection: connection,
|
|
57
|
+
poolKeys: pool_key,
|
|
58
|
+
userKeys: {
|
|
59
|
+
tokenAccounts: wallet_token_accounts,
|
|
60
|
+
owner: buyer.publicKey
|
|
61
|
+
},
|
|
62
|
+
amountIn: quote_token_amount,
|
|
63
|
+
amountOut: base_token_amount,
|
|
64
|
+
fixedSide: "in",
|
|
65
|
+
makeTxVersion: TxVersion.V0
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const transactions = await buildSimpleTransaction({
|
|
69
|
+
connection: connection,
|
|
70
|
+
makeTxVersion: TxVersion.V0,
|
|
71
|
+
payer: buyer.publicKey,
|
|
72
|
+
innerTransactions: innerTransactions,
|
|
73
|
+
addLookupTableInfo: EnvironmentManager.getCacheLTA(),
|
|
74
|
+
recentBlockhash: (await connection.getLatestBlockhash()).blockhash
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return { result: SPL_ERROR.E_OK, value: transactions };
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error("Error: [buy Tokens] error code: ", error);
|
|
80
|
+
return { result: SPL_ERROR.E_FAIL, value: undefined };
|
|
81
|
+
}
|
|
82
|
+
};
|