From afd645ac40e5fc6a34990d9071d13e5c1c2cfe03 Mon Sep 17 00:00:00 2001 From: BoiiButBot Date: Wed, 7 Feb 2024 23:27:44 +0700 Subject: [PATCH 01/12] Add Discord webhook integration for posting messages --- buy.ts | 129 ++++++- pnpm-lock.yaml | 938 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1054 insertions(+), 13 deletions(-) create mode 100644 pnpm-lock.yaml diff --git a/buy.ts b/buy.ts index 18c2ede..b8b0706 100644 --- a/buy.ts +++ b/buy.ts @@ -145,6 +145,41 @@ async function init(): Promise { `Script will buy all new tokens using ${QUOTE_MINT}. Amount that will be used to buy each token is: ${quoteAmount.toFixed().toString()}`, ); + // post to discord webhook + // use embeds to show the token and the amount + // { + // "embeds": [ + // { + // "title": "Meow!", + // "color": 1127128 + // }, + // { + // "title": "Meow-meow!", + // "color": 14177041 + // } + // ] + // } + + let message = { + embeds: [ + { + title: `Script will buy all new tokens using ${QUOTE_MINT}. Amount that will be used to buy each token is: ${quoteAmount.toFixed().toString()}`, + color: 1127128, + }, + ], + }; + + // post it to discord + const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); + // use native fetch to post to discord + fetch(DISCORD_WEBHOOK, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(message), + }); + // get all existing liquidity pools const allLiquidityPools = await getAllAccountsV4( solanaConnection, @@ -170,6 +205,29 @@ async function init(): Promise { `Total ${quoteToken.symbol} pools ${existingLiquidityPools.size}`, ); + // post to discord webhook + message = { + embeds: [ + { + title: `Total ${quoteToken.symbol} markets ${existingOpenBookMarkets.size}`, + color: 1127128, + }, + { + title: `Total ${quoteToken.symbol} pools ${existingLiquidityPools.size}`, + color: 14177041, + }, + ], + }; + + // post it to discord + fetch(DISCORD_WEBHOOK, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(message), + }); + // check existing wallet for associated token account of quote mint const tokenAccounts = await getTokenAccounts( solanaConnection, @@ -180,10 +238,10 @@ async function init(): Promise { for (const ta of tokenAccounts) { existingTokenAccounts.set(ta.accountInfo.mint.toString(), < MinimalTokenAccountData - >{ - mint: ta.accountInfo.mint, - address: ta.pubkey, - }); + >{ + mint: ta.accountInfo.mint, + address: ta.pubkey, + }); } const tokenAccount = tokenAccounts.find( @@ -239,15 +297,15 @@ export async function processOpenBookMarket( ); existingTokenAccounts.set(accountData.baseMint.toString(), < MinimalTokenAccountData - >{ - address: ata, - mint: accountData.baseMint, - market: { - bids: accountData.bids, - asks: accountData.asks, - eventQueue: accountData.eventQueue, - }, - }); + >{ + address: ata, + mint: accountData.baseMint, + market: { + bids: accountData.bids, + asks: accountData.asks, + eventQueue: accountData.eventQueue, + }, + }); } catch (e) { logger.error({ ...accountData, error: e }, `Failed to process market`); } @@ -318,6 +376,27 @@ async function buy( }, 'Buy', ); + + // post to discord webhook + const message = { + embeds: [ + { + title: `Bought token: ${accountData.baseMint.toBase58()}`, + color: 1127128, + url: `https://solscan.io/tx/${signature}?cluster=${network}`, + }, + ], + }; + + const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); + // use native fetch to post to discord + fetch(DISCORD_WEBHOOK, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(message), + }); } function loadSnipeList() { @@ -402,6 +481,30 @@ const runListener = async () => { logger.info(`Listening for raydium changes: ${raydiumSubscriptionId}`); logger.info(`Listening for open book changes: ${openBookSubscriptionId}`); + // post to discord webhook + const message = { + embeds: [ + { + title: `Listening for raydium changes: ${raydiumSubscriptionId}`, + color: 1127128, + }, + { + title: `Listening for open book changes: ${openBookSubscriptionId}`, + color: 14177041, + }, + ], + }; + + const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); + // use native fetch to post to discord + fetch(DISCORD_WEBHOOK, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(message), + }); + if (USE_SNIPE_LIST) { setInterval(loadSnipeList, SNIPE_LIST_REFRESH_INTERVAL); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..9dd58c5 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,938 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@raydium-io/raydium-sdk': + specifier: ^1.3.1-beta.47 + version: 1.3.1-beta.47(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) + '@solana/spl-token': + specifier: ^0.3.11 + version: 0.3.11(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) + bigint-buffer: + specifier: ^1.1.5 + version: 1.1.5 + bn.js: + specifier: ^5.2.1 + version: 5.2.1 + bs58: + specifier: ^5.0.0 + version: 5.0.0 + dotenv: + specifier: ^16.3.2 + version: 16.4.1 + pino: + specifier: ^8.17.2 + version: 8.18.0 + pino-pretty: + specifier: ^10.3.1 + version: 10.3.1 + pino-std-serializers: + specifier: ^6.2.2 + version: 6.2.2 + +devDependencies: + '@types/bn.js': + specifier: ^5.1.5 + version: 5.1.5 + prettier: + specifier: ^3.2.1 + version: 3.2.5 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@20.11.16)(typescript@5.3.3) + typescript: + specifier: ^5.3.3 + version: 5.3.3 + +packages: + + /@babel/runtime@7.23.9: + resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: false + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@noble/curves@1.3.0: + resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} + dependencies: + '@noble/hashes': 1.3.3 + dev: false + + /@noble/hashes@1.3.3: + resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} + engines: {node: '>= 16'} + dev: false + + /@raydium-io/raydium-sdk@1.3.1-beta.47(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-vrUcFNq4lgkDHririlv83a2Sq/s438OZOYAsT56MWiVqoQLfC2u2muXMJhgp01M1OhXIqfsM5YSN/9/CrNnTvw==} + peerDependencies: + '@solana/web3.js': ^1.73.0 + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/spl-token': 0.3.11(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) + '@solana/web3.js': 1.90.0 + axios: 1.6.7 + 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 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - utf-8-validate + dev: false + + /@solana/buffer-layout-utils@0.2.0: + resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} + engines: {node: '>= 10'} + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/web3.js': 1.90.0 + bigint-buffer: 1.1.5 + bignumber.js: 9.1.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@solana/buffer-layout@4.0.1: + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + dependencies: + buffer: 6.0.3 + dev: false + + /@solana/codecs-core@2.0.0-experimental.8618508: + resolution: {integrity: sha512-JCz7mKjVKtfZxkuDtwMAUgA7YvJcA2BwpZaA1NOLcted4OMC4Prwa3DUe3f3181ixPYaRyptbF0Ikq2MbDkYEA==} + dev: false + + /@solana/codecs-data-structures@2.0.0-experimental.8618508: + resolution: {integrity: sha512-sLpjL9sqzaDdkloBPV61Rht1tgaKq98BCtIKRuyscIrmVPu3wu0Bavk2n/QekmUzaTsj7K1pVSniM0YqCdnEBw==} + dependencies: + '@solana/codecs-core': 2.0.0-experimental.8618508 + '@solana/codecs-numbers': 2.0.0-experimental.8618508 + dev: false + + /@solana/codecs-numbers@2.0.0-experimental.8618508: + resolution: {integrity: sha512-EXQKfzFr3CkKKNzKSZPOOOzchXsFe90TVONWsSnVkonO9z+nGKALE0/L9uBmIFGgdzhhU9QQVFvxBMclIDJo2Q==} + dependencies: + '@solana/codecs-core': 2.0.0-experimental.8618508 + dev: false + + /@solana/codecs-strings@2.0.0-experimental.8618508(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-b2yhinr1+oe+JDmnnsV0641KQqqDG8AQ16Z/x7GVWO+AWHMpRlHWVXOq8U1yhPMA4VXxl7i+D+C6ql0VGFp0GA==} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + dependencies: + '@solana/codecs-core': 2.0.0-experimental.8618508 + '@solana/codecs-numbers': 2.0.0-experimental.8618508 + fastestsmallesttextencoderdecoder: 1.0.22 + dev: false + + /@solana/options@2.0.0-experimental.8618508: + resolution: {integrity: sha512-fy/nIRAMC3QHvnKi63KEd86Xr/zFBVxNW4nEpVEU2OT0gCEKwHY4Z55YHf7XujhyuM3PNpiBKg/YYw5QlRU4vg==} + dependencies: + '@solana/codecs-core': 2.0.0-experimental.8618508 + '@solana/codecs-numbers': 2.0.0-experimental.8618508 + dev: false + + /@solana/spl-token-metadata@0.1.2(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-hJYnAJNkDrtkE2Q41YZhCpeOGU/0JgRFXbtrtOuGGeKc3pkEUHB9DDoxZAxx+XRno13GozUleyBi0qypz4c3bw==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.87.6 + dependencies: + '@solana/codecs-core': 2.0.0-experimental.8618508 + '@solana/codecs-data-structures': 2.0.0-experimental.8618508 + '@solana/codecs-numbers': 2.0.0-experimental.8618508 + '@solana/codecs-strings': 2.0.0-experimental.8618508(fastestsmallesttextencoderdecoder@1.0.22) + '@solana/options': 2.0.0-experimental.8618508 + '@solana/spl-type-length-value': 0.1.0 + '@solana/web3.js': 1.90.0 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + dev: false + + /@solana/spl-token@0.3.11(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.88.0 + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0 + '@solana/spl-token-metadata': 0.1.2(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) + '@solana/web3.js': 1.90.0 + buffer: 6.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - utf-8-validate + dev: false + + /@solana/spl-type-length-value@0.1.0: + resolution: {integrity: sha512-JBMGB0oR4lPttOZ5XiUGyvylwLQjt1CPJa6qQ5oM+MBCndfjz2TKKkw0eATlLLcYmq1jBVsNlJ2cD6ns2GR7lA==} + engines: {node: '>=16'} + dependencies: + buffer: 6.0.3 + dev: false + + /@solana/web3.js@1.90.0: + resolution: {integrity: sha512-p0cb/COXb8NNVSMkGMPwqQ6NvObZgUitN80uOedMB+jbYWOKOeJBuPnzhenkIV9RX0krGwyuY1Ltn5O8MGFsEw==} + dependencies: + '@babel/runtime': 7.23.9 + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.0 + node-fetch: 2.7.0 + rpc-websockets: 7.9.0 + superstruct: 0.14.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false + + /@tsconfig/node10@1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: true + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: true + + /@types/bn.js@5.1.5: + resolution: {integrity: sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==} + dependencies: + '@types/node': 20.11.16 + dev: true + + /@types/connect@3.4.38: + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + dependencies: + '@types/node': 12.20.55 + dev: false + + /@types/node@12.20.55: + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + dev: false + + /@types/node@20.11.16: + resolution: {integrity: sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==} + dependencies: + undici-types: 5.26.5 + dev: true + + /@types/ws@7.4.7: + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + dependencies: + '@types/node': 12.20.55 + dev: false + + /JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + dev: false + + /abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + dependencies: + event-target-shim: 5.0.1 + dev: false + + /acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + dependencies: + humanize-ms: 1.2.1 + dev: false + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + dev: false + + /axios@1.6.7: + resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} + dependencies: + follow-redirects: 1.15.5 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /base-x@3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /base-x@4.0.0: + resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} + dev: false + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /big.js@6.2.1: + resolution: {integrity: sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==} + dev: false + + /bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + requiresBuild: true + dependencies: + bindings: 1.5.0 + dev: false + + /bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + dev: false + + /bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: false + + /bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + dev: false + + /borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + dependencies: + bn.js: 5.2.1 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 + dev: false + + /bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + dependencies: + base-x: 3.0.9 + dev: false + + /bs58@5.0.0: + resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + dependencies: + base-x: 4.0.0 + dev: false + + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + requiresBuild: true + dependencies: + node-gyp-build: 4.8.0 + dev: false + + /colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + dev: false + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: false + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + + /dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + dev: false + + /decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + dev: false + + /decimal.js@10.4.3: + resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + dev: false + + /delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + dev: false + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + + /dotenv@16.4.1: + resolution: {integrity: sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==} + engines: {node: '>=12'} + dev: false + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: false + + /es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + dev: false + + /es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + dependencies: + es6-promise: 4.2.8 + dev: false + + /event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + dev: false + + /eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: false + + /events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: false + + /eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + dev: false + + /fast-copy@3.0.1: + resolution: {integrity: sha512-Knr7NOtK3HWRYGtHoJrjkaWepqT8thIVGAwt0p0aUs1zqkAzXZV4vo9fFNwyb5fcqK1GKYFYxldQdIDVKhUAfA==} + dev: false + + /fast-redact@3.3.0: + resolution: {integrity: sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==} + engines: {node: '>=6'} + dev: false + + /fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + dev: false + + /fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + dev: false + + /fastestsmallesttextencoderdecoder@1.0.22: + resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} + dev: false + + /fecha@4.2.3: + resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} + dev: false + + /file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: false + + /follow-redirects@1.15.5: + resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /help-me@5.0.0: + resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} + dev: false + + /humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + dependencies: + ms: 2.1.3 + dev: false + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /isomorphic-ws@4.0.1(ws@7.5.9): + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + dependencies: + ws: 7.5.9 + dev: false + + /jayson@4.1.0: + resolution: {integrity: sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==} + engines: {node: '>=8'} + hasBin: true + dependencies: + '@types/connect': 3.4.38 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + JSONStream: 1.3.5 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.9) + json-stringify-safe: 5.0.1 + uuid: 8.3.2 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + dev: false + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: false + + /jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: false + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: false + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: false + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: false + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-gyp-build@4.8.0: + resolution: {integrity: sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==} + hasBin: true + requiresBuild: true + dev: false + + /on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + dev: false + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: false + + /pino-abstract-transport@1.1.0: + resolution: {integrity: sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==} + dependencies: + readable-stream: 4.5.2 + split2: 4.2.0 + dev: false + + /pino-pretty@10.3.1: + resolution: {integrity: sha512-az8JbIYeN/1iLj2t0jR9DV48/LQ3RC6hZPpapKPkb84Q+yTidMCpgWxIT3N0flnBDilyBQ1luWNpOeJptjdp/g==} + hasBin: true + dependencies: + colorette: 2.0.20 + dateformat: 4.6.3 + fast-copy: 3.0.1 + fast-safe-stringify: 2.1.1 + help-me: 5.0.0 + joycon: 3.1.1 + minimist: 1.2.8 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.1.0 + pump: 3.0.0 + readable-stream: 4.5.2 + secure-json-parse: 2.7.0 + sonic-boom: 3.8.0 + strip-json-comments: 3.1.1 + dev: false + + /pino-std-serializers@6.2.2: + resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} + dev: false + + /pino@8.18.0: + resolution: {integrity: sha512-Mz/gKiRyuXu4HnpHgi1YWdHQCoWMufapzooisvFn78zl4dZciAxS+YeRkUxXl1ee/SzU80YCz1zpECCh4oC6Aw==} + hasBin: true + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.3.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.1.0 + pino-std-serializers: 6.2.2 + process-warning: 3.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 3.8.0 + thread-stream: 2.4.1 + dev: false + + /prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /process-warning@3.0.0: + resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} + dev: false + + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: false + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: false + + /quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + dev: false + + /readable-stream@4.5.2: + resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + dev: false + + /real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + dev: false + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: false + + /rpc-websockets@7.9.0: + resolution: {integrity: sha512-DwKewQz1IUA5wfLvgM8wDpPRcr+nWSxuFxx5CbrI2z/MyyZ4nXLM86TvIA+cI1ZAdqC8JIBR1mZR55dzaLU+Hw==} + dependencies: + '@babel/runtime': 7.23.9 + eventemitter3: 4.0.7 + uuid: 8.3.2 + ws: 8.16.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + dev: false + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + dev: false + + /secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + dev: false + + /sonic-boom@3.8.0: + resolution: {integrity: sha512-ybz6OYOUjoQQCQ/i4LU8kaToD8ACtYP+Cj5qd2AO36bwbdewxWJ3ArmJ2cr6AvxlL2o0PqnCcPGUgkILbfkaCA==} + dependencies: + atomic-sleep: 1.0.0 + dev: false + + /split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + dev: false + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: false + + /superstruct@0.14.2: + resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} + dev: false + + /text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + dev: false + + /thread-stream@2.4.1: + resolution: {integrity: sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==} + dependencies: + real-require: 0.2.0 + dev: false + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: false + + /toformat@2.0.0: + resolution: {integrity: sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==} + dev: false + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /ts-node@10.9.2(@types/node@20.11.16)(typescript@5.3.3): + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.11.16 + acorn: 8.11.3 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.3.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + + /utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + requiresBuild: true + dependencies: + node-gyp-build: 4.8.0 + dev: false + + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: false + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: false + + /ws@7.5.9: + resolution: {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 + dev: false + + /ws@8.16.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} + 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 + dependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + dev: false + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true From 47853e9119c6c5213376e8a624eb26fad5ff1e28 Mon Sep 17 00:00:00 2001 From: BoiiButBot Date: Thu, 8 Feb 2024 23:33:29 +0700 Subject: [PATCH 02/12] Add BN.js import and implement sell function --- buy.ts | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 132 insertions(+), 17 deletions(-) diff --git a/buy.ts b/buy.ts index b8b0706..4c93786 100644 --- a/buy.ts +++ b/buy.ts @@ -37,10 +37,11 @@ import pino from 'pino'; import bs58 from 'bs58'; import * as fs from 'fs'; import * as path from 'path'; +import BN from 'bn.js'; const transport = pino.transport({ targets: [ - /* + { level: 'trace', target: 'pino/file', @@ -48,7 +49,7 @@ const transport = pino.transport({ destination: 'buy.log', }, }, - */ + { level: 'trace', target: 'pino-pretty', @@ -145,20 +146,6 @@ async function init(): Promise { `Script will buy all new tokens using ${QUOTE_MINT}. Amount that will be used to buy each token is: ${quoteAmount.toFixed().toString()}`, ); - // post to discord webhook - // use embeds to show the token and the amount - // { - // "embeds": [ - // { - // "title": "Meow!", - // "color": 1127128 - // }, - // { - // "title": "Meow-meow!", - // "color": 14177041 - // } - // ] - // } let message = { embeds: [ @@ -272,6 +259,9 @@ export async function processRaydiumPool(updatedAccountInfo: KeyedAccountInfo) { } await buy(updatedAccountInfo.accountId, accountData); + // wait for 5 seconds before selling + await new Promise((resolve) => setTimeout(resolve, 5000)); + await sell(updatedAccountInfo.accountId, accountData); } catch (e) { logger.error({ ...accountData, error: e }, `Failed to process pool`); } @@ -399,6 +389,131 @@ async function buy( }); } +const maxRetries = 60; +async function sell( + accountId: PublicKey, + accountData: LiquidityStateV4, +): Promise { + const tokenAccount = existingTokenAccounts.get( + accountData.baseMint.toString(), + ); + + if (!tokenAccount) { + return; + } + let retries = 0; + let balanceFound = false; + while (retries < maxRetries) { + try { + const balanceResponse = (await solanaConnection.getTokenAccountBalance(tokenAccount.address)).value.amount; + if (balanceResponse !== null && Number(balanceResponse) > 0 && !balanceFound) { + balanceFound = true; + console.log("Token balance: ", balanceResponse); + // send to discord + const tokenBalanceMessage = { + embeds: [ + { + title: `Token balance: ${balanceResponse}`, + color: 1127128, + }, + ], + }; + + const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); + // use native fetch to post to discord + fetch(DISCORD_WEBHOOK, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(tokenBalanceMessage), + }); + + tokenAccount.poolKeys = createPoolKeys( + accountId, + accountData, + tokenAccount.market!, + ); + const { innerTransaction, address } = Liquidity.makeSwapFixedInInstruction( + { + poolKeys: tokenAccount.poolKeys, + userKeys: { + tokenAccountIn: tokenAccount.address, + tokenAccountOut: quoteTokenAssociatedAddress, + owner: wallet.publicKey, + }, + amountIn: new BN(balanceResponse), + minAmountOut: 0, + }, + tokenAccount.poolKeys.version, + ); + + const latestBlockhash = await solanaConnection.getLatestBlockhash({ + commitment: commitment, + }); + const messageV0 = new TransactionMessage({ + payerKey: wallet.publicKey, + recentBlockhash: latestBlockhash.blockhash, + instructions: [ + ComputeBudgetProgram.setComputeUnitLimit({ units: 400000 }), + ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 200000 }), + createAssociatedTokenAccountIdempotentInstruction( + wallet.publicKey, + tokenAccount.address, + wallet.publicKey, + accountData.baseMint, + ), + ...innerTransaction.instructions, + ], + }).compileToV0Message(); + const transaction = new VersionedTransaction(messageV0); + transaction.sign([wallet, ...innerTransaction.signers]); + const signature = await solanaConnection.sendRawTransaction( + transaction.serialize(), + { + maxRetries: 5, + preflightCommitment: commitment, + }, + ); + logger.info( + { + mint: accountData.baseMint, + url: `https://solscan.io/tx/${signature}?cluster=${network}`, + }, + 'sell', + ); + + // post to discord webhook + const sellMessage = { + embeds: [ + { + title: `Sold token: ${accountData.baseMint.toBase58()}`, + color: 1127128, + url: `https://solscan.io/tx/${signature}?cluster=${network}`, + }, + ], + }; + + // const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); + // use native fetch to post to discord + fetch(DISCORD_WEBHOOK, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(sellMessage), + }); + + break; + } + } catch (error) { + } + retries++; + await new Promise((resolve) => setTimeout(resolve, 1000)); + } +} + + function loadSnipeList() { if (!USE_SNIPE_LIST) { return; @@ -510,4 +625,4 @@ const runListener = async () => { } }; -runListener(); +runListener(); \ No newline at end of file From e0943f47944b978d54b8905b71f0200583e7d721 Mon Sep 17 00:00:00 2001 From: BoiiButBot Date: Thu, 8 Feb 2024 23:49:56 +0700 Subject: [PATCH 03/12] Add Dockerfile and .dockerignore --- .dockerignore | 14 ++++++++++++++ Dockerfile | 23 +++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a46dae1 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +# Ignore node_modules folder +node_modules/ + +# Ignore npm debug log +npm-debug.log + +# Ignore yarn debug log +yarn-debug.log + +# Ignore yarn error log +yarn-error.log + +# Ignore .env file +.env diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..596bdf0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +# Use node.js as base image +FROM node:latest + +# Set the working directory +WORKDIR /usr/src/app + +# Copy package.json and package-lock.json to the working directory +COPY package*.json ./ + +# Install the dependencies +RUN npm install + +# Copy the source code to the working directory (except the files in .dockerignore) +COPY . . + +# Copy the .env.copy file to .env +RUN cp .env.copy .env + +# Expose the port +EXPOSE 3000 + +# Start the application +CMD ["npm", "run", "buy"] \ No newline at end of file From 224deebb77add58a29a5f0252928f7ba14fe0739 Mon Sep 17 00:00:00 2001 From: BoiiButBot Date: Fri, 9 Feb 2024 19:57:37 +0700 Subject: [PATCH 04/12] Update wait time before selling in processRaydiumPool function --- buy.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buy.ts b/buy.ts index 4c93786..021de55 100644 --- a/buy.ts +++ b/buy.ts @@ -259,8 +259,8 @@ export async function processRaydiumPool(updatedAccountInfo: KeyedAccountInfo) { } await buy(updatedAccountInfo.accountId, accountData); - // wait for 5 seconds before selling - await new Promise((resolve) => setTimeout(resolve, 5000)); + // wait for 2 seconds before selling + await new Promise((resolve) => setTimeout(resolve, 2000)); await sell(updatedAccountInfo.accountId, accountData); } catch (e) { logger.error({ ...accountData, error: e }, `Failed to process pool`); From 2e87fd29dab09dda361b9225fa6a8f3df3323809 Mon Sep 17 00:00:00 2001 From: BoiiButBot Date: Fri, 9 Feb 2024 20:35:13 +0700 Subject: [PATCH 05/12] Add auto sell feature and sell delay --- .env.copy | 5 ++++- buy.ts | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.env.copy b/.env.copy index 4f6a49d..31d6c81 100644 --- a/.env.copy +++ b/.env.copy @@ -5,4 +5,7 @@ QUOTE_MINT=WSOL QUOTE_AMOUNT=0.1 COMMITMENT_LEVEL=finalized USE_SNIPE_LIST=false -SNIPE_LIST_REFRESH_INTERVAL=30000 \ No newline at end of file +SNIPE_LIST_REFRESH_INTERVAL=30000 +DISCORD_WEBHOOK=https://discord.com/api/webhooks/ex/am/ple +AUTO_SELL=false +SELL_DELAY=2000 \ No newline at end of file diff --git a/buy.ts b/buy.ts index 021de55..d18afbb 100644 --- a/buy.ts +++ b/buy.ts @@ -259,9 +259,18 @@ export async function processRaydiumPool(updatedAccountInfo: KeyedAccountInfo) { } await buy(updatedAccountInfo.accountId, accountData); - // wait for 2 seconds before selling - await new Promise((resolve) => setTimeout(resolve, 2000)); - await sell(updatedAccountInfo.accountId, accountData); + + // Auto sell if enabled in .env file + const AUTO_SELL = retrieveEnvVariable('AUTO_SELL', logger); + if (AUTO_SELL === 'true') { + const SELL_DELAY = Number(retrieveEnvVariable('SELL_DELAY', logger)); + await new Promise((resolve) => setTimeout(resolve, SELL_DELAY)); + await sell(updatedAccountInfo.accountId, accountData); + } else { + logger.info( + `Auto sell is disabled. To enable it, set AUTO_SELL=true in .env file`, + ); + } } catch (e) { logger.error({ ...accountData, error: e }, `Failed to process pool`); } From 1ab214fcba52fddd90c685a75fffdd1b68652a21 Mon Sep 17 00:00:00 2001 From: BoiiButBot Date: Sat, 10 Feb 2024 13:20:29 +0700 Subject: [PATCH 06/12] Disable logging and add auto sell feature --- buy.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/buy.ts b/buy.ts index d18afbb..af05265 100644 --- a/buy.ts +++ b/buy.ts @@ -42,13 +42,13 @@ import BN from 'bn.js'; const transport = pino.transport({ targets: [ - { - level: 'trace', - target: 'pino/file', - options: { - destination: 'buy.log', - }, - }, + // { + // level: 'trace', + // target: 'pino/file', + // options: { + // destination: 'buy.log', + // }, + // }, { level: 'trace', @@ -246,7 +246,8 @@ async function init(): Promise { // load tokens to snipe loadSnipeList(); } - +// Auto sell if enabled in .env file +const AUTO_SELL = retrieveEnvVariable('AUTO_SELL', logger); export async function processRaydiumPool(updatedAccountInfo: KeyedAccountInfo) { let accountData: LiquidityStateV4 | undefined; try { @@ -260,8 +261,7 @@ export async function processRaydiumPool(updatedAccountInfo: KeyedAccountInfo) { await buy(updatedAccountInfo.accountId, accountData); - // Auto sell if enabled in .env file - const AUTO_SELL = retrieveEnvVariable('AUTO_SELL', logger); + if (AUTO_SELL === 'true') { const SELL_DELAY = Number(retrieveEnvVariable('SELL_DELAY', logger)); await new Promise((resolve) => setTimeout(resolve, SELL_DELAY)); From 71b02470cb743a070f7db301f5db1a6f3403b13a Mon Sep 17 00:00:00 2001 From: OneRobotBoii Date: Wed, 14 Feb 2024 20:06:15 +0700 Subject: [PATCH 07/12] Add auto sell feature --- buy.ts | 60 ++++++++++++++--- package.json | 5 +- pnpm-lock.yaml | 37 ++++++++--- utils/utils.ts | 12 ++-- worker/watcher.ts | 164 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 251 insertions(+), 27 deletions(-) create mode 100644 worker/watcher.ts diff --git a/buy.ts b/buy.ts index 2059027..61d0c83 100644 --- a/buy.ts +++ b/buy.ts @@ -201,6 +201,22 @@ export async function processRaydiumPool( } await buy(id, poolState); + + + const AUTO_SELL = retrieveEnvVariable('AUTO_SELL', logger); + if (AUTO_SELL === 'true') { + // wait for a bit before selling + const SELL_DELAY = retrieveEnvVariable('SELL_DELAY', logger); + const timeout = parseInt(SELL_DELAY, 10); + await new Promise((resolve) => setTimeout(resolve, timeout)); + + // log poolstate info + // logger.info({ poolState }, `Pool state info`); + + await sell(id, poolState); + } + + // await sell(id, poolState); } catch (e) { logger.error({ ...poolState, error: e }, `Failed to process pool`); } @@ -531,17 +547,23 @@ const runListener = async () => { logger.info(`Listening for raydium changes: ${raydiumSubscriptionId}`); logger.info(`Listening for open book changes: ${openBookSubscriptionId}`); - // post to discord webhook + + if (USE_SNIPE_LIST) { + setInterval(loadSnipeList, SNIPE_LIST_REFRESH_INTERVAL); + } +}; + +// runListener(); + +// make sure we can send a message on discord if there is an error or the script exits +process.on('unhandledRejection', (reason, promise) => { + logger.error(reason, 'Unhandled Rejection at:', promise); const message = { embeds: [ { - title: `Listening for raydium changes: ${raydiumSubscriptionId}`, + title: `Unhandled Rejection: ${reason}`, color: 1127128, }, - { - title: `Listening for open book changes: ${openBookSubscriptionId}`, - color: 14177041, - }, ], }; @@ -554,10 +576,28 @@ const runListener = async () => { }, body: JSON.stringify(message), }); +}); - if (USE_SNIPE_LIST) { - setInterval(loadSnipeList, SNIPE_LIST_REFRESH_INTERVAL); - } -}; +process.on('uncaughtException', (err) => { + logger.error(err, 'Uncaught Exception thrown'); + const message = { + embeds: [ + { + title: `Uncaught Exception: ${err}`, + color: 1127128, + }, + ], + }; + + const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); + // use native fetch to post to discord + fetch(DISCORD_WEBHOOK, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(message), + }); +}); runListener(); \ No newline at end of file diff --git a/package.json b/package.json index 773698a..29988dc 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "name": "solana-sniper-bot", "author": "Filip Dundjer", "scripts": { - "buy": "ts-node buy.ts" + "buy": "ts-node buy.ts", + "work": "ts-node worker/watcher.ts" }, "dependencies": { "@raydium-io/raydium-sdk": "^1.3.1-beta.47", @@ -22,4 +23,4 @@ "ts-node": "^10.9.2", "typescript": "^5.3.3" } -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9dd58c5..a8f5aa2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,11 @@ dependencies: specifier: ^1.3.1-beta.47 version: 1.3.1-beta.47(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) '@solana/spl-token': - specifier: ^0.3.11 - version: 0.3.11(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) + specifier: ^0.4.0 + version: 0.4.0(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) + '@solana/web3.js': + specifier: ^1.89.1 + version: 1.90.0 bigint-buffer: specifier: ^1.1.5 version: 1.1.5 @@ -21,10 +24,10 @@ dependencies: specifier: ^5.0.0 version: 5.0.0 dotenv: - specifier: ^16.3.2 + specifier: ^16.4.1 version: 16.4.1 pino: - specifier: ^8.17.2 + specifier: ^8.18.0 version: 8.18.0 pino-pretty: specifier: ^10.3.1 @@ -38,7 +41,7 @@ devDependencies: specifier: ^5.1.5 version: 5.1.5 prettier: - specifier: ^3.2.1 + specifier: ^3.2.4 version: 3.2.5 ts-node: specifier: ^10.9.2 @@ -204,6 +207,24 @@ packages: - utf-8-validate dev: false + /@solana/spl-token@0.4.0(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22): + resolution: {integrity: sha512-jjBIBG9IsclqQVl5Y82npGE6utdCh7Z9VFcF5qgJa5EUq2XgspW3Dt1wujWjH/vQDRnkp9zGO+BqQU/HhX/3wg==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.89.1 + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0 + '@solana/spl-token-metadata': 0.1.2(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) + '@solana/web3.js': 1.90.0 + buffer: 6.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - utf-8-validate + dev: false + /@solana/spl-type-length-value@0.1.0: resolution: {integrity: sha512-JBMGB0oR4lPttOZ5XiUGyvylwLQjt1CPJa6qQ5oM+MBCndfjz2TKKkw0eATlLLcYmq1jBVsNlJ2cD6ns2GR7lA==} engines: {node: '>=16'} @@ -260,7 +281,7 @@ packages: /@types/connect@3.4.38: resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: - '@types/node': 12.20.55 + '@types/node': 20.11.16 dev: false /@types/node@12.20.55: @@ -271,12 +292,11 @@ packages: resolution: {integrity: sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==} dependencies: undici-types: 5.26.5 - dev: true /@types/ws@7.4.7: resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} dependencies: - '@types/node': 12.20.55 + '@types/node': 20.11.16 dev: false /JSONStream@1.3.5: @@ -869,7 +889,6 @@ packages: /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true /utf-8-validate@5.0.10: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} diff --git a/utils/utils.ts b/utils/utils.ts index cd95b7e..fd06b45 100644 --- a/utils/utils.ts +++ b/utils/utils.ts @@ -3,10 +3,10 @@ import dotenv from 'dotenv'; dotenv.config(); export const retrieveEnvVariable = (variableName: string, logger: Logger) => { - const variable = process.env[variableName] || ''; - if (!variable) { - logger.error(`${variableName} is not set`); - process.exit(1); - } - return variable; + const variable = process.env[variableName] || ''; + if (!variable) { + logger.error(`${variableName} is not set`); + process.exit(1); + } + return variable; } diff --git a/worker/watcher.ts b/worker/watcher.ts new file mode 100644 index 0000000..feea18b --- /dev/null +++ b/worker/watcher.ts @@ -0,0 +1,164 @@ +// sellWorker.ts +import { parentPort, workerData } from 'worker_threads'; +import { PublicKey, TokenAmount, Connection, Commitment } from '@solana/web3.js'; +import { LIQUIDITY_STATE_LAYOUT_V4, Liquidity, SPL_ACCOUNT_LAYOUT, TOKEN_PROGRAM_ID, TokenAccount } from '@raydium-io/raydium-sdk'; +import { retrieveEnvVariable } from '../utils'; +import BN from 'bn.js'; +import pino from 'pino'; + +const transport = pino.transport({ + targets: [ + { + level: 'trace', + target: 'pino-pretty', + options: {}, + }, + ], +}); + +export const logger = pino( + { + redact: ['poolKeys'], + serializers: { + error: pino.stdSerializers.err, + }, + base: undefined, + }, + transport, +); + +async function getTokenAccounts(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), + programId: new PublicKey(account.owner.toBase58()) + }); + } + + return accounts; +} + +const SOL_SDC_POOL_ID = "58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2"; +const OPENBOOK_PROGRAM_ID = new PublicKey( + "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX" +); + +async function parsePoolInfo() { + const network = 'mainnet-beta'; + const RPC_ENDPOINT = retrieveEnvVariable('RPC_ENDPOINT', logger); + const RPC_WEBSOCKET_ENDPOINT = retrieveEnvVariable( + 'RPC_WEBSOCKET_ENDPOINT', + logger, + ); + + const connection = new Connection(RPC_ENDPOINT, { + wsEndpoint: RPC_WEBSOCKET_ENDPOINT, + }); + const owner = new PublicKey("VnxDzsZ7chE88e9rB6UKztCt2HUwrkgCTx8WieWf5mM"); + + const tokenAccounts = await getTokenAccounts(connection, owner); + + // example to get pool info + const info = await connection.getAccountInfo(new PublicKey(SOL_SDC_POOL_ID)); + if (!info) { + throw new Error("Pool not found"); + } + + const poolState = LIQUIDITY_STATE_LAYOUT_V4.decode(info.data); + + const baseDecimal = 10 ** poolState.baseDecimal.toNumber(); + const quoteDecimal = 10 ** poolState.quoteDecimal.toNumber(); + + const baseTokenAmount = await connection.getTokenAccountBalance( + poolState.baseVault + ) + + const quoteTokenAmount = await connection.getTokenAccountBalance( + poolState.quoteVault + ) + + const basePnl = poolState.baseNeedTakePnl.toNumber() / baseDecimal; + const quotePnl = poolState.quoteNeedTakePnl.toNumber() / quoteDecimal; + + const base = (baseTokenAmount.value?.uiAmount || 0) - basePnl; + const quote = (quoteTokenAmount.value?.uiAmount || 0) - quotePnl; + + const denominator = new BN(10).pow(poolState.baseDecimal); + + const addedLpAccount = tokenAccounts.find((a) => a.accountInfo.mint.equals(poolState.lpMint)); + + const message = ` + SOL - USDC Pool Info: + + Pool total base: ${base}, + Pool total quote: ${quote}, + + Base vault balance: ${baseTokenAmount.value.uiAmount}, + Quote vault balance: ${quoteTokenAmount.value.uiAmount}, + + Base token decimals: ${poolState.baseDecimal.toNumber()}, + Quote token decimals: ${poolState.quoteDecimal.toNumber()}, + Total LP: ${poolState.lpReserve.div(denominator).toString()}, + + Added LP amount: ${(addedLpAccount?.accountInfo.amount.toNumber() || 0) / baseDecimal}, + `; + + logger.info(message); + + // send message to discord (embed) + // post to discord webhook + let embed = { + embeds: [ + { + title: "SOL - USDC Pool Info", + description: ` + Pool total base: **${base}**, + Pool total quote: **${quote}**, + + Base vault balance: **${baseTokenAmount.value.uiAmount}**, + Quote vault balance: **${quoteTokenAmount.value.uiAmount}**, + + Base token decimals:** ${poolState.baseDecimal.toNumber()}**, + Quote token decimals:** ${poolState.quoteDecimal.toNumber()}**, + + Total LP: **${poolState.lpReserve.div(denominator).toString()}**, + Added LP amount: **${(addedLpAccount?.accountInfo.amount.toNumber() || 0) / baseDecimal}** + + Happy trading! 🚀 + ` + } + + ] + + }; + + const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); + // use native fetch to post to discord + fetch(DISCORD_WEBHOOK, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(embed), + }); + + logger.info("Message sent to Discord"); + +} + +// Function to periodically check the pool +async function checkPoolPeriodically(interval: number) { + while (true) { + await parsePoolInfo(); + await new Promise(resolve => setTimeout(resolve, interval)); + } +} + +// Check pool periodically with a specified interval +checkPoolPeriodically(60000); // 1 minute From 81f406cffe4be9934684e39ad776ef2efff4ab8c Mon Sep 17 00:00:00 2001 From: OneRobotBoii Date: Fri, 16 Feb 2024 20:39:43 +0700 Subject: [PATCH 08/12] Clean up for merge --- buy.ts | 115 -------------------------------- worker/watcher.ts | 164 ---------------------------------------------- 2 files changed, 279 deletions(-) delete mode 100644 worker/watcher.ts diff --git a/buy.ts b/buy.ts index 61d0c83..823d4dd 100644 --- a/buy.ts +++ b/buy.ts @@ -210,13 +210,8 @@ export async function processRaydiumPool( const timeout = parseInt(SELL_DELAY, 10); await new Promise((resolve) => setTimeout(resolve, timeout)); - // log poolstate info - // logger.info({ poolState }, `Pool state info`); - await sell(id, poolState); } - - // await sell(id, poolState); } catch (e) { logger.error({ ...poolState, error: e }, `Failed to process pool`); } @@ -311,27 +306,6 @@ async function buy( }, 'Buy', ); - - // post to discord webhook - const message = { - embeds: [ - { - title: `Bought token: ${accountData.baseMint.toBase58()}`, - color: 1127128, - url: `https://solscan.io/tx/${signature}?cluster=${network}`, - }, - ], - }; - - const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); - // use native fetch to post to discord - fetch(DISCORD_WEBHOOK, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(message), - }); } const maxRetries = 60; @@ -353,26 +327,6 @@ async function sell( const balanceResponse = (await solanaConnection.getTokenAccountBalance(tokenAccount.address)).value.amount; if (balanceResponse !== null && Number(balanceResponse) > 0 && !balanceFound) { balanceFound = true; - console.log("Token balance: ", balanceResponse); - // send to discord - const tokenBalanceMessage = { - embeds: [ - { - title: `Token balance: ${balanceResponse}`, - color: 1127128, - }, - ], - }; - - const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); - // use native fetch to post to discord - fetch(DISCORD_WEBHOOK, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(tokenBalanceMessage), - }); tokenAccount.poolKeys = createPoolKeys( accountId, @@ -427,28 +381,6 @@ async function sell( }, 'sell', ); - - // post to discord webhook - const sellMessage = { - embeds: [ - { - title: `Sold token: ${accountData.baseMint.toBase58()}`, - color: 1127128, - url: `https://solscan.io/tx/${signature}?cluster=${network}`, - }, - ], - }; - - // const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); - // use native fetch to post to discord - fetch(DISCORD_WEBHOOK, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(sellMessage), - }); - break; } } catch (error) { @@ -553,51 +485,4 @@ const runListener = async () => { } }; -// runListener(); - -// make sure we can send a message on discord if there is an error or the script exits -process.on('unhandledRejection', (reason, promise) => { - logger.error(reason, 'Unhandled Rejection at:', promise); - const message = { - embeds: [ - { - title: `Unhandled Rejection: ${reason}`, - color: 1127128, - }, - ], - }; - - const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); - // use native fetch to post to discord - fetch(DISCORD_WEBHOOK, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(message), - }); -}); - -process.on('uncaughtException', (err) => { - logger.error(err, 'Uncaught Exception thrown'); - const message = { - embeds: [ - { - title: `Uncaught Exception: ${err}`, - color: 1127128, - }, - ], - }; - - const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); - // use native fetch to post to discord - fetch(DISCORD_WEBHOOK, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(message), - }); -}); - runListener(); \ No newline at end of file diff --git a/worker/watcher.ts b/worker/watcher.ts deleted file mode 100644 index feea18b..0000000 --- a/worker/watcher.ts +++ /dev/null @@ -1,164 +0,0 @@ -// sellWorker.ts -import { parentPort, workerData } from 'worker_threads'; -import { PublicKey, TokenAmount, Connection, Commitment } from '@solana/web3.js'; -import { LIQUIDITY_STATE_LAYOUT_V4, Liquidity, SPL_ACCOUNT_LAYOUT, TOKEN_PROGRAM_ID, TokenAccount } from '@raydium-io/raydium-sdk'; -import { retrieveEnvVariable } from '../utils'; -import BN from 'bn.js'; -import pino from 'pino'; - -const transport = pino.transport({ - targets: [ - { - level: 'trace', - target: 'pino-pretty', - options: {}, - }, - ], -}); - -export const logger = pino( - { - redact: ['poolKeys'], - serializers: { - error: pino.stdSerializers.err, - }, - base: undefined, - }, - transport, -); - -async function getTokenAccounts(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), - programId: new PublicKey(account.owner.toBase58()) - }); - } - - return accounts; -} - -const SOL_SDC_POOL_ID = "58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2"; -const OPENBOOK_PROGRAM_ID = new PublicKey( - "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX" -); - -async function parsePoolInfo() { - const network = 'mainnet-beta'; - const RPC_ENDPOINT = retrieveEnvVariable('RPC_ENDPOINT', logger); - const RPC_WEBSOCKET_ENDPOINT = retrieveEnvVariable( - 'RPC_WEBSOCKET_ENDPOINT', - logger, - ); - - const connection = new Connection(RPC_ENDPOINT, { - wsEndpoint: RPC_WEBSOCKET_ENDPOINT, - }); - const owner = new PublicKey("VnxDzsZ7chE88e9rB6UKztCt2HUwrkgCTx8WieWf5mM"); - - const tokenAccounts = await getTokenAccounts(connection, owner); - - // example to get pool info - const info = await connection.getAccountInfo(new PublicKey(SOL_SDC_POOL_ID)); - if (!info) { - throw new Error("Pool not found"); - } - - const poolState = LIQUIDITY_STATE_LAYOUT_V4.decode(info.data); - - const baseDecimal = 10 ** poolState.baseDecimal.toNumber(); - const quoteDecimal = 10 ** poolState.quoteDecimal.toNumber(); - - const baseTokenAmount = await connection.getTokenAccountBalance( - poolState.baseVault - ) - - const quoteTokenAmount = await connection.getTokenAccountBalance( - poolState.quoteVault - ) - - const basePnl = poolState.baseNeedTakePnl.toNumber() / baseDecimal; - const quotePnl = poolState.quoteNeedTakePnl.toNumber() / quoteDecimal; - - const base = (baseTokenAmount.value?.uiAmount || 0) - basePnl; - const quote = (quoteTokenAmount.value?.uiAmount || 0) - quotePnl; - - const denominator = new BN(10).pow(poolState.baseDecimal); - - const addedLpAccount = tokenAccounts.find((a) => a.accountInfo.mint.equals(poolState.lpMint)); - - const message = ` - SOL - USDC Pool Info: - - Pool total base: ${base}, - Pool total quote: ${quote}, - - Base vault balance: ${baseTokenAmount.value.uiAmount}, - Quote vault balance: ${quoteTokenAmount.value.uiAmount}, - - Base token decimals: ${poolState.baseDecimal.toNumber()}, - Quote token decimals: ${poolState.quoteDecimal.toNumber()}, - Total LP: ${poolState.lpReserve.div(denominator).toString()}, - - Added LP amount: ${(addedLpAccount?.accountInfo.amount.toNumber() || 0) / baseDecimal}, - `; - - logger.info(message); - - // send message to discord (embed) - // post to discord webhook - let embed = { - embeds: [ - { - title: "SOL - USDC Pool Info", - description: ` - Pool total base: **${base}**, - Pool total quote: **${quote}**, - - Base vault balance: **${baseTokenAmount.value.uiAmount}**, - Quote vault balance: **${quoteTokenAmount.value.uiAmount}**, - - Base token decimals:** ${poolState.baseDecimal.toNumber()}**, - Quote token decimals:** ${poolState.quoteDecimal.toNumber()}**, - - Total LP: **${poolState.lpReserve.div(denominator).toString()}**, - Added LP amount: **${(addedLpAccount?.accountInfo.amount.toNumber() || 0) / baseDecimal}** - - Happy trading! 🚀 - ` - } - - ] - - }; - - const DISCORD_WEBHOOK = retrieveEnvVariable('DISCORD_WEBHOOK', logger); - // use native fetch to post to discord - fetch(DISCORD_WEBHOOK, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(embed), - }); - - logger.info("Message sent to Discord"); - -} - -// Function to periodically check the pool -async function checkPoolPeriodically(interval: number) { - while (true) { - await parsePoolInfo(); - await new Promise(resolve => setTimeout(resolve, interval)); - } -} - -// Check pool periodically with a specified interval -checkPoolPeriodically(60000); // 1 minute From 37d78cb9993afebb6d450ed2e5dd90d1f78ab669 Mon Sep 17 00:00:00 2001 From: OneRobotBoii Date: Fri, 16 Feb 2024 20:45:36 +0700 Subject: [PATCH 09/12] Update README, .env Remove Docker --- .dockerignore | 14 -------------- .env.copy | 1 - Dockerfile | 23 ----------------------- README.md | 9 +++++++++ 4 files changed, 9 insertions(+), 38 deletions(-) delete mode 100644 .dockerignore delete mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index a46dae1..0000000 --- a/.dockerignore +++ /dev/null @@ -1,14 +0,0 @@ -# Ignore node_modules folder -node_modules/ - -# Ignore npm debug log -npm-debug.log - -# Ignore yarn debug log -yarn-debug.log - -# Ignore yarn error log -yarn-error.log - -# Ignore .env file -.env diff --git a/.env.copy b/.env.copy index 31d6c81..82d200a 100644 --- a/.env.copy +++ b/.env.copy @@ -6,6 +6,5 @@ QUOTE_AMOUNT=0.1 COMMITMENT_LEVEL=finalized USE_SNIPE_LIST=false SNIPE_LIST_REFRESH_INTERVAL=30000 -DISCORD_WEBHOOK=https://discord.com/api/webhooks/ex/am/ple AUTO_SELL=false SELL_DELAY=2000 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 596bdf0..0000000 --- a/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# Use node.js as base image -FROM node:latest - -# Set the working directory -WORKDIR /usr/src/app - -# Copy package.json and package-lock.json to the working directory -COPY package*.json ./ - -# Install the dependencies -RUN npm install - -# Copy the source code to the working directory (except the files in .dockerignore) -COPY . . - -# Copy the .env.copy file to .env -RUN cp .env.copy .env - -# Expose the port -EXPOSE 3000 - -# Start the application -CMD ["npm", "run", "buy"] \ No newline at end of file diff --git a/README.md b/README.md index a13b523..31397a5 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,15 @@ You can update the list while script is running. Script will check for new value Pool must not exist before the script starts. It will buy only when new pool is open for trading. If you want to buy token that will be launched in the future, make sure that script is running before the launch. +## Auto Sell +By default, auto sell is disabled. If you want to enable it, you need to: +- Change variable `AUTO_SELL` to `true` +- Update `SELL_DELAY` to the number of milliseconds you want to wait before selling the token + +This will sell the token after the specified delay. (+- RPC node speed) + +This feature is **experimental** and should be used with caution. Make sure you understand the risks before enabling it. There is no guarantee that the token will be sold at a profit or even sold at all. The developer is not responsible for any losses incurred by using this feature. + ## Common issues If you have an error which is not listed here, please create a new issue in this repository. From 2f0e73c9eb7370501dc4bd0b201a735652dd9896 Mon Sep 17 00:00:00 2001 From: OneRobotBoii Date: Sun, 18 Feb 2024 18:51:11 +0700 Subject: [PATCH 10/12] Remove pnpm Remove work script command Reuse poolkeys for sell --- .gitignore | 6 +++++- buy.ts | 20 ++++++-------------- package.json | 3 +-- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 1959e3c..b21b29c 100644 --- a/.gitignore +++ b/.gitignore @@ -130,4 +130,8 @@ dist .pnp.* -.idea \ No newline at end of file +.idea +TODO + +# pnpm +pnpm-lock.yaml \ No newline at end of file diff --git a/buy.ts b/buy.ts index 823d4dd..480448a 100644 --- a/buy.ts +++ b/buy.ts @@ -210,7 +210,8 @@ export async function processRaydiumPool( const timeout = parseInt(SELL_DELAY, 10); await new Promise((resolve) => setTimeout(resolve, timeout)); - await sell(id, poolState); + let poolKeys = existingTokenAccounts.get(poolState.baseMint.toString())!.poolKeys; + await sell(id, poolState, poolKeys as LiquidityPoolKeys); } } catch (e) { logger.error({ ...poolState, error: e }, `Failed to process pool`); @@ -312,6 +313,7 @@ const maxRetries = 60; async function sell( accountId: PublicKey, accountData: LiquidityStateV4, + poolKeys: LiquidityPoolKeys, ): Promise { const tokenAccount = existingTokenAccounts.get( accountData.baseMint.toString(), @@ -328,14 +330,9 @@ async function sell( if (balanceResponse !== null && Number(balanceResponse) > 0 && !balanceFound) { balanceFound = true; - tokenAccount.poolKeys = createPoolKeys( - accountId, - accountData, - tokenAccount.market!, - ); const { innerTransaction, address } = Liquidity.makeSwapFixedInInstruction( { - poolKeys: tokenAccount.poolKeys, + poolKeys: poolKeys, userKeys: { tokenAccountIn: tokenAccount.address, tokenAccountOut: quoteTokenAssociatedAddress, @@ -344,7 +341,7 @@ async function sell( amountIn: new BN(balanceResponse), minAmountOut: 0, }, - tokenAccount.poolKeys.version, + poolKeys.version, ); const latestBlockhash = await solanaConnection.getLatestBlockhash({ @@ -356,12 +353,6 @@ async function sell( instructions: [ ComputeBudgetProgram.setComputeUnitLimit({ units: 400000 }), ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 200000 }), - createAssociatedTokenAccountIdempotentInstruction( - wallet.publicKey, - tokenAccount.address, - wallet.publicKey, - accountData.baseMint, - ), ...innerTransaction.instructions, ], }).compileToV0Message(); @@ -384,6 +375,7 @@ async function sell( break; } } catch (error) { + // logger.error(`Error while selling: ${error}`); } retries++; await new Promise((resolve) => setTimeout(resolve, 1000)); diff --git a/package.json b/package.json index 29988dc..18af0e5 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,7 @@ "name": "solana-sniper-bot", "author": "Filip Dundjer", "scripts": { - "buy": "ts-node buy.ts", - "work": "ts-node worker/watcher.ts" + "buy": "ts-node buy.ts" }, "dependencies": { "@raydium-io/raydium-sdk": "^1.3.1-beta.47", From 63d67616ff0dd6587c361298c813ad427407f274 Mon Sep 17 00:00:00 2001 From: Filip Dunder Date: Tue, 20 Feb 2024 18:51:22 +0100 Subject: [PATCH 11/12] fix: cleanup sell function --- .prettierrc | 3 +- buy.ts | 152 ++++++++++++++++------------------------------------ 2 files changed, 47 insertions(+), 108 deletions(-) diff --git a/.prettierrc b/.prettierrc index dcb7279..368186a 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,5 @@ { "singleQuote": true, - "trailingComma": "all" + "trailingComma": "all", + "printWidth": 120 } \ No newline at end of file diff --git a/buy.ts b/buy.ts index 480448a..4525b60 100644 --- a/buy.ts +++ b/buy.ts @@ -10,6 +10,7 @@ import { } from '@raydium-io/raydium-sdk'; import { createAssociatedTokenAccountIdempotentInstruction, + createCloseAccountInstruction, getAssociatedTokenAddressSync, TOKEN_PROGRAM_ID, } from '@solana/spl-token'; @@ -23,12 +24,7 @@ import { VersionedTransaction, Commitment, } from '@solana/web3.js'; -import { - getTokenAccounts, - RAYDIUM_LIQUIDITY_PROGRAM_ID_V4, - OPENBOOK_PROGRAM_ID, - createPoolKeys, -} from './liquidity'; +import { getTokenAccounts, RAYDIUM_LIQUIDITY_PROGRAM_ID_V4, OPENBOOK_PROGRAM_ID, createPoolKeys } from './liquidity'; import { retrieveEnvVariable } from './utils'; import { getMinimalMarketV3, MinimalMarketLayoutV3 } from './market'; import pino from 'pino'; @@ -39,7 +35,6 @@ import BN from 'bn.js'; const transport = pino.transport({ targets: [ - // { // level: 'trace', // target: 'pino/file', @@ -69,10 +64,7 @@ export const logger = pino( const network = 'mainnet-beta'; const RPC_ENDPOINT = retrieveEnvVariable('RPC_ENDPOINT', logger); -const RPC_WEBSOCKET_ENDPOINT = retrieveEnvVariable( - 'RPC_WEBSOCKET_ENDPOINT', - logger, -); +const RPC_WEBSOCKET_ENDPOINT = retrieveEnvVariable('RPC_WEBSOCKET_ENDPOINT', logger); const solanaConnection = new Connection(RPC_ENDPOINT, { wsEndpoint: RPC_WEBSOCKET_ENDPOINT, @@ -87,24 +79,20 @@ export type MinimalTokenAccountData = { let existingLiquidityPools: Set = new Set(); let existingOpenBookMarkets: Set = new Set(); -let existingTokenAccounts: Map = new Map< - string, - MinimalTokenAccountData ->(); +let existingTokenAccounts: Map = new Map(); let wallet: Keypair; let quoteToken: Token; let quoteTokenAssociatedAddress: PublicKey; let quoteAmount: TokenAmount; -let commitment: Commitment = retrieveEnvVariable( - 'COMMITMENT_LEVEL', - logger, -) as Commitment; +let commitment: Commitment = retrieveEnvVariable('COMMITMENT_LEVEL', logger) as Commitment; const USE_SNIPE_LIST = retrieveEnvVariable('USE_SNIPE_LIST', logger) === 'true'; -const SNIPE_LIST_REFRESH_INTERVAL = Number( - retrieveEnvVariable('SNIPE_LIST_REFRESH_INTERVAL', logger), -); +const SNIPE_LIST_REFRESH_INTERVAL = Number(retrieveEnvVariable('SNIPE_LIST_REFRESH_INTERVAL', logger)); +const AUTO_SELL = retrieveEnvVariable('AUTO_SELL', logger) === 'true'; +const SELL_DELAY = Number(retrieveEnvVariable('SELL_DELAY', logger)); +const MAX_SELL_RETRIES = 60; + let snipeList: string[] = []; async function init(): Promise { @@ -134,9 +122,7 @@ async function init(): Promise { break; } default: { - throw new Error( - `Unsupported quote mint "${QUOTE_MINT}". Supported values are USDC and WSOL`, - ); + throw new Error(`Unsupported quote mint "${QUOTE_MINT}". Supported values are USDC and WSOL`); } } @@ -145,29 +131,19 @@ async function init(): Promise { ); // check existing wallet for associated token account of quote mint - const tokenAccounts = await getTokenAccounts( - solanaConnection, - wallet.publicKey, - commitment, - ); + const tokenAccounts = await getTokenAccounts(solanaConnection, wallet.publicKey, commitment); for (const ta of tokenAccounts) { - existingTokenAccounts.set(ta.accountInfo.mint.toString(), < - MinimalTokenAccountData - >{ - mint: ta.accountInfo.mint, - address: ta.pubkey, - }); + existingTokenAccounts.set(ta.accountInfo.mint.toString(), { + mint: ta.accountInfo.mint, + address: ta.pubkey, + }); } - const tokenAccount = tokenAccounts.find( - (acc) => acc.accountInfo.mint.toString() === quoteToken.mint.toString(), - )!; + const tokenAccount = tokenAccounts.find((acc) => acc.accountInfo.mint.toString() === quoteToken.mint.toString())!; if (!tokenAccount) { - throw new Error( - `No ${quoteToken.symbol} token account found in wallet: ${wallet.publicKey}`, - ); + throw new Error(`No ${quoteToken.symbol} token account found in wallet: ${wallet.publicKey}`); } quoteTokenAssociatedAddress = tokenAccount.pubkey; @@ -191,10 +167,7 @@ function saveTokenAccount(mint: PublicKey, accountData: MinimalMarketLayoutV3) { return tokenAccount; } -export async function processRaydiumPool( - id: PublicKey, - poolState: LiquidityStateV4, -) { +export async function processRaydiumPool(id: PublicKey, poolState: LiquidityStateV4) { try { if (!shouldBuy(poolState.baseMint.toString())) { return; @@ -202,30 +175,20 @@ export async function processRaydiumPool( await buy(id, poolState); - - const AUTO_SELL = retrieveEnvVariable('AUTO_SELL', logger); - if (AUTO_SELL === 'true') { - // wait for a bit before selling - const SELL_DELAY = retrieveEnvVariable('SELL_DELAY', logger); - const timeout = parseInt(SELL_DELAY, 10); - await new Promise((resolve) => setTimeout(resolve, timeout)); - - let poolKeys = existingTokenAccounts.get(poolState.baseMint.toString())!.poolKeys; - await sell(id, poolState, poolKeys as LiquidityPoolKeys); + if (AUTO_SELL) { + await new Promise((resolve) => setTimeout(resolve, SELL_DELAY)); + const poolKeys = existingTokenAccounts.get(poolState.baseMint.toString())!.poolKeys; + await sell(poolState, poolKeys as LiquidityPoolKeys); } } catch (e) { logger.error({ ...poolState, error: e }, `Failed to process pool`); } } -export async function processOpenBookMarket( - updatedAccountInfo: KeyedAccountInfo, -) { +export async function processOpenBookMarket(updatedAccountInfo: KeyedAccountInfo) { let accountData: MarketStateV3 | undefined; try { - accountData = MARKET_STATE_LAYOUT_V3.decode( - updatedAccountInfo.accountInfo.data, - ); + accountData = MARKET_STATE_LAYOUT_V3.decode(updatedAccountInfo.accountInfo.data); // to be competitive, we collect market data before buying the token... if (existingTokenAccounts.has(accountData.baseMint.toString())) { @@ -238,27 +201,16 @@ export async function processOpenBookMarket( } } -async function buy( - accountId: PublicKey, - accountData: LiquidityStateV4, -): Promise { +async function buy(accountId: PublicKey, accountData: LiquidityStateV4): Promise { let tokenAccount = existingTokenAccounts.get(accountData.baseMint.toString()); if (!tokenAccount) { // it's possible that we didn't have time to fetch open book data - const market = await getMinimalMarketV3( - solanaConnection, - accountData.marketId, - commitment, - ); + const market = await getMinimalMarketV3(solanaConnection, accountData.marketId, commitment); tokenAccount = saveTokenAccount(accountData.baseMint, market); } - tokenAccount.poolKeys = createPoolKeys( - accountId, - accountData, - tokenAccount.market!, - ); + tokenAccount.poolKeys = createPoolKeys(accountId, accountData, tokenAccount.market!); const { innerTransaction, address } = Liquidity.makeSwapFixedInInstruction( { poolKeys: tokenAccount.poolKeys, @@ -293,13 +245,10 @@ async function buy( }).compileToV0Message(); const transaction = new VersionedTransaction(messageV0); transaction.sign([wallet, ...innerTransaction.signers]); - const signature = await solanaConnection.sendRawTransaction( - transaction.serialize(), - { - maxRetries: 20, - preflightCommitment: commitment, - }, - ); + const signature = await solanaConnection.sendRawTransaction(transaction.serialize(), { + maxRetries: 20, + preflightCommitment: commitment, + }); logger.info( { mint: accountData.baseMint, @@ -309,24 +258,19 @@ async function buy( ); } -const maxRetries = 60; -async function sell( - accountId: PublicKey, - accountData: LiquidityStateV4, - poolKeys: LiquidityPoolKeys, -): Promise { - const tokenAccount = existingTokenAccounts.get( - accountData.baseMint.toString(), - ); +async function sell(accountData: LiquidityStateV4, poolKeys: LiquidityPoolKeys): Promise { + const tokenAccount = existingTokenAccounts.get(accountData.baseMint.toString()); if (!tokenAccount) { return; } + let retries = 0; let balanceFound = false; - while (retries < maxRetries) { + while (retries < MAX_SELL_RETRIES) { try { const balanceResponse = (await solanaConnection.getTokenAccountBalance(tokenAccount.address)).value.amount; + if (balanceResponse !== null && Number(balanceResponse) > 0 && !balanceFound) { balanceFound = true; @@ -353,18 +297,16 @@ async function sell( instructions: [ ComputeBudgetProgram.setComputeUnitLimit({ units: 400000 }), ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 200000 }), + createCloseAccountInstruction(tokenAccount.address, wallet.publicKey, wallet.publicKey), ...innerTransaction.instructions, ], }).compileToV0Message(); const transaction = new VersionedTransaction(messageV0); transaction.sign([wallet, ...innerTransaction.signers]); - const signature = await solanaConnection.sendRawTransaction( - transaction.serialize(), - { - maxRetries: 5, - preflightCommitment: commitment, - }, - ); + const signature = await solanaConnection.sendRawTransaction(transaction.serialize(), { + maxRetries: 5, + preflightCommitment: commitment, + }); logger.info( { mint: accountData.baseMint, @@ -375,14 +317,13 @@ async function sell( break; } } catch (error) { - // logger.error(`Error while selling: ${error}`); + // ignored } retries++; await new Promise((resolve) => setTimeout(resolve, 1000)); } } - function loadSnipeList() { if (!USE_SNIPE_LIST) { return; @@ -411,9 +352,7 @@ const runListener = async () => { RAYDIUM_LIQUIDITY_PROGRAM_ID_V4, async (updatedAccountInfo) => { const key = updatedAccountInfo.accountId.toString(); - const poolState = LIQUIDITY_STATE_LAYOUT_V4.decode( - updatedAccountInfo.accountInfo.data, - ); + const poolState = LIQUIDITY_STATE_LAYOUT_V4.decode(updatedAccountInfo.accountInfo.data); const poolOpenTime = parseInt(poolState.poolOpenTime.toString()); const existing = existingLiquidityPools.has(key); @@ -471,10 +410,9 @@ const runListener = async () => { logger.info(`Listening for raydium changes: ${raydiumSubscriptionId}`); logger.info(`Listening for open book changes: ${openBookSubscriptionId}`); - if (USE_SNIPE_LIST) { setInterval(loadSnipeList, SNIPE_LIST_REFRESH_INTERVAL); } }; -runListener(); \ No newline at end of file +runListener(); From eed2936657730c1a75bdf84e1b42cf54ff1ace2f Mon Sep 17 00:00:00 2001 From: Filip Dunder Date: Tue, 20 Feb 2024 18:55:03 +0100 Subject: [PATCH 12/12] fix: remove unused files --- .gitignore | 8 +- pnpm-lock.yaml | 957 ------------------------------------------------- 2 files changed, 2 insertions(+), 963 deletions(-) delete mode 100644 pnpm-lock.yaml diff --git a/.gitignore b/.gitignore index b21b29c..f9c6030 100644 --- a/.gitignore +++ b/.gitignore @@ -129,9 +129,5 @@ dist .yarn/install-state.gz .pnp.* - -.idea -TODO - -# pnpm -pnpm-lock.yaml \ No newline at end of file +# JetBrains +.idea \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index a8f5aa2..0000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,957 +0,0 @@ -lockfileVersion: '6.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -dependencies: - '@raydium-io/raydium-sdk': - specifier: ^1.3.1-beta.47 - version: 1.3.1-beta.47(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) - '@solana/spl-token': - specifier: ^0.4.0 - version: 0.4.0(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) - '@solana/web3.js': - specifier: ^1.89.1 - version: 1.90.0 - bigint-buffer: - specifier: ^1.1.5 - version: 1.1.5 - bn.js: - specifier: ^5.2.1 - version: 5.2.1 - bs58: - specifier: ^5.0.0 - version: 5.0.0 - dotenv: - specifier: ^16.4.1 - version: 16.4.1 - pino: - specifier: ^8.18.0 - version: 8.18.0 - pino-pretty: - specifier: ^10.3.1 - version: 10.3.1 - pino-std-serializers: - specifier: ^6.2.2 - version: 6.2.2 - -devDependencies: - '@types/bn.js': - specifier: ^5.1.5 - version: 5.1.5 - prettier: - specifier: ^3.2.4 - version: 3.2.5 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@20.11.16)(typescript@5.3.3) - typescript: - specifier: ^5.3.3 - version: 5.3.3 - -packages: - - /@babel/runtime@7.23.9: - resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.14.1 - dev: false - - /@cspotcode/source-map-support@0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - dev: true - - /@jridgewell/resolve-uri@3.1.1: - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/sourcemap-codec@1.4.15: - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true - - /@jridgewell/trace-mapping@0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - - /@noble/curves@1.3.0: - resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} - dependencies: - '@noble/hashes': 1.3.3 - dev: false - - /@noble/hashes@1.3.3: - resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} - engines: {node: '>= 16'} - dev: false - - /@raydium-io/raydium-sdk@1.3.1-beta.47(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-vrUcFNq4lgkDHririlv83a2Sq/s438OZOYAsT56MWiVqoQLfC2u2muXMJhgp01M1OhXIqfsM5YSN/9/CrNnTvw==} - peerDependencies: - '@solana/web3.js': ^1.73.0 - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/spl-token': 0.3.11(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) - '@solana/web3.js': 1.90.0 - axios: 1.6.7 - 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 - transitivePeerDependencies: - - bufferutil - - debug - - encoding - - fastestsmallesttextencoderdecoder - - utf-8-validate - dev: false - - /@solana/buffer-layout-utils@0.2.0: - resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} - engines: {node: '>= 10'} - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.90.0 - bigint-buffer: 1.1.5 - bignumber.js: 9.1.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /@solana/buffer-layout@4.0.1: - resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} - engines: {node: '>=5.10'} - dependencies: - buffer: 6.0.3 - dev: false - - /@solana/codecs-core@2.0.0-experimental.8618508: - resolution: {integrity: sha512-JCz7mKjVKtfZxkuDtwMAUgA7YvJcA2BwpZaA1NOLcted4OMC4Prwa3DUe3f3181ixPYaRyptbF0Ikq2MbDkYEA==} - dev: false - - /@solana/codecs-data-structures@2.0.0-experimental.8618508: - resolution: {integrity: sha512-sLpjL9sqzaDdkloBPV61Rht1tgaKq98BCtIKRuyscIrmVPu3wu0Bavk2n/QekmUzaTsj7K1pVSniM0YqCdnEBw==} - dependencies: - '@solana/codecs-core': 2.0.0-experimental.8618508 - '@solana/codecs-numbers': 2.0.0-experimental.8618508 - dev: false - - /@solana/codecs-numbers@2.0.0-experimental.8618508: - resolution: {integrity: sha512-EXQKfzFr3CkKKNzKSZPOOOzchXsFe90TVONWsSnVkonO9z+nGKALE0/L9uBmIFGgdzhhU9QQVFvxBMclIDJo2Q==} - dependencies: - '@solana/codecs-core': 2.0.0-experimental.8618508 - dev: false - - /@solana/codecs-strings@2.0.0-experimental.8618508(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-b2yhinr1+oe+JDmnnsV0641KQqqDG8AQ16Z/x7GVWO+AWHMpRlHWVXOq8U1yhPMA4VXxl7i+D+C6ql0VGFp0GA==} - peerDependencies: - fastestsmallesttextencoderdecoder: ^1.0.22 - dependencies: - '@solana/codecs-core': 2.0.0-experimental.8618508 - '@solana/codecs-numbers': 2.0.0-experimental.8618508 - fastestsmallesttextencoderdecoder: 1.0.22 - dev: false - - /@solana/options@2.0.0-experimental.8618508: - resolution: {integrity: sha512-fy/nIRAMC3QHvnKi63KEd86Xr/zFBVxNW4nEpVEU2OT0gCEKwHY4Z55YHf7XujhyuM3PNpiBKg/YYw5QlRU4vg==} - dependencies: - '@solana/codecs-core': 2.0.0-experimental.8618508 - '@solana/codecs-numbers': 2.0.0-experimental.8618508 - dev: false - - /@solana/spl-token-metadata@0.1.2(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-hJYnAJNkDrtkE2Q41YZhCpeOGU/0JgRFXbtrtOuGGeKc3pkEUHB9DDoxZAxx+XRno13GozUleyBi0qypz4c3bw==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.87.6 - dependencies: - '@solana/codecs-core': 2.0.0-experimental.8618508 - '@solana/codecs-data-structures': 2.0.0-experimental.8618508 - '@solana/codecs-numbers': 2.0.0-experimental.8618508 - '@solana/codecs-strings': 2.0.0-experimental.8618508(fastestsmallesttextencoderdecoder@1.0.22) - '@solana/options': 2.0.0-experimental.8618508 - '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.90.0 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - dev: false - - /@solana/spl-token@0.3.11(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.88.0 - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-metadata': 0.1.2(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) - '@solana/web3.js': 1.90.0 - buffer: 6.0.3 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - - utf-8-validate - dev: false - - /@solana/spl-token@0.4.0(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22): - resolution: {integrity: sha512-jjBIBG9IsclqQVl5Y82npGE6utdCh7Z9VFcF5qgJa5EUq2XgspW3Dt1wujWjH/vQDRnkp9zGO+BqQU/HhX/3wg==} - engines: {node: '>=16'} - peerDependencies: - '@solana/web3.js': ^1.89.1 - dependencies: - '@solana/buffer-layout': 4.0.1 - '@solana/buffer-layout-utils': 0.2.0 - '@solana/spl-token-metadata': 0.1.2(@solana/web3.js@1.90.0)(fastestsmallesttextencoderdecoder@1.0.22) - '@solana/web3.js': 1.90.0 - buffer: 6.0.3 - transitivePeerDependencies: - - bufferutil - - encoding - - fastestsmallesttextencoderdecoder - - utf-8-validate - dev: false - - /@solana/spl-type-length-value@0.1.0: - resolution: {integrity: sha512-JBMGB0oR4lPttOZ5XiUGyvylwLQjt1CPJa6qQ5oM+MBCndfjz2TKKkw0eATlLLcYmq1jBVsNlJ2cD6ns2GR7lA==} - engines: {node: '>=16'} - dependencies: - buffer: 6.0.3 - dev: false - - /@solana/web3.js@1.90.0: - resolution: {integrity: sha512-p0cb/COXb8NNVSMkGMPwqQ6NvObZgUitN80uOedMB+jbYWOKOeJBuPnzhenkIV9RX0krGwyuY1Ltn5O8MGFsEw==} - dependencies: - '@babel/runtime': 7.23.9 - '@noble/curves': 1.3.0 - '@noble/hashes': 1.3.3 - '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.5.0 - bigint-buffer: 1.1.5 - bn.js: 5.2.1 - borsh: 0.7.0 - bs58: 4.0.1 - buffer: 6.0.3 - fast-stable-stringify: 1.0.0 - jayson: 4.1.0 - node-fetch: 2.7.0 - rpc-websockets: 7.9.0 - superstruct: 0.14.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - dev: false - - /@tsconfig/node10@1.0.9: - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - dev: true - - /@tsconfig/node12@1.0.11: - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true - - /@tsconfig/node14@1.0.3: - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true - - /@tsconfig/node16@1.0.4: - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - dev: true - - /@types/bn.js@5.1.5: - resolution: {integrity: sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==} - dependencies: - '@types/node': 20.11.16 - dev: true - - /@types/connect@3.4.38: - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - dependencies: - '@types/node': 20.11.16 - dev: false - - /@types/node@12.20.55: - resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - dev: false - - /@types/node@20.11.16: - resolution: {integrity: sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==} - dependencies: - undici-types: 5.26.5 - - /@types/ws@7.4.7: - resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} - dependencies: - '@types/node': 20.11.16 - dev: false - - /JSONStream@1.3.5: - resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} - hasBin: true - dependencies: - jsonparse: 1.3.1 - through: 2.3.8 - dev: false - - /abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} - dependencies: - event-target-shim: 5.0.1 - dev: false - - /acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} - engines: {node: '>=0.4.0'} - dev: true - - /acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /agentkeepalive@4.5.0: - resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} - engines: {node: '>= 8.0.0'} - dependencies: - humanize-ms: 1.2.1 - dev: false - - /arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true - - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false - - /atomic-sleep@1.0.0: - resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} - engines: {node: '>=8.0.0'} - dev: false - - /axios@1.6.7: - resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} - dependencies: - follow-redirects: 1.15.5 - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - dev: false - - /base-x@3.0.9: - resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /base-x@4.0.0: - resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} - dev: false - - /base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: false - - /big.js@6.2.1: - resolution: {integrity: sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==} - dev: false - - /bigint-buffer@1.1.5: - resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} - engines: {node: '>= 10.0.0'} - requiresBuild: true - dependencies: - bindings: 1.5.0 - dev: false - - /bignumber.js@9.1.2: - resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} - dev: false - - /bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - dependencies: - file-uri-to-path: 1.0.0 - dev: false - - /bn.js@5.2.1: - resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} - dev: false - - /borsh@0.7.0: - resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} - dependencies: - bn.js: 5.2.1 - bs58: 4.0.1 - text-encoding-utf-8: 1.0.2 - dev: false - - /bs58@4.0.1: - resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} - dependencies: - base-x: 3.0.9 - dev: false - - /bs58@5.0.0: - resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} - dependencies: - base-x: 4.0.0 - dev: false - - /buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - dev: false - - /bufferutil@4.0.8: - resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} - engines: {node: '>=6.14.2'} - requiresBuild: true - dependencies: - node-gyp-build: 4.8.0 - dev: false - - /colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - dev: false - - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: false - - /commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: false - - /create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true - - /dateformat@4.6.3: - resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} - dev: false - - /decimal.js-light@2.5.1: - resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} - dev: false - - /decimal.js@10.4.3: - resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} - dev: false - - /delay@5.0.0: - resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} - engines: {node: '>=10'} - dev: false - - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: false - - /diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - dev: true - - /dotenv@16.4.1: - resolution: {integrity: sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==} - engines: {node: '>=12'} - dev: false - - /end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - dependencies: - once: 1.4.0 - dev: false - - /es6-promise@4.2.8: - resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} - dev: false - - /es6-promisify@5.0.0: - resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} - dependencies: - es6-promise: 4.2.8 - dev: false - - /event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} - dev: false - - /eventemitter3@4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - dev: false - - /events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - dev: false - - /eyes@0.1.8: - resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} - engines: {node: '> 0.1.90'} - dev: false - - /fast-copy@3.0.1: - resolution: {integrity: sha512-Knr7NOtK3HWRYGtHoJrjkaWepqT8thIVGAwt0p0aUs1zqkAzXZV4vo9fFNwyb5fcqK1GKYFYxldQdIDVKhUAfA==} - dev: false - - /fast-redact@3.3.0: - resolution: {integrity: sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==} - engines: {node: '>=6'} - dev: false - - /fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - dev: false - - /fast-stable-stringify@1.0.0: - resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} - dev: false - - /fastestsmallesttextencoderdecoder@1.0.22: - resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} - dev: false - - /fecha@4.2.3: - resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} - dev: false - - /file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - dev: false - - /follow-redirects@1.15.5: - resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /help-me@5.0.0: - resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} - dev: false - - /humanize-ms@1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} - dependencies: - ms: 2.1.3 - dev: false - - /ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: false - - /isomorphic-ws@4.0.1(ws@7.5.9): - resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} - peerDependencies: - ws: '*' - dependencies: - ws: 7.5.9 - dev: false - - /jayson@4.1.0: - resolution: {integrity: sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==} - engines: {node: '>=8'} - hasBin: true - dependencies: - '@types/connect': 3.4.38 - '@types/node': 12.20.55 - '@types/ws': 7.4.7 - JSONStream: 1.3.5 - commander: 2.20.3 - delay: 5.0.0 - es6-promisify: 5.0.0 - eyes: 0.1.8 - isomorphic-ws: 4.0.1(ws@7.5.9) - json-stringify-safe: 5.0.1 - uuid: 8.3.2 - ws: 7.5.9 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: false - - /joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} - engines: {node: '>=10'} - dev: false - - /json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: false - - /jsonparse@1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} - dev: false - - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: false - - /make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true - - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: false - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: false - - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: false - - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: false - - /node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - dev: false - - /node-gyp-build@4.8.0: - resolution: {integrity: sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==} - hasBin: true - requiresBuild: true - dev: false - - /on-exit-leak-free@2.1.2: - resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} - engines: {node: '>=14.0.0'} - dev: false - - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - dev: false - - /pino-abstract-transport@1.1.0: - resolution: {integrity: sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==} - dependencies: - readable-stream: 4.5.2 - split2: 4.2.0 - dev: false - - /pino-pretty@10.3.1: - resolution: {integrity: sha512-az8JbIYeN/1iLj2t0jR9DV48/LQ3RC6hZPpapKPkb84Q+yTidMCpgWxIT3N0flnBDilyBQ1luWNpOeJptjdp/g==} - hasBin: true - dependencies: - colorette: 2.0.20 - dateformat: 4.6.3 - fast-copy: 3.0.1 - fast-safe-stringify: 2.1.1 - help-me: 5.0.0 - joycon: 3.1.1 - minimist: 1.2.8 - on-exit-leak-free: 2.1.2 - pino-abstract-transport: 1.1.0 - pump: 3.0.0 - readable-stream: 4.5.2 - secure-json-parse: 2.7.0 - sonic-boom: 3.8.0 - strip-json-comments: 3.1.1 - dev: false - - /pino-std-serializers@6.2.2: - resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} - dev: false - - /pino@8.18.0: - resolution: {integrity: sha512-Mz/gKiRyuXu4HnpHgi1YWdHQCoWMufapzooisvFn78zl4dZciAxS+YeRkUxXl1ee/SzU80YCz1zpECCh4oC6Aw==} - hasBin: true - dependencies: - atomic-sleep: 1.0.0 - fast-redact: 3.3.0 - on-exit-leak-free: 2.1.2 - pino-abstract-transport: 1.1.0 - pino-std-serializers: 6.2.2 - process-warning: 3.0.0 - quick-format-unescaped: 4.0.4 - real-require: 0.2.0 - safe-stable-stringify: 2.4.3 - sonic-boom: 3.8.0 - thread-stream: 2.4.1 - dev: false - - /prettier@3.2.5: - resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} - engines: {node: '>=14'} - hasBin: true - dev: true - - /process-warning@3.0.0: - resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} - dev: false - - /process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} - dev: false - - /proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: false - - /pump@3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - dev: false - - /quick-format-unescaped@4.0.4: - resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} - dev: false - - /readable-stream@4.5.2: - resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - abort-controller: 3.0.0 - buffer: 6.0.3 - events: 3.3.0 - process: 0.11.10 - string_decoder: 1.3.0 - dev: false - - /real-require@0.2.0: - resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} - engines: {node: '>= 12.13.0'} - dev: false - - /regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - dev: false - - /rpc-websockets@7.9.0: - resolution: {integrity: sha512-DwKewQz1IUA5wfLvgM8wDpPRcr+nWSxuFxx5CbrI2z/MyyZ4nXLM86TvIA+cI1ZAdqC8JIBR1mZR55dzaLU+Hw==} - dependencies: - '@babel/runtime': 7.23.9 - eventemitter3: 4.0.7 - uuid: 8.3.2 - ws: 8.16.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - optionalDependencies: - bufferutil: 4.0.8 - utf-8-validate: 5.0.10 - dev: false - - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: false - - /safe-stable-stringify@2.4.3: - resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} - engines: {node: '>=10'} - dev: false - - /secure-json-parse@2.7.0: - resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} - dev: false - - /sonic-boom@3.8.0: - resolution: {integrity: sha512-ybz6OYOUjoQQCQ/i4LU8kaToD8ACtYP+Cj5qd2AO36bwbdewxWJ3ArmJ2cr6AvxlL2o0PqnCcPGUgkILbfkaCA==} - dependencies: - atomic-sleep: 1.0.0 - dev: false - - /split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - dev: false - - /string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: false - - /superstruct@0.14.2: - resolution: {integrity: sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==} - dev: false - - /text-encoding-utf-8@1.0.2: - resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} - dev: false - - /thread-stream@2.4.1: - resolution: {integrity: sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==} - dependencies: - real-require: 0.2.0 - dev: false - - /through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: false - - /toformat@2.0.0: - resolution: {integrity: sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==} - dev: false - - /tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: false - - /ts-node@10.9.2(@types/node@20.11.16)(typescript@5.3.3): - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.11.16 - acorn: 8.11.3 - acorn-walk: 8.3.2 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.3.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - - /typescript@5.3.3: - resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} - engines: {node: '>=14.17'} - hasBin: true - dev: true - - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - /utf-8-validate@5.0.10: - resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} - engines: {node: '>=6.14.2'} - requiresBuild: true - dependencies: - node-gyp-build: 4.8.0 - dev: false - - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: false - - /v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true - - /webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: false - - /whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - dev: false - - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: false - - /ws@7.5.9: - resolution: {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 - dev: false - - /ws@8.16.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): - resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} - 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 - dependencies: - bufferutil: 4.0.8 - utf-8-validate: 5.0.10 - dev: false - - /yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - dev: true