mirror of
https://github.com/fdundjer/solana-sniper-bot.git
synced 2025-11-22 12:41:08 +10:00
tsc & prettier
This commit is contained in:
43
filters/burn.filter.js
Normal file
43
filters/burn.filter.js
Normal file
@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.BurnFilter = void 0;
|
||||
const helpers_1 = require("../helpers");
|
||||
class BurnFilter {
|
||||
constructor(connection) {
|
||||
this.connection = connection;
|
||||
this.cachedResult = undefined;
|
||||
}
|
||||
execute(poolKeys) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.cachedResult) {
|
||||
return this.cachedResult;
|
||||
}
|
||||
try {
|
||||
const amount = yield this.connection.getTokenSupply(poolKeys.lpMint, this.connection.commitment);
|
||||
const burned = amount.value.uiAmount === 0;
|
||||
const result = { ok: burned, message: burned ? undefined : "Burned -> Creator didn't burn LP" };
|
||||
if (result.ok) {
|
||||
this.cachedResult = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (e) {
|
||||
if (e.code == -32602) {
|
||||
return { ok: true };
|
||||
}
|
||||
helpers_1.logger.error({ mint: poolKeys.baseMint }, `Failed to check if LP is burned`);
|
||||
}
|
||||
return { ok: false, message: "Failed to check if LP is burned" };
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.BurnFilter = BurnFilter;
|
||||
@ -1,36 +1,36 @@
|
||||
import { Filter, FilterResult } from './pool-filters';
|
||||
import { Connection } from '@solana/web3.js';
|
||||
import { LiquidityPoolKeysV4 } from '@raydium-io/raydium-sdk';
|
||||
import { logger } from '../helpers';
|
||||
import { Filter, FilterResult } from "./pool-filters";
|
||||
import { Connection } from "@solana/web3.js";
|
||||
import { LiquidityPoolKeysV4 } from "@raydium-io/raydium-sdk";
|
||||
import { logger } from "../helpers";
|
||||
|
||||
export class BurnFilter implements Filter {
|
||||
private cachedResult: FilterResult | undefined = undefined;
|
||||
private cachedResult: FilterResult | undefined = undefined;
|
||||
|
||||
constructor(private readonly connection: Connection) {}
|
||||
constructor(private readonly connection: Connection) {}
|
||||
|
||||
async execute(poolKeys: LiquidityPoolKeysV4): Promise<FilterResult> {
|
||||
if (this.cachedResult) {
|
||||
return this.cachedResult;
|
||||
}
|
||||
async execute(poolKeys: LiquidityPoolKeysV4): Promise<FilterResult> {
|
||||
if (this.cachedResult) {
|
||||
return this.cachedResult;
|
||||
}
|
||||
|
||||
try {
|
||||
const amount = await this.connection.getTokenSupply(poolKeys.lpMint, this.connection.commitment);
|
||||
const burned = amount.value.uiAmount === 0;
|
||||
const result = { ok: burned, message: burned ? undefined : "Burned -> Creator didn't burn LP" };
|
||||
try {
|
||||
const amount = await this.connection.getTokenSupply(poolKeys.lpMint, this.connection.commitment);
|
||||
const burned = amount.value.uiAmount === 0;
|
||||
const result = { ok: burned, message: burned ? undefined : "Burned -> Creator didn't burn LP" };
|
||||
|
||||
if (result.ok) {
|
||||
this.cachedResult = result;
|
||||
}
|
||||
if (result.ok) {
|
||||
this.cachedResult = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (e: any) {
|
||||
if (e.code == -32602) {
|
||||
return { ok: true };
|
||||
}
|
||||
return result;
|
||||
} catch (e: any) {
|
||||
if (e.code == -32602) {
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
logger.error({ mint: poolKeys.baseMint }, `Failed to check if LP is burned`);
|
||||
}
|
||||
logger.error({ mint: poolKeys.baseMint }, `Failed to check if LP is burned`);
|
||||
}
|
||||
|
||||
return { ok: false, message: 'Failed to check if LP is burned' };
|
||||
}
|
||||
return { ok: false, message: "Failed to check if LP is burned" };
|
||||
}
|
||||
}
|
||||
|
||||
21
filters/index.js
Normal file
21
filters/index.js
Normal file
@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./burn.filter"), exports);
|
||||
__exportStar(require("./mutable.filter"), exports);
|
||||
__exportStar(require("./pool-filters"), exports);
|
||||
__exportStar(require("./pool-size.filter"), exports);
|
||||
__exportStar(require("./renounced.filter"), exports);
|
||||
@ -1,5 +1,5 @@
|
||||
export * from './burn.filter';
|
||||
export * from './mutable.filter';
|
||||
export * from './pool-filters';
|
||||
export * from './pool-size.filter';
|
||||
export * from './renounced.filter';
|
||||
export * from "./burn.filter";
|
||||
export * from "./mutable.filter";
|
||||
export * from "./pool-filters";
|
||||
export * from "./pool-size.filter";
|
||||
export * from "./renounced.filter";
|
||||
|
||||
76
filters/mutable.filter.js
Normal file
76
filters/mutable.filter.js
Normal file
@ -0,0 +1,76 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MutableFilter = void 0;
|
||||
const raydium_sdk_1 = require("@raydium-io/raydium-sdk");
|
||||
const helpers_1 = require("../helpers");
|
||||
class MutableFilter {
|
||||
constructor(connection, metadataSerializer, checkMutable, checkSocials) {
|
||||
this.connection = connection;
|
||||
this.metadataSerializer = metadataSerializer;
|
||||
this.checkMutable = checkMutable;
|
||||
this.checkSocials = checkSocials;
|
||||
this.errorMessage = [];
|
||||
this.cachedResult = undefined;
|
||||
if (this.checkMutable) {
|
||||
this.errorMessage.push("mutable");
|
||||
}
|
||||
if (this.checkSocials) {
|
||||
this.errorMessage.push("socials");
|
||||
}
|
||||
}
|
||||
execute(poolKeys) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.cachedResult) {
|
||||
return this.cachedResult;
|
||||
}
|
||||
try {
|
||||
const metadataPDA = (0, raydium_sdk_1.getPdaMetadataKey)(poolKeys.baseMint);
|
||||
const metadataAccount = yield this.connection.getAccountInfo(metadataPDA.publicKey, this.connection.commitment);
|
||||
if (!(metadataAccount === null || metadataAccount === void 0 ? void 0 : metadataAccount.data)) {
|
||||
return { ok: false, message: "Mutable -> Failed to fetch account data" };
|
||||
}
|
||||
const deserialize = this.metadataSerializer.deserialize(metadataAccount.data);
|
||||
const mutable = !this.checkMutable || deserialize[0].isMutable;
|
||||
const hasSocials = !this.checkSocials || (yield this.hasSocials(deserialize[0]));
|
||||
const ok = !mutable && hasSocials;
|
||||
const message = [];
|
||||
if (mutable) {
|
||||
message.push("metadata can be changed");
|
||||
}
|
||||
if (!hasSocials) {
|
||||
message.push("has no socials");
|
||||
}
|
||||
const result = { ok: ok, message: ok ? undefined : `MutableSocials -> Token ${message.join(" and ")}` };
|
||||
if (!mutable) {
|
||||
this.cachedResult = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (e) {
|
||||
helpers_1.logger.error({ mint: poolKeys.baseMint }, `MutableSocials -> Failed to check ${this.errorMessage.join(" and ")}`);
|
||||
}
|
||||
return {
|
||||
ok: false,
|
||||
message: `MutableSocials -> Failed to check ${this.errorMessage.join(" and ")}`,
|
||||
};
|
||||
});
|
||||
}
|
||||
hasSocials(metadata) {
|
||||
var _a;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const response = yield fetch(metadata.uri);
|
||||
const data = yield response.json();
|
||||
return Object.values((_a = data === null || data === void 0 ? void 0 : data.extensions) !== null && _a !== void 0 ? _a : {}).filter((value) => value).length > 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.MutableFilter = MutableFilter;
|
||||
@ -1,77 +1,77 @@
|
||||
import { Filter, FilterResult } from './pool-filters';
|
||||
import { Connection } from '@solana/web3.js';
|
||||
import { LiquidityPoolKeysV4 } from '@raydium-io/raydium-sdk';
|
||||
import { getPdaMetadataKey } from '@raydium-io/raydium-sdk';
|
||||
import { MetadataAccountData, MetadataAccountDataArgs } from '@metaplex-foundation/mpl-token-metadata';
|
||||
import { Serializer } from '@metaplex-foundation/umi/serializers';
|
||||
import { logger } from '../helpers';
|
||||
import { Filter, FilterResult } from "./pool-filters";
|
||||
import { Connection } from "@solana/web3.js";
|
||||
import { LiquidityPoolKeysV4 } from "@raydium-io/raydium-sdk";
|
||||
import { getPdaMetadataKey } from "@raydium-io/raydium-sdk";
|
||||
import { MetadataAccountData, MetadataAccountDataArgs } from "@metaplex-foundation/mpl-token-metadata";
|
||||
import { Serializer } from "@metaplex-foundation/umi/serializers";
|
||||
import { logger } from "../helpers";
|
||||
|
||||
export class MutableFilter implements Filter {
|
||||
private readonly errorMessage: string[] = [];
|
||||
private cachedResult: FilterResult | undefined = undefined;
|
||||
private readonly errorMessage: string[] = [];
|
||||
private cachedResult: FilterResult | undefined = undefined;
|
||||
|
||||
constructor(
|
||||
private readonly connection: Connection,
|
||||
private readonly metadataSerializer: Serializer<MetadataAccountDataArgs, MetadataAccountData>,
|
||||
private readonly checkMutable: boolean,
|
||||
private readonly checkSocials: boolean,
|
||||
) {
|
||||
if (this.checkMutable) {
|
||||
this.errorMessage.push('mutable');
|
||||
}
|
||||
constructor(
|
||||
private readonly connection: Connection,
|
||||
private readonly metadataSerializer: Serializer<MetadataAccountDataArgs, MetadataAccountData>,
|
||||
private readonly checkMutable: boolean,
|
||||
private readonly checkSocials: boolean,
|
||||
) {
|
||||
if (this.checkMutable) {
|
||||
this.errorMessage.push("mutable");
|
||||
}
|
||||
|
||||
if (this.checkSocials) {
|
||||
this.errorMessage.push('socials');
|
||||
}
|
||||
}
|
||||
if (this.checkSocials) {
|
||||
this.errorMessage.push("socials");
|
||||
}
|
||||
}
|
||||
|
||||
async execute(poolKeys: LiquidityPoolKeysV4): Promise<FilterResult> {
|
||||
if (this.cachedResult) {
|
||||
return this.cachedResult;
|
||||
}
|
||||
async execute(poolKeys: LiquidityPoolKeysV4): Promise<FilterResult> {
|
||||
if (this.cachedResult) {
|
||||
return this.cachedResult;
|
||||
}
|
||||
|
||||
try {
|
||||
const metadataPDA = getPdaMetadataKey(poolKeys.baseMint);
|
||||
const metadataAccount = await this.connection.getAccountInfo(metadataPDA.publicKey, this.connection.commitment);
|
||||
try {
|
||||
const metadataPDA = getPdaMetadataKey(poolKeys.baseMint);
|
||||
const metadataAccount = await this.connection.getAccountInfo(metadataPDA.publicKey, this.connection.commitment);
|
||||
|
||||
if (!metadataAccount?.data) {
|
||||
return { ok: false, message: 'Mutable -> Failed to fetch account data' };
|
||||
}
|
||||
if (!metadataAccount?.data) {
|
||||
return { ok: false, message: "Mutable -> Failed to fetch account data" };
|
||||
}
|
||||
|
||||
const deserialize = this.metadataSerializer.deserialize(metadataAccount.data);
|
||||
const mutable = !this.checkMutable || deserialize[0].isMutable;
|
||||
const hasSocials = !this.checkSocials || (await this.hasSocials(deserialize[0]));
|
||||
const ok = !mutable && hasSocials;
|
||||
const message: string[] = [];
|
||||
const deserialize = this.metadataSerializer.deserialize(metadataAccount.data);
|
||||
const mutable = !this.checkMutable || deserialize[0].isMutable;
|
||||
const hasSocials = !this.checkSocials || (await this.hasSocials(deserialize[0]));
|
||||
const ok = !mutable && hasSocials;
|
||||
const message: string[] = [];
|
||||
|
||||
if (mutable) {
|
||||
message.push('metadata can be changed');
|
||||
}
|
||||
if (mutable) {
|
||||
message.push("metadata can be changed");
|
||||
}
|
||||
|
||||
if (!hasSocials) {
|
||||
message.push('has no socials');
|
||||
}
|
||||
if (!hasSocials) {
|
||||
message.push("has no socials");
|
||||
}
|
||||
|
||||
const result = { ok: ok, message: ok ? undefined : `MutableSocials -> Token ${message.join(' and ')}` };
|
||||
const result = { ok: ok, message: ok ? undefined : `MutableSocials -> Token ${message.join(" and ")}` };
|
||||
|
||||
if (!mutable) {
|
||||
this.cachedResult = result;
|
||||
}
|
||||
if (!mutable) {
|
||||
this.cachedResult = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (e) {
|
||||
logger.error({ mint: poolKeys.baseMint }, `MutableSocials -> Failed to check ${this.errorMessage.join(' and ')}`);
|
||||
}
|
||||
return result;
|
||||
} catch (e) {
|
||||
logger.error({ mint: poolKeys.baseMint }, `MutableSocials -> Failed to check ${this.errorMessage.join(" and ")}`);
|
||||
}
|
||||
|
||||
return {
|
||||
ok: false,
|
||||
message: `MutableSocials -> Failed to check ${this.errorMessage.join(' and ')}`,
|
||||
};
|
||||
}
|
||||
return {
|
||||
ok: false,
|
||||
message: `MutableSocials -> Failed to check ${this.errorMessage.join(" and ")}`,
|
||||
};
|
||||
}
|
||||
|
||||
private async hasSocials(metadata: MetadataAccountData) {
|
||||
const response = await fetch(metadata.uri);
|
||||
const data = await response.json();
|
||||
return Object.values(data?.extensions ?? {}).filter((value: any) => value).length > 0;
|
||||
}
|
||||
private async hasSocials(metadata: MetadataAccountData) {
|
||||
const response = await fetch(metadata.uri);
|
||||
const data = await response.json();
|
||||
return Object.values(data?.extensions ?? {}).filter((value: any) => value).length > 0;
|
||||
}
|
||||
}
|
||||
|
||||
54
filters/pool-filters.js
Normal file
54
filters/pool-filters.js
Normal file
@ -0,0 +1,54 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PoolFilters = void 0;
|
||||
const mpl_token_metadata_1 = require("@metaplex-foundation/mpl-token-metadata");
|
||||
const burn_filter_1 = require("./burn.filter");
|
||||
const mutable_filter_1 = require("./mutable.filter");
|
||||
const renounced_filter_1 = require("./renounced.filter");
|
||||
const pool_size_filter_1 = require("./pool-size.filter");
|
||||
const helpers_1 = require("../helpers");
|
||||
class PoolFilters {
|
||||
constructor(connection, args) {
|
||||
this.connection = connection;
|
||||
this.args = args;
|
||||
this.filters = [];
|
||||
if (helpers_1.CHECK_IF_BURNED) {
|
||||
this.filters.push(new burn_filter_1.BurnFilter(connection));
|
||||
}
|
||||
if (helpers_1.CHECK_IF_MINT_IS_RENOUNCED || helpers_1.CHECK_IF_FREEZABLE) {
|
||||
this.filters.push(new renounced_filter_1.RenouncedFreezeFilter(connection, helpers_1.CHECK_IF_MINT_IS_RENOUNCED, helpers_1.CHECK_IF_FREEZABLE));
|
||||
}
|
||||
if (helpers_1.CHECK_IF_MUTABLE || helpers_1.CHECK_IF_SOCIALS) {
|
||||
this.filters.push(new mutable_filter_1.MutableFilter(connection, (0, mpl_token_metadata_1.getMetadataAccountDataSerializer)(), helpers_1.CHECK_IF_MUTABLE, helpers_1.CHECK_IF_SOCIALS));
|
||||
}
|
||||
if (!args.minPoolSize.isZero() || !args.maxPoolSize.isZero()) {
|
||||
this.filters.push(new pool_size_filter_1.PoolSizeFilter(connection, args.quoteToken, args.minPoolSize, args.maxPoolSize));
|
||||
}
|
||||
}
|
||||
execute(poolKeys) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.filters.length === 0) {
|
||||
return true;
|
||||
}
|
||||
const result = yield Promise.all(this.filters.map((f) => f.execute(poolKeys)));
|
||||
const pass = result.every((r) => r.ok);
|
||||
if (pass) {
|
||||
return true;
|
||||
}
|
||||
for (const filterResult of result.filter((r) => !r.ok)) {
|
||||
helpers_1.logger.trace(filterResult.message);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.PoolFilters = PoolFilters;
|
||||
@ -1,67 +1,76 @@
|
||||
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, CHECK_IF_MUTABLE, CHECK_IF_SOCIALS, logger } from '../helpers';
|
||||
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,
|
||||
CHECK_IF_MUTABLE,
|
||||
CHECK_IF_SOCIALS,
|
||||
logger,
|
||||
} from "../helpers";
|
||||
|
||||
export interface Filter {
|
||||
execute(poolKeysV4: LiquidityPoolKeysV4): Promise<FilterResult>;
|
||||
execute(poolKeysV4: LiquidityPoolKeysV4): Promise<FilterResult>;
|
||||
}
|
||||
|
||||
export interface FilterResult {
|
||||
ok: boolean;
|
||||
message?: string;
|
||||
ok: boolean;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export interface PoolFilterArgs {
|
||||
minPoolSize: TokenAmount;
|
||||
maxPoolSize: TokenAmount;
|
||||
quoteToken: Token;
|
||||
minPoolSize: TokenAmount;
|
||||
maxPoolSize: TokenAmount;
|
||||
quoteToken: Token;
|
||||
}
|
||||
|
||||
export class PoolFilters {
|
||||
private readonly filters: Filter[] = [];
|
||||
private readonly filters: Filter[] = [];
|
||||
|
||||
constructor(
|
||||
readonly connection: Connection,
|
||||
readonly args: PoolFilterArgs,
|
||||
) {
|
||||
if (CHECK_IF_BURNED) {
|
||||
this.filters.push(new BurnFilter(connection));
|
||||
}
|
||||
constructor(
|
||||
readonly connection: Connection,
|
||||
readonly args: PoolFilterArgs,
|
||||
) {
|
||||
if (CHECK_IF_BURNED) {
|
||||
this.filters.push(new BurnFilter(connection));
|
||||
}
|
||||
|
||||
if (CHECK_IF_MINT_IS_RENOUNCED || CHECK_IF_FREEZABLE) {
|
||||
this.filters.push(new RenouncedFreezeFilter(connection, CHECK_IF_MINT_IS_RENOUNCED, CHECK_IF_FREEZABLE));
|
||||
}
|
||||
if (CHECK_IF_MINT_IS_RENOUNCED || CHECK_IF_FREEZABLE) {
|
||||
this.filters.push(new RenouncedFreezeFilter(connection, CHECK_IF_MINT_IS_RENOUNCED, CHECK_IF_FREEZABLE));
|
||||
}
|
||||
|
||||
if (CHECK_IF_MUTABLE || CHECK_IF_SOCIALS) {
|
||||
this.filters.push(new MutableFilter(connection, getMetadataAccountDataSerializer(), CHECK_IF_MUTABLE, CHECK_IF_SOCIALS));
|
||||
}
|
||||
if (CHECK_IF_MUTABLE || CHECK_IF_SOCIALS) {
|
||||
this.filters.push(
|
||||
new MutableFilter(connection, getMetadataAccountDataSerializer(), CHECK_IF_MUTABLE, CHECK_IF_SOCIALS),
|
||||
);
|
||||
}
|
||||
|
||||
if (!args.minPoolSize.isZero() || !args.maxPoolSize.isZero()) {
|
||||
this.filters.push(new PoolSizeFilter(connection, args.quoteToken, args.minPoolSize, args.maxPoolSize));
|
||||
}
|
||||
}
|
||||
if (!args.minPoolSize.isZero() || !args.maxPoolSize.isZero()) {
|
||||
this.filters.push(new PoolSizeFilter(connection, args.quoteToken, args.minPoolSize, args.maxPoolSize));
|
||||
}
|
||||
}
|
||||
|
||||
public async execute(poolKeys: LiquidityPoolKeysV4): Promise<boolean> {
|
||||
if (this.filters.length === 0) {
|
||||
return true;
|
||||
}
|
||||
public async execute(poolKeys: LiquidityPoolKeysV4): Promise<boolean> {
|
||||
if (this.filters.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const result = await Promise.all(this.filters.map((f) => f.execute(poolKeys)));
|
||||
const pass = result.every((r) => r.ok);
|
||||
const result = await Promise.all(this.filters.map((f) => f.execute(poolKeys)));
|
||||
const pass = result.every((r) => r.ok);
|
||||
|
||||
if (pass) {
|
||||
return true;
|
||||
}
|
||||
if (pass) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const filterResult of result.filter((r) => !r.ok)) {
|
||||
logger.trace(filterResult.message);
|
||||
}
|
||||
for (const filterResult of result.filter((r) => !r.ok)) {
|
||||
logger.trace(filterResult.message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
50
filters/pool-size.filter.js
Normal file
50
filters/pool-size.filter.js
Normal file
@ -0,0 +1,50 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PoolSizeFilter = void 0;
|
||||
const raydium_sdk_1 = require("@raydium-io/raydium-sdk");
|
||||
const helpers_1 = require("../helpers");
|
||||
class PoolSizeFilter {
|
||||
constructor(connection, quoteToken, minPoolSize, maxPoolSize) {
|
||||
this.connection = connection;
|
||||
this.quoteToken = quoteToken;
|
||||
this.minPoolSize = minPoolSize;
|
||||
this.maxPoolSize = maxPoolSize;
|
||||
}
|
||||
execute(poolKeys) {
|
||||
var _a, _b;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const response = yield this.connection.getTokenAccountBalance(poolKeys.quoteVault, this.connection.commitment);
|
||||
const poolSize = new raydium_sdk_1.TokenAmount(this.quoteToken, response.value.amount, true);
|
||||
let inRange = true;
|
||||
if (!((_a = this.maxPoolSize) === null || _a === void 0 ? void 0 : _a.isZero())) {
|
||||
inRange = poolSize.raw.lte(this.maxPoolSize.raw);
|
||||
if (!inRange) {
|
||||
return { ok: false, message: `PoolSize -> Pool size ${poolSize.toFixed()} > ${this.maxPoolSize.toFixed()}` };
|
||||
}
|
||||
}
|
||||
if (!((_b = this.minPoolSize) === null || _b === void 0 ? void 0 : _b.isZero())) {
|
||||
inRange = poolSize.raw.gte(this.minPoolSize.raw);
|
||||
if (!inRange) {
|
||||
return { ok: false, message: `PoolSize -> Pool size ${poolSize.toFixed()} < ${this.minPoolSize.toFixed()}` };
|
||||
}
|
||||
}
|
||||
return { ok: inRange };
|
||||
}
|
||||
catch (error) {
|
||||
helpers_1.logger.error({ mint: poolKeys.baseMint }, `Failed to check pool size`);
|
||||
}
|
||||
return { ok: false, message: "PoolSize -> Failed to check pool size" };
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.PoolSizeFilter = PoolSizeFilter;
|
||||
@ -1,43 +1,43 @@
|
||||
import { Filter, FilterResult } from './pool-filters';
|
||||
import { LiquidityPoolKeysV4, Token, TokenAmount } from '@raydium-io/raydium-sdk';
|
||||
import { Connection } from '@solana/web3.js';
|
||||
import { logger } from '../helpers';
|
||||
import { Filter, FilterResult } from "./pool-filters";
|
||||
import { LiquidityPoolKeysV4, Token, TokenAmount } from "@raydium-io/raydium-sdk";
|
||||
import { Connection } from "@solana/web3.js";
|
||||
import { logger } from "../helpers";
|
||||
|
||||
export class PoolSizeFilter implements Filter {
|
||||
constructor(
|
||||
private readonly connection: Connection,
|
||||
private readonly quoteToken: Token,
|
||||
private readonly minPoolSize: TokenAmount,
|
||||
private readonly maxPoolSize: TokenAmount,
|
||||
) {}
|
||||
constructor(
|
||||
private readonly connection: Connection,
|
||||
private readonly quoteToken: Token,
|
||||
private readonly minPoolSize: TokenAmount,
|
||||
private readonly maxPoolSize: TokenAmount,
|
||||
) {}
|
||||
|
||||
async execute(poolKeys: LiquidityPoolKeysV4): Promise<FilterResult> {
|
||||
try {
|
||||
const response = await this.connection.getTokenAccountBalance(poolKeys.quoteVault, this.connection.commitment);
|
||||
const poolSize = new TokenAmount(this.quoteToken, response.value.amount, true);
|
||||
let inRange = true;
|
||||
async execute(poolKeys: LiquidityPoolKeysV4): Promise<FilterResult> {
|
||||
try {
|
||||
const response = await this.connection.getTokenAccountBalance(poolKeys.quoteVault, this.connection.commitment);
|
||||
const poolSize = new TokenAmount(this.quoteToken, response.value.amount, true);
|
||||
let inRange = true;
|
||||
|
||||
if (!this.maxPoolSize?.isZero()) {
|
||||
inRange = poolSize.raw.lte(this.maxPoolSize.raw);
|
||||
if (!this.maxPoolSize?.isZero()) {
|
||||
inRange = poolSize.raw.lte(this.maxPoolSize.raw);
|
||||
|
||||
if (!inRange) {
|
||||
return { ok: false, message: `PoolSize -> Pool size ${poolSize.toFixed()} > ${this.maxPoolSize.toFixed()}` };
|
||||
}
|
||||
}
|
||||
if (!inRange) {
|
||||
return { ok: false, message: `PoolSize -> Pool size ${poolSize.toFixed()} > ${this.maxPoolSize.toFixed()}` };
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.minPoolSize?.isZero()) {
|
||||
inRange = poolSize.raw.gte(this.minPoolSize.raw);
|
||||
if (!this.minPoolSize?.isZero()) {
|
||||
inRange = poolSize.raw.gte(this.minPoolSize.raw);
|
||||
|
||||
if (!inRange) {
|
||||
return { ok: false, message: `PoolSize -> Pool size ${poolSize.toFixed()} < ${this.minPoolSize.toFixed()}` };
|
||||
}
|
||||
}
|
||||
if (!inRange) {
|
||||
return { ok: false, message: `PoolSize -> Pool size ${poolSize.toFixed()} < ${this.minPoolSize.toFixed()}` };
|
||||
}
|
||||
}
|
||||
|
||||
return { ok: inRange };
|
||||
} catch (error) {
|
||||
logger.error({ mint: poolKeys.baseMint }, `Failed to check pool size`);
|
||||
}
|
||||
return { ok: inRange };
|
||||
} catch (error) {
|
||||
logger.error({ mint: poolKeys.baseMint }, `Failed to check pool size`);
|
||||
}
|
||||
|
||||
return { ok: false, message: 'PoolSize -> Failed to check pool size' };
|
||||
}
|
||||
return { ok: false, message: "PoolSize -> Failed to check pool size" };
|
||||
}
|
||||
}
|
||||
|
||||
69
filters/renounced.filter.js
Normal file
69
filters/renounced.filter.js
Normal file
@ -0,0 +1,69 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RenouncedFreezeFilter = void 0;
|
||||
const spl_token_1 = require("@solana/spl-token");
|
||||
const helpers_1 = require("../helpers");
|
||||
class RenouncedFreezeFilter {
|
||||
constructor(connection, checkRenounced, checkFreezable) {
|
||||
this.connection = connection;
|
||||
this.checkRenounced = checkRenounced;
|
||||
this.checkFreezable = checkFreezable;
|
||||
this.errorMessage = [];
|
||||
this.cachedResult = undefined;
|
||||
if (this.checkRenounced) {
|
||||
this.errorMessage.push("mint");
|
||||
}
|
||||
if (this.checkFreezable) {
|
||||
this.errorMessage.push("freeze");
|
||||
}
|
||||
}
|
||||
execute(poolKeys) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this.cachedResult) {
|
||||
return this.cachedResult;
|
||||
}
|
||||
try {
|
||||
const accountInfo = yield this.connection.getAccountInfo(poolKeys.baseMint, this.connection.commitment);
|
||||
if (!(accountInfo === null || accountInfo === void 0 ? void 0 : accountInfo.data)) {
|
||||
return { ok: false, message: "RenouncedFreeze -> Failed to fetch account data" };
|
||||
}
|
||||
const deserialize = spl_token_1.MintLayout.decode(accountInfo.data);
|
||||
const renounced = !this.checkRenounced || deserialize.mintAuthorityOption === 0;
|
||||
const freezable = !this.checkFreezable || deserialize.freezeAuthorityOption !== 0;
|
||||
const ok = renounced && !freezable;
|
||||
const message = [];
|
||||
if (!renounced) {
|
||||
message.push("mint");
|
||||
}
|
||||
if (freezable) {
|
||||
message.push("freeze");
|
||||
}
|
||||
const result = {
|
||||
ok: ok,
|
||||
message: ok ? undefined : `RenouncedFreeze -> Creator can ${message.join(" and ")} tokens`,
|
||||
};
|
||||
if (result.ok) {
|
||||
this.cachedResult = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (e) {
|
||||
helpers_1.logger.error({ mint: poolKeys.baseMint }, `RenouncedFreeze -> Failed to check if creator can ${this.errorMessage.join(" and ")} tokens`);
|
||||
}
|
||||
return {
|
||||
ok: false,
|
||||
message: `RenouncedFreeze -> Failed to check if creator can ${this.errorMessage.join(" and ")} tokens`,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.RenouncedFreezeFilter = RenouncedFreezeFilter;
|
||||
@ -1,72 +1,72 @@
|
||||
import { Filter, FilterResult } from './pool-filters';
|
||||
import { MintLayout } from '@solana/spl-token';
|
||||
import { Connection } from '@solana/web3.js';
|
||||
import { LiquidityPoolKeysV4 } from '@raydium-io/raydium-sdk';
|
||||
import { logger } from '../helpers';
|
||||
import { Filter, FilterResult } from "./pool-filters";
|
||||
import { MintLayout } from "@solana/spl-token";
|
||||
import { Connection } from "@solana/web3.js";
|
||||
import { LiquidityPoolKeysV4 } from "@raydium-io/raydium-sdk";
|
||||
import { logger } from "../helpers";
|
||||
|
||||
export class RenouncedFreezeFilter implements Filter {
|
||||
private readonly errorMessage: string[] = [];
|
||||
private cachedResult: FilterResult | undefined = undefined;
|
||||
private readonly errorMessage: string[] = [];
|
||||
private cachedResult: FilterResult | undefined = undefined;
|
||||
|
||||
constructor(
|
||||
private readonly connection: Connection,
|
||||
private readonly checkRenounced: boolean,
|
||||
private readonly checkFreezable: boolean,
|
||||
) {
|
||||
if (this.checkRenounced) {
|
||||
this.errorMessage.push('mint');
|
||||
}
|
||||
constructor(
|
||||
private readonly connection: Connection,
|
||||
private readonly checkRenounced: boolean,
|
||||
private readonly checkFreezable: boolean,
|
||||
) {
|
||||
if (this.checkRenounced) {
|
||||
this.errorMessage.push("mint");
|
||||
}
|
||||
|
||||
if (this.checkFreezable) {
|
||||
this.errorMessage.push('freeze');
|
||||
}
|
||||
}
|
||||
if (this.checkFreezable) {
|
||||
this.errorMessage.push("freeze");
|
||||
}
|
||||
}
|
||||
|
||||
async execute(poolKeys: LiquidityPoolKeysV4): Promise<FilterResult> {
|
||||
if (this.cachedResult) {
|
||||
return this.cachedResult;
|
||||
}
|
||||
async execute(poolKeys: LiquidityPoolKeysV4): Promise<FilterResult> {
|
||||
if (this.cachedResult) {
|
||||
return this.cachedResult;
|
||||
}
|
||||
|
||||
try {
|
||||
const accountInfo = await this.connection.getAccountInfo(poolKeys.baseMint, this.connection.commitment);
|
||||
if (!accountInfo?.data) {
|
||||
return { ok: false, message: 'RenouncedFreeze -> Failed to fetch account data' };
|
||||
}
|
||||
try {
|
||||
const accountInfo = await this.connection.getAccountInfo(poolKeys.baseMint, this.connection.commitment);
|
||||
if (!accountInfo?.data) {
|
||||
return { ok: false, message: "RenouncedFreeze -> Failed to fetch account data" };
|
||||
}
|
||||
|
||||
const deserialize = MintLayout.decode(accountInfo.data);
|
||||
const renounced = !this.checkRenounced || deserialize.mintAuthorityOption === 0;
|
||||
const freezable = !this.checkFreezable || deserialize.freezeAuthorityOption !== 0;
|
||||
const ok = renounced && !freezable;
|
||||
const message: string[] = [];
|
||||
const deserialize = MintLayout.decode(accountInfo.data);
|
||||
const renounced = !this.checkRenounced || deserialize.mintAuthorityOption === 0;
|
||||
const freezable = !this.checkFreezable || deserialize.freezeAuthorityOption !== 0;
|
||||
const ok = renounced && !freezable;
|
||||
const message: string[] = [];
|
||||
|
||||
if (!renounced) {
|
||||
message.push('mint');
|
||||
}
|
||||
if (!renounced) {
|
||||
message.push("mint");
|
||||
}
|
||||
|
||||
if (freezable) {
|
||||
message.push('freeze');
|
||||
}
|
||||
if (freezable) {
|
||||
message.push("freeze");
|
||||
}
|
||||
|
||||
const result = {
|
||||
ok: ok,
|
||||
message: ok ? undefined : `RenouncedFreeze -> Creator can ${message.join(' and ')} tokens`,
|
||||
};
|
||||
const result = {
|
||||
ok: ok,
|
||||
message: ok ? undefined : `RenouncedFreeze -> Creator can ${message.join(" and ")} tokens`,
|
||||
};
|
||||
|
||||
if (result.ok) {
|
||||
this.cachedResult = result;
|
||||
}
|
||||
if (result.ok) {
|
||||
this.cachedResult = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (e) {
|
||||
logger.error(
|
||||
{ mint: poolKeys.baseMint },
|
||||
`RenouncedFreeze -> Failed to check if creator can ${this.errorMessage.join(' and ')} tokens`,
|
||||
);
|
||||
}
|
||||
return result;
|
||||
} catch (e) {
|
||||
logger.error(
|
||||
{ mint: poolKeys.baseMint },
|
||||
`RenouncedFreeze -> Failed to check if creator can ${this.errorMessage.join(" and ")} tokens`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
ok: false,
|
||||
message: `RenouncedFreeze -> Failed to check if creator can ${this.errorMessage.join(' and ')} tokens`,
|
||||
};
|
||||
}
|
||||
return {
|
||||
ok: false,
|
||||
message: `RenouncedFreeze -> Failed to check if creator can ${this.errorMessage.join(" and ")} tokens`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user