@deserialize/multi-vm-wallet 1.0.12 → 1.0.21
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/dist/IChainWallet.d.ts +17 -0
- package/dist/IChainWallet.js +23 -0
- package/dist/IChainWallet.js.map +1 -0
- package/dist/bip32.d.ts +11 -0
- package/dist/bip32.js +100 -0
- package/dist/bip32.js.map +1 -0
- package/dist/evm/evm.d.ts +39 -0
- package/dist/evm/evm.js +234 -0
- package/dist/evm/evm.js.map +1 -0
- package/dist/evm/index.d.ts +2 -0
- package/dist/evm/index.js +19 -0
- package/dist/evm/index.js.map +1 -0
- package/dist/evm/utils.d.ts +207 -0
- package/dist/evm/utils.js +538 -0
- package/dist/evm/utils.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/svm/index.d.ts +1 -0
- package/dist/svm/index.js +18 -0
- package/dist/svm/index.js.map +1 -0
- package/dist/svm/svm.d.ts +36 -0
- package/dist/svm/svm.js +167 -0
- package/dist/svm/svm.js.map +1 -0
- package/dist/svm/transactionSender.d.ts +8 -0
- package/dist/svm/transactionSender.js +84 -0
- package/dist/svm/transactionSender.js.map +1 -0
- package/dist/svm/utils.d.ts +85 -0
- package/dist/svm/utils.js +305 -0
- package/dist/svm/utils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +44 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/evm/evm.d.ts +4 -3
- package/dist/utils/evm/evm.js +18 -6
- package/dist/utils/svm/svm.d.ts +3 -2
- package/dist/utils/svm/svm.js +17 -5
- package/dist/utils/vm.d.ts +2 -3
- package/dist/utils/vm.js +5 -6
- package/dist/vm.d.ts +12 -0
- package/dist/vm.js +49 -0
- package/dist/vm.js.map +1 -0
- package/package.json +1 -1
- package/tsconfig.json +11 -111
- package/utils/evm/evm.ts +22 -10
- package/utils/svm/svm.ts +17 -5
- package/utils/vm.ts +5 -5
package/dist/svm/svm.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SVMChainWallet = exports.SVMVM = void 0;
|
|
7
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
8
|
+
const bip32_1 = require("../bip32");
|
|
9
|
+
const vm_1 = require("../vm");
|
|
10
|
+
const IChainWallet_1 = require("../IChainWallet");
|
|
11
|
+
const utils_1 = require("./utils");
|
|
12
|
+
const bn_js_1 = __importDefault(require("bn.js"));
|
|
13
|
+
class SVMVM extends vm_1.VM {
|
|
14
|
+
constructor(seed) {
|
|
15
|
+
super(seed, "SVM");
|
|
16
|
+
this.derivationPath = "m/44'/501'/"; // Default SVM derivation path
|
|
17
|
+
}
|
|
18
|
+
static validateAddress(address) {
|
|
19
|
+
return web3_js_1.PublicKey.isOnCurve(address.toBuffer());
|
|
20
|
+
}
|
|
21
|
+
static getNativeBalance(address, connection) {
|
|
22
|
+
return (0, utils_1.getSvmNativeBalance)(address, connection);
|
|
23
|
+
}
|
|
24
|
+
static async getTokenBalance(address, tokenAddress, connection) {
|
|
25
|
+
const balance = await (0, utils_1.getTokenBalance)(address, tokenAddress, connection);
|
|
26
|
+
if (balance === 0) {
|
|
27
|
+
return { balance: new bn_js_1.default(0), formatted: 0, decimal: 0 };
|
|
28
|
+
}
|
|
29
|
+
return { balance: new bn_js_1.default(balance.amount), formatted: balance.uiAmount || parseInt(balance.amount) / 10 ** balance.decimals, decimal: balance.decimals };
|
|
30
|
+
}
|
|
31
|
+
generatePrivateKey(index, seed, mnemonic, derivationPath = this.derivationPath) {
|
|
32
|
+
let _seed;
|
|
33
|
+
if (seed) {
|
|
34
|
+
_seed = seed;
|
|
35
|
+
}
|
|
36
|
+
else if (mnemonic) {
|
|
37
|
+
_seed = vm_1.VM.mnemonicToSeed(mnemonic);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
_seed = this.seed;
|
|
41
|
+
}
|
|
42
|
+
const privateKey = (0, bip32_1.SVMDeriveChildPrivateKey)(_seed, index, derivationPath);
|
|
43
|
+
return { privateKey, index };
|
|
44
|
+
}
|
|
45
|
+
static fromMnemonic(seed) {
|
|
46
|
+
return new SVMVM(seed);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.SVMVM = SVMVM;
|
|
50
|
+
SVMVM.signAndSendTransaction = utils_1.signAndSendTransaction;
|
|
51
|
+
class SVMChainWallet extends IChainWallet_1.ChainWallet {
|
|
52
|
+
constructor(config, privateKey, index) {
|
|
53
|
+
super(config, privateKey, index);
|
|
54
|
+
this.address = privateKey.publicKey;
|
|
55
|
+
this.privateKey = privateKey;
|
|
56
|
+
this.connection = new web3_js_1.Connection(config.rpcUrl);
|
|
57
|
+
}
|
|
58
|
+
generateAddress() {
|
|
59
|
+
return this.address;
|
|
60
|
+
}
|
|
61
|
+
async getNativeBalance() {
|
|
62
|
+
// Implement native balance retrieval logic here
|
|
63
|
+
return await SVMVM.getNativeBalance(this.address, this.connection);
|
|
64
|
+
}
|
|
65
|
+
async getTokenBalance(tokenAddress) {
|
|
66
|
+
// Implement token balance retrieval logic here
|
|
67
|
+
return await SVMVM.getTokenBalance(this.address, (tokenAddress), this.connection);
|
|
68
|
+
}
|
|
69
|
+
async transferNative(to, amount) {
|
|
70
|
+
// Implement native transfer logic here
|
|
71
|
+
const transaction = await (0, utils_1.getTransferNativeTransaction)(this.privateKey, to, amount, this.connection);
|
|
72
|
+
const hash = await SVMVM.signAndSendTransaction(transaction, this.connection, [this.privateKey]);
|
|
73
|
+
return { success: true, hash }; // Placeholder
|
|
74
|
+
}
|
|
75
|
+
async transferToken(token, to, amount) {
|
|
76
|
+
// Implement token transfer logic here
|
|
77
|
+
const transaction = await (0, utils_1.getTransferTokenTransaction)(this.privateKey, new web3_js_1.PublicKey(to), token, (amount), this.connection);
|
|
78
|
+
const hash = await SVMVM.signAndSendTransaction(transaction, this.connection, [this.privateKey]);
|
|
79
|
+
return { success: true, hash }; // Placeholder
|
|
80
|
+
}
|
|
81
|
+
async swap(fromToken, toToken, amount, slippage = 50) {
|
|
82
|
+
try {
|
|
83
|
+
if (amount <= 0) {
|
|
84
|
+
return {
|
|
85
|
+
success: false,
|
|
86
|
+
hash: "",
|
|
87
|
+
error: "Amount must be greater than 0"
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (slippage < 0 || slippage > 5000) {
|
|
91
|
+
return {
|
|
92
|
+
success: false,
|
|
93
|
+
hash: "",
|
|
94
|
+
error: "Slippage must be between 0 and 5000 basis points (0-50%)"
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
const fromTokenMint = new web3_js_1.PublicKey(fromToken.address);
|
|
98
|
+
const toTokenMint = toToken;
|
|
99
|
+
const validation = await (0, utils_1.validateJupiterTokens)(fromTokenMint.toString(), toTokenMint.toString());
|
|
100
|
+
if (!validation.valid) {
|
|
101
|
+
return {
|
|
102
|
+
success: false,
|
|
103
|
+
hash: "",
|
|
104
|
+
error: validation.message || "Token validation failed"
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const baseAmount = (0, utils_1.uiAmountToBaseUnits)(amount, fromToken.decimals);
|
|
108
|
+
const balance = await this.getTokenBalance(fromTokenMint);
|
|
109
|
+
if (balance.balance.lt(new bn_js_1.default(baseAmount))) {
|
|
110
|
+
return {
|
|
111
|
+
success: false,
|
|
112
|
+
hash: "",
|
|
113
|
+
error: "Insufficient balance for swap"
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
const swapResult = await (0, utils_1.executeJupiterSwap)({
|
|
117
|
+
fromToken: fromTokenMint,
|
|
118
|
+
toToken: toTokenMint,
|
|
119
|
+
amount: baseAmount,
|
|
120
|
+
slippageBps: slippage,
|
|
121
|
+
userPublicKey: this.address
|
|
122
|
+
}, this.connection, this.privateKey);
|
|
123
|
+
if (!swapResult.success) {
|
|
124
|
+
return {
|
|
125
|
+
success: false,
|
|
126
|
+
hash: "",
|
|
127
|
+
error: swapResult.error || "Swap failed"
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
success: true,
|
|
132
|
+
hash: swapResult.hash || ""
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
console.error("Swap error:", error);
|
|
137
|
+
return {
|
|
138
|
+
success: false,
|
|
139
|
+
hash: "",
|
|
140
|
+
error: error instanceof Error ? error.message : "Unknown swap error occurred"
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async getSwapQuote(fromToken, toToken, amount, slippage = 50) {
|
|
145
|
+
try {
|
|
146
|
+
const fromTokenMint = new web3_js_1.PublicKey(fromToken.address);
|
|
147
|
+
const baseAmount = (0, utils_1.uiAmountToBaseUnits)(amount, fromToken.decimals);
|
|
148
|
+
const quote = await (0, utils_1.getJupiterQuote)(fromTokenMint.toString(), toToken.toString(), baseAmount, slippage);
|
|
149
|
+
return {
|
|
150
|
+
success: true,
|
|
151
|
+
inputAmount: quote.inAmount,
|
|
152
|
+
outputAmount: quote.outAmount,
|
|
153
|
+
priceImpact: quote.priceImpactPct,
|
|
154
|
+
routePlan: quote.routePlan,
|
|
155
|
+
slippageBps: quote.slippageBps
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
return {
|
|
160
|
+
success: false,
|
|
161
|
+
error: error instanceof Error ? error.message : "Failed to get swap quote"
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
exports.SVMChainWallet = SVMChainWallet;
|
|
167
|
+
//# sourceMappingURL=svm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svm.js","sourceRoot":"","sources":["../../utils/svm/svm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BlockhashWithExpiryBlockHeight, Connection, VersionedTransactionResponse } from "@solana/web3.js";
|
|
2
|
+
type TransactionSenderAndConfirmationWaiterArgs = {
|
|
3
|
+
connection: Connection;
|
|
4
|
+
serializedTransaction: Buffer;
|
|
5
|
+
blockhashWithExpiryBlockHeight: BlockhashWithExpiryBlockHeight;
|
|
6
|
+
};
|
|
7
|
+
export declare function transactionSenderAndConfirmationWaiter({ connection, serializedTransaction, blockhashWithExpiryBlockHeight, }: TransactionSenderAndConfirmationWaiterArgs): Promise<VersionedTransactionResponse | null>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.transactionSenderAndConfirmationWaiter = transactionSenderAndConfirmationWaiter;
|
|
7
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
8
|
+
const promise_retry_1 = __importDefault(require("promise-retry"));
|
|
9
|
+
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
10
|
+
const SEND_OPTIONS = {
|
|
11
|
+
skipPreflight: false,
|
|
12
|
+
};
|
|
13
|
+
async function transactionSenderAndConfirmationWaiter({ connection, serializedTransaction, blockhashWithExpiryBlockHeight, }) {
|
|
14
|
+
const txid = await connection.sendRawTransaction(serializedTransaction, SEND_OPTIONS);
|
|
15
|
+
const controller = new AbortController();
|
|
16
|
+
const abortSignal = controller.signal;
|
|
17
|
+
const abortableResender = async () => {
|
|
18
|
+
while (true) {
|
|
19
|
+
await wait(2000);
|
|
20
|
+
if (abortSignal.aborted)
|
|
21
|
+
return;
|
|
22
|
+
try {
|
|
23
|
+
await connection.sendRawTransaction(serializedTransaction, SEND_OPTIONS);
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
console.warn(`Failed to resend transaction: ${e}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
try {
|
|
31
|
+
abortableResender();
|
|
32
|
+
const lastValidBlockHeight = blockhashWithExpiryBlockHeight.lastValidBlockHeight - 150;
|
|
33
|
+
// this would throw TransactionExpiredBlockheightExceededError
|
|
34
|
+
await Promise.race([
|
|
35
|
+
connection.confirmTransaction({
|
|
36
|
+
...blockhashWithExpiryBlockHeight,
|
|
37
|
+
lastValidBlockHeight,
|
|
38
|
+
signature: txid,
|
|
39
|
+
abortSignal,
|
|
40
|
+
}, "confirmed"),
|
|
41
|
+
new Promise(async (resolve) => {
|
|
42
|
+
// in case ws socket died
|
|
43
|
+
while (!abortSignal.aborted) {
|
|
44
|
+
await wait(2000);
|
|
45
|
+
const tx = await connection.getSignatureStatus(txid, {
|
|
46
|
+
searchTransactionHistory: false,
|
|
47
|
+
});
|
|
48
|
+
if (tx?.value?.confirmationStatus === "confirmed") {
|
|
49
|
+
resolve(tx);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}),
|
|
53
|
+
]);
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
if (e instanceof web3_js_1.TransactionExpiredBlockheightExceededError) {
|
|
57
|
+
// we consume this error and getTransaction would return null
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// invalid state from web3.js
|
|
62
|
+
throw e;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
controller.abort();
|
|
67
|
+
}
|
|
68
|
+
// in case rpc is not synced yet, we add some retries
|
|
69
|
+
const response = (0, promise_retry_1.default)(async (retry) => {
|
|
70
|
+
const response = await connection.getTransaction(txid, {
|
|
71
|
+
commitment: "confirmed",
|
|
72
|
+
maxSupportedTransactionVersion: 0,
|
|
73
|
+
});
|
|
74
|
+
if (!response) {
|
|
75
|
+
retry(response);
|
|
76
|
+
}
|
|
77
|
+
return response;
|
|
78
|
+
}, {
|
|
79
|
+
retries: 5,
|
|
80
|
+
minTimeout: 1e3,
|
|
81
|
+
});
|
|
82
|
+
return response;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=transactionSender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactionSender.js","sourceRoot":"","sources":["../../utils/svm/transactionSender.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Account } from "@solana/spl-token";
|
|
2
|
+
import { Connection, Keypair, PublicKey, TransactionInstruction, VersionedTransaction } from "@solana/web3.js";
|
|
3
|
+
import { TokenInfo } from "../types";
|
|
4
|
+
export interface JupiterQuoteResponse {
|
|
5
|
+
inputMint: string;
|
|
6
|
+
inAmount: string;
|
|
7
|
+
outputMint: string;
|
|
8
|
+
outAmount: string;
|
|
9
|
+
otherAmountThreshold: string;
|
|
10
|
+
swapMode: string;
|
|
11
|
+
slippageBps: number;
|
|
12
|
+
platformFee: null | any;
|
|
13
|
+
priceImpactPct: string;
|
|
14
|
+
routePlan: RoutePlan[];
|
|
15
|
+
contextSlot: number;
|
|
16
|
+
timeTaken: number;
|
|
17
|
+
}
|
|
18
|
+
interface RoutePlan {
|
|
19
|
+
swapInfo: SwapInfo;
|
|
20
|
+
percent: number;
|
|
21
|
+
}
|
|
22
|
+
interface SwapInfo {
|
|
23
|
+
ammKey: string;
|
|
24
|
+
label: string;
|
|
25
|
+
inputMint: string;
|
|
26
|
+
outputMint: string;
|
|
27
|
+
inAmount: string;
|
|
28
|
+
outAmount: string;
|
|
29
|
+
feeAmount: string;
|
|
30
|
+
feeMint: string;
|
|
31
|
+
}
|
|
32
|
+
interface JupiterSwapResponse {
|
|
33
|
+
swapTransaction: string;
|
|
34
|
+
lastValidBlockHeight: number;
|
|
35
|
+
prioritizationFeeLamports: number;
|
|
36
|
+
}
|
|
37
|
+
interface SwapParams {
|
|
38
|
+
fromToken: PublicKey;
|
|
39
|
+
toToken: PublicKey;
|
|
40
|
+
amount: number;
|
|
41
|
+
slippageBps?: number;
|
|
42
|
+
userPublicKey: PublicKey;
|
|
43
|
+
}
|
|
44
|
+
interface SwapResult {
|
|
45
|
+
success: boolean;
|
|
46
|
+
hash?: string;
|
|
47
|
+
error?: string;
|
|
48
|
+
inputAmount?: string;
|
|
49
|
+
outputAmount?: string;
|
|
50
|
+
priceImpact?: string;
|
|
51
|
+
}
|
|
52
|
+
export declare const createV0Transaction: (connection: Connection, inX: TransactionInstruction[], signers: Keypair[], payerPubKey: PublicKey, blockHash?: string) => Promise<VersionedTransaction>;
|
|
53
|
+
export declare const createAtaAndIx: (token: PublicKey, ownerPublicKey: PublicKey, tokenProgramId: PublicKey, connection: Connection) => Promise<{
|
|
54
|
+
AtaTokenIx: TransactionInstruction | undefined;
|
|
55
|
+
associatedToken: PublicKey;
|
|
56
|
+
}>;
|
|
57
|
+
export declare const getSureAssociatedTokenAddressAndAccount: (connection: Connection, token: PublicKey, owner: PublicKey) => Promise<{
|
|
58
|
+
ATA: PublicKey;
|
|
59
|
+
programId: PublicKey;
|
|
60
|
+
tokenAccount: Account;
|
|
61
|
+
}>;
|
|
62
|
+
export declare const getProgramIdOfToken: (owner: PublicKey, token: PublicKey, connection: Connection) => Promise<PublicKey>;
|
|
63
|
+
export declare const getSvmNativeBalance: (address: PublicKey, connection: Connection) => Promise<{
|
|
64
|
+
balance: import("bn.js");
|
|
65
|
+
formatted: number;
|
|
66
|
+
decimal: number;
|
|
67
|
+
}>;
|
|
68
|
+
export declare const getTokenBalance: (address: PublicKey, token: PublicKey, connection: Connection) => Promise<0 | import("@solana/web3.js").TokenAmount>;
|
|
69
|
+
export declare const getTokenAccountAccount: (token: PublicKey, address: PublicKey, connection: Connection) => Promise<Account | null>;
|
|
70
|
+
export declare const getTransferNativeInx: (from: PublicKey, to: PublicKey, amount: number) => Promise<TransactionInstruction>;
|
|
71
|
+
export declare const getTransferNativeTransaction: (from: Keypair, to: PublicKey, amount: number, connection: Connection) => Promise<VersionedTransaction>;
|
|
72
|
+
export declare const getTransferTokenInx: (from: PublicKey, to: PublicKey, token: TokenInfo, amount: number, connection: Connection) => Promise<TransactionInstruction[]>;
|
|
73
|
+
export declare const getTransferTokenTransaction: (from: Keypair, to: PublicKey, token: TokenInfo, amount: number, connection: Connection) => Promise<VersionedTransaction>;
|
|
74
|
+
export declare const signAndSendTransaction: (transaction: VersionedTransaction, connection: Connection, signers: Keypair[]) => Promise<string>;
|
|
75
|
+
export declare const getJupiterQuote: (inputMint: string, outputMint: string, amount: number, slippageBps?: number) => Promise<JupiterQuoteResponse>;
|
|
76
|
+
export declare const buildJupiterSwapTransaction: (quote: JupiterQuoteResponse, userPublicKey: string, prioritizationFeeLamports?: number) => Promise<JupiterSwapResponse>;
|
|
77
|
+
export declare const executeJupiterSwap: (swapParams: SwapParams, connection: Connection, payer: Keypair) => Promise<SwapResult>;
|
|
78
|
+
export declare const uiAmountToBaseUnits: (uiAmount: number, decimals: number) => number;
|
|
79
|
+
export declare const baseUnitsToUiAmount: (baseAmount: string | number, decimals: number) => number;
|
|
80
|
+
export declare const getJupiterTokenList: () => Promise<any[]>;
|
|
81
|
+
export declare const validateJupiterTokens: (inputMint: string, outputMint: string) => Promise<{
|
|
82
|
+
valid: boolean;
|
|
83
|
+
message?: string;
|
|
84
|
+
}>;
|
|
85
|
+
export {};
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//we will write all the svm utils function here
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.validateJupiterTokens = exports.getJupiterTokenList = exports.baseUnitsToUiAmount = exports.uiAmountToBaseUnits = exports.executeJupiterSwap = exports.buildJupiterSwapTransaction = exports.getJupiterQuote = exports.signAndSendTransaction = exports.getTransferTokenTransaction = exports.getTransferTokenInx = exports.getTransferNativeTransaction = exports.getTransferNativeInx = exports.getTokenAccountAccount = exports.getTokenBalance = exports.getSvmNativeBalance = exports.getProgramIdOfToken = exports.getSureAssociatedTokenAddressAndAccount = exports.createAtaAndIx = exports.createV0Transaction = void 0;
|
|
5
|
+
const spl_token_1 = require("@solana/spl-token");
|
|
6
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
7
|
+
const transactionSender_1 = require("./transactionSender");
|
|
8
|
+
const bn_js_1 = require("bn.js");
|
|
9
|
+
const JUPITER_BASE_URL = 'https://lite-api.jup.ag';
|
|
10
|
+
const createV0Transaction = async (connection, inX, signers, payerPubKey, blockHash) => {
|
|
11
|
+
const blockhash = blockHash || (await connection.getLatestBlockhash()).blockhash;
|
|
12
|
+
const message = new web3_js_1.TransactionMessage({
|
|
13
|
+
payerKey: payerPubKey,
|
|
14
|
+
instructions: inX,
|
|
15
|
+
recentBlockhash: blockhash,
|
|
16
|
+
}).compileToV0Message();
|
|
17
|
+
const transaction = new web3_js_1.VersionedTransaction(message);
|
|
18
|
+
transaction.message.staticAccountKeys;
|
|
19
|
+
if (signers.length < 1) {
|
|
20
|
+
transaction.sign(signers);
|
|
21
|
+
}
|
|
22
|
+
return transaction;
|
|
23
|
+
};
|
|
24
|
+
exports.createV0Transaction = createV0Transaction;
|
|
25
|
+
const createAtaAndIx = async (token, ownerPublicKey, tokenProgramId, connection) => {
|
|
26
|
+
let AtaTokenIx;
|
|
27
|
+
const associatedToken = (0, spl_token_1.getAssociatedTokenAddressSync)(token, ownerPublicKey, false, tokenProgramId);
|
|
28
|
+
const accountExist = await connection.getAccountInfo(associatedToken);
|
|
29
|
+
if (!accountExist) {
|
|
30
|
+
AtaTokenIx = (0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(ownerPublicKey, associatedToken, ownerPublicKey, token, tokenProgramId);
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
AtaTokenIx,
|
|
34
|
+
associatedToken,
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
exports.createAtaAndIx = createAtaAndIx;
|
|
38
|
+
const getSureAssociatedTokenAddressAndAccount = async (connection, token, owner) => {
|
|
39
|
+
let ATA;
|
|
40
|
+
let programId;
|
|
41
|
+
let tokenAccount;
|
|
42
|
+
try {
|
|
43
|
+
programId = token.equals(spl_token_1.NATIVE_MINT)
|
|
44
|
+
? spl_token_1.TOKEN_PROGRAM_ID
|
|
45
|
+
: spl_token_1.TOKEN_2022_PROGRAM_ID;
|
|
46
|
+
ATA = (0, spl_token_1.getAssociatedTokenAddressSync)(token, owner, true, programId);
|
|
47
|
+
tokenAccount = await (0, spl_token_1.getAccount)(connection, ATA, "confirmed", programId);
|
|
48
|
+
return { ATA, programId, tokenAccount };
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
programId = spl_token_1.TOKEN_PROGRAM_ID;
|
|
52
|
+
ATA = (0, spl_token_1.getAssociatedTokenAddressSync)(token, owner, true, programId);
|
|
53
|
+
tokenAccount = await (0, spl_token_1.getAccount)(connection, ATA, "confirmed", programId);
|
|
54
|
+
return { ATA, programId, tokenAccount };
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
exports.getSureAssociatedTokenAddressAndAccount = getSureAssociatedTokenAddressAndAccount;
|
|
58
|
+
const getProgramIdOfToken = async (owner, token, connection) => {
|
|
59
|
+
if (token.equals(spl_token_1.NATIVE_MINT)) {
|
|
60
|
+
return spl_token_1.TOKEN_PROGRAM_ID;
|
|
61
|
+
}
|
|
62
|
+
let ATA;
|
|
63
|
+
let programId = spl_token_1.TOKEN_PROGRAM_ID;
|
|
64
|
+
let tokenAccount;
|
|
65
|
+
try {
|
|
66
|
+
ATA = (0, spl_token_1.getAssociatedTokenAddressSync)(token, owner, true, programId);
|
|
67
|
+
tokenAccount = await (0, spl_token_1.getAccount)(connection, ATA, "confirmed", programId);
|
|
68
|
+
return spl_token_1.TOKEN_PROGRAM_ID;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
return spl_token_1.TOKEN_2022_PROGRAM_ID;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
exports.getProgramIdOfToken = getProgramIdOfToken;
|
|
75
|
+
//get native balance
|
|
76
|
+
const getSvmNativeBalance = async (address, connection) => {
|
|
77
|
+
const balance = await connection.getBalance(address);
|
|
78
|
+
return { balance: new bn_js_1.BN(balance), formatted: balance / web3_js_1.LAMPORTS_PER_SOL, decimal: 9 };
|
|
79
|
+
};
|
|
80
|
+
exports.getSvmNativeBalance = getSvmNativeBalance;
|
|
81
|
+
const getTokenBalance = async (address, token, connection) => {
|
|
82
|
+
try {
|
|
83
|
+
// Get the balance from the token account
|
|
84
|
+
const tokenAccount = await (0, exports.getTokenAccountAccount)(token, address, connection);
|
|
85
|
+
if (!tokenAccount) {
|
|
86
|
+
console.error("Token account not found");
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
const tokenBalance = await connection.getTokenAccountBalance(tokenAccount.address);
|
|
90
|
+
if (!tokenBalance) {
|
|
91
|
+
console.error("Token balance not found");
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
return tokenBalance.value;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
exports.getTokenBalance = getTokenBalance;
|
|
101
|
+
const getTokenAccountAccount = async (token, address, connection) => {
|
|
102
|
+
try {
|
|
103
|
+
// Get the associated token account address for the user and the token mint
|
|
104
|
+
const associatedTokenAccount = await (0, spl_token_1.getAssociatedTokenAddress)(token, // The token mint address
|
|
105
|
+
address // The user's public key
|
|
106
|
+
);
|
|
107
|
+
// Fetch the token account information
|
|
108
|
+
const tokenAccount = await (0, spl_token_1.getAccount)(connection, associatedTokenAccount);
|
|
109
|
+
return tokenAccount;
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
console.error("Error getting token balance:");
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
exports.getTokenAccountAccount = getTokenAccountAccount;
|
|
117
|
+
const getTransferNativeInx = async (from, to, amount) => {
|
|
118
|
+
return web3_js_1.SystemProgram.transfer({
|
|
119
|
+
fromPubkey: from,
|
|
120
|
+
toPubkey: to,
|
|
121
|
+
lamports: amount * web3_js_1.LAMPORTS_PER_SOL, // Convert SOL to lamports
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
exports.getTransferNativeInx = getTransferNativeInx;
|
|
125
|
+
const getTransferNativeTransaction = async (from, to, amount, connection) => {
|
|
126
|
+
const instruction = await (0, exports.getTransferNativeInx)(from.publicKey, to, amount);
|
|
127
|
+
const transaction = await (0, exports.createV0Transaction)(connection, [instruction], [from], from.publicKey);
|
|
128
|
+
return transaction;
|
|
129
|
+
};
|
|
130
|
+
exports.getTransferNativeTransaction = getTransferNativeTransaction;
|
|
131
|
+
const getTransferTokenInx = async (from, to, token, amount, connection) => {
|
|
132
|
+
const inx = [];
|
|
133
|
+
const tokenToSend = new web3_js_1.PublicKey(token.address);
|
|
134
|
+
const { ATA: source, programId, tokenAccount } = await (0, exports.getSureAssociatedTokenAddressAndAccount)(connection, from, tokenToSend);
|
|
135
|
+
const { associatedToken: destination, AtaTokenIx } = await (0, exports.createAtaAndIx)(tokenToSend, to, programId, connection);
|
|
136
|
+
if (!tokenAccount) {
|
|
137
|
+
throw new Error("Token account not found");
|
|
138
|
+
}
|
|
139
|
+
if (AtaTokenIx) {
|
|
140
|
+
inx.push(AtaTokenIx);
|
|
141
|
+
}
|
|
142
|
+
const tInx = (0, spl_token_1.createTransferCheckedInstruction)(source, tokenToSend, destination, from, amount, token.decimals, undefined, programId);
|
|
143
|
+
inx.push(tInx);
|
|
144
|
+
return inx;
|
|
145
|
+
};
|
|
146
|
+
exports.getTransferTokenInx = getTransferTokenInx;
|
|
147
|
+
const getTransferTokenTransaction = async (from, to, token, amount, connection) => {
|
|
148
|
+
const instruction = await (0, exports.getTransferTokenInx)(from.publicKey, to, token, amount, connection);
|
|
149
|
+
const transaction = await (0, exports.createV0Transaction)(connection, instruction, [from], from.publicKey);
|
|
150
|
+
return transaction;
|
|
151
|
+
};
|
|
152
|
+
exports.getTransferTokenTransaction = getTransferTokenTransaction;
|
|
153
|
+
const signAndSendTransaction = async (transaction, connection, signers) => {
|
|
154
|
+
transaction.sign(signers);
|
|
155
|
+
const blockhash = await connection.getLatestBlockhash();
|
|
156
|
+
const res = await (0, transactionSender_1.transactionSenderAndConfirmationWaiter)({ connection, serializedTransaction: Buffer.from(transaction.serialize()), blockhashWithExpiryBlockHeight: { blockhash: blockhash.blockhash, lastValidBlockHeight: blockhash.lastValidBlockHeight } });
|
|
157
|
+
if (!res) {
|
|
158
|
+
throw new Error("Transaction failed to send or confirm");
|
|
159
|
+
}
|
|
160
|
+
return res.transaction.signatures[0];
|
|
161
|
+
};
|
|
162
|
+
exports.signAndSendTransaction = signAndSendTransaction;
|
|
163
|
+
//swap
|
|
164
|
+
//you will. use jupiter for this
|
|
165
|
+
const getJupiterQuote = async (inputMint, outputMint, amount, slippageBps = 50) => {
|
|
166
|
+
const params = new URLSearchParams({
|
|
167
|
+
inputMint,
|
|
168
|
+
outputMint,
|
|
169
|
+
amount: amount.toString(),
|
|
170
|
+
slippageBps: slippageBps.toString(),
|
|
171
|
+
onlyDirectRoutes: 'false',
|
|
172
|
+
asLegacyTransaction: 'false'
|
|
173
|
+
});
|
|
174
|
+
const response = await fetch(`${JUPITER_BASE_URL}/swap/v1/quote?${params}`);
|
|
175
|
+
if (!response.ok) {
|
|
176
|
+
const error = await response.json();
|
|
177
|
+
throw new Error(`Jupiter quote failed: ${error.message || response.statusText}`);
|
|
178
|
+
}
|
|
179
|
+
return await response.json();
|
|
180
|
+
};
|
|
181
|
+
exports.getJupiterQuote = getJupiterQuote;
|
|
182
|
+
const buildJupiterSwapTransaction = async (quote, userPublicKey, prioritizationFeeLamports) => {
|
|
183
|
+
const body = {
|
|
184
|
+
quoteResponse: quote,
|
|
185
|
+
userPublicKey,
|
|
186
|
+
wrapAndUnwrapSol: true,
|
|
187
|
+
useSharedAccounts: true,
|
|
188
|
+
feeAccount: undefined,
|
|
189
|
+
trackingAccount: undefined,
|
|
190
|
+
computeUnitPriceMicroLamports: undefined,
|
|
191
|
+
prioritizationFeeLamports: prioritizationFeeLamports || 1000,
|
|
192
|
+
asLegacyTransaction: false,
|
|
193
|
+
useTokenLedger: false,
|
|
194
|
+
destinationTokenAccount: undefined,
|
|
195
|
+
dynamicComputeUnitLimit: true,
|
|
196
|
+
skipUserAccountsRpcCalls: false
|
|
197
|
+
};
|
|
198
|
+
const response = await fetch(`${JUPITER_BASE_URL}/swap/v1/swap`, {
|
|
199
|
+
method: 'POST',
|
|
200
|
+
headers: {
|
|
201
|
+
'Content-Type': 'application/json',
|
|
202
|
+
},
|
|
203
|
+
body: JSON.stringify(body),
|
|
204
|
+
});
|
|
205
|
+
if (!response.ok) {
|
|
206
|
+
const error = await response.json();
|
|
207
|
+
throw new Error(`Jupiter swap transaction build failed: ${error.message || response.statusText}`);
|
|
208
|
+
}
|
|
209
|
+
return await response.json();
|
|
210
|
+
};
|
|
211
|
+
exports.buildJupiterSwapTransaction = buildJupiterSwapTransaction;
|
|
212
|
+
const executeJupiterSwap = async (swapParams, connection, payer) => {
|
|
213
|
+
try {
|
|
214
|
+
console.log('Getting Jupiter quote...');
|
|
215
|
+
const quote = await (0, exports.getJupiterQuote)(swapParams.fromToken.toString(), swapParams.toToken.toString(), swapParams.amount, swapParams.slippageBps);
|
|
216
|
+
console.log('Quote received:', {
|
|
217
|
+
inputAmount: quote.inAmount,
|
|
218
|
+
outputAmount: quote.outAmount,
|
|
219
|
+
priceImpact: quote.priceImpactPct
|
|
220
|
+
});
|
|
221
|
+
console.log('Building swap transaction...');
|
|
222
|
+
const swapResponse = await (0, exports.buildJupiterSwapTransaction)(quote, swapParams.userPublicKey.toString());
|
|
223
|
+
console.log('Deserializing transaction...');
|
|
224
|
+
const swapTransactionBuf = Buffer.from(swapResponse.swapTransaction, 'base64');
|
|
225
|
+
const transaction = web3_js_1.VersionedTransaction.deserialize(swapTransactionBuf);
|
|
226
|
+
console.log('Signing transaction...');
|
|
227
|
+
transaction.sign([payer]);
|
|
228
|
+
console.log('Sending transaction...');
|
|
229
|
+
const blockhash = await connection.getLatestBlockhash();
|
|
230
|
+
const signature = await (0, transactionSender_1.transactionSenderAndConfirmationWaiter)({
|
|
231
|
+
connection,
|
|
232
|
+
serializedTransaction: Buffer.from(transaction.serialize()),
|
|
233
|
+
blockhashWithExpiryBlockHeight: {
|
|
234
|
+
blockhash: blockhash.blockhash,
|
|
235
|
+
lastValidBlockHeight: blockhash.lastValidBlockHeight
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
if (!signature) {
|
|
239
|
+
return {
|
|
240
|
+
success: false,
|
|
241
|
+
error: 'Transaction failed to confirm'
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
console.log('Swap successful! Signature:', signature.transaction.signatures[0]);
|
|
245
|
+
return {
|
|
246
|
+
success: true,
|
|
247
|
+
hash: signature.transaction.signatures[0],
|
|
248
|
+
inputAmount: quote.inAmount,
|
|
249
|
+
outputAmount: quote.outAmount,
|
|
250
|
+
priceImpact: quote.priceImpactPct
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
console.error('Jupiter swap failed:', error);
|
|
255
|
+
return {
|
|
256
|
+
success: false,
|
|
257
|
+
error: error instanceof Error ? error.message : 'Unknown error occurred'
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
exports.executeJupiterSwap = executeJupiterSwap;
|
|
262
|
+
const uiAmountToBaseUnits = (uiAmount, decimals) => {
|
|
263
|
+
return Math.floor(uiAmount * Math.pow(10, decimals));
|
|
264
|
+
};
|
|
265
|
+
exports.uiAmountToBaseUnits = uiAmountToBaseUnits;
|
|
266
|
+
const baseUnitsToUiAmount = (baseAmount, decimals) => {
|
|
267
|
+
return Number(baseAmount) / Math.pow(10, decimals);
|
|
268
|
+
};
|
|
269
|
+
exports.baseUnitsToUiAmount = baseUnitsToUiAmount;
|
|
270
|
+
const getJupiterTokenList = async () => {
|
|
271
|
+
try {
|
|
272
|
+
const response = await fetch(`${JUPITER_BASE_URL}/tokens/v1/mints/tradable`);
|
|
273
|
+
if (!response.ok) {
|
|
274
|
+
throw new Error(`Failed to fetch token list: ${response.statusText}`);
|
|
275
|
+
}
|
|
276
|
+
return await response.json();
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
console.error('Failed to fetch Jupiter token list:', error);
|
|
280
|
+
return [];
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
exports.getJupiterTokenList = getJupiterTokenList;
|
|
284
|
+
const validateJupiterTokens = async (inputMint, outputMint) => {
|
|
285
|
+
try {
|
|
286
|
+
const tokenList = await (0, exports.getJupiterTokenList)();
|
|
287
|
+
const inputSupported = tokenList.includes(inputMint);
|
|
288
|
+
const outputSupported = tokenList.includes(outputMint);
|
|
289
|
+
if (!inputSupported && !outputSupported) {
|
|
290
|
+
return { valid: false, message: 'Both input and output tokens are not supported' };
|
|
291
|
+
}
|
|
292
|
+
if (!inputSupported) {
|
|
293
|
+
return { valid: false, message: 'Input token is not supported' };
|
|
294
|
+
}
|
|
295
|
+
if (!outputSupported) {
|
|
296
|
+
return { valid: false, message: 'Output token is not supported' };
|
|
297
|
+
}
|
|
298
|
+
return { valid: true };
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
return { valid: false, message: 'Failed to validate tokens' };
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
exports.validateJupiterTokens = validateJupiterTokens;
|
|
305
|
+
//# sourceMappingURL=utils.js.map
|