Merge pull request #93 from TheoBrigitte/mutable

Add mutable filter
This commit is contained in:
Filip Dunđer
2024-04-22 17:47:39 +02:00
committed by GitHub
9 changed files with 126 additions and 2 deletions

View File

@ -42,8 +42,9 @@ SNIPE_LIST_REFRESH_INTERVAL=30000
FILTER_CHECK_DURATION=60000
FILTER_CHECK_INTERVAL=2000
CONSECUTIVE_FILTER_MATCHES=3
CHECK_IF_MUTABLE=false
CHECK_IF_MINT_IS_RENOUNCED=true
CHECK_IF_FREEZABLE=true
CHECK_IF_FREEZABLE=false
CHECK_IF_BURNED=true
MIN_POOL_SIZE=5
MAX_POOL_SIZE=50

View File

@ -84,6 +84,7 @@ Note: When using snipe list filters below will be disabled.
- Set to zero to disable filters.
- `CONSECUTIVE_FILTER_MATCHES` - How many times in a row pool needs to match the filters.
- This is useful because when pool is burned (and rugged), other filters may not report the same behavior. eg. pool size may still have old value
- `CHECK_IF_MUTABLE` - Set to `true` to buy tokens only if their metadata are not mutable.
- `CHECK_IF_MINT_IS_RENOUNCED` - Set to `true` to buy tokens only if their mint is renounced.
- `CHECK_IF_FREEZABLE` - Set to `true` to buy tokens only if they are not freezable.
- `CHECK_IF_BURNED` - Set to `true` to buy tokens only if their liquidity pool is burned.

View File

@ -1,4 +1,5 @@
export * from './burn.filter';
export * from './mutable.filter';
export * from './pool-filters';
export * from './pool-size.filter';
export * from './renounced.filter';

29
filters/mutable.filter.ts Normal file
View File

@ -0,0 +1,29 @@
import { Filter, FilterResult } from './pool-filters';
import { Connection, PublicKey } from '@solana/web3.js';
import { LiquidityPoolKeysV4 } from '@raydium-io/raydium-sdk';
import { getPdaMetadataKey } from '@raydium-io/raydium-sdk';
import { getMetadataAccountDataSerializer, MetadataAccountData, MetadataAccountDataArgs } from '@metaplex-foundation/mpl-token-metadata';
import { Serializer } from '@metaplex-foundation/umi/serializers';
import { logger } from '../helpers';
export class MutableFilter implements Filter {
constructor(private readonly connection: Connection, private readonly metadataSerializer: Serializer<MetadataAccountDataArgs, MetadataAccountData>) {}
async execute(poolKeys: LiquidityPoolKeysV4): Promise<FilterResult> {
try {
const metadataPDA = getPdaMetadataKey(poolKeys.baseMint);
const metadataAccount = await this.connection.getAccountInfo(metadataPDA.publicKey);
if (!metadataAccount?.data) {
return { ok: false, message: 'Mutable -> Failed to fetch account data' };
}
const deserialize = this.metadataSerializer.deserialize(metadataAccount.data);
const mutable = deserialize[0].isMutable;
return { ok: !mutable, message: !mutable ? undefined : "Mutable -> Creator can change metadata" };
} catch (e: any) {
logger.error({ mint: poolKeys.baseMint }, `Mutable -> Failed to check if metadata are mutable`);
}
return { ok: false, message: 'Mutable -> Failed to check if metadata are mutable' };
}
}

View File

@ -1,9 +1,11 @@
import { Connection } from '@solana/web3.js';
import { LiquidityPoolKeysV4, Token, TokenAmount } from '@raydium-io/raydium-sdk';
import { getMetadataAccountDataSerializer } from '@metaplex-foundation/mpl-token-metadata';
import { BurnFilter } from './burn.filter';
import { MutableFilter } from './mutable.filter';
import { RenouncedFreezeFilter } from './renounced.filter';
import { PoolSizeFilter } from './pool-size.filter';
import { CHECK_IF_BURNED, CHECK_IF_FREEZABLE, CHECK_IF_MINT_IS_RENOUNCED, logger } from '../helpers';
import { CHECK_IF_BURNED, CHECK_IF_FREEZABLE, CHECK_IF_MINT_IS_RENOUNCED, CHECK_IF_MUTABLE, logger } from '../helpers';
export interface Filter {
execute(poolKeysV4: LiquidityPoolKeysV4): Promise<FilterResult>;
@ -35,6 +37,10 @@ export class PoolFilters {
this.filters.push(new RenouncedFreezeFilter(connection, CHECK_IF_MINT_IS_RENOUNCED, CHECK_IF_FREEZABLE));
}
if (CHECK_IF_MUTABLE) {
this.filters.push(new MutableFilter(connection, getMetadataAccountDataSerializer()));
}
if (!args.minPoolSize.isZero() || !args.maxPoolSize.isZero()) {
this.filters.push(new PoolSizeFilter(connection, args.quoteToken, args.minPoolSize, args.maxPoolSize));
}

View File

@ -54,6 +54,7 @@ export const SELL_SLIPPAGE = Number(retrieveEnvVariable('SELL_SLIPPAGE', logger)
export const FILTER_CHECK_INTERVAL = Number(retrieveEnvVariable('FILTER_CHECK_INTERVAL', logger));
export const FILTER_CHECK_DURATION = Number(retrieveEnvVariable('FILTER_CHECK_DURATION', logger));
export const CONSECUTIVE_FILTER_MATCHES = Number(retrieveEnvVariable('CONSECUTIVE_FILTER_MATCHES', logger));
export const CHECK_IF_MUTABLE = retrieveEnvVariable('CHECK_IF_MUTABLE', logger) === 'true';
export const CHECK_IF_MINT_IS_RENOUNCED = retrieveEnvVariable('CHECK_IF_MINT_IS_RENOUNCED', logger) === 'true';
export const CHECK_IF_FREEZABLE = retrieveEnvVariable('CHECK_IF_FREEZABLE', logger) === 'true';
export const CHECK_IF_BURNED = retrieveEnvVariable('CHECK_IF_BURNED', logger) === 'true';

View File

@ -14,6 +14,7 @@ import {
RPC_WEBSOCKET_ENDPOINT,
PRE_LOAD_EXISTING_MARKETS,
LOG_LEVEL,
CHECK_IF_MUTABLE,
CHECK_IF_MINT_IS_RENOUNCED,
CHECK_IF_FREEZABLE,
CHECK_IF_BURNED,

83
package-lock.json generated
View File

@ -8,6 +8,7 @@
"name": "warp-solana-bot",
"version": "2.0.1",
"dependencies": {
"@metaplex-foundation/mpl-token-metadata": "^3.2.1",
"@raydium-io/raydium-sdk": "^1.3.1-beta.47",
"@solana/spl-token": "^0.4.0",
"@solana/web3.js": "^1.89.1",
@ -75,6 +76,88 @@
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"node_modules/@metaplex-foundation/mpl-token-metadata": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/@metaplex-foundation/mpl-token-metadata/-/mpl-token-metadata-3.2.1.tgz",
"integrity": "sha512-26W1NhQwDWmLOg/pBRYut7x/vEs/5kFS2sWVEY5/X0f2jJOLhnd4NaZQcq+5u+XZsXvm1jq2AtrRGPNK43oqWQ==",
"dependencies": {
"@metaplex-foundation/mpl-toolbox": "^0.9.4"
},
"peerDependencies": {
"@metaplex-foundation/umi": ">= 0.8.2 < 1"
}
},
"node_modules/@metaplex-foundation/mpl-toolbox": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/@metaplex-foundation/mpl-toolbox/-/mpl-toolbox-0.9.4.tgz",
"integrity": "sha512-fd6JxfoLbj/MM8FG2x91KYVy1U6AjBQw4qjt7+Da3trzQaWnSaYHDcYRG/53xqfvZ9qofY1T2t53GXPlD87lnQ==",
"peerDependencies": {
"@metaplex-foundation/umi": ">= 0.8.2 < 1"
}
},
"node_modules/@metaplex-foundation/umi": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/@metaplex-foundation/umi/-/umi-0.9.1.tgz",
"integrity": "sha512-IhHoOvp4vfO/++YL+78+iVuLM53+FDwUOZDYgH6lx0jYXyQ27BeaieeR5i+q3A9dz4KxQo5Nzc5aCA1109QGCQ==",
"peer": true,
"dependencies": {
"@metaplex-foundation/umi-options": "^0.8.9",
"@metaplex-foundation/umi-public-keys": "^0.8.9",
"@metaplex-foundation/umi-serializers": "^0.9.0"
}
},
"node_modules/@metaplex-foundation/umi-options": {
"version": "0.8.9",
"resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-options/-/umi-options-0.8.9.tgz",
"integrity": "sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A==",
"peer": true
},
"node_modules/@metaplex-foundation/umi-public-keys": {
"version": "0.8.9",
"resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-public-keys/-/umi-public-keys-0.8.9.tgz",
"integrity": "sha512-CxMzN7dgVGOq9OcNCJe2casKUpJ3RmTVoOvDFyeoTQuK+vkZ1YSSahbqC1iGuHEtKTLSjtWjKvUU6O7zWFTw3Q==",
"peer": true,
"dependencies": {
"@metaplex-foundation/umi-serializers-encodings": "^0.8.9"
}
},
"node_modules/@metaplex-foundation/umi-serializers": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-serializers/-/umi-serializers-0.9.0.tgz",
"integrity": "sha512-hAOW9Djl4w4ioKeR4erDZl5IG4iJdP0xA19ZomdaCbMhYAAmG/FEs5khh0uT2mq53/MnzWcXSUPoO8WBN4Q+Vg==",
"peer": true,
"dependencies": {
"@metaplex-foundation/umi-options": "^0.8.9",
"@metaplex-foundation/umi-public-keys": "^0.8.9",
"@metaplex-foundation/umi-serializers-core": "^0.8.9",
"@metaplex-foundation/umi-serializers-encodings": "^0.8.9",
"@metaplex-foundation/umi-serializers-numbers": "^0.8.9"
}
},
"node_modules/@metaplex-foundation/umi-serializers-core": {
"version": "0.8.9",
"resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-serializers-core/-/umi-serializers-core-0.8.9.tgz",
"integrity": "sha512-WT82tkiYJ0Qmscp7uTj1Hz6aWQPETwaKLAENAUN5DeWghkuBKtuxyBKVvEOuoXerJSdhiAk0e8DWA4cxcTTQ/w==",
"peer": true
},
"node_modules/@metaplex-foundation/umi-serializers-encodings": {
"version": "0.8.9",
"resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-serializers-encodings/-/umi-serializers-encodings-0.8.9.tgz",
"integrity": "sha512-N3VWLDTJ0bzzMKcJDL08U3FaqRmwlN79FyE4BHj6bbAaJ9LEHjDQ9RJijZyWqTm0jE7I750fU7Ow5EZL38Xi6Q==",
"peer": true,
"dependencies": {
"@metaplex-foundation/umi-serializers-core": "^0.8.9"
}
},
"node_modules/@metaplex-foundation/umi-serializers-numbers": {
"version": "0.8.9",
"resolved": "https://registry.npmjs.org/@metaplex-foundation/umi-serializers-numbers/-/umi-serializers-numbers-0.8.9.tgz",
"integrity": "sha512-NtBf1fnVNQJHFQjLFzRu2i9GGnigb9hOm/Gfrk628d0q0tRJB7BOM3bs5C61VAs7kJs4yd+pDNVAERJkknQ7Lg==",
"peer": true,
"dependencies": {
"@metaplex-foundation/umi-serializers-core": "^0.8.9"
}
},
"node_modules/@noble/curves": {
"version": "1.3.0",
"license": "MIT",

View File

@ -8,6 +8,7 @@
"tsc": "tsc --noEmit"
},
"dependencies": {
"@metaplex-foundation/mpl-token-metadata": "^3.2.1",
"@raydium-io/raydium-sdk": "^1.3.1-beta.47",
"@solana/spl-token": "^0.4.0",
"@solana/web3.js": "^1.89.1",