UNPKG

@frakters/nft-lending-v2

Version:

Client library for interacting with nft lenging solana program

356 lines (355 loc) 15.7 kB
"use strict"; 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.getFilteredTokenAccountsByOwner = exports.getMintDecimals = exports.mergeTransactions = exports.sendTransaction = exports.signTransaction = exports.getMultipleAccounts = exports.getFilteredProgramAccountsAmmOrMarketCache = exports.getFilteredProgramAccounts = exports.createAssociatedTokenAccount = exports.createProgramAccountIfNotExist = exports.createAtaSolIfNotExistAndWrap = exports.createAssociatedTokenAccountIfNotExist = exports.createTokenAccountIfNotExist = exports.findAssociatedStakeInfoAddress = exports.findAssociatedTokenAddress = exports.createAssociatedId = exports.createAmmAuthority = exports.findProgramAddress = exports.commitment = exports.web3Config = void 0; const token_instructions_1 = require("@project-serum/serum/lib/token-instructions"); // @ts-ignore without ts ignore, yarn build will failed const spl_token_1 = require("@solana/spl-token"); const web3_js_1 = require("@solana/web3.js"); const ids_1 = require("./ids"); const layouts_1 = require("./layouts"); const tokens_1 = require("./tokens"); exports.web3Config = { strategy: 'speed', rpcs: [ { url: 'https://api.devnet.solana.com', weight: 10 }, { url: 'https://api.devnet.solana.com', weight: 10 }, { url: 'https://api.devnet.solana.com', weight: 10 }, { url: 'https://api.devnet.solana.com', weight: 10 }, { url: 'https://api.devnet.solana.com', weight: 50 }, { url: 'https://api.mainnet-beta.solana.com', weight: 10 }, ], }; // export const commitment: Commitment = 'processed' exports.commitment = 'confirmed'; // export const commitment: Commitment = 'finalized' function findProgramAddress(seeds, programId) { return __awaiter(this, void 0, void 0, function* () { const [publicKey, nonce] = yield web3_js_1.PublicKey.findProgramAddress(seeds, programId); return { publicKey, nonce }; }); } exports.findProgramAddress = findProgramAddress; function createAmmAuthority(programId) { return __awaiter(this, void 0, void 0, function* () { return yield findProgramAddress([new Uint8Array(Buffer.from('amm authority'.replace('\u00A0', ' '), 'utf-8'))], programId); }); } exports.createAmmAuthority = createAmmAuthority; function createAssociatedId(infoId, marketAddress, bufferKey) { return __awaiter(this, void 0, void 0, function* () { const { publicKey } = yield findProgramAddress([infoId.toBuffer(), marketAddress.toBuffer(), Buffer.from(bufferKey)], infoId); return publicKey; }); } exports.createAssociatedId = createAssociatedId; function findAssociatedTokenAddress(walletAddress, tokenMintAddress) { return __awaiter(this, void 0, void 0, function* () { const { publicKey } = yield findProgramAddress([walletAddress.toBuffer(), ids_1.TOKEN_PROGRAM_ID.toBuffer(), tokenMintAddress.toBuffer()], ids_1.ASSOCIATED_TOKEN_PROGRAM_ID); return publicKey; }); } exports.findAssociatedTokenAddress = findAssociatedTokenAddress; function findAssociatedStakeInfoAddress(poolId, walletAddress, programId) { return __awaiter(this, void 0, void 0, function* () { const { publicKey } = yield findProgramAddress([poolId.toBuffer(), walletAddress.toBuffer(), Buffer.from('staker_info_v2_associated_seed')], programId); return publicKey; }); } exports.findAssociatedStakeInfoAddress = findAssociatedStakeInfoAddress; function createTokenAccountIfNotExist(connection, account, owner, mintAddress, lamports, transaction, signer) { return __awaiter(this, void 0, void 0, function* () { let publicKey; if (account) { publicKey = new web3_js_1.PublicKey(account); } else { publicKey = yield createProgramAccountIfNotExist(connection, account, owner, ids_1.TOKEN_PROGRAM_ID, lamports, layouts_1.ACCOUNT_LAYOUT, transaction, signer); transaction.add(token_instructions_1.initializeAccount({ account: publicKey, mint: new web3_js_1.PublicKey(mintAddress), owner, })); } return publicKey; }); } exports.createTokenAccountIfNotExist = createTokenAccountIfNotExist; function createAssociatedTokenAccountIfNotExist(account, owner, mintAddress, 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); // @ts-ignore without ts ignore, yarn build will failed const ata = yield spl_token_1.Token.getAssociatedTokenAddress(ids_1.ASSOCIATED_TOKEN_PROGRAM_ID, ids_1.TOKEN_PROGRAM_ID, mint, owner, true); if ((!publicKey || !ata.equals(publicKey)) && !atas.includes(ata.toBase58())) { transaction.add(spl_token_1.Token.createAssociatedTokenAccountInstruction(ids_1.ASSOCIATED_TOKEN_PROGRAM_ID, ids_1.TOKEN_PROGRAM_ID, mint, ata, owner, owner)); atas.push(ata.toBase58()); } return ata; }); } exports.createAssociatedTokenAccountIfNotExist = createAssociatedTokenAccountIfNotExist; function createAtaSolIfNotExistAndWrap(connection, account, owner, transaction, signers, amount) { 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(tokens_1.TOKENS.WSOL.mintAddress); // @ts-ignore without ts ignore, yarn build will failed const ata = yield spl_token_1.Token.getAssociatedTokenAddress(ids_1.ASSOCIATED_TOKEN_PROGRAM_ID, ids_1.TOKEN_PROGRAM_ID, mint, owner, true); if (!publicKey) { const rent = yield spl_token_1.Token.getMinBalanceRentForExemptAccount(connection); transaction.add(web3_js_1.SystemProgram.transfer({ fromPubkey: owner, toPubkey: ata, lamports: amount + rent }), spl_token_1.Token.createAssociatedTokenAccountInstruction(ids_1.ASSOCIATED_TOKEN_PROGRAM_ID, ids_1.TOKEN_PROGRAM_ID, mint, ata, owner, owner)); } else { const rent = yield spl_token_1.Token.getMinBalanceRentForExemptAccount(connection); const wsol = yield createTokenAccountIfNotExist(connection, null, owner, tokens_1.TOKENS.WSOL.mintAddress, amount + rent, transaction, signers); transaction.add(spl_token_1.Token.createTransferInstruction(ids_1.TOKEN_PROGRAM_ID, wsol, ata, owner, [], amount), spl_token_1.Token.createCloseAccountInstruction(ids_1.TOKEN_PROGRAM_ID, wsol, owner, owner, [])); } }); } exports.createAtaSolIfNotExistAndWrap = createAtaSolIfNotExistAndWrap; function createProgramAccountIfNotExist(connection, account, owner, programId, lamports, layout, transaction, signer) { return __awaiter(this, void 0, void 0, function* () { let publicKey; if (account) { publicKey = new web3_js_1.PublicKey(account); } else { const newAccount = new web3_js_1.Account(); publicKey = newAccount.publicKey; transaction.add(web3_js_1.SystemProgram.createAccount({ fromPubkey: owner, newAccountPubkey: publicKey, lamports: lamports !== null && lamports !== void 0 ? lamports : (yield connection.getMinimumBalanceForRentExemption(layout.span)), space: layout.span, programId, })); signer.push(newAccount); } return publicKey; }); } exports.createProgramAccountIfNotExist = createProgramAccountIfNotExist; function createAssociatedTokenAccount(tokenMintAddress, owner, transaction) { return __awaiter(this, void 0, void 0, function* () { const associatedTokenAddress = yield findAssociatedTokenAddress(owner, tokenMintAddress); const keys = [ { pubkey: owner, isSigner: true, isWritable: false, }, { pubkey: associatedTokenAddress, isSigner: false, isWritable: true, }, { pubkey: owner, isSigner: false, isWritable: false, }, { pubkey: tokenMintAddress, isSigner: false, isWritable: false, }, { pubkey: ids_1.SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false, }, { pubkey: ids_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false, }, { pubkey: ids_1.RENT_PROGRAM_ID, isSigner: false, isWritable: false, }, ]; transaction.add(new web3_js_1.TransactionInstruction({ keys, programId: ids_1.ASSOCIATED_TOKEN_PROGRAM_ID, data: Buffer.from([]), })); return associatedTokenAddress; }); } exports.createAssociatedTokenAccount = createAssociatedTokenAccount; function getFilteredProgramAccounts(connection, programId, filters) { return __awaiter(this, void 0, void 0, function* () { // @ts-ignore const resp = yield connection._rpcRequest('getProgramAccounts', [ programId.toBase58(), { commitment: connection.commitment, filters, encoding: 'base64', }, ]); if (resp.error) { throw new Error(resp.error.message); } // @ts-ignore return resp.result.map(({ pubkey, account: { data, executable, owner, lamports } }) => ({ publicKey: new web3_js_1.PublicKey(pubkey), accountInfo: { data: Buffer.from(data[0], 'base64'), executable, owner: new web3_js_1.PublicKey(owner), lamports, }, })); }); } exports.getFilteredProgramAccounts = getFilteredProgramAccounts; function getFilteredProgramAccountsAmmOrMarketCache(cacheName, connection, programId, filters) { return __awaiter(this, void 0, void 0, function* () { try { if (!cacheName) { throw new Error('cacheName error'); } const resp = yield (yield fetch('https://api.raydium.io/cache/rpc/' + cacheName)).json(); if (resp.error) { throw new Error(resp.error.message); } // @ts-ignore return resp.result.map(({ pubkey, account: { data, executable, owner, lamports } }) => ({ publicKey: new web3_js_1.PublicKey(pubkey), accountInfo: { data: Buffer.from(data[0], 'base64'), executable, owner: new web3_js_1.PublicKey(owner), lamports, }, })); } catch (e) { return getFilteredProgramAccounts(connection, programId, filters); } }); } exports.getFilteredProgramAccountsAmmOrMarketCache = getFilteredProgramAccountsAmmOrMarketCache; // getMultipleAccounts function getMultipleAccounts(connection, publicKeys, commitment) { return __awaiter(this, void 0, void 0, function* () { const keys = []; let tempKeys = []; publicKeys.forEach((k) => { if (tempKeys.length >= 100) { keys.push(tempKeys); tempKeys = []; } tempKeys.push(k); }); if (tempKeys.length > 0) { keys.push(tempKeys); } const accounts = []; const resArray = {}; yield Promise.all(keys.map((key, index) => __awaiter(this, void 0, void 0, function* () { const res = yield connection.getMultipleAccountsInfo(key, commitment); resArray[index] = res; }))); Object.keys(resArray) .sort((a, b) => parseInt(a) - parseInt(b)) .forEach((itemIndex) => { const res = resArray[parseInt(itemIndex)]; for (const account of res) { accounts.push(account); } }); return accounts.map((account, idx) => { if (account === null) { return null; } return { publicKey: publicKeys[idx], account, }; }); }); } exports.getMultipleAccounts = getMultipleAccounts; // transaction function signTransaction(connection, wallet, transaction, signers = []) { return __awaiter(this, void 0, void 0, function* () { transaction.recentBlockhash = (yield connection.getRecentBlockhash()).blockhash; transaction.setSigners(wallet.publicKey, ...signers.map((s) => s.publicKey)); if (signers.length > 0) { transaction.partialSign(...signers); } return yield wallet.signTransaction(transaction); }); } exports.signTransaction = signTransaction; function sendTransaction(connection, wallet, transaction, signers = []) { return __awaiter(this, void 0, void 0, function* () { const txid = yield wallet.sendTransaction(transaction, connection, { signers, skipPreflight: true, preflightCommitment: exports.commitment, }); return txid; }); } exports.sendTransaction = sendTransaction; function mergeTransactions(transactions) { const transaction = new web3_js_1.Transaction(); transactions .filter((t) => t !== undefined) .forEach((t) => { transaction.add(t); }); return transaction; } exports.mergeTransactions = mergeTransactions; function throwIfNull(value, message = 'account not found') { if (value === null) { throw new Error(message); } return value; } function getMintDecimals(connection, mint) { return __awaiter(this, void 0, void 0, function* () { const { data } = throwIfNull(yield connection.getAccountInfo(mint), 'mint not found'); const { decimals } = layouts_1.MINT_LAYOUT.decode(data); return decimals; }); } exports.getMintDecimals = getMintDecimals; function getFilteredTokenAccountsByOwner(connection, programId, mint) { return __awaiter(this, void 0, void 0, function* () { // @ts-ignore const resp = yield connection._rpcRequest('getTokenAccountsByOwner', [ programId.toBase58(), { mint: mint.toBase58(), }, { encoding: 'jsonParsed', }, ]); if (resp.error) { throw new Error(resp.error.message); } return resp.result; }); } exports.getFilteredTokenAccountsByOwner = getFilteredTokenAccountsByOwner;