diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..23a378a --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ + +## Installation + +1. Clone this repository to your local machine. +2. Navigate to the cloned directory . +3. Install dependencies using your package manager of choice: `npm install` or `yarn install`. + + +## Verbose Manual + +Go to `Sniper Mode` => `usage` + +## Usage: +start Application: `npm run start`. + +## Config + +All configurations should prefereably be done inside the settings menu of the application. + +# Contributing + +Contributions are welcome! If you find a bug or want to enhance the application, feel free to create an issue or submit a pull request. + diff --git a/build/auth/KeyAuth.js b/build/auth/KeyAuth.js new file mode 100644 index 0000000..b0cebc4 --- /dev/null +++ b/build/auth/KeyAuth.js @@ -0,0 +1,596 @@ +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()); + }); +}; +//* Importing ExecSync from "child_process" *// +const { execSync } = require('child_process'); +//* Importing Axios *// +const axios = require('axios'); +//* Importing OS *// +const os = require('os'); +//* Import FS *// +const fs = require("fs"); +//* KeyAuth Class *// +class KeyAuth { + /** + * @param {string} [name] - The name of the application + * @param {string} [ownerId] - The ownerId of the application + * @param {string} [secret] - The secret of the application + * @param {string} [version] - The version of the application + **/ + constructor(name, ownerId, secret, version) { + /** + * Initializes the connection with KeyAuth in order to use any of the functions + **/ + this.Initialize = () => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + const post_data = { + type: 'init', + ver: this.version, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + if (Json === 'KeyAuth_Invalid') { + Misc.error('Invalid Application, please check your application details.'); + } + if (!Json.success || Json.success == false) { + return resolve(false); + } + this.app_data = Json.appinfo; + this.sessionid = Json.sessionid; + this.initialized = true; + resolve(true); + })); + /** + * Registers the user using a license and gives the user a subscription that matches their license level + * @param {string} [username] - The username for the user + * @param {string} [password] - The password for the user + * @param {string} [license] - The License Key for the sub + **/ + this.register = (user, password, license, email = "") => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + let hwId; + if (!hwId) { + hwId = Misc.GetCurrentHardwareId(); + } + const post_data = { + type: 'register', + username: user, + pass: password, + email, + key: license, + hwid: hwId, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success) { + this.Load_User_Data(Json.info); + return resolve(Json.message); + } + else { + Misc.error(Json.message); + } + })); + this.forgot = (username, email) => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'forgot', + username, + email, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + })); + /** + * Authenticates the user using their username and password + * @param {string} [username] - The username for the user + * @param {string} [password] - The password for the user + **/ + this.login = (username, password) => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + let hwId; + if (!hwId) { + hwId = Misc.GetCurrentHardwareId(); + } + const post_data = { + type: 'login', + username, + pass: password, + hwid: hwId, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + this.Load_User_Data(Json.info); + return resolve(Json); + } + else { + Misc.error(Json.message); + } + })); + /** + * Authenticate without using usernames and passwords + * @param {string} [key] - Licence used to login with + **/ + this.license = (key) => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + let hwId; + if (!hwId) { + hwId = Misc.GetCurrentHardwareId(); + } + const post_data = { + type: 'license', + key, + hwid: hwId, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + this.Load_User_Data(Json.info); + return resolve(Json); + } + else { + Misc.error(Json.message); + } + })); + /** + * Gives the user a subscription that has the same level as the key + * @param {string} [username] - Username of the user thats going to get upgraded + * @param {string} [license] - License with the same level as the subscription you want to give the user + **/ + this.upgrade = (username, license) => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'upgrade', + username, + key: license, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (!Json.success || Json.success == false) { + return resolve(Json.message); + } + else { + // Don't let them yet for dashboard. + Misc.error(Json.message); + } + })); + /** + * Gets an existing global variable + * @param {string} [VarId] - Name of the variable / Variable ID + * returns {string} - The value of the variable / The content of the variable + **/ + this.var = (VarId) => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'var', + varid: VarId, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + return resolve(Json); + } + resolve(Json.message); + })); + /** + * Gets the an existing user variable + * @Param {string} [VarId] - User Variable Name + * returns {string} - The value of the variable / The content of the user variable + **/ + this.GetVar = (VarId) => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'getvar', + var: VarId, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + return resolve(Json); + } + resolve(Json.message); + })); + /** + * Change the data of an existing user variable, *User must be logged in* + * @Param {string} [VarId] - User variable name + * @Param {string} [VarData] - The content of the variable + **/ + this.SetVar = (VarId, VarData) => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'setvar', + var: VarId, + data: VarData, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + return resolve(Json); + } + resolve(Json.message); + })); + /** + * Bans the current logged in user + **/ + this.ban = () => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'ban', + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + return resolve(true); + } + resolve(Json.message); + })); + /** + * KeyAuth acts as proxy and downlods the file in a secure way + * @Param {string} [fileId] - File ID + * @Param {string} [path] - Path to save the file + * @Param {boolean} [execute] - Execute the file after download - Windows Only Requires path for file! + * returns {byte} - Returns The bytes of the download file + **/ + this.file = (fileId, path = null, execute = false) => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'file', + fileid: fileId.toString(), + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + if (path != null) { + var bytes = yield this.strToByteArray(Json.contents); + fs.writeFile(path, bytes, (err) => __awaiter(this, void 0, void 0, function* () { + if (err) + throw err; + if (execute) { + var exec = require('child_process').exec; + yield exec(path, function (error, stdout, stderr) { + if (error) { + console.error(error); + return; + } + }); + return resolve(true); + } + else { + return resolve(true); + } + })); + } + else { + return resolve(this.strToByteArray(Json.contents)); + } + } + resolve(Json.message); + })); + /** + * Sends a request to a webhook that you've added in the dashboard in a safe way without it being showed for example a http debugger + * @Param {string} [webId] - Webhook ID + * @Param {string} [Params] - Webhook Parameters + * @Param {string} [message] - Body of the request, empty by default + * @Param {string} [username] - Content type, empty by default + * Returns {string} - Returns the response of the webhook + **/ + this.webhook = (webId, Params, body = '', contType = '') => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'webhook', + webid: webId, + params: Params, + body, + conttype: contType, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + return resolve(Json.response); + } + resolve(Json.message); + })); + /** + * Check if the current session is validated or not + * Returns {string} - Returns if the session is valid or not + **/ + this.check = () => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'check', + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + return resolve(Json); + } + ; + resolve(Json.message); + })); + /** + * Checks if the current IP Address/HardwareId is blacklisted + * returns {boolean} - Returns true if the IP Address/HardwareId is blacklisted, otherwise false + **/ + this.checkBlack = () => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const hwId = Misc.GetCurrentHardwareId(); + const post_data = { + type: 'checkblacklist', + hwid: hwId, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + return resolve(true); + } + resolve(false); + })); + /** + * Fetch usernames of online users + * Returns {array} - Returns an array of usernames + **/ + this.fetchOnline = () => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'fetchOnline', + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + return resolve(Json.users); + } + else { + return resolve(Json.message); + } + })); + /** + * Gets the last 20 sent messages of that channel + * @param {string} [ChannelName] - The name of the channel, where you want the messages + * Returns {array} the last 20 sent messages of that channel + **/ + this.ChatGet = (ChannelName) => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'chatget', + channel: ChannelName, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + if (Json.messages[0].message == 'not_found') { + return resolve([]); + } + else { + return resolve(Json.messages); + } + } + else { + return resolve([]); + } + })); + /** + * Sends a message to the given channel name + * @param {string} [ChannelName] - Channel Name where the message will be sent to + * @param {string} [Message] - Message what will be sent to [ChannelName] + * Returns {bool} - Returns true if the message was sent, otherwise false + **/ + this.ChatSend = (ChannelName, Message) => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'fetchOnline', + message: Message, + channel: ChannelName, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + const Json = yield this.make_request(post_data); + this.Load_Response_Struct(Json); + if (Json.success && Json.success == true) { + return resolve(true); + } + else { + return resolve(false); + } + })); + /** + * Logs the IP address,PC Name with a message, if a discord webhook is set up in the app settings, the log will get sent there and the dashboard if not set up it will only be in the dashboard + * @param {string} [message] - Message / Discord Embed Title Message + * Returns None + **/ + this.log = (message) => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + this.check_initialize(); + const post_data = { + type: 'log', + pcuser: os.userInfo().username, + message, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + }; + yield this.make_request(post_data); + resolve(true); + })); + this.strToByteArray = (hex) => new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + try { + const numberChars = hex.length; + const bytes = new Uint8Array(numberChars / 2); + for (let i = 0; i < numberChars; i += 2) { + bytes[i / 2] = parseInt(hex.substr(i, 2), 16); + } + resolve(bytes); + } + catch (err) { + console.error('The session has ended, open program again.'); + process.exit(0); + } + })); + if (!(name && ownerId && secret && version)) { + Misc.error('Application not setup correctly.'); + } + this.name = name; + this.ownerId = ownerId; + this.secret = secret; + this.version = version; + this.responseTime = null; + } + ; + /** + * Check if the current session is initialized + * @returns [true] if client is Initialized. + **/ + check_initialize() { + if (!this.initialized) { + Misc.error('You must initialize the API before using it!'); + } + return true; + } + ; + /** + * Load the response struct for Response of Request + **/ + Load_Response_Struct(data) { + this.response = { + success: data.success, + message: data.message + }; + } + ; + /** + * Load the response struct for User Data + **/ + Load_User_Data(data) { + this.user_data = { + username: data.username, + ip: data.ip, + hwid: data.hwid, + createdate: data.createdate, + lastlogin: data.lastlogin, + subscriptions: data.subscriptions + }; + } + ; + /** + * Change Console Application Title + * @param {string} [title] - Your new Title for the App + * Returns Promise Timeout + **/ + setTitle(title) { + process.stdout.write(String.fromCharCode(27) + ']0;' + title + String.fromCharCode(7)); + } + ; + /** + * Sleeping / Timeout Function + * @param {number} [ms] - Time in milliseconds + * Returns Promise Timeout + **/ + sleep(ms) { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); + } + ; + /** + * Request the API with the POST Data + * @param {string} [data] - Post Data Array + * Returns {array} - Returns the API Response [NON-ENCRYPTED] + **/ + make_request(data) { + const startTime = Date.now(); // Start the stopwatch + return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + const request = yield axios({ + method: 'POST', + url: 'https://keyauth.win/api/1.1/', + data: new URLSearchParams(data).toString() + }).catch((err) => { + Misc.error(err); + }); + const endTime = Date.now(); // Stop the stopwatch + this.responseTime = `${endTime - startTime} ms`; + if (request && request.data) { + resolve(request.data); + } + else { + resolve(null); + } + ; + })); + } +} +class Misc { + /** + * Get the current user HardwareId + * @returns {string} - Returns user HardwareID + **/ + static GetCurrentHardwareId() { + if (os.platform() != 'win32') + return false; + const cmd = execSync('wmic useraccount where name="%username%" get sid').toString('utf-8'); + const system_id = cmd.split('\n')[1].trim(); + return system_id; + } + ; + /** + * Error Print Function + * @param {string} [message] - Message to Show and then exit app. + **/ + static error(message) { + console.log(message); + return process.exit(0); + } +} +/** + * Export KeyAuth Class to be used in other files +**/ +module.exports = KeyAuth; diff --git a/build/auth/checkKey.js b/build/auth/checkKey.js new file mode 100644 index 0000000..4bc4467 --- /dev/null +++ b/build/auth/checkKey.js @@ -0,0 +1,33 @@ +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()); + }); +}; +const KeyAuth = require('./KeyAuth'); +const readline = require("readline"); +const moment = require("moment"); +const CRL = readline.createInterface({ input: process.stdin, output: process.stdout }); +const KeyAuthApp = new KeyAuth("DexSpyder", "8d7VumkIWc", "86342a655b33a96164cf9899837d05e20b8e568bacbd414c3a3839c21dab7eab", // Application Secret +"1.0"); +(() => __awaiter(this, void 0, void 0, function* () { + yield KeyAuthApp.Initialize(); + yield KeyAuthApp.check(); + yield KeyAuthApp.sleep(1200); + var license = ""; + yield CRL.question("License : ", (lic) => __awaiter(this, void 0, void 0, function* () { + license = lic; + yield KeyAuthApp.license(license); + if (KeyAuthApp.response.status == "failed") { + console.log(KeyAuthApp.response.message); + process.exit(0); + } + console.log(KeyAuthApp.response.message); + yield CRL.question("Press any key to continue...", () => __awaiter(this, void 0, void 0, function* () { + console.clear(); + })); + })); +}))(); diff --git a/build/config.json b/build/config.json new file mode 100644 index 0000000..cda38c2 --- /dev/null +++ b/build/config.json @@ -0,0 +1 @@ +{"webhook_url":"None","rpc_endpoint":"https://white-quiet-glitter.solana-mainnet.quiknode.pro/2d4bcbb69148d23b481215ff6c3776ecb183f698/","wallet":"2tRxLG6a5dWmrAi4TdFS9KtGo5VEFBNtpA79P3cB163n74Mzkgaws4cUncDzFd9HwTAJdikWMugKZ7FY31mwEFnB","slippage":5,"license":"ZeNA-dN2b-cUVu-zr1A"} \ No newline at end of file diff --git a/build/main.js b/build/main.js new file mode 100644 index 0000000..3d5bbb3 --- /dev/null +++ b/build/main.js @@ -0,0 +1,525 @@ +"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()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const readline_1 = __importDefault(require("readline")); +const utils_1 = __importDefault(require("./utils")); +const chalk_1 = __importDefault(require("chalk")); +const config_1 = require("./modules/config"); +const fs_1 = __importDefault(require("fs")); +const cli_spinners_1 = __importDefault(require("cli-spinners")); +const fetch_token_1 = require("./modules/fetch_token"); +const request_1 = require("request"); +const hwid_1 = require("hwid"); +const get_keypair_1 = require("./modules/get_keypair"); +const web3_js_1 = require("@solana/web3.js"); +const pool_keys_1 = require("./modules/pool_keys"); +const compute_1 = require("./modules/compute"); +const swap_1 = require("./modules/swap"); +const get_accounts_1 = require("./modules/get_accounts"); +//control variables +var choice = 0; +//key auth instance +//spinner function +const Spinner = cli_spinners_1.default.dots4; +let i = 0; +let animationInterval; +const updateSpinner = () => { + const frame = Spinner.frames[i % Spinner.frames.length]; + process.stdout.cursorTo(0); + process.stdout.write('\t' + frame); + i++; +}; +const startSpinner = () => { + animationInterval = setInterval(updateSpinner, Spinner.interval); +}; +const stopSpinner = () => { + clearInterval(animationInterval); + process.stdout.clearLine(0); + process.stdout.cursorTo(0); +}; +//creating interface +const rl = readline_1.default.createInterface({ + input: process.stdin, + output: process.stdout +}); +//clearing-resetting screen +function clear_screen() { + console.clear(); +} +//sleep function +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} +//saving license for ease of use +function save_license(new_license) { + var config_txt = fs_1.default.readFileSync('config.json', 'utf8'); + var config_obj = JSON.parse(config_txt); + //updating config + config_obj.license = new_license; + //writing new config + const new_config = JSON.stringify(config_obj); + fs_1.default.writeFileSync('config.json', new_config); +} +//authenticating +function verify_license(license) { + return __awaiter(this, void 0, void 0, function* () { + startSpinner(); + // post request to URL: + // https://api.cactusweb.io/api/v1/devices + // Headers: + // content-type: application/json + // Body: + // { + // key: '[licenseKey]', + // device: '[deviceId]', + // id: '6473bfaa496af9a7ca1291c6' + // } + let hwid = yield (0, hwid_1.getHWID)(); + const options = { + url: 'https://api.cactusweb.io/api/v1/devices', + headers: { + 'content-type': 'application/json' + }, + body: { + key: license, + device: hwid, + id: '6473bfaa496af9a7ca1291c6' + }, + json: true + }; + (0, request_1.post)(options, (err, res, body) => { var res; return __awaiter(this, void 0, void 0, function* () { + if (err) { + console.error('Error, please try again later'); + throw err; + } + res = res; + if (res.statusCode == 200) { + stopSpinner(); + console.log(chalk_1.default.green("\n\tLicense Verified!")); + save_license(license); + yield sleep(1500); + main(); + } + else { + stopSpinner(); + console.log(chalk_1.default.red("\n\tInvalid License!")); + yield sleep(1500); + process.exit(0); + } + }); }); + // if (res.statusCode == 200) { + // stopSpinner() + // console.log(chalk.green("\n\tLicense Verified!")); + // save_license(license); + // await sleep(1500); + // main(); + // } else { + // stopSpinner() + // console.log(chalk.red("\n\tInvalid License!")); + // await sleep(1500); + // process.exit(0); + // } + }); +} +//program start +//initial authentication +//(async () => { +// +// startSpinner() +// stopSpinner() +// +// var config_txt = fs.readFileSync('config.json','utf8'); +// var config_obj:config = JSON.parse(config_txt); +// const license = config_obj.license; +// if (license != ''){ +// await verify_license(license) +// }else{ +// rl.question("\tLicense : ", async (lic) => { +// await verify_license(lic); +// }); +// } +//})(); +main(); +function start_swapping(connection, is_snipe, amount_in, pool, slip, owner) { + return __awaiter(this, void 0, void 0, function* () { + console.log(chalk_1.default.greenBright('\tinputs valid\n')); + console.log(chalk_1.default.white(`\t[1] - ${chalk_1.default.blueBright(is_snipe ? 'Snipe' : 'Sell')}`)); + console.log(chalk_1.default.white('\t[2] - Return')); + rl.question(`\n\t${is_snipe ? '[Sniper]' : '[Exit Position]'} - choice: `, (answer) => __awaiter(this, void 0, void 0, function* () { + const ans = parseInt(answer); + if (ans == 1) { + finished = false; + const SwapSpinner = cli_spinners_1.default.dots4; + let i = 0; + let animationInterval; + const updateSwapSpinner = () => { + const frame = Spinner.frames[i % Spinner.frames.length]; + process.stdout.cursorTo(0); + process.stdout.write(chalk_1.default.blueBright('\tSwapping' + frame)); + i++; + }; + const startSwapSpinner = () => { + animationInterval = setInterval(updateSwapSpinner, SwapSpinner.interval); + }; + const stopSwapSpinner = () => { + clearInterval(animationInterval); + process.stdout.clearLine(0); + process.stdout.cursorTo(0); + }; + startSpinner(); + var finished = false; + const pool_keys = yield (0, pool_keys_1.fetchPoolKeys)(connection, new web3_js_1.PublicKey(pool)); + var token_in_key; + var token_out_key; + if (is_snipe) { + token_in_key = pool_keys.quoteMint; + token_out_key = pool_keys.baseMint; + } + else { + token_in_key = pool_keys.baseMint; + token_out_key = pool_keys.quoteMint; + } + while (!finished) { + const computation = yield (0, compute_1.compute)(connection, pool_keys, token_in_key, token_out_key, amount_in, slip); + const amountOut = computation[0]; + const minAmountOut = computation[1]; + const currentPrice = computation[2]; + const executionPrice = computation[3]; + const priceImpact = computation[4]; + const fee = computation[5]; + const amountIn = computation[6]; + stopSpinner(); + console.log(`\n\tAmount out: ${amountOut.toFixed()},\n\tMin Amount out: ${minAmountOut.toFixed()}`); + if (priceImpact.toFixed() > 5) { + console.log(chalk_1.default.red(`\tpriceImpact: ${priceImpact.toFixed()}`)); + } + else if (priceImpact.toFixed() < 5 && priceImpact.toFixed() > 1) { + console.log(chalk_1.default.yellowBright(`\tpriceImpact: ${priceImpact.toFixed()}`)); + } + else { + console.log(chalk_1.default.green(`\tpriceImpact: ${priceImpact.toFixed()}`)); + } + console.log('\n'); + startSwapSpinner(); + const token_accounts = yield (0, get_accounts_1.getTokenAccountsByOwner)(connection, owner.publicKey); + const swap_status = yield (0, swap_1.swap)(connection, pool_keys, owner, token_accounts, is_snipe, amountIn, minAmountOut); + stopSwapSpinner(); + if (swap_status == 0) { + console.log(chalk_1.default.greenBright('\tSwap successful!')); + rl.question("\tpress enter to return..", () => __awaiter(this, void 0, void 0, function* () { + snipe_menu(); + })); + break; + } + else { + console.log(chalk_1.default.red('\tSwap failed, retrying...')); + continue; + } + } + } + else if (ans == 2) { + snipe_menu(); + } + else { + console.log(chalk_1.default.red("\n\tInvalid choice")); + yield sleep(1000); + snipe_menu(); + } + })); + }); +} +function snipe_choice() { + return __awaiter(this, void 0, void 0, function* () { + clear_screen(); + utils_1.default.aff_logo(); + utils_1.default.aff_title(); + utils_1.default.aff_snipe_option(); + const owner = (0, get_keypair_1.get_wallet)('config.json'); + var config_txt = fs_1.default.readFileSync('config.json', 'utf8'); + var config_obj = JSON.parse(config_txt); + const slip = config_obj.slippage; + const connection = new web3_js_1.Connection(config_obj.rpc_endpoint); + rl.question("\n\tPool ID: ", (answer) => __awaiter(this, void 0, void 0, function* () { + const pool = answer; + rl.question("\n\tAmount in(enter 'MAX' for max amount): ", (answer) => __awaiter(this, void 0, void 0, function* () { + console.log('\n\t'); + startSpinner(); + var res; + const amount_in = parseFloat(answer); + const is_max = answer; + const token_amount = yield (0, fetch_token_1.get_token_amount)(pool, true); + stopSpinner(); + if (token_amount == -1) { + console.log(chalk_1.default.red("\n\tInvalid Pool ID or an error has occured.")); + yield sleep(1000); + snipe_menu(); + } + else if (token_amount == -2) { + console.log(chalk_1.default.red("\n\tSol Balance less than 0.01")); + yield sleep(1000); + snipe_menu(); + } + else if (token_amount == 0) { + console.log(chalk_1.default.red("\n\tNo balance found.")); + yield sleep(1000); + snipe_menu(); + } + else { + if (is_max.toUpperCase() == 'MAX') { + if (token_amount < 0.00001) { + console.log(chalk_1.default.red("\n\tInput too small.")); + yield sleep(1000); + snipe_menu(); + } + else { + yield start_swapping(connection, true, token_amount, pool, slip, owner); + } + } + else if (isNaN(amount_in)) { + console.log(chalk_1.default.red("\n\tInvalid Input.")); + yield sleep(1000); + snipe_menu(); + } + else { + if (amount_in > token_amount) { + console.log(chalk_1.default.red("\n\tinsufficient balance.")); + yield sleep(1000); + snipe_menu(); + } + else { + if (amount_in < 0.00001) { + console.log(chalk_1.default.red("\n\tInput too small.")); + yield sleep(1000); + snipe_menu(); + } + else { + yield start_swapping(connection, true, amount_in, pool, slip, owner); + } + } + } + } + })); + })); + }); +} +function sell_choice() { + return __awaiter(this, void 0, void 0, function* () { + clear_screen(); + utils_1.default.aff_logo(); + utils_1.default.aff_title(); + utils_1.default.aff_sell_option(); + const owner = (0, get_keypair_1.get_wallet)('config.json'); + var config_txt = fs_1.default.readFileSync('config.json', 'utf8'); + var config_obj = JSON.parse(config_txt); + const slip = config_obj.slippage; + const connection = new web3_js_1.Connection(config_obj.rpc_endpoint); + rl.question("\n\tPool ID: ", (answer) => __awaiter(this, void 0, void 0, function* () { + const pool = answer; + rl.question("\n\tAmount in(enter 'MAX' for max amount): ", (answer) => __awaiter(this, void 0, void 0, function* () { + console.log('\n\t'); + startSpinner(); + var res; + const amount_in = parseFloat(answer); + const is_max = answer; + const token_amount = yield (0, fetch_token_1.get_token_amount)(pool, false); + stopSpinner(); + if (token_amount == -1) { + console.log(chalk_1.default.red("\n\tInvalid Pool ID or an error has occured.")); + yield sleep(1000); + snipe_menu(); + } + else if (token_amount == -2) { + console.log(chalk_1.default.red("\n\tSol Balance less than 0.01")); + yield sleep(1000); + snipe_menu(); + } + else if (token_amount == 0) { + console.log(chalk_1.default.red("\n\tNo balance found.")); + yield sleep(1000); + snipe_menu(); + } + else { + if (is_max.toUpperCase() == 'MAX') { + yield start_swapping(connection, false, token_amount, pool, slip, owner); + } + else if (isNaN(amount_in)) { + console.log(chalk_1.default.red("\n\tInvalid Input.")); + yield sleep(1000); + snipe_menu(); + } + else { + if (amount_in > token_amount) { + console.log(chalk_1.default.red("\n\tinsufficient balance.")); + yield sleep(1000); + snipe_menu(); + } + else { + yield start_swapping(connection, false, amount_in, pool, slip, owner); + } + } + } + })); + })); + }); +} +function usage() { + clear_screen(); + utils_1.default.aff_logo(); + utils_1.default.aff_title(); + utils_1.default.aff_guide(); + rl.question("\n\tpress enter to return..", () => __awaiter(this, void 0, void 0, function* () { + snipe_menu(); + })); +} +//sniper menu +function snipe_menu() { + return __awaiter(this, void 0, void 0, function* () { + var config_txt = fs_1.default.readFileSync('config.json', 'utf8'); + var config_obj = JSON.parse(config_txt); + const wallet = config_obj.wallet; + if (wallet === 'None') { + console.log(chalk_1.default.red("\n\tPlease add a wallet in settings")); + yield sleep(1500); + main(); + } + else { + clear_screen(); + utils_1.default.aff_logo(); + utils_1.default.aff_title(); + utils_1.default.aff_sniper_menu(); + rl.question(chalk_1.default.white('\t[Sniper Mode] - Choice: '), (answer) => __awaiter(this, void 0, void 0, function* () { + choice = parseInt(answer); + if (choice == 1) { + snipe_choice(); + } + else if (choice == 2) { + sell_choice(); + } + else if (choice == 3) { + usage(); + } + else if (choice == 4) { + main(); + } + else { + console.log(chalk_1.default.red("\tInvalid choice.")); + yield sleep(1500); + snipe_menu(); + } + })); + } + }); +} +//settings menu +function settings_menu() { + clear_screen(); + utils_1.default.aff_logo(); + utils_1.default.aff_title(); + utils_1.default.aff_settings_menu(); + rl.question(chalk_1.default.white('\t[Settings] - Choice: '), (answer) => __awaiter(this, void 0, void 0, function* () { + choice = parseInt(answer); + if (choice == 1) { + rl.question(chalk_1.default.white('\t[Settings] - New RPC Endpoint: '), (answer) => __awaiter(this, void 0, void 0, function* () { + const res = yield (0, config_1.update_rpc)(answer); + yield sleep(1000); + if (res === 1) { + console.log(chalk_1.default.red('\tInvalid RPC Value')); + yield sleep(1000); + settings_menu(); + } + else { + console.log('\tRPC Updated'); + yield sleep(1000); + settings_menu(); + } + })); + } + else if (choice == 2) { + } + else if (choice == 3) { + rl.question(chalk_1.default.white('\t[Settings] - New Slippage(0-100): '), (answer) => __awaiter(this, void 0, void 0, function* () { + const res = (0, config_1.update_slippage)(answer); + if (res === 1) { + console.log(chalk_1.default.red('\tInvalid Slippage Value')); + yield sleep(1000); + settings_menu(); + } + else { + console.log('\tSlippage Updated!'); + yield sleep(1000); + settings_menu(); + } + })); + } + else if (choice == 4) { + rl.question(chalk_1.default.white('\t[Settings] - Enter Private Key: '), (answer) => __awaiter(this, void 0, void 0, function* () { + const res = (0, config_1.update_wallet)(answer); + if (res === 1) { + console.log(chalk_1.default.red('\tInvalid Input or Wallet Not Found')); + yield sleep(1000); + settings_menu(); + } + else { + console.log('\tWallet Updated!'); + yield sleep(1000); + settings_menu(); + } + })); + } + else if (choice == 5) { + clear_screen(); + utils_1.default.aff_logo(); + utils_1.default.aff_title(); + (0, config_1.show_config)(); + rl.question(chalk_1.default.white('\n\tpress enter to return..'), (answer) => { + settings_menu(); + }); + } + else if (choice == 6) { + main(); + } + else { + console.log(chalk_1.default.red("\tInvalid choice.")); + yield sleep(1500); + settings_menu(); + } + })); +} +//main menu +function main() { + console.clear(); + utils_1.default.aff_logo(); + utils_1.default.aff_title(); + utils_1.default.aff_main_menu(); + rl.question(chalk_1.default.white('\t[Main] - Choice: '), (answer) => __awaiter(this, void 0, void 0, function* () { + choice = parseInt(answer); + if (choice == 1) { + snipe_menu(); + } + else if (choice == 2) { + settings_menu(); + } + else if (choice == 3) { + process.exit(); + } + else { + console.log(chalk_1.default.red("\tInvalid choice.")); + yield sleep(1500); + main(); + } + })); +} +module.exports = { + main +}; diff --git a/build/modules/compute.js b/build/modules/compute.js new file mode 100644 index 0000000..3e0e787 --- /dev/null +++ b/build/modules/compute.js @@ -0,0 +1,52 @@ +"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.compute = void 0; +const raydium_sdk_1 = require("@raydium-io/raydium-sdk"); +//computes live estimates of the swap and returns details for transaction building or display on UI. +//returns a list containing trade details (fees,price impact,expected amount out etc..) +function compute(connection, poolKeys, curr_in, curr_out, amount_in, slip) { + return __awaiter(this, void 0, void 0, function* () { + try { + const poolInfo = yield raydium_sdk_1.Liquidity.fetchInfo({ connection, poolKeys }); + //setting up decimals + var in_decimal; + var out_decimal; + if (curr_in.toBase58() === poolKeys.baseMint.toBase58()) { + in_decimal = poolInfo.baseDecimals; + out_decimal = poolInfo.quoteDecimals; + } + else { + out_decimal = poolInfo.baseDecimals; + in_decimal = poolInfo.quoteDecimals; + } + //priming and computing + const amountIn = new raydium_sdk_1.TokenAmount(new raydium_sdk_1.Token(curr_in, in_decimal), amount_in, false); + const currencyOut = new raydium_sdk_1.Token(curr_out, out_decimal); + const slippage = new raydium_sdk_1.Percent(slip, 100); + const { amountOut, minAmountOut, currentPrice, executionPrice, priceImpact, fee, } = raydium_sdk_1.Liquidity.computeAmountOut({ poolKeys, poolInfo, amountIn, currencyOut, slippage }); + return [ + amountOut, + minAmountOut, + currentPrice, + executionPrice, + priceImpact, + fee, + amountIn, + ]; + } + catch (e) { + console.log(e); + return 1; + } + }); +} +exports.compute = compute; diff --git a/build/modules/config.js b/build/modules/config.js new file mode 100644 index 0000000..b3b8bac --- /dev/null +++ b/build/modules/config.js @@ -0,0 +1,110 @@ +"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()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.update_wallet = exports.update_slippage = exports.update_rpc = exports.show_config = void 0; +const web3_js_1 = require("@solana/web3.js"); +const bs58_1 = __importDefault(require("bs58")); +const fs_1 = __importDefault(require("fs")); +const hash_key = "pleasedonotlookatstringsincodethanks"; +//fetching from config +function show_config() { + var config_txt = fs_1.default.readFileSync('config.json', 'utf8'); + var config_obj = JSON.parse(config_txt); + var pubkey; + try { + const secretkey = bs58_1.default.decode(config_obj.wallet); + const ownerKeypair = web3_js_1.Keypair.fromSecretKey(secretkey); + var pubkey = ownerKeypair.publicKey.toBase58(); + } + catch (e) { + pubkey = config_obj.wallet; + } + console.log(`\tWallet Address: ${pubkey}`); + console.log(`\tRPC URL: ${config_obj.rpc_endpoint}`); + console.log(`\tWebhook URL: ${config_obj.webhook_url}`); + console.log(`\tSlippage: ${config_obj.slippage}%`); +} +exports.show_config = show_config; +//updating config +//returns 0 for success and 1 for failure +function update_rpc(rpc) { + return __awaiter(this, void 0, void 0, function* () { + try { + const connection = new web3_js_1.Connection(rpc); + const balance = yield connection.getBalance(new web3_js_1.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA')); + if (balance) { + //reading config file + var config_txt = fs_1.default.readFileSync('config.json', 'utf8'); + var config_obj = JSON.parse(config_txt); + //updating config + config_obj.rpc_endpoint = rpc; + //writing new config + const new_config = JSON.stringify(config_obj); + fs_1.default.writeFileSync('config.json', new_config); + return 0; + } + else { + return 1; + } + } + catch (e) { + return 1; + } + }); +} +exports.update_rpc = update_rpc; +function update_slippage(slip) { + try { + const parsedSlippage = parseInt(slip); + if (isNaN(parsedSlippage)) { + return 1; + } + else if (parsedSlippage > 100 || parsedSlippage < 0) { + return 1; + } + else { + //reading config file + var config_txt = fs_1.default.readFileSync('config.json', 'utf8'); + var config_obj = JSON.parse(config_txt); + //updating config + config_obj.slippage = parsedSlippage; + //writing new config + const new_config = JSON.stringify(config_obj); + fs_1.default.writeFileSync('config.json', new_config); + return 0; + } + } + catch (e) { + return 1; + } +} +exports.update_slippage = update_slippage; +function update_wallet(wallet) { + var config_txt = fs_1.default.readFileSync('config.json', 'utf8'); + var config_obj = JSON.parse(config_txt); + try { + const secretkey = bs58_1.default.decode(wallet); + const ownerKeypair = web3_js_1.Keypair.fromSecretKey(secretkey); + //updating config + config_obj.wallet = wallet; + //writing new config + const new_config = JSON.stringify(config_obj); + fs_1.default.writeFileSync('config.json', new_config); + return 0; + } + catch (e) { + return 1; + } +} +exports.update_wallet = update_wallet; diff --git a/build/modules/fetch_token.js b/build/modules/fetch_token.js new file mode 100644 index 0000000..573605e --- /dev/null +++ b/build/modules/fetch_token.js @@ -0,0 +1,80 @@ +"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()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.get_token_amount = void 0; +const web3_js_1 = require("@solana/web3.js"); +const fs_1 = __importDefault(require("fs")); +const bs58_1 = __importDefault(require("bs58")); +const raydium_sdk_1 = require("@raydium-io/raydium-sdk"); +function get_token_amount(poolId, buying) { + return __awaiter(this, void 0, void 0, function* () { + try { + //fetching pool data + var config_txt = fs_1.default.readFileSync('config.json', 'utf8'); + var config_obj = JSON.parse(config_txt); + const rpc_url = config_obj.rpc_endpoint; + const version = 4; + const connection = new web3_js_1.Connection(rpc_url); + const account = yield connection.getAccountInfo(new web3_js_1.PublicKey(poolId)); + const { state: LiquidityStateLayout } = raydium_sdk_1.Liquidity.getLayouts(version); + //@ts-ignore + const fields = LiquidityStateLayout.decode(account === null || account === void 0 ? void 0 : account.data); + const { status, baseMint, quoteMint, lpMint, openOrders, targetOrders, baseVault, quoteVault, marketId, baseDecimal, quoteDecimal, } = fields; + var is_valid = false; + [quoteMint, baseMint, lpMint].forEach((e) => { + if (e.toBase58() != '11111111111111111111111111111111') { + is_valid = true; + } + }); + if (!is_valid) { + return -1; + } + //fetching token data + const secretkey = bs58_1.default.decode(config_obj.wallet); + const ownerKeypair = web3_js_1.Keypair.fromSecretKey(secretkey); + const owner_address = ownerKeypair.publicKey; + const tokenAddress = buying ? quoteMint : baseMint; + //console.log(tokenAddress.toBase58()); + const bal = yield connection.getBalance(new web3_js_1.PublicKey(owner_address.toBase58())); + if (bal < 0.01) { + return -2; + } + if (tokenAddress.toBase58() == 'So11111111111111111111111111111111111111112') { + return (bal / 1000000000) - 0.0099; + } + else { + const tokenAccounts = yield connection.getParsedTokenAccountsByOwner(owner_address, { programId: new web3_js_1.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA') }); + for (var cand in tokenAccounts.value) { + if (tokenAccounts.value[cand].account.data.parsed.info.mint === tokenAddress.toBase58()) { + const tokenAccount = tokenAccounts.value[cand]; + const tokenBalance = tokenAccount.account.data.parsed.info.tokenAmount.uiAmount; + return tokenBalance; + } + } + return 0; + } + } + catch (e) { + return -1; + } + }); +} +exports.get_token_amount = get_token_amount; +function test() { + return __awaiter(this, void 0, void 0, function* () { + const res = yield get_token_amount('AZqjt9vYMGZMuNfzSmFjMFgcMHnkBPndpTn1uprKLrq2', false); + console.log(res); + }); +} +//test(); diff --git a/build/modules/get_accounts.js b/build/modules/get_accounts.js new file mode 100644 index 0000000..655a2f2 --- /dev/null +++ b/build/modules/get_accounts.js @@ -0,0 +1,30 @@ +"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.getTokenAccountsByOwner = void 0; +const raydium_sdk_1 = require("@raydium-io/raydium-sdk"); +//fetching token accounts +function getTokenAccountsByOwner(connection, owner) { + return __awaiter(this, void 0, void 0, function* () { + const tokenResp = yield connection.getTokenAccountsByOwner(owner, { + programId: raydium_sdk_1.TOKEN_PROGRAM_ID + }); + const accounts = []; + for (const { pubkey, account } of tokenResp.value) { + accounts.push({ + pubkey, + accountInfo: raydium_sdk_1.SPL_ACCOUNT_LAYOUT.decode(account.data) + }); + } + return accounts; + }); +} +exports.getTokenAccountsByOwner = getTokenAccountsByOwner; diff --git a/build/modules/get_keypair.js b/build/modules/get_keypair.js new file mode 100644 index 0000000..227f983 --- /dev/null +++ b/build/modules/get_keypair.js @@ -0,0 +1,23 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.get_wallet = void 0; +const web3_js_1 = require("@solana/web3.js"); +const bs58_1 = __importDefault(require("bs58")); +const fs_1 = __importDefault(require("fs")); +//function to fetch the owners keypair object from config +//returns Keypair instance if valid or undefined if not +function get_wallet(config_path) { + var config_txt = fs_1.default.readFileSync(config_path, 'utf8'); + var config_obj = JSON.parse(config_txt); + try { + const secretkey = bs58_1.default.decode(config_obj.wallet); + const ownerKeypair = web3_js_1.Keypair.fromSecretKey(secretkey); + return ownerKeypair; + } + catch (_a) { + } +} +exports.get_wallet = get_wallet; diff --git a/build/modules/pool_keys.js b/build/modules/pool_keys.js new file mode 100644 index 0000000..179c613 --- /dev/null +++ b/build/modules/pool_keys.js @@ -0,0 +1,86 @@ +"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.fetchPoolKeys = void 0; +const raydium_sdk_1 = require("@raydium-io/raydium-sdk"); +const web3_js_1 = require("@solana/web3.js"); +//returns the pool keys (info and required params/program id's) +//neccessary to interact with the liquidity pool program and compute live prices and estimates. +function fetchPoolKeys(connection, poolId, version = 4) { + return __awaiter(this, void 0, void 0, function* () { + const serumVersion = 10; + const marketVersion = 3; + const programId = new web3_js_1.PublicKey('675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8'); + const serumProgramId = new web3_js_1.PublicKey('srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX'); + const account = yield connection.getAccountInfo(poolId); + const { state: LiquidityStateLayout } = raydium_sdk_1.Liquidity.getLayouts(version); + //@ts-ignore + const fields = LiquidityStateLayout.decode(account === null || account === void 0 ? void 0 : account.data); + const { status, baseMint, quoteMint, lpMint, openOrders, targetOrders, baseVault, quoteVault, marketId, baseDecimal, quoteDecimal, } = fields; + let withdrawQueue, lpVault; + if (raydium_sdk_1.Liquidity.isV4(fields)) { + withdrawQueue = fields.withdrawQueue; + lpVault = fields.lpVault; + } + else { + withdrawQueue = web3_js_1.PublicKey.default; + lpVault = web3_js_1.PublicKey.default; + } + // uninitialized + // if (status.isZero()) { + // return ; + // } + const associatedPoolKeys = raydium_sdk_1.Liquidity.getAssociatedPoolKeys({ + version: version, + marketVersion, + marketId, + baseMint: baseMint, + quoteMint: quoteMint, + baseDecimals: baseDecimal.toNumber(), + quoteDecimals: quoteDecimal.toNumber(), + programId, + marketProgramId: serumProgramId, + }); + const poolKeys = { + id: poolId, + baseMint, + quoteMint, + lpMint, + version, + programId, + authority: associatedPoolKeys.authority, + openOrders, + targetOrders, + baseVault, + quoteVault, + withdrawQueue, + lpVault, + marketVersion: serumVersion, + marketProgramId: serumProgramId, + marketId, + marketAuthority: associatedPoolKeys.marketAuthority, + }; + const marketInfo = yield connection.getAccountInfo(marketId); + const { state: MARKET_STATE_LAYOUT } = raydium_sdk_1.Market.getLayouts(marketVersion); + //@ts-ignore + const market = MARKET_STATE_LAYOUT.decode(marketInfo.data); + const { baseVault: marketBaseVault, quoteVault: marketQuoteVault, bids: marketBids, asks: marketAsks, eventQueue: marketEventQueue, } = market; + // const poolKeys: LiquidityPoolKeys; + return Object.assign(Object.assign({}, poolKeys), { + marketBaseVault, + marketQuoteVault, + marketBids, + marketAsks, + marketEventQueue, + }); + }); +} +exports.fetchPoolKeys = fetchPoolKeys; diff --git a/build/modules/send_transaction.js b/build/modules/send_transaction.js new file mode 100644 index 0000000..554565c --- /dev/null +++ b/build/modules/send_transaction.js @@ -0,0 +1,55 @@ +"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.sendTx = void 0; +//sleep function +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} +//sending a transaction +function sendTx(connection, transaction, signers) { + return __awaiter(this, void 0, void 0, function* () { + const hash_info = (yield connection.getLatestBlockhashAndContext()).value; + transaction.recentBlockhash = hash_info.blockhash; + transaction.lastValidBlockHeight = hash_info.lastValidBlockHeight; + transaction.feePayer = signers[0].publicKey; + transaction.sign(...signers); + const rawTransaction = transaction.serialize(); + var txid; + try { + txid = yield connection.sendRawTransaction(rawTransaction, { skipPreflight: true, }); + } + catch (e) { + return 1; + } + while (true) { + const ret = yield connection.getSignatureStatus(txid, { searchTransactionHistory: true }); + try { + //@ts-ignore + if (ret) { + if (ret.value && ret.value.err == null) { + return 0; + } + else if (ret.value && ret.value.err != null) { + return 1; + } + else { + continue; + } + } + } + catch (e) { + return 1; + } + } + }); +} +exports.sendTx = sendTx; diff --git a/build/modules/swap.js b/build/modules/swap.js new file mode 100644 index 0000000..b6a47a5 --- /dev/null +++ b/build/modules/swap.js @@ -0,0 +1,48 @@ +"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.swap = void 0; +const raydium_sdk_1 = require("@raydium-io/raydium-sdk"); +const web3_js_1 = require("@solana/web3.js"); +const send_transaction_1 = require("./send_transaction"); +function swap(connection, poolKeys, ownerKeypair, tokenAccounts, is_snipe, amountIn, minAmountOut) { + return __awaiter(this, void 0, void 0, function* () { + const owner = ownerKeypair.publicKey; + const inst = yield raydium_sdk_1.Liquidity.makeSwapInstructionSimple({ + connection: connection, + poolKeys: poolKeys, + userKeys: { + tokenAccounts, + owner, + }, + amountIn, + amountOut: minAmountOut, + fixedSide: 'in', + config: {} + }); + //@ts-ignore + //const instructions = inst.innerTransactions[0].instructions[0]; + //console.log(inst.innerTransactions); + //console.log(inst.innerTransactions[0]); + //console.log(inst.innerTransactions[0].signers) + const tx = new web3_js_1.Transaction(); + const signers = [ownerKeypair]; + inst.innerTransactions[0].instructions.forEach(e => { + tx.add(e); + }); + inst.innerTransactions[0].signers.forEach(e => { + signers.push(e); + }); + const res = yield (0, send_transaction_1.sendTx)(connection, tx, signers); + return res; + }); +} +exports.swap = swap; diff --git a/build/utils.js b/build/utils.js new file mode 100644 index 0000000..4cf1b31 --- /dev/null +++ b/build/utils.js @@ -0,0 +1,132 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.aff_settings_menu = exports.aff_sniper_menu = exports.aff_main_menu = exports.aff_guide = exports.aff_sell_option = exports.aff_snipe_option = exports.aff_title = exports.aff_logo = void 0; +const chalk_1 = __importDefault(require("chalk")); +const logo = ` +\t +\t +\t ( & +\t % % +\t & % & +\t &&/ &****& & +\t % % (*****./ .( +\t % ./ ((((((,( *( +\t % % %///( ( +\t &&&.*//////**// % * .,/ ./ * / /,,/((# / +\t * (//*.. & / */( .# ,.*/(( +\t *** , /&( / *(( +\t , .,*,./, .,*,/%#//(# #*# +\t */*# &*, /( &/ .( * +\t ./ * /% (&, (#/ +\t ( (,( / /( %,/# +\t ,/% /,/ +\t ( .( +\t (( , +\t , +\t ( / +\t +`; +const title = ` +\t▓█████▄ ▓█████ ▒██ ██▒ ██████ ██▓███ ▓██ ██▓▓█████▄ ▓█████ ██▀███ +\t▒██▀ ██▌▓█ ▀ ▒▒ █ █ ▒░▒██ ▒ ▓██░ ██▒▒██ ██▒▒██▀ ██▌▓█ ▀ ▓██ ▒ ██▒ +\t░██ █▌▒███ ░░ █ ░░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░░██ █▌▒███ ▓██ ░▄█ ▒ +\t░▓█▄ ▌▒▓█ ▄ ░ █ █ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░░▓█▄ ▌▒▓█ ▄ ▒██▀▀█▄ +\t░▒████▓ ░▒████▒▒██▒ ▒██▒▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░░▒████▓ ░▒████▒░██▓ ▒██▒ +\t ▒▒▓ ▒ ░░ ▒░ ░▒▒ ░ ░▓ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒ ▒▒▓ ▒ ░░ ▒░ ░░ ▒▓ ░▒▓░ +\t ░ ▒ ▒ ░ ░ ░░░ ░▒ ░░ ░▒ ░ ░░▒ ░ ▓██ ░▒░ ░ ▒ ▒ ░ ░ ░ ░▒ ░ ▒░ +\t ░ ░ ░ ░ ░ ░ ░ ░ ░ ░░ ▒ ▒ ░░ ░ ░ ░ ░ ░░ ░ +\t ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ +\t ░ ░ ░ ░ + + +`; +function aff_logo() { + for (let i = 0; i < logo.length; i++) { + if (logo[i] == '@') { + process.stdout.write(chalk_1.default.black(logo[i])); + } + else { + process.stdout.write(chalk_1.default.magenta(logo[i])); + } + } +} +exports.aff_logo = aff_logo; +function aff_title() { + for (let i = 0; i < title.length; i++) { + if (title[i] == '▓') { + process.stdout.write(chalk_1.default.black(title[i])); + } + else { + process.stdout.write(chalk_1.default.magenta(title[i])); + } + } +} +exports.aff_title = aff_title; +function aff_snipe_option() { + console.log(chalk_1.default.cyanBright('\tDisclaimer: \t- the tool will start sniping if all inputs are valid!')); + console.log(chalk_1.default.cyanBright('\t \t- double check the amount and pool details in the monitor')); + console.log(chalk_1.default.cyanBright('\t \t to avoid miss-inputs and big price impact')); +} +exports.aff_snipe_option = aff_snipe_option; +function aff_sell_option() { + console.log(chalk_1.default.cyanBright('\tDisclaimer: \t- the tool will sell supplied balance if all inputs are valid!')); + console.log(chalk_1.default.cyanBright('\t \t- double check the held balance and pool details in the monitor')); + console.log(chalk_1.default.cyanBright('\t \t to avoid miss-inputs and big price impact')); +} +exports.aff_sell_option = aff_sell_option; +function aff_guide() { + console.log(chalk_1.default.white('\tUSAGE: ')); + console.log(chalk_1.default.white('\n')); + console.log(chalk_1.default.white('\tsniper option \t - requires AMM pool ID and amount of token in as input')); + console.log(chalk_1.default.white('\t \t - Amount in should be the Quote of the pair (from on-chain monitor)')); + console.log(chalk_1.default.white('\t \t - make sure to have the supplied amount of token in or the transaction will not go through')); + console.log(chalk_1.default.white('\n')); + console.log(chalk_1.default.white('\texit position option\t - requires AMM pool ID and amount of token out as input')); + console.log(chalk_1.default.white('\t \t - Amount in should be the Base of the pair (from on-chain monitor)')); + console.log(chalk_1.default.white('\t \t - make sure to have the supplied amount of token out or the transactions will not got through')); + console.log(chalk_1.default.white('\n')); + console.log(chalk_1.default.white('\tdefault slippage \t - 10%')); + console.log(chalk_1.default.white('\tsuggested slippage \t - between 10% and 30%')); + console.log(chalk_1.default.white("\tRPCs \t - Custom RPC's are highly suggested for fast transaction commitment speed")); + console.log(chalk_1.default.white('\n')); +} +exports.aff_guide = aff_guide; +function aff_main_menu() { + console.log(chalk_1.default.white('\t[1] - Sniper Mode')); + console.log(chalk_1.default.white('\t[2] - Settings')); + console.log(chalk_1.default.white('\t[3] - Exit')); + console.log("\n"); +} +exports.aff_main_menu = aff_main_menu; +function aff_sniper_menu() { + console.log(chalk_1.default.blueBright('\t[1] - Snipe')); + console.log(chalk_1.default.greenBright('\t[2] - Exit Position')); + console.log(chalk_1.default.white('\t[3] - Usage')); + console.log(chalk_1.default.white('\t[4] - return')); + console.log("\n"); +} +exports.aff_sniper_menu = aff_sniper_menu; +function aff_settings_menu() { + console.log(chalk_1.default.white('\t[1] - Change RPC')); + console.log(chalk_1.default.white('\t[2] - Change Webhook')); + console.log(chalk_1.default.white('\t[3] - Change Slippage')); + console.log(chalk_1.default.white('\t[4] - Change Wallet')); + console.log(chalk_1.default.white('\t[5] - Show Current Settings')); + console.log(chalk_1.default.white('\t[6] - Back')); + console.log("\n"); +} +exports.aff_settings_menu = aff_settings_menu; +const default_export = { + aff_logo, + aff_title, + aff_main_menu, + aff_settings_menu, + aff_sniper_menu, + aff_snipe_option, + aff_sell_option, + aff_guide, +}; +exports.default = default_export; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..600e050 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1424 @@ +{ + "name": "dexspyder_v1_cli", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "dexspyder_v1_cli", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@raydium-io/raydium-sdk": "^1.3.0-beta.18", + "@solana/spl-token": "^0.3.7", + "@solana/web3.js": "^1.77.2", + "axios": "^1.4.0", + "bs58": "^5.0.0", + "chalk": "^4.1.2", + "clear": "^0.1.0", + "cli-spinners": "^2.9.0", + "hwid": "^0.3.0", + "moment": "^2.29.4", + "request": "^2.88.2", + "requests": "^0.3.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.22.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.3.tgz", + "integrity": "sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ==", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@noble/curves": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.0.0.tgz", + "integrity": "sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "1.3.0" + } + }, + "node_modules/@noble/ed25519": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.3.tgz", + "integrity": "sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/hashes": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz", + "integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@raydium-io/raydium-sdk": { + "version": "1.3.0-beta.18", + "resolved": "https://registry.npmjs.org/@raydium-io/raydium-sdk/-/raydium-sdk-1.3.0-beta.18.tgz", + "integrity": "sha512-gMBZ+WcwOhggwEZQqvasUhdOnm77bRoX83K6kWT5EykShk41ThhUGGxyv/siLu64w1K6ImlMGXjy4I5668/Gtw==", + "dependencies": { + "@solana/buffer-layout": "^4.0.1", + "@solana/spl-token": "^0.3.7", + "@solana/web3.js": "1.73.0", + "axios": "^1.2.6", + "big.js": "^6.2.1", + "bn.js": "^5.2.1", + "decimal.js": "^10.4.3", + "decimal.js-light": "^2.5.1", + "fecha": "^4.2.3", + "lodash": "^4.17.21", + "toformat": "^2.0.0" + } + }, + "node_modules/@raydium-io/raydium-sdk/node_modules/@solana/web3.js": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.73.0.tgz", + "integrity": "sha512-YrgX3Py7ylh8NYkbanoINUPCj//bWUjYZ5/WPy9nQ9SK3Cl7QWCR+NmbDjmC/fTspZGR+VO9LTQslM++jr5PRw==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@noble/ed25519": "^1.7.0", + "@noble/hashes": "^1.1.2", + "@noble/secp256k1": "^1.6.3", + "@solana/buffer-layout": "^4.0.0", + "agentkeepalive": "^4.2.1", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "node-fetch": "2", + "rpc-websockets": "^7.5.0", + "superstruct": "^0.14.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@raydium-io/raydium-sdk/node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@raydium-io/raydium-sdk/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/@raydium-io/raydium-sdk/node_modules/buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", + "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/@solana/buffer-layout": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz", + "integrity": "sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==", + "dependencies": { + "buffer": "~6.0.3" + }, + "engines": { + "node": ">=5.10" + } + }, + "node_modules/@solana/buffer-layout-utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", + "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/web3.js": "^1.32.0", + "bigint-buffer": "^1.1.5", + "bignumber.js": "^9.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@solana/spl-token": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.3.7.tgz", + "integrity": "sha512-bKGxWTtIw6VDdCBngjtsGlKGLSmiu/8ghSt/IOYJV24BsymRbgq7r12GToeetpxmPaZYLddKwAz7+EwprLfkfg==", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "buffer": "^6.0.3" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "@solana/web3.js": "^1.47.4" + } + }, + "node_modules/@solana/web3.js": { + "version": "1.77.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.77.2.tgz", + "integrity": "sha512-pKu9S21NGAi6Nsayz2KEdhqOlPUJIr3L911bgQvPg2Dbk/U4gJsk41XGdxyfsfnwKPEI/KbitcByterst4VQ3g==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@noble/curves": "^1.0.0", + "@noble/hashes": "^1.3.0", + "@solana/buffer-layout": "^4.0.0", + "agentkeepalive": "^4.2.1", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.3", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "node-fetch": "^2.6.7", + "rpc-websockets": "^7.5.1", + "superstruct": "^0.14.2" + } + }, + "node_modules/@solana/web3.js/node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/@solana/web3.js/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/agentkeepalive": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", + "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", + "dependencies": { + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" + }, + "node_modules/axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axo": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/axo/-/axo-0.0.2.tgz", + "integrity": "sha512-8CC4Mb+OhK97UEng0PgiqUDNZjzVcWDsV+G2vLYCQn1jEL7y6VqiRVlZlRu+aA/ckSznmNzW6X1I6nj2As/haQ==" + }, + "node_modules/base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/big.js": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.1.tgz", + "integrity": "sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==", + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bigjs" + } + }, + "node_modules/bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.3.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bignumber.js": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", + "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==", + "engines": { + "node": "*" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/borsh": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", + "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", + "dependencies": { + "bn.js": "^5.2.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "node_modules/borsh/node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/borsh/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/bufferutil": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz", + "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/clear": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/clear/-/clear-0.1.0.tgz", + "integrity": "sha512-qMjRnoL+JDPJHeLePZJuao6+8orzHMGP04A8CdwCNsKhRbOnKRjefxONR7bwILT3MHecxKBjHkKL/tkZ8r4Uzw==", + "engines": { + "node": "*" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", + "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, + "node_modules/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extendible": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/extendible/-/extendible-0.1.1.tgz", + "integrity": "sha512-AglckQA0TJV8/ZmhQcNmaaFcFFPXFIoZbfuoQOlGDK7Jh/roWotYzJ7ik1FBBCHBr8n7CgTR8lXXPAN8Rfb7rw==" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==", + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/failure": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/failure/-/failure-1.1.1.tgz", + "integrity": "sha512-lzrrk0NUfjVeU3jLmfU01zP5bfg4XVFxHREYGvgJowaCqHLSQtqIGENH/CU+oSs6yfYObdSM7b9UY/3p2VJOSg==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-stable-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", + "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==" + }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/hang": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hang/-/hang-1.0.0.tgz", + "integrity": "sha512-vtBz98Bt/Tbm03cZO5Ymc7ZL8ead/jIx9T5Wg/xuz+9BXPAJNJSdGQW63LoaesogUQKTpHyal339hxTaTf/APg==" + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/hwid": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/hwid/-/hwid-0.3.0.tgz", + "integrity": "sha512-CpTrSl34DPnDawpYIeOPgb/Xjto0y8GfmlvmwjcborTXA+IED15t1b97WIa9F2cXwrA3RSy4UADfEGl/uQ91QA==", + "dependencies": { + "tslib": "^2.1.0", + "winreg": "^1.2.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + }, + "node_modules/jayson": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.7.0.tgz", + "integrity": "sha512-tfy39KJMrrXJ+mFcMpxwBvFDetS8LAID93+rycFglIQM4kl3uNR3W4lBLE/FFhsoUCEox5Dt2adVpDm/XtebbQ==", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "lodash": "^4.17.20", + "uuid": "^8.3.2", + "ws": "^7.4.5" + }, + "bin": { + "jayson": "bin/jayson.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jayson/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/loads": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/loads/-/loads-0.0.4.tgz", + "integrity": "sha512-XjPzzYIHkuMNqYyvh6AECQAHi682nyKO9TMdMYnaz7QbPDI/KIeSIjRhAlXIbRMPYAgtLUYgPlD3mtKZ4Q8SYA==", + "dependencies": { + "failure": "1.1.x", + "one-time": "0.0.x", + "xhr-response": "1.0.x", + "xhr-status": "1.0.x" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-http-xhr": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/node-http-xhr/-/node-http-xhr-1.3.4.tgz", + "integrity": "sha512-0bA08/2RKWxw6pMkOVd3KP+0F5+ifQLMMTDxrCgxlgkoU1N8DhCbCSAYEqpgaVYM2smvbVVewiXjW+8AyoLfxQ==" + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "node_modules/one-time": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", + "integrity": "sha512-qAMrwuk2xLEutlASoiPiAMW3EN3K96Ka/ilSXYr6qR1zSVXw2j7+yDSqGTC4T9apfLYxM3tLLjKvgPdAUK7kYQ==" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/requests": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/requests/-/requests-0.3.0.tgz", + "integrity": "sha512-1B6nkiHjC1O1cSgFhEwkc+xd8vuj04h7xSmCg5yI8nmhCIKbPkX47od8erQ2pokBt5qxUO7dwP4jplXD6k6ISA==", + "dependencies": { + "axo": "0.0.x", + "eventemitter3": "~4.0.0", + "extendible": "0.1.x", + "hang": "1.0.x", + "loads": "0.0.x", + "node-http-xhr": "~1.3.0", + "xhr-send": "1.0.x" + } + }, + "node_modules/rpc-websockets": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.5.1.tgz", + "integrity": "sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w==", + "dependencies": { + "@babel/runtime": "^7.17.2", + "eventemitter3": "^4.0.7", + "uuid": "^8.3.2", + "ws": "^8.5.0" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + } + }, + "node_modules/rpc-websockets/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/rpc-websockets/node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/superstruct": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", + "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/toformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/toformat/-/toformat-2.0.0.tgz", + "integrity": "sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==" + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/tslib": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz", + "integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/winreg": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.4.tgz", + "integrity": "sha512-IHpzORub7kYlb8A43Iig3reOvlcBJGX9gZ0WycHhghHtA65X0LYnMRuJs+aH1abVnMJztQkvQNlltnbPi5aGIA==" + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xhr-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xhr-response/-/xhr-response-1.0.1.tgz", + "integrity": "sha512-m2FlVRCl3VqDcpc8UaWZJpwuHpFR2vYeXv6ipXU2Uuu4vNKFYVEFI0emuJN370Fge+JCbiAnS+JJmSoWVmWrjQ==" + }, + "node_modules/xhr-send": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/xhr-send/-/xhr-send-1.0.0.tgz", + "integrity": "sha512-789EG4qW6Z0nPvG74AV3WWQCnBG5HxJXNiBsnEivZ8OpbvVA0amH0+g+MNT99o5kt/XLdRezm5KS1wJzcGJztw==" + }, + "node_modules/xhr-status": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xhr-status/-/xhr-status-1.0.1.tgz", + "integrity": "sha512-VF0WSqtmkf56OmF26LCWsWvRb1a+WYGdHDoQnPPCVUQTM8CVUAOBcUDsm7nP7SQcgEEdrvF4DmhEADuXdGieyw==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..2e03526 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "dexspyder_v1_cli", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@raydium-io/raydium-sdk": "^1.3.0-beta.18", + "@solana/spl-token": "^0.3.7", + "@solana/web3.js": "^1.77.2", + "axios": "^1.4.0", + "bs58": "^5.0.0", + "chalk": "^4.1.2", + "clear": "^0.1.0", + "cli-spinners": "^2.9.0", + "hwid": "^0.3.0", + "moment": "^2.29.4", + "request": "^2.88.2", + "requests": "^0.3.0" + } +} diff --git a/src/auth/KeyAuth.js b/src/auth/KeyAuth.js new file mode 100644 index 0000000..eaf6fd1 --- /dev/null +++ b/src/auth/KeyAuth.js @@ -0,0 +1,680 @@ +//* Importing ExecSync from "child_process" *// +const { execSync } = require('child_process') + +//* Importing Axios *// +const axios = require('axios') + +//* Importing OS *// +const os = require('os') + +//* Import FS *// +const fs = require("fs") + +//* KeyAuth Class *// +class KeyAuth { + /** + * @param {string} [name] - The name of the application + * @param {string} [ownerId] - The ownerId of the application + * @param {string} [secret] - The secret of the application + * @param {string} [version] - The version of the application + **/ + constructor(name, ownerId, secret, version) { + if (!(name && ownerId && secret && version)) { + Misc.error('Application not setup correctly.') + } + + this.name = name + this.ownerId = ownerId + this.secret = secret + this.version = version + this.responseTime = null; + }; + + /** + * Initializes the connection with KeyAuth in order to use any of the functions + **/ + Initialize = () => new Promise(async (resolve) => { + const post_data = { + type: 'init', + ver: this.version, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + if (Json === 'KeyAuth_Invalid') { + Misc.error('Invalid Application, please check your application details.') + } + + if (!Json.success || Json.success == false) { + return resolve(false) + } + + this.app_data = Json.appinfo + + this.sessionid = Json.sessionid + this.initialized = true + + resolve(true) + }) + + /** + * Registers the user using a license and gives the user a subscription that matches their license level + * @param {string} [username] - The username for the user + * @param {string} [password] - The password for the user + * @param {string} [license] - The License Key for the sub + **/ + register = (user, password, license, email = "") => new Promise(async (resolve) => { + this.check_initialize() + + let hwId + if (!hwId) { + hwId = Misc.GetCurrentHardwareId() + } + + const post_data = { + type: 'register', + username: user, + pass: password, + email, + key: license, + hwid: hwId, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success) { + this.Load_User_Data(Json.info) + return resolve(Json.message) + } else { + Misc.error(Json.message) + } + }) + + forgot = (username, email) => new Promise(async (resolve) => { + this.check_initialize() + + const post_data = { + type: 'forgot', + username, + email, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + }); + + /** + * Authenticates the user using their username and password + * @param {string} [username] - The username for the user + * @param {string} [password] - The password for the user + **/ + login = (username, password) => new Promise(async (resolve) => { + this.check_initialize() + + let hwId + if (!hwId) { + hwId = Misc.GetCurrentHardwareId() + } + + const post_data = { + type: 'login', + username, + pass: password, + hwid: hwId, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + this.Load_User_Data(Json.info) + return resolve(Json) + } else { + Misc.error(Json.message) + } + }) + + /** + * Authenticate without using usernames and passwords + * @param {string} [key] - Licence used to login with + **/ + license = (key) => new Promise(async (resolve) => { + this.check_initialize() + + let hwId + if (!hwId) { + hwId = Misc.GetCurrentHardwareId() + } + + const post_data = { + type: 'license', + key, + hwid: hwId, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + this.Load_User_Data(Json.info) + return resolve(Json) + } else { + Misc.error(Json.message) + } + }) + + /** + * Gives the user a subscription that has the same level as the key + * @param {string} [username] - Username of the user thats going to get upgraded + * @param {string} [license] - License with the same level as the subscription you want to give the user + **/ + upgrade = (username, license) => new Promise(async (resolve) => { + this.check_initialize() + + const post_data = { + type: 'upgrade', + username, + key: license, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (!Json.success || Json.success == false) { + return resolve(Json.message) + } else { + // Don't let them yet for dashboard. + Misc.error(Json.message) + } + }) + + /** + * Gets an existing global variable + * @param {string} [VarId] - Name of the variable / Variable ID + * returns {string} - The value of the variable / The content of the variable + **/ + var = (VarId) => new Promise(async (resolve) => { + this.check_initialize() + + const post_data = { + type: 'var', + varid: VarId, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + return resolve(Json) + } + + resolve(Json.message) + }) + + /** + * Gets the an existing user variable + * @Param {string} [VarId] - User Variable Name + * returns {string} - The value of the variable / The content of the user variable + **/ + GetVar = (VarId) => new Promise(async (resolve) => { + this.check_initialize() + + const post_data = { + type: 'getvar', + var: VarId, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + return resolve(Json) + } + + resolve(Json.message) + }) + + /** + * Change the data of an existing user variable, *User must be logged in* + * @Param {string} [VarId] - User variable name + * @Param {string} [VarData] - The content of the variable + **/ + SetVar = (VarId, VarData) => new Promise(async (resolve) => { + this.check_initialize() + + const post_data = { + type: 'setvar', + var: VarId, + data: VarData, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + return resolve(Json) + } + + resolve(Json.message) + }) + + /** + * Bans the current logged in user + **/ + ban = () => new Promise(async (resolve) => { + this.check_initialize() + + const post_data = { + type: 'ban', + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + return resolve(true) + } + + resolve(Json.message) + }) + + /** + * KeyAuth acts as proxy and downlods the file in a secure way + * @Param {string} [fileId] - File ID + * @Param {string} [path] - Path to save the file + * @Param {boolean} [execute] - Execute the file after download - Windows Only Requires path for file! + * returns {byte} - Returns The bytes of the download file + **/ + file = (fileId, path = null, execute = false) => new Promise(async (resolve) => { + this.check_initialize() + + const post_data = { + type: 'file', + fileid: fileId.toString(), + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + + if (path != null) { + var bytes = await this.strToByteArray(Json.contents); + fs.writeFile(path, bytes, async (err) => { + if (err) throw err; + + if (execute) { + var exec = require('child_process').exec; + await exec(path, function (error, stdout, stderr) { + if (error) { + console.error(error); + return; + } + }); + + return resolve(true); + } else { + return resolve(true); + } + }); + } else { + return resolve(this.strToByteArray(Json.contents)) + } + } + + resolve(Json.message) + }) + + + /** + * Sends a request to a webhook that you've added in the dashboard in a safe way without it being showed for example a http debugger + * @Param {string} [webId] - Webhook ID + * @Param {string} [Params] - Webhook Parameters + * @Param {string} [message] - Body of the request, empty by default + * @Param {string} [username] - Content type, empty by default + * Returns {string} - Returns the response of the webhook + **/ + webhook = (webId, Params, body = '', contType = '') => new Promise(async (resolve) => { // havent tested + this.check_initialize() + + const post_data = { + type: 'webhook', + webid: webId, + params: Params, + body, + conttype: contType, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + return resolve(Json.response) + } + + resolve(Json.message) + }) + + /** + * Check if the current session is validated or not + * Returns {string} - Returns if the session is valid or not + **/ + check = () => new Promise(async (resolve) => { + this.check_initialize() + + const post_data = { + type: 'check', + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + return resolve(Json) + }; + + resolve(Json.message) + }) + + /** + * Checks if the current IP Address/HardwareId is blacklisted + * returns {boolean} - Returns true if the IP Address/HardwareId is blacklisted, otherwise false + **/ + checkBlack = () => new Promise(async (resolve) => { + this.check_initialize() + + const hwId = Misc.GetCurrentHardwareId() + + const post_data = { + type: 'checkblacklist', + hwid: hwId, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + return resolve(true) + } + + resolve(false) + }) + + /** + * Fetch usernames of online users + * Returns {array} - Returns an array of usernames + **/ + fetchOnline = () => new Promise(async (resolve) => { + this.check_initialize() + + const post_data = { + type: 'fetchOnline', + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + return resolve(Json.users) + } else { + return resolve(Json.message) + } + }) + + /** + * Gets the last 20 sent messages of that channel + * @param {string} [ChannelName] - The name of the channel, where you want the messages + * Returns {array} the last 20 sent messages of that channel + **/ + ChatGet = (ChannelName) => new Promise(async (resolve) => { + this.check_initialize() + + const post_data = { + type: 'chatget', + channel: ChannelName, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + if (Json.messages[0].message == 'not_found') { + return resolve([]) + } else { + return resolve(Json.messages) + } + } else { + return resolve([]) + } + }) + + /** + * Sends a message to the given channel name + * @param {string} [ChannelName] - Channel Name where the message will be sent to + * @param {string} [Message] - Message what will be sent to [ChannelName] + * Returns {bool} - Returns true if the message was sent, otherwise false + **/ + ChatSend = (ChannelName, Message) => new Promise(async (resolve) => { + this.check_initialize() + + const post_data = { + type: 'fetchOnline', + message: Message, + channel: ChannelName, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + const Json = await this.make_request(post_data) + + this.Load_Response_Struct(Json) + if (Json.success && Json.success == true) { + return resolve(true) + } else { + return resolve(false) + } + }) + + /** + * Logs the IP address,PC Name with a message, if a discord webhook is set up in the app settings, the log will get sent there and the dashboard if not set up it will only be in the dashboard + * @param {string} [message] - Message / Discord Embed Title Message + * Returns None + **/ + log = (message) => new Promise(async (resolve) => { + this.check_initialize() + + const post_data = { + type: 'log', + pcuser: os.userInfo().username, + message, + sessionid: this.sessionid, + name: this.name, + ownerid: this.ownerId + } + + await this.make_request(post_data) + resolve(true) + }) + + + strToByteArray = (hex) => new Promise(async (resolve) => { + try { + const numberChars = hex.length; + const bytes = new Uint8Array(numberChars / 2); + for (let i = 0; i < numberChars; i += 2) { + bytes[i / 2] = parseInt(hex.substr(i, 2), 16); + } + resolve(bytes) + } catch (err) { + console.error('The session has ended, open program again.'); + process.exit(0); + } + }) + + /** + * Check if the current session is initialized + * @returns [true] if client is Initialized. + **/ + check_initialize() { + if (!this.initialized) { + Misc.error('You must initialize the API before using it!') + } + return true + }; + + /** + * Load the response struct for Response of Request + **/ + Load_Response_Struct(data) { + this.response = { + success: data.success, + message: data.message + } + }; + + /** + * Load the response struct for User Data + **/ + Load_User_Data(data) { + this.user_data = { + username: data.username, + ip: data.ip, + hwid: data.hwid, + createdate: data.createdate, + lastlogin: data.lastlogin, + subscriptions: data.subscriptions + } + }; + + /** + * Change Console Application Title + * @param {string} [title] - Your new Title for the App + * Returns Promise Timeout + **/ + setTitle(title) { + process.stdout.write( + String.fromCharCode(27) + ']0;' + title + String.fromCharCode(7) + ) + }; + + /** + * Sleeping / Timeout Function + * @param {number} [ms] - Time in milliseconds + * Returns Promise Timeout + **/ + sleep(ms) { + return new Promise((resolve) => { + setTimeout(resolve, ms) + }) + }; + + /** + * Request the API with the POST Data + * @param {string} [data] - Post Data Array + * Returns {array} - Returns the API Response [NON-ENCRYPTED] + **/ + make_request(data) { + const startTime = Date.now(); // Start the stopwatch + + return new Promise(async (resolve) => { + const request = await axios({ + method: 'POST', + url: 'https://keyauth.win/api/1.1/', + data: new URLSearchParams(data).toString() + }).catch((err) => { + Misc.error(err) + }) + + const endTime = Date.now(); // Stop the stopwatch + + this.responseTime = `${endTime - startTime} ms`; + + if (request && request.data) { + resolve(request.data) + } else { + resolve(null) + }; + }) + } + + +} + +class Misc { + /** + * Get the current user HardwareId + * @returns {string} - Returns user HardwareID + **/ + static GetCurrentHardwareId() { + if (os.platform() != 'win32') return false + + const cmd = execSync('wmic useraccount where name="%username%" get sid').toString('utf-8') + + const system_id = cmd.split('\n')[1].trim() + return system_id + }; + + /** + * Error Print Function + * @param {string} [message] - Message to Show and then exit app. + **/ + static error(message) { + console.log(message) + return process.exit(0) + } +} + +/** + * Export KeyAuth Class to be used in other files +**/ +module.exports = KeyAuth diff --git a/src/auth/checkKey.js b/src/auth/checkKey.js new file mode 100644 index 0000000..d03d4b1 --- /dev/null +++ b/src/auth/checkKey.js @@ -0,0 +1,32 @@ +const KeyAuth = require('./KeyAuth'); +const readline = require("readline"); +const moment = require("moment"); +const CRL = readline.createInterface({ input: process.stdin, output: process.stdout }); + +const KeyAuthApp = new KeyAuth( + "DexSpyder", + "8d7VumkIWc", + "86342a655b33a96164cf9899837d05e20b8e568bacbd414c3a3839c21dab7eab", // Application Secret + "1.0" +); + + +(async () => { + await KeyAuthApp.Initialize(); + await KeyAuthApp.check(); + await KeyAuthApp.sleep(1200); + var license = ""; + + await CRL.question("License : ", async (lic) => { + license = lic; + await KeyAuthApp.license(license); + if (KeyAuthApp.response.status == "failed") { + console.log(KeyAuthApp.response.message); + process.exit(0); + } + console.log(KeyAuthApp.response.message); + await CRL.question("Press any key to continue...", async () => { + console.clear(); + }); + }); +})(); \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..7949587 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,499 @@ +import readline from 'readline'; +import graph_menu from './utils'; +import chalk from 'chalk'; +import {update_slippage,update_rpc,update_wallet,show_config, config} from "./modules/config" +import fs from "fs"; +import spinner from "cli-spinners"; +import {get_token_amount} from "./modules/fetch_token" +import {get_wallet} from "./modules/get_keypair" +import { Connection, Keypair, PublicKey } from '@solana/web3.js'; +import { fetchPoolKeys } from './modules/pool_keys'; +import {compute} from "./modules/compute"; +import {swap} from "./modules/swap"; +import { getTokenAccountsByOwner } from "./modules/get_accounts"; + + +//control variables +var choice = 0; + +//key auth instance + +//spinner function + +const Spinner = spinner.dots4; +let i = 0; +let animationInterval; + +const updateSpinner = () => { + const frame = Spinner.frames[i % Spinner.frames.length]; + process.stdout.cursorTo(0); + process.stdout.write('\t'+frame); + i++; + }; + + +const startSpinner = () => { + animationInterval = setInterval(updateSpinner, Spinner.interval); +}; + +const stopSpinner = () => { + clearInterval(animationInterval); + process.stdout.clearLine(0); + process.stdout.cursorTo(0); + }; + +//creating interface +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +//clearing-resetting screen +function clear_screen() { + console.clear(); +} + +//sleep function +function sleep(ms:number) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + + +//program start + +//initial authentication + +//(async () => { +// +// startSpinner() +// stopSpinner() +// +// var config_txt = fs.readFileSync('config.json','utf8'); +// var config_obj:config = JSON.parse(config_txt); +// const license = config_obj.license; +// if (license != ''){ +// await verify_license(license) +// }else{ +// rl.question("\tLicense : ", async (lic) => { +// await verify_license(lic); +// }); +// } +//})(); + +main() + + +async function start_swapping( + connection:Connection, + is_snipe:boolean, + amount_in:number, + pool:string, + slip:number, + owner:Keypair +) +{ + + console.log(chalk.greenBright('\tinputs valid\n')); + console.log(chalk.white(`\t[1] - ${chalk.blueBright(is_snipe?'Snipe':'Sell')}`)); + console.log(chalk.white('\t[2] - Return')); + + rl.question(`\n\t${is_snipe?'[Sniper]':'[Exit Position]'} - choice: `, async (answer) => { + + const ans = parseInt(answer); + if (ans == 1){ + finished = false; + const SwapSpinner = spinner.dots4; + let i = 0; + let animationInterval; + + const updateSwapSpinner = () => { + const frame = Spinner.frames[i % Spinner.frames.length]; + process.stdout.cursorTo(0); + process.stdout.write(chalk.blueBright('\tSwapping'+frame)); + i++; + }; + + + const startSwapSpinner = () => { + animationInterval = setInterval(updateSwapSpinner, SwapSpinner.interval); + }; + + const stopSwapSpinner = () => { + clearInterval(animationInterval); + process.stdout.clearLine(0); + process.stdout.cursorTo(0); + }; + + startSpinner(); + var finished:boolean = false; + const pool_keys = await fetchPoolKeys(connection, new PublicKey(pool)); + + var token_in_key:PublicKey; + var token_out_key:PublicKey; + + if(is_snipe){ + token_in_key = pool_keys.quoteMint; + token_out_key = pool_keys.baseMint; + }else{ + token_in_key = pool_keys.baseMint; + token_out_key = pool_keys.quoteMint; + } + + while(!finished){ + + const computation:any = await compute(connection,pool_keys,token_in_key,token_out_key,amount_in,slip); + + const amountOut = computation[0]; + + const minAmountOut = computation[1]; + + const currentPrice = computation[2]; + + const executionPrice = computation[3]; + + const priceImpact = computation[4]; + + const fee = computation[5]; + + const amountIn = computation[6]; + + stopSpinner(); + + + console.log(`\n\tAmount out: ${amountOut.toFixed()},\n\tMin Amount out: ${minAmountOut.toFixed()}`) + if (priceImpact.toFixed() > 5){ + console.log(chalk.red(`\tpriceImpact: ${priceImpact.toFixed()}`)) + }else if(priceImpact.toFixed() < 5 && priceImpact.toFixed() > 1){ + console.log(chalk.yellowBright(`\tpriceImpact: ${priceImpact.toFixed()}`)) + }else{ + console.log(chalk.green(`\tpriceImpact: ${priceImpact.toFixed()}`)) + } + + + console.log('\n') + + startSwapSpinner() + const token_accounts = await getTokenAccountsByOwner(connection, owner.publicKey); + + const swap_status = await swap(connection,pool_keys,owner,token_accounts,is_snipe,amountIn,minAmountOut); + stopSwapSpinner() + + if (swap_status == 0){ + console.log(chalk.greenBright('\tSwap successful!')) + rl.question("\tpress enter to return..", async () => { + snipe_menu(); + }); + break + }else{ + console.log(chalk.red('\tSwap failed, retrying...')) + continue + } + } + + }else if(ans == 2){ + snipe_menu(); + }else{ + console.log(chalk.red("\n\tInvalid choice")); + await sleep(1000); + snipe_menu(); + } + + }) +} + +async function snipe_choice(){ + clear_screen(); + graph_menu.aff_logo(); + graph_menu.aff_title(); + graph_menu.aff_snipe_option(); + + const owner = get_wallet('config.json'); + var config_txt = fs.readFileSync('config.json','utf8'); + var config_obj:config = JSON.parse(config_txt); + const slip = config_obj.slippage; + const connection = new Connection(config_obj.rpc_endpoint); + + rl.question("\n\tPool ID: ", async (answer) => { + + const pool:string = answer; + + rl.question("\n\tAmount in(enter 'MAX' for max amount): ", async(answer)=>{ + + console.log('\n\t'); + startSpinner(); + + + var res:number; + const amount_in = parseFloat(answer); + const is_max = answer; + const token_amount= await get_token_amount(pool,true); + + stopSpinner() + + if (token_amount == -1){ + console.log(chalk.red("\n\tInvalid Pool ID or an error has occured.")); + await sleep(1000); + snipe_menu(); + }else if(token_amount == -2){ + console.log(chalk.red("\n\tSol Balance less than 0.01")); + await sleep(1000); + snipe_menu(); + }else if(token_amount == 0){ + console.log(chalk.red("\n\tNo balance found.")); + await sleep(1000); + snipe_menu(); + }else{ + if (is_max.toUpperCase() == 'MAX'){ + if (token_amount < 0.00001){ + console.log(chalk.red("\n\tInput too small.")); + await sleep(1000); + snipe_menu(); + }else{ + await start_swapping(connection,true,token_amount,pool,slip,owner); + } + }else if(isNaN(amount_in)){ + console.log(chalk.red("\n\tInvalid Input.")); + await sleep(1000); + snipe_menu(); + }else{ + if (amount_in > token_amount){ + console.log(chalk.red("\n\tinsufficient balance.")); + await sleep(1000); + snipe_menu(); + }else{ + if (amount_in < 0.00001){ + console.log(chalk.red("\n\tInput too small.")); + await sleep(1000); + snipe_menu(); + }else{ + await start_swapping(connection,true,amount_in,pool,slip,owner); + } + } + } + } + }) + }); +} + + +async function sell_choice(){ + clear_screen(); + graph_menu.aff_logo(); + graph_menu.aff_title(); + graph_menu.aff_sell_option(); + + const owner = get_wallet('config.json'); + var config_txt = fs.readFileSync('config.json','utf8'); + var config_obj:config = JSON.parse(config_txt); + const slip = config_obj.slippage; + const connection = new Connection(config_obj.rpc_endpoint); + + rl.question("\n\tPool ID: ", async (answer) => { + + const pool:string = answer; + + rl.question("\n\tAmount in(enter 'MAX' for max amount): ", async(answer)=>{ + + console.log('\n\t'); + startSpinner(); + + + var res:number; + const amount_in = parseFloat(answer); + const is_max = answer; + const token_amount= await get_token_amount(pool,false); + + stopSpinner() + + if (token_amount == -1){ + console.log(chalk.red("\n\tInvalid Pool ID or an error has occured.")); + await sleep(1000); + snipe_menu(); + }else if(token_amount == -2){ + console.log(chalk.red("\n\tSol Balance less than 0.01")); + await sleep(1000); + snipe_menu() + }else if(token_amount == 0){ + console.log(chalk.red("\n\tNo balance found.")); + await sleep(1000); + snipe_menu() + }else{ + if (is_max.toUpperCase() == 'MAX'){ + await start_swapping(connection,false,token_amount,pool,slip,owner); + }else if(isNaN(amount_in)){ + console.log(chalk.red("\n\tInvalid Input.")); + await sleep(1000); + snipe_menu() + }else{ + if (amount_in > token_amount){ + console.log(chalk.red("\n\tinsufficient balance.")); + await sleep(1000); + snipe_menu() + }else{ + await start_swapping(connection,false,amount_in,pool,slip,owner); + } + } + } + }) + }); +} + +function usage(){ + clear_screen(); + graph_menu.aff_logo(); + graph_menu.aff_title(); + graph_menu.aff_guide() + + rl.question("\n\tpress enter to return..", async () => { + snipe_menu(); + }); +} + +//sniper menu’t miss your chance to claim the title and make history! Join us at Keymasters 2023: + + +async function snipe_menu(){ + var config_txt = fs.readFileSync('config.json','utf8'); + var config_obj:config = JSON.parse(config_txt); + + const wallet = config_obj.wallet; + if (wallet === 'None'){ + console.log(chalk.red("\n\tPlease add a wallet in settings")); + await sleep(1500); + main(); + }else{ + clear_screen(); + graph_menu.aff_logo(); + graph_menu.aff_title(); + graph_menu.aff_sniper_menu(); + + rl.question(chalk.white('\t[Sniper Mode] - Choice: '), async(answer) => { + choice = parseInt(answer); + if (choice == 1){ + snipe_choice(); + }else if(choice == 2 ){ + sell_choice(); + }else if(choice == 3 ){ + usage(); + }else if (choice == 4){ + main(); + }else{ + console.log(chalk.red("\tInvalid choice.")); + await sleep(1500); + snipe_menu(); + } + }) + } + +} + +//settings menu +function settings_menu(){ + clear_screen(); + graph_menu.aff_logo(); + graph_menu.aff_title(); + graph_menu.aff_settings_menu(); + rl.question(chalk.white('\t[Settings] - Choice: '), async(answer) => { + choice = parseInt(answer); + if (choice == 1) { + + rl.question(chalk.white('\t[Settings] - New RPC Endpoint: '),async (answer)=>{ + + const res = await update_rpc(answer); + await sleep(1000); + + if (res === 1){ + console.log(chalk.red('\tInvalid RPC Value')); + await sleep(1000); + settings_menu(); + }else{ + console.log('\tRPC Updated'); + await sleep(1000); + settings_menu(); + } + + }) + } else if (choice == 2) { + + } else if (choice == 3) { + + rl.question(chalk.white('\t[Settings] - New Slippage(0-100): '),async (answer)=>{ + + const res = update_slippage(answer); + + if (res === 1){ + console.log(chalk.red('\tInvalid Slippage Value')); + await sleep(1000); + settings_menu(); + }else{ + console.log('\tSlippage Updated!'); + await sleep(1000); + settings_menu(); + } + + }) + + } else if (choice == 4) { + rl.question(chalk.white('\t[Settings] - Enter Private Key: '),async (answer)=>{ + + const res = update_wallet(answer); + + if (res === 1){ + console.log(chalk.red('\tInvalid Input or Wallet Not Found')); + await sleep(1000); + settings_menu(); + }else{ + console.log('\tWallet Updated!'); + await sleep(1000); + settings_menu(); + } + }) + + } else if(choice == 5){ + clear_screen(); + graph_menu.aff_logo(); + graph_menu.aff_title(); + show_config() + rl.question(chalk.white('\n\tpress enter to return..'),(answer)=>{ + settings_menu(); + }) + + + }else if(choice == 6){ + main(); + + }else { + console.log(chalk.red("\tInvalid choice.")); + await sleep(1500); + settings_menu(); + } + }); +} + + +//main menu +function main() { + console.clear(); + graph_menu.aff_logo(); + graph_menu.aff_title(); + graph_menu.aff_main_menu(); + rl.question(chalk.white('\t[Main] - Choice: '), async (answer) => { + choice = parseInt(answer); + if (choice == 1) { + snipe_menu(); + } else if (choice == 2) { + settings_menu(); + } else if (choice == 3) { + process.exit(); + } else { + console.log(chalk.red("\tInvalid choice.")); + await sleep(1500); + main(); + } + }); +} + + +module.exports = { + main +} \ No newline at end of file diff --git a/src/modules/compute.ts b/src/modules/compute.ts new file mode 100644 index 0000000..153ca47 --- /dev/null +++ b/src/modules/compute.ts @@ -0,0 +1,63 @@ + +import { Connection, PublicKey } from "@solana/web3.js"; +import { Liquidity, Percent, Token, TokenAmount,CurrencyAmount, LiquidityPoolInfo } from "@raydium-io/raydium-sdk"; + + + +//computes live estimates of the swap and returns details for transaction building or display on UI. +//returns a list containing trade details (fees,price impact,expected amount out etc..) + +export async function compute( + + connection: Connection, poolKeys: any, + curr_in:PublicKey , curr_out:PublicKey, + amount_in:number, slip:number + ){ + try{ + + const poolInfo = await Liquidity.fetchInfo({connection,poolKeys}) + + //setting up decimals + var in_decimal:number; + var out_decimal:number; + + if(curr_in.toBase58() === poolKeys.baseMint.toBase58()){ + in_decimal = poolInfo.baseDecimals + out_decimal = poolInfo.quoteDecimals + }else{ + out_decimal = poolInfo.baseDecimals; + in_decimal = poolInfo.quoteDecimals; + } + + + //priming and computing + const amountIn = new TokenAmount(new Token(curr_in, in_decimal), amount_in, false); + + const currencyOut = new Token(curr_out, out_decimal); + + const slippage = new Percent(slip, 100) + + const { + amountOut, + minAmountOut, + currentPrice, + executionPrice, + priceImpact, + fee, + } = Liquidity.computeAmountOut({ poolKeys, poolInfo, amountIn, currencyOut, slippage}) + + return [ + amountOut, + minAmountOut, + currentPrice, + executionPrice, + priceImpact, + fee, + amountIn, + ] + + }catch(e){ + console.log(e); + return 1 + } +} \ No newline at end of file diff --git a/src/modules/config.ts b/src/modules/config.ts new file mode 100644 index 0000000..2c4374d --- /dev/null +++ b/src/modules/config.ts @@ -0,0 +1,115 @@ +import { Connection, Keypair, PublicKey } from "@solana/web3.js"; +import bs58 from "bs58"; +import fs from "fs"; + +const hash_key = "pleasedonotlookatstringsincodethanks" + +//config interface | type +export interface config { + webhook_url : string, + rpc_endpoint : string, + wallet : string, + slippage : number, + license: string, +} + + +//fetching from config +export function show_config(){ + + var config_txt = fs.readFileSync('config.json','utf8'); + var config_obj:config = JSON.parse(config_txt); + + var pubkey:string; + try{ + const secretkey = bs58.decode(config_obj.wallet); + const ownerKeypair = Keypair.fromSecretKey(secretkey); + var pubkey = ownerKeypair.publicKey.toBase58(); + }catch(e){ + pubkey = config_obj.wallet + } + + console.log(`\tWallet Address: ${pubkey}`) + console.log(`\tRPC URL: ${config_obj.rpc_endpoint}`) + console.log(`\tWebhook URL: ${config_obj.webhook_url}`) + console.log(`\tSlippage: ${config_obj.slippage}%`) + +} + + +//updating config +//returns 0 for success and 1 for failure + + +export async function update_rpc(rpc:string){ + try{ + const connection = new Connection(rpc); + const balance = await connection.getBalance(new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA')) + if (balance){ + + //reading config file + var config_txt = fs.readFileSync('config.json','utf8'); + var config_obj:config = JSON.parse(config_txt); + + //updating config + config_obj.rpc_endpoint = rpc; + + //writing new config + const new_config = JSON.stringify(config_obj); + fs.writeFileSync('config.json',new_config) + return 0 + }else{ + return 1 + } + }catch(e){ + return 1 + } +} + +export function update_slippage(slip:string){ + try{ + const parsedSlippage = parseInt(slip); + if (isNaN(parsedSlippage)){ + return 1 + } else if(parsedSlippage > 100 || parsedSlippage < 0){ + return 1 + } else{ + + //reading config file + var config_txt = fs.readFileSync('config.json','utf8'); + var config_obj:config = JSON.parse(config_txt); + + //updating config + config_obj.slippage = parsedSlippage; + + //writing new config + const new_config = JSON.stringify(config_obj); + fs.writeFileSync('config.json',new_config); + return 0 + + } + }catch(e){ + return 1 + } +} + + +export function update_wallet(wallet:string){ + var config_txt = fs.readFileSync('config.json','utf8'); + var config_obj:config = JSON.parse(config_txt); + try{ + + const secretkey = bs58.decode(wallet); + const ownerKeypair = Keypair.fromSecretKey(secretkey); + + //updating config + config_obj.wallet = wallet; + //writing new config + const new_config = JSON.stringify(config_obj); + fs.writeFileSync('config.json',new_config); + return 0; + + }catch(e){ + return 1 + } +} \ No newline at end of file diff --git a/src/modules/fetch_token.ts b/src/modules/fetch_token.ts new file mode 100644 index 0000000..2765f64 --- /dev/null +++ b/src/modules/fetch_token.ts @@ -0,0 +1,87 @@ +import { Connection,Keypair,PublicKey } from "@solana/web3.js"; +import fs from "fs"; +import {config} from "./config"; +import bs58 from "bs58"; +import { Liquidity} from "@raydium-io/raydium-sdk"; + + +export async function get_token_amount(poolId:string, buying:boolean){ + + try{ + + //fetching pool data + var config_txt = fs.readFileSync('config.json','utf8'); + var config_obj:config = JSON.parse(config_txt); + + const rpc_url = config_obj.rpc_endpoint; + + + const version : 4 | 5 = 4 + + + const connection = new Connection(rpc_url); + + const account = await connection.getAccountInfo(new PublicKey(poolId)); + const { state: LiquidityStateLayout } = Liquidity.getLayouts(version) + + //@ts-ignore + const fields = LiquidityStateLayout.decode(account?.data); + + const { status, baseMint, quoteMint, lpMint, openOrders, targetOrders, baseVault, quoteVault, marketId, baseDecimal, quoteDecimal, } = fields; + + var is_valid:boolean = false; + + [quoteMint,baseMint,lpMint].forEach((e)=>{ + if (e.toBase58() != '11111111111111111111111111111111'){ + is_valid = true; + } + }) + if (!is_valid){return -1} + + //fetching token data + const secretkey = bs58.decode(config_obj.wallet); + const ownerKeypair = Keypair.fromSecretKey(secretkey); + + const owner_address = ownerKeypair.publicKey; + + + const tokenAddress = buying?quoteMint:baseMint + + //console.log(tokenAddress.toBase58()); + + const bal = await connection.getBalance(new PublicKey(owner_address.toBase58())); + + if (bal < 0.01){ + return -2 + } + + if (tokenAddress.toBase58() == 'So11111111111111111111111111111111111111112'){ + return (bal / 1000000000) - 0.0099 + }else{ + + const tokenAccounts = await connection.getParsedTokenAccountsByOwner(owner_address, { programId: new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA')}); + + for (var cand in tokenAccounts.value){ + if (tokenAccounts.value[cand].account.data.parsed.info.mint === tokenAddress.toBase58()){ + const tokenAccount = tokenAccounts.value[cand]; + const tokenBalance:number = tokenAccount.account.data.parsed.info.tokenAmount.uiAmount; + return tokenBalance + } + } + return 0 + + } + + }catch(e){ + return -1 + } + +} + + +async function test(){ + const res = await get_token_amount('AZqjt9vYMGZMuNfzSmFjMFgcMHnkBPndpTn1uprKLrq2',false); + console.log(res); +} + +//test(); diff --git a/src/modules/get_accounts.ts b/src/modules/get_accounts.ts new file mode 100644 index 0000000..47d40ba --- /dev/null +++ b/src/modules/get_accounts.ts @@ -0,0 +1,26 @@ +import { SPL_ACCOUNT_LAYOUT, TOKEN_PROGRAM_ID, TokenAccount } from "@raydium-io/raydium-sdk"; +import { Connection, PublicKey } from "@solana/web3.js"; + +//fetching token accounts +export async function getTokenAccountsByOwner( + connection: Connection, + owner: PublicKey, + ) { + const tokenResp = await connection.getTokenAccountsByOwner( + owner, + { + programId: TOKEN_PROGRAM_ID + }, + ); + + const accounts: TokenAccount[] = []; + + for (const { pubkey, account } of tokenResp.value) { + accounts.push({ + pubkey, + accountInfo:SPL_ACCOUNT_LAYOUT.decode(account.data) + }); + } + + return accounts; + } \ No newline at end of file diff --git a/src/modules/get_keypair.ts b/src/modules/get_keypair.ts new file mode 100644 index 0000000..1d07b33 --- /dev/null +++ b/src/modules/get_keypair.ts @@ -0,0 +1,22 @@ +import { Keypair } from "@solana/web3.js"; +import { config } from "./config"; +import bs58 from "bs58"; +import fs from "fs" + +//function to fetch the owners keypair object from config +//returns Keypair instance if valid or undefined if not +export function get_wallet(config_path:string):Keypair|undefined{ + + var config_txt = fs.readFileSync(config_path,'utf8'); + var config_obj:config = JSON.parse(config_txt); + try{ + + const secretkey = bs58.decode(config_obj.wallet); + const ownerKeypair = Keypair.fromSecretKey(secretkey); + + return ownerKeypair + }catch{ + + } + +} \ No newline at end of file diff --git a/src/modules/pool_keys.ts b/src/modules/pool_keys.ts new file mode 100644 index 0000000..82c024e --- /dev/null +++ b/src/modules/pool_keys.ts @@ -0,0 +1,97 @@ +import { Liquidity, Market } from "@raydium-io/raydium-sdk"; +import { Connection, PublicKey } from "@solana/web3.js"; + + +//returns the pool keys (info and required params/program id's) +//neccessary to interact with the liquidity pool program and compute live prices and estimates. +export async function fetchPoolKeys( + connection: Connection, + poolId: PublicKey, + version : 4 | 5 = 4 + ) { + + const serumVersion = 10 + const marketVersion:3 = 3 + + const programId = new PublicKey('675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8'); + const serumProgramId = new PublicKey('srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX') + + const account = await connection.getAccountInfo(poolId) + const { state: LiquidityStateLayout } = Liquidity.getLayouts(version) + + //@ts-ignore + const fields = LiquidityStateLayout.decode(account?.data); + const { status, baseMint, quoteMint, lpMint, openOrders, targetOrders, baseVault, quoteVault, marketId, baseDecimal, quoteDecimal, } = fields; + + let withdrawQueue, lpVault; + if (Liquidity.isV4(fields)) { + withdrawQueue = fields.withdrawQueue; + lpVault = fields.lpVault; + } else { + withdrawQueue = PublicKey.default; + lpVault = PublicKey.default; + } + + // uninitialized + // if (status.isZero()) { + // return ; + // } + + const associatedPoolKeys = Liquidity.getAssociatedPoolKeys({ + version:version, + marketVersion, + marketId, + baseMint: baseMint, + quoteMint:quoteMint, + baseDecimals: baseDecimal.toNumber(), + quoteDecimals: quoteDecimal.toNumber(), + programId, + marketProgramId:serumProgramId, + }); + + const poolKeys = { + id: poolId, + baseMint, + quoteMint, + lpMint, + version, + programId, + + authority: associatedPoolKeys.authority, + openOrders, + targetOrders, + baseVault, + quoteVault, + withdrawQueue, + lpVault, + marketVersion: serumVersion, + marketProgramId: serumProgramId, + marketId, + marketAuthority: associatedPoolKeys.marketAuthority, + }; + + const marketInfo = await connection.getAccountInfo(marketId); + const { state: MARKET_STATE_LAYOUT } = Market.getLayouts(marketVersion); + //@ts-ignore + const market = MARKET_STATE_LAYOUT.decode(marketInfo.data); + + const { + baseVault: marketBaseVault, + quoteVault: marketQuoteVault, + bids: marketBids, + asks: marketAsks, + eventQueue: marketEventQueue, + } = market; + + // const poolKeys: LiquidityPoolKeys; + return { + ...poolKeys, + ...{ + marketBaseVault, + marketQuoteVault, + marketBids, + marketAsks, + marketEventQueue, + }, + }; + } \ No newline at end of file diff --git a/src/modules/send_transaction.ts b/src/modules/send_transaction.ts new file mode 100644 index 0000000..4025be8 --- /dev/null +++ b/src/modules/send_transaction.ts @@ -0,0 +1,52 @@ + +import {Connection, Signer, Transaction} from "@solana/web3.js"; + + + +//sleep function +function sleep(ms:number) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +//sending a transaction +export async function sendTx(connection: Connection, transaction: Transaction, signers: Array){ + + const hash_info = (await connection.getLatestBlockhashAndContext()).value; + + transaction.recentBlockhash = hash_info.blockhash + transaction.lastValidBlockHeight = hash_info.lastValidBlockHeight + transaction.feePayer = signers[0].publicKey + + + transaction.sign(...signers); + const rawTransaction = transaction.serialize(); + + + var txid:string; + try{ + txid = await connection.sendRawTransaction(rawTransaction,{skipPreflight: true,}) + } + catch(e){ + return 1 + } + + while (true){ + const ret = await connection.getSignatureStatus(txid, {searchTransactionHistory:true}) + try { + //@ts-ignore + if (ret){ + if (ret.value && ret.value.err == null){ + return 0 + } else if (ret.value && ret.value.err != null){ + return 1 + }else{ + continue + } + } + } catch(e){ + return 1 + } + + } + + } \ No newline at end of file diff --git a/src/modules/swap.ts b/src/modules/swap.ts new file mode 100644 index 0000000..1359ba3 --- /dev/null +++ b/src/modules/swap.ts @@ -0,0 +1,47 @@ +import { Liquidity, Percent, Token, TokenAccount, TokenAmount } from "@raydium-io/raydium-sdk"; +import {Connection,Keypair,Transaction,} from "@solana/web3.js"; +import { sendTx } from "./send_transaction"; + + +export async function swap(connection: Connection, poolKeys: any, ownerKeypair: Keypair, tokenAccounts: TokenAccount[],is_snipe:boolean,amountIn:any,minAmountOut:any){ + + const owner = ownerKeypair.publicKey + + const inst = await Liquidity.makeSwapInstructionSimple({ + connection:connection, + poolKeys:poolKeys, + userKeys:{ + tokenAccounts, + owner, + }, + amountIn, + amountOut:minAmountOut, + fixedSide:'in', + config:{} + }) + + + //@ts-ignore + //const instructions = inst.innerTransactions[0].instructions[0]; + //console.log(inst.innerTransactions); + //console.log(inst.innerTransactions[0]); + //console.log(inst.innerTransactions[0].signers) + + const tx = new Transaction() + const signers:Keypair[] = [ownerKeypair] + + inst.innerTransactions[0].instructions.forEach(e=>{ + tx.add(e); + }) + + inst.innerTransactions[0].signers.forEach(e=>{ + signers.push(e); + }) + + + const res:number = await sendTx(connection, tx, signers); + return res; + +} + + \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..b8ca6c2 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,130 @@ +import chalk from 'chalk'; + +const logo = ` +\t +\t +\t ( & +\t % % +\t & % & +\t &&/ &****& & +\t % % (*****./ .( +\t % ./ ((((((,( *( +\t % % %///( ( +\t &&&.*//////**// % * .,/ ./ * / /,,/((# / +\t * (//*.. & / */( .# ,.*/(( +\t *** , /&( / *(( +\t , .,*,./, .,*,/%#//(# #*# +\t */*# &*, /( &/ .( * +\t ./ * /% (&, (#/ +\t ( (,( / /( %,/# +\t ,/% /,/ +\t ( .( +\t (( , +\t , +\t ( / +\t +` + +const title = ` +\t▓█████▄ ▓█████ ▒██ ██▒ ██████ ██▓███ ▓██ ██▓▓█████▄ ▓█████ ██▀███ +\t▒██▀ ██▌▓█ ▀ ▒▒ █ █ ▒░▒██ ▒ ▓██░ ██▒▒██ ██▒▒██▀ ██▌▓█ ▀ ▓██ ▒ ██▒ +\t░██ █▌▒███ ░░ █ ░░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░░██ █▌▒███ ▓██ ░▄█ ▒ +\t░▓█▄ ▌▒▓█ ▄ ░ █ █ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░░▓█▄ ▌▒▓█ ▄ ▒██▀▀█▄ +\t░▒████▓ ░▒████▒▒██▒ ▒██▒▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░░▒████▓ ░▒████▒░██▓ ▒██▒ +\t ▒▒▓ ▒ ░░ ▒░ ░▒▒ ░ ░▓ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒ ▒▒▓ ▒ ░░ ▒░ ░░ ▒▓ ░▒▓░ +\t ░ ▒ ▒ ░ ░ ░░░ ░▒ ░░ ░▒ ░ ░░▒ ░ ▓██ ░▒░ ░ ▒ ▒ ░ ░ ░ ░▒ ░ ▒░ +\t ░ ░ ░ ░ ░ ░ ░ ░ ░ ░░ ▒ ▒ ░░ ░ ░ ░ ░ ░░ ░ +\t ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ +\t ░ ░ ░ ░ + + +` + + +export function aff_logo() { + for (let i = 0; i < logo.length; i++) { + if (logo[i] == '@') { + process.stdout.write(chalk.black(logo[i])); + } else { + process.stdout.write(chalk.magenta(logo[i])); + } + } +} + +export function aff_title(){ + for (let i = 0; i < title.length; i++) { + if (title[i] == '▓') { + process.stdout.write(chalk.black(title[i])); + } else { + process.stdout.write(chalk.magenta(title[i])); + } + } +} + +export function aff_snipe_option(){ + console.log(chalk.cyanBright('\tDisclaimer: \t- the tool will start sniping if all inputs are valid!')); + console.log(chalk.cyanBright('\t \t- double check the amount and pool details in the monitor')); + console.log(chalk.cyanBright('\t \t to avoid miss-inputs and big price impact')); +} + +export function aff_sell_option(){ + console.log(chalk.cyanBright('\tDisclaimer: \t- the tool will sell supplied balance if all inputs are valid!')); + console.log(chalk.cyanBright('\t \t- double check the held balance and pool details in the monitor')); + console.log(chalk.cyanBright('\t \t to avoid miss-inputs and big price impact')); +} + +export function aff_guide(){ + console.log(chalk.white('\tUSAGE: ')) + console.log(chalk.white('\n')) + console.log(chalk.white('\tsniper option \t - requires AMM pool ID and amount of token in as input')); + console.log(chalk.white('\t \t - Amount in should be the Quote of the pair (from on-chain monitor)')); + console.log(chalk.white('\t \t - make sure to have the supplied amount of token in or the transaction will not go through')); + console.log(chalk.white('\n')); + console.log(chalk.white('\texit position option\t - requires AMM pool ID and amount of token out as input')); + console.log(chalk.white('\t \t - Amount in should be the Base of the pair (from on-chain monitor)')); + console.log(chalk.white('\t \t - make sure to have the supplied amount of token out or the transactions will not got through')); + console.log(chalk.white('\n')); + console.log(chalk.white('\tdefault slippage \t - 10%')); + console.log(chalk.white('\tsuggested slippage \t - between 10% and 30%')); + console.log(chalk.white("\tRPCs \t - Custom RPC's are highly suggested for fast transaction commitment speed")); + console.log(chalk.white('\n')); +} + +export function aff_main_menu(){ + console.log(chalk.white('\t[1] - Sniper Mode')); + console.log(chalk.white('\t[2] - Settings')); + console.log(chalk.white('\t[3] - Exit')); + console.log("\n"); +} + +export function aff_sniper_menu(){ + console.log(chalk.blueBright('\t[1] - Snipe')); + console.log(chalk.greenBright('\t[2] - Exit Position')); + console.log(chalk.white('\t[3] - Usage')); + console.log(chalk.white('\t[4] - return')); + console.log("\n"); +} + +export function aff_settings_menu() { + console.log(chalk.white('\t[1] - Change RPC')); + console.log(chalk.white('\t[2] - Change Webhook')); + console.log(chalk.white('\t[3] - Change Slippage')); + console.log(chalk.white('\t[4] - Change Wallet')); + console.log(chalk.white('\t[5] - Show Current Settings')); + console.log(chalk.white('\t[6] - Back')); + console.log("\n"); +} + +const default_export = { + aff_logo, + aff_title, + aff_main_menu, + aff_settings_menu, + aff_sniper_menu, + aff_snipe_option, + aff_sell_option, + aff_guide, +} + +export default default_export + diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..5df412d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,103 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "lib": ["es6"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + "rootDir": "src", /* Specify the root folder within your source files. */ + "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "build", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": false, /* Enable all strict type-checking options. */ + "noImplicitAny": false, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } + }