@symmetry-hq/liquidity-sdk
Version:
Exchange functionality using symmetry funds liquidity
154 lines (153 loc) • 8.05 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.prepareAccounts = exports.createAssociatedTokenAccount = exports.createSyncNativeInstruction = exports.delay = exports.sendAndConfirmTransaction = exports.applyBlockHashAndPartialSign = void 0;
const borsh_1 = require("@coral-xyz/borsh");
const spl_token_1 = require("@solana/spl-token");
const web3_js_1 = require("@solana/web3.js");
function applyBlockHashAndPartialSign(connection, wallet, preTransaction, transaction, postTransaction, preSigners, signers) {
return __awaiter(this, void 0, void 0, function* () {
let { blockhash } = yield connection.getRecentBlockhash('processed');
let result = [];
let txIndex = 0;
if (preTransaction.instructions.length > 0) {
txIndex = 1;
preTransaction.recentBlockhash = blockhash;
preTransaction.feePayer = wallet.publicKey;
preTransaction.setSigners(wallet.publicKey, ...preSigners.map((s) => s.publicKey));
if (preSigners.length > 0)
preTransaction.partialSign(...preSigners);
result.push(preTransaction);
}
transaction.recentBlockhash = blockhash;
transaction.feePayer = wallet.publicKey;
transaction.setSigners(wallet.publicKey, ...signers.map((s) => s.publicKey));
if (signers.length > 0)
transaction.partialSign(...signers);
result.push(transaction);
if (postTransaction.instructions.length > 0) {
postTransaction.recentBlockhash = blockhash;
postTransaction.feePayer = wallet.publicKey;
postTransaction.setSigners(wallet.publicKey, ...signers.map((s) => s.publicKey));
if (signers.length > 0)
postTransaction.partialSign(...signers);
result.push(postTransaction);
}
return {
txIndex: txIndex,
transactions: result
};
});
}
exports.applyBlockHashAndPartialSign = applyBlockHashAndPartialSign;
function sendAndConfirmTransaction(connection, serialized) {
return __awaiter(this, void 0, void 0, function* () {
let tries = 0;
let signature = null;
let signatureResponse = null;
while (true) {
connection.sendRawTransaction(serialized, { skipPreflight: true }).catch((e) => {
return null;
}).then(result => { if (!signature)
signature = result; });
if (signature) {
if (tries % 2 == 0) {
let response = yield connection.getTransaction(signature, { commitment: "confirmed" }).catch(() => { return "Error"; });
if (response) {
signatureResponse = response;
break;
}
}
}
tries = tries + 1;
if (tries == 30)
break;
yield delay(1000);
}
return {
signature: signature,
response: signatureResponse
};
});
}
exports.sendAndConfirmTransaction = sendAndConfirmTransaction;
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
exports.delay = delay;
function createSyncNativeInstruction(nativeAccount) {
const dataLayout = (0, borsh_1.struct)([
(0, borsh_1.u8)("instruction"),
]);
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode({
instruction: 17, // SyncNative instruction
}, data);
const keys = [{ pubkey: nativeAccount, isSigner: false, isWritable: true }];
return new web3_js_1.TransactionInstruction({
keys,
programId: spl_token_1.TOKEN_PROGRAM_ID,
data,
});
}
exports.createSyncNativeInstruction = createSyncNativeInstruction;
function createAssociatedTokenAccount(account, owner, mintAddress, connection, transaction, atas = []) {
return __awaiter(this, void 0, void 0, function* () {
let publicKey;
if (account) {
publicKey = new web3_js_1.PublicKey(account);
}
const mint = new web3_js_1.PublicKey(mintAddress);
const ata = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, owner);
const infoAta = yield connection.getAccountInfo(ata);
if ((!publicKey || !ata.equals(publicKey)) && !atas.includes(ata.toBase58()) && !infoAta) {
transaction.add((0, spl_token_1.createAssociatedTokenAccountInstruction)(owner, ata, owner, mint));
atas.push(ata.toBase58());
}
return ata;
});
}
exports.createAssociatedTokenAccount = createAssociatedTokenAccount;
function prepareAccounts(wallet, connection, tokenListData, routeData, fromTokenAccount, toTokenAccount) {
return __awaiter(this, void 0, void 0, function* () {
let preTransaction = new web3_js_1.Transaction();
let postTransaction = new web3_js_1.Transaction();
if (fromTokenAccount == undefined || fromTokenAccount.equals(wallet.publicKey)) {
if (tokenListData[routeData.fromTokenId].tokenMint === "So11111111111111111111111111111111111111112") {
fromTokenAccount = yield createAssociatedTokenAccount(fromTokenAccount === null || fromTokenAccount === void 0 ? void 0 : fromTokenAccount.toBase58(), wallet.publicKey, tokenListData[routeData.fromTokenId].tokenMint, connection, preTransaction);
preTransaction.add(web3_js_1.SystemProgram.transfer({
fromPubkey: wallet.publicKey,
toPubkey: fromTokenAccount,
lamports: routeData.fromAmount * 1e9 + 1e7, // 1 sol
}));
preTransaction.add(createSyncNativeInstruction(fromTokenAccount));
postTransaction.add((0, spl_token_1.createCloseAccountInstruction)(fromTokenAccount, wallet.publicKey, wallet.publicKey));
}
else
fromTokenAccount = yield createAssociatedTokenAccount(fromTokenAccount === null || fromTokenAccount === void 0 ? void 0 : fromTokenAccount.toBase58(), wallet.publicKey, tokenListData[routeData.fromTokenId].tokenMint, connection, preTransaction);
}
if (toTokenAccount == undefined || toTokenAccount.equals(wallet.publicKey)) {
if (tokenListData[routeData.toTokenId].tokenMint === "So11111111111111111111111111111111111111112") {
toTokenAccount = yield createAssociatedTokenAccount(toTokenAccount === null || toTokenAccount === void 0 ? void 0 : toTokenAccount.toBase58(), wallet.publicKey, tokenListData[routeData.toTokenId].tokenMint, connection, preTransaction);
postTransaction.add((0, spl_token_1.createCloseAccountInstruction)(toTokenAccount, wallet.publicKey, wallet.publicKey));
}
else
toTokenAccount = yield createAssociatedTokenAccount(toTokenAccount === null || toTokenAccount === void 0 ? void 0 : toTokenAccount.toBase58(), wallet.publicKey, tokenListData[routeData.toTokenId].tokenMint, connection, preTransaction);
}
return {
preTransaction: preTransaction,
postTransaction: postTransaction,
fromTokenAccount: fromTokenAccount,
toTokenAccount: toTokenAccount,
};
});
}
exports.prepareAccounts = prepareAccounts;