UNPKG

@bsv/overlay-express

Version:
78 lines 3.17 kB
import { PushDrop, Utils } from '@bsv/sdk'; /** * Wraps a SHIP or SLAP LookupService to intercept outputAdmittedByTopic calls * and block outputs whose domain or outpoint appears in the persistent ban list. * * This prevents GASP from re-syncing stale or banned tokens that were previously * removed by the Janitor or an admin. */ export class BanAwareLookupWrapper { wrapped; banService; protocol; logger; admissionMode; spendNotificationMode; constructor(wrapped, banService, protocol, logger = console) { this.wrapped = wrapped; this.banService = banService; this.protocol = protocol; this.logger = logger; this.admissionMode = wrapped.admissionMode; this.spendNotificationMode = wrapped.spendNotificationMode; } /** * Intercepts admission to check the ban list before delegating to the wrapped service. * If the output's domain or outpoint is banned, the admission is silently blocked. */ async outputAdmittedByTopic(payload) { if (payload.mode === 'locking-script') { const { txid, outputIndex, lockingScript } = payload; // Check if the specific outpoint is banned if (await this.banService.isOutpointBanned(txid, outputIndex)) { this.logger.log(`[BAN] Blocked banned outpoint ${txid}.${outputIndex} from ${this.protocol}`); return; } // Try to parse the domain from PushDrop fields and check domain ban try { const result = PushDrop.decode(lockingScript); if (result.fields.length >= 3) { const domain = Utils.toUTF8(result.fields[2]); if (await this.banService.isDomainBanned(domain)) { this.logger.log(`[BAN] Blocked banned domain ${domain} from ${this.protocol} (${txid}.${outputIndex})`); return; } } } catch { // If we can't parse PushDrop fields, let it through to the wrapped service // which will apply its own validation } } // Delegate to the wrapped service return await this.wrapped.outputAdmittedByTopic(payload); } async outputSpent(payload) { if (typeof this.wrapped.outputSpent === 'function') { return await this.wrapped.outputSpent(payload); } } async outputNoLongerRetainedInHistory(txid, outputIndex, topic) { if (typeof this.wrapped.outputNoLongerRetainedInHistory === 'function') { return await this.wrapped.outputNoLongerRetainedInHistory(txid, outputIndex, topic); } } async outputEvicted(txid, outputIndex) { return await this.wrapped.outputEvicted(txid, outputIndex); } async lookup(question) { return await this.wrapped.lookup(question); } async getDocumentation() { return await this.wrapped.getDocumentation(); } async getMetaData() { return await this.wrapped.getMetaData(); } } //# sourceMappingURL=BanAwareLookupWrapper.js.map