Support p2pk track-address websocket subscriptions
This commit is contained in:
		
							parent
							
								
									395f47516a
								
							
						
					
					
						commit
						74b87b6006
					
				@ -3,6 +3,7 @@ import { IEsploraApi } from './bitcoin/esplora-api.interface';
 | 
			
		||||
import { Common } from './common';
 | 
			
		||||
import bitcoinApi, { bitcoinCoreApi } from './bitcoin/bitcoin-api-factory';
 | 
			
		||||
import * as bitcoinjs from 'bitcoinjs-lib';
 | 
			
		||||
import crypto from 'node:crypto';
 | 
			
		||||
 | 
			
		||||
class TransactionUtils {
 | 
			
		||||
  constructor() { }
 | 
			
		||||
@ -170,6 +171,14 @@ class TransactionUtils {
 | 
			
		||||
      16
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public calcScriptHash(script: string): string {
 | 
			
		||||
    if (!/^[0-9a-fA-F]*$/.test(script) || script.length % 2 !== 0) {
 | 
			
		||||
      throw new Error('script is not a valid hex string');
 | 
			
		||||
    }
 | 
			
		||||
    const buf = Buffer.from(script, 'hex');
 | 
			
		||||
    return crypto.createHash('sha256').update(buf).digest('hex');
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default new TransactionUtils();
 | 
			
		||||
 | 
			
		||||
@ -183,15 +183,22 @@ class WebsocketHandler {
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (parsedMessage && parsedMessage['track-address']) {
 | 
			
		||||
            if (/^([a-km-zA-HJ-NP-Z1-9]{26,35}|[a-km-zA-HJ-NP-Z1-9]{80}|[a-z]{2,5}1[ac-hj-np-z02-9]{8,100}|[A-Z]{2,5}1[AC-HJ-NP-Z02-9]{8,100})$/
 | 
			
		||||
            if (/^([a-km-zA-HJ-NP-Z1-9]{26,35}|[a-km-zA-HJ-NP-Z1-9]{80}|[a-z]{2,5}1[ac-hj-np-z02-9]{8,100}|[A-Z]{2,5}1[AC-HJ-NP-Z02-9]{8,100}|[0-9a-fA-F]{130})$/
 | 
			
		||||
              .test(parsedMessage['track-address'])) {
 | 
			
		||||
              let matchedAddress = parsedMessage['track-address'];
 | 
			
		||||
              if (/^[A-Z]{2,5}1[AC-HJ-NP-Z02-9]{8,100}$/.test(parsedMessage['track-address'])) {
 | 
			
		||||
                matchedAddress = matchedAddress.toLowerCase();
 | 
			
		||||
              }
 | 
			
		||||
              client['track-address'] = matchedAddress;
 | 
			
		||||
              if (/^[0-9a-fA-F]{130}$/.test(parsedMessage['track-address'])) {
 | 
			
		||||
                client['track-address'] = null;
 | 
			
		||||
                client['track-scripthash'] = transactionUtils.calcScriptHash('41' + matchedAddress + 'ac');
 | 
			
		||||
              } else {
 | 
			
		||||
                client['track-address'] = matchedAddress;
 | 
			
		||||
                client['track-scripthash'] = null;
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              client['track-address'] = null;
 | 
			
		||||
              client['track-scripthash'] = null;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
@ -546,6 +553,44 @@ class WebsocketHandler {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (client['track-scripthash']) {
 | 
			
		||||
        const foundTransactions: TransactionExtended[] = [];
 | 
			
		||||
 | 
			
		||||
        for (const tx of newTransactions) {
 | 
			
		||||
          const someVin = tx.vin.some((vin) => !!vin.prevout && vin.prevout.scriptpubkey_type === 'p2pk' && vin.prevout.scriptpubkey === client['track-scripthash']);
 | 
			
		||||
          if (someVin) {
 | 
			
		||||
            if (config.MEMPOOL.BACKEND !== 'esplora') {
 | 
			
		||||
              try {
 | 
			
		||||
                const fullTx = await transactionUtils.$getMempoolTransactionExtended(tx.txid, true);
 | 
			
		||||
                foundTransactions.push(fullTx);
 | 
			
		||||
              } catch (e) {
 | 
			
		||||
                logger.debug('Error finding transaction in mempool: ' + (e instanceof Error ? e.message : e));
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              foundTransactions.push(tx);
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          const someVout = tx.vout.some((vout) => vout.scriptpubkey_type === 'p2pk' && vout.scriptpubkey === client['track-scripthash']);
 | 
			
		||||
          if (someVout) {
 | 
			
		||||
            if (config.MEMPOOL.BACKEND !== 'esplora') {
 | 
			
		||||
              try {
 | 
			
		||||
                const fullTx = await transactionUtils.$getMempoolTransactionExtended(tx.txid, true);
 | 
			
		||||
                foundTransactions.push(fullTx);
 | 
			
		||||
              } catch (e) {
 | 
			
		||||
                logger.debug('Error finding transaction in mempool: ' + (e instanceof Error ? e.message : e));
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              foundTransactions.push(tx);
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (foundTransactions.length) {
 | 
			
		||||
          response['address-transactions'] = JSON.stringify(foundTransactions);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (client['track-asset']) {
 | 
			
		||||
        const foundTransactions: TransactionExtended[] = [];
 | 
			
		||||
 | 
			
		||||
@ -821,6 +866,33 @@ class WebsocketHandler {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (client['track-scripthash']) {
 | 
			
		||||
        const foundTransactions: TransactionExtended[] = [];
 | 
			
		||||
 | 
			
		||||
        transactions.forEach((tx) => {
 | 
			
		||||
          if (tx.vin && tx.vin.some((vin) => !!vin.prevout && vin.prevout.scriptpubkey_type === 'p2pk' && vin.prevout.scriptpubkey === client['track-scripthash'])) {
 | 
			
		||||
            foundTransactions.push(tx);
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          if (tx.vout && tx.vout.some((vout) => vout.scriptpubkey_type === 'p2pk' && vout.scriptpubkey === client['track-scripthash'])) {
 | 
			
		||||
            foundTransactions.push(tx);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (foundTransactions.length) {
 | 
			
		||||
          foundTransactions.forEach((tx) => {
 | 
			
		||||
            tx.status = {
 | 
			
		||||
              confirmed: true,
 | 
			
		||||
              block_height: block.height,
 | 
			
		||||
              block_hash: block.id,
 | 
			
		||||
              block_time: block.timestamp,
 | 
			
		||||
            };
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          response['block-transactions'] = JSON.stringify(foundTransactions);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (client['track-asset']) {
 | 
			
		||||
        const foundTransactions: TransactionExtended[] = [];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user