From 8335c98d1975c5155e4ef8dbf10bded5248eb310 Mon Sep 17 00:00:00 2001 From: Filip Dunder Date: Sat, 27 Apr 2024 13:56:43 +0200 Subject: [PATCH 1/2] filter cleanup --- filters/mutable.filter.ts | 51 +++++++++++++++++++++++++++---------- filters/renounced.filter.ts | 38 ++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/filters/mutable.filter.ts b/filters/mutable.filter.ts index 52f370f..cccdadb 100644 --- a/filters/mutable.filter.ts +++ b/filters/mutable.filter.ts @@ -7,37 +7,60 @@ 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, private readonly checkMutable: boolean, private readonly checkSocials: boolean) {} + private readonly errorMessage: string[] = []; + + constructor( + private readonly connection: Connection, + private readonly metadataSerializer: Serializer, + private readonly checkMutable: boolean, + private readonly checkSocials: boolean, + ) { + if (this.checkMutable) { + this.errorMessage.push('mutable'); + } + + if (this.checkSocials) { + this.errorMessage.push('socials'); + } + } async execute(poolKeys: LiquidityPoolKeysV4): Promise { - const errorMessage = [ this.checkMutable ? 'mutable' : undefined, this.checkSocials ? 'socials' : undefined ].filter((e) => e !== undefined); try { const metadataPDA = getPdaMetadataKey(poolKeys.baseMint); - const metadataAccount = await this.connection.getAccountInfo(metadataPDA.publicKey); + const metadataAccount = await this.connection.getAccountInfo(metadataPDA.publicKey, this.connection.commitment); + 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: false; - - const hasSocials = this.checkSocials ? (Object.values(await this.getSocials(deserialize[0])).some((value: any) => value !== null && value.length > 0)) === true: true; - - const message = [ !mutable ? undefined : 'metadata can be changed', hasSocials ? undefined : 'has no socials' ].filter((e) => e !== undefined); + 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 (!hasSocials) { + message.push('has no socials'); + } return { ok: ok, message: ok ? undefined : `MutableSocials -> Token ${message.join(' and ')}` }; } catch (e) { - logger.error({ mint: poolKeys.baseMint, error: e }, `MutableSocials -> Failed to check ${errorMessage.join(' and ')}`); - return { ok: false, message: `MutableSocials -> Failed to check ${errorMessage.join(' and ')}` }; + logger.error({ mint: poolKeys.baseMint }, `MutableSocials -> Failed to check ${this.errorMessage.join(' and ')}`); } - logger.error({ mint: poolKeys.baseMint }, `MutableSocials -> Failed to check ${errorMessage.join(' and ')}`); - return { ok: false, message: `MutableSocials -> Failed to check ${errorMessage.join(' and ')}` }; + return { + ok: false, + message: `MutableSocials -> Failed to check ${this.errorMessage.join(' and ')}`, + }; } - async getSocials(metadata: MetadataAccountData): Promise { + private async hasSocials(metadata: MetadataAccountData) { const response = await fetch(metadata.uri); const data = await response.json(); - return data?.extensions; + return Object.values(data?.extensions ?? {}).some((value: any) => value !== null && value.length > 0); } } diff --git a/filters/renounced.filter.ts b/filters/renounced.filter.ts index b18ecbb..1894094 100644 --- a/filters/renounced.filter.ts +++ b/filters/renounced.filter.ts @@ -5,10 +5,23 @@ import { LiquidityPoolKeysV4 } from '@raydium-io/raydium-sdk'; import { logger } from '../helpers'; export class RenouncedFreezeFilter implements Filter { - constructor(private readonly connection: Connection, private readonly checkRenounced: boolean, private readonly checkFreezable: boolean) {} + private readonly errorMessage: string[] = []; + + 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'); + } + } async execute(poolKeys: LiquidityPoolKeysV4): Promise { - const errorMessage = [ this.checkRenounced ? 'mint' : undefined, this.checkFreezable ? 'freeze' : undefined ].filter((e) => e !== undefined); try { const accountInfo = await this.connection.getAccountInfo(poolKeys.baseMint, this.connection.commitment); if (!accountInfo?.data) { @@ -18,15 +31,28 @@ export class RenouncedFreezeFilter implements Filter { const deserialize = MintLayout.decode(accountInfo.data); const renounced = !this.checkRenounced || deserialize.mintAuthorityOption === 0; const freezable = !this.checkFreezable || deserialize.freezeAuthorityOption !== 0; - - const message = [ renounced ? undefined : 'mint', !freezable ? undefined : 'freeze' ].filter((e) => e !== undefined); const ok = renounced && !freezable; + const message: string[] = []; + + if (!renounced) { + message.push('mint'); + } + + if (freezable) { + message.push('freeze'); + } return { ok: ok, message: ok ? undefined : `RenouncedFreeze -> Creator can ${message.join(' and ')} tokens` }; } catch (e) { - logger.error({ mint: poolKeys.baseMint }, `RenouncedFreeze -> Failed to check if creator can ${errorMessage.join(' and ')} tokens`); + 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 ${errorMessage.join(' and ')} tokens` }; + return { + ok: false, + message: `RenouncedFreeze -> Failed to check if creator can ${this.errorMessage.join(' and ')} tokens`, + }; } } From c76a5d3065d73fb94b1dbc4bce525c74518a14fb Mon Sep 17 00:00:00 2001 From: Filip Dunder Date: Sat, 27 Apr 2024 14:08:08 +0200 Subject: [PATCH 2/2] lint --- transactions/jito-rpc-transaction-executor.ts | 2 +- transactions/warp-transaction-executor.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/transactions/jito-rpc-transaction-executor.ts b/transactions/jito-rpc-transaction-executor.ts index bcb8da1..cac2739 100644 --- a/transactions/jito-rpc-transaction-executor.ts +++ b/transactions/jito-rpc-transaction-executor.ts @@ -44,7 +44,7 @@ export class JitoTransactionExecutor implements TransactionExecutor { transaction: VersionedTransaction, payer: Keypair, latestBlockhash: BlockhashWithExpiryBlockHeight, - ): Promise<{ confirmed: boolean; signature?: string }> { + ): Promise<{ confirmed: boolean; signature?: string; error?: string }> { logger.debug('Starting Jito transaction execution...'); this.JitoFeeWallet = this.getRandomValidatorKey(); // Update wallet key each execution logger.trace(`Selected Jito fee wallet: ${this.JitoFeeWallet.toBase58()}`); diff --git a/transactions/warp-transaction-executor.ts b/transactions/warp-transaction-executor.ts index da4245f..be26786 100644 --- a/transactions/warp-transaction-executor.ts +++ b/transactions/warp-transaction-executor.ts @@ -21,7 +21,7 @@ export class WarpTransactionExecutor implements TransactionExecutor { transaction: VersionedTransaction, payer: Keypair, latestBlockhash: BlockhashWithExpiryBlockHeight, - ): Promise<{ confirmed: boolean; signature?: string }> { + ): Promise<{ confirmed: boolean; signature?: string; error?: string }> { logger.debug('Executing transaction...'); try { @@ -41,7 +41,7 @@ export class WarpTransactionExecutor implements TransactionExecutor { const warpFeeTx = new VersionedTransaction(warpFeeMessage); warpFeeTx.sign([payer]); - const response = await axios.post<{ confirmed: boolean; signature: string, error?: string }>( + const response = await axios.post<{ confirmed: boolean; signature: string; error?: string }>( 'https://tx.warp.id/transaction/execute', { transactions: [bs58.encode(warpFeeTx.serialize()), bs58.encode(transaction.serialize())],