@@ -665,10 +665,87 @@ const getAddressFromUncompressedPublicKey = (uncompressedPublicKey) => {
665665 const uncompressedPublicKey0xPrefix = ensure0x ( uncompressedPublicKeyWithoutCompressionPrefix ) ;
666666 const hash = keccak256 ( uncompressedPublicKey0xPrefix ) ;
667667 const hashWithout0xPrefix = removePrefix0x ( hash ) ;
668- const address = hashWithout0xPrefix . substring ( 24 , hash . length ) ;
668+ const address = hashWithout0xPrefix . substring ( 24 , hash . length ) ;
669669 return address ;
670670} ;
671671
672+ /**
673+ * Imports multiple private keys into the RSK transaction helper
674+ * @param {RskTransactionHelper } rskTxHelper
675+ * @param {string[] } privateKeys array of private keys to import
676+ * @returns {Promise<string[]> } array of imported addresses
677+ */
678+ const importAccounts = async ( rskTxHelper , privateKeys ) => {
679+ const importedAddresses = [ ] ;
680+ for ( const privateKey of privateKeys ) {
681+ const address = await rskTxHelper . importAccount ( privateKey ) ;
682+ importedAddresses . push ( address ) ;
683+ }
684+ return importedAddresses ;
685+ } ;
686+
687+ const decodeLogs = ( rskClient , txReceipt , contractAbi ) => {
688+ const eventSignatureMap = buildEventSignatureMap ( rskClient , contractAbi ) ;
689+ const events = [ ] ;
690+ for ( let log of txReceipt . logs ) {
691+ if ( log . topics . length === 0 ) {
692+ continue ;
693+ }
694+
695+ const eventSignature = log . topics [ 0 ] ;
696+ const abiElement = eventSignatureMap [ eventSignature ] ;
697+ if ( ! abiElement ) {
698+ continue ;
699+ }
700+ const event = decodeLog ( rskClient , log , abiElement ) ;
701+ events . push ( event ) ;
702+ }
703+ return events ;
704+ } ;
705+
706+ const buildEventSignatureMap = ( rskClient , contractAbi ) => {
707+ return contractAbi
708+ . flat ( )
709+ . filter ( ( element ) => element . type === "event" )
710+ . reduce ( ( acc , element ) => {
711+ const signature = rskClient . eth . abi . encodeEventSignature ( element ) ;
712+ acc [ signature ] = element ;
713+ return acc ;
714+ } , { } ) ;
715+ } ;
716+
717+ const decodeLog = ( rskClient , log , abiElement ) => {
718+ const decodedLog = rskClient . eth . abi . decodeLog ( abiElement . inputs , log . data , log . topics . slice ( 1 ) ) ;
719+
720+ const args = { } ;
721+ for ( let input of abiElement . inputs ) {
722+ args [ input . name ] = decodedLog [ input . name ] ;
723+ }
724+
725+ return {
726+ name : abiElement . name ,
727+ signature : log . topics [ 0 ] ,
728+ args : args ,
729+ } ;
730+ } ;
731+
732+ const assertContractCallFails = async ( methodCall , options ) => {
733+ await expect ( methodCall . call ( options ) ) . to . be . rejected ;
734+ } ;
735+
736+ const findEventInTx = async ( rskTxHelper , txHash , eventName , contractAbi = [ ] ) => {
737+ const rskClient = rskTxHelper . getClient ( ) ;
738+ // Fetch the transaction receipt to get all the logs (including the ones from internal txs)
739+ const txReceipt = await rskTxHelper . getTxReceipt ( txHash ) ;
740+ const events = decodeLogs ( rskClient , txReceipt , contractAbi ) ;
741+ return events . find ( ( event ) => event . name === eventName ) ;
742+ } ;
743+
744+ const assertNoEventWasEmitted = async ( txReceipt ) => {
745+ const isEmpty = Object . keys ( txReceipt . events ) . length === 0 ;
746+ expect ( isEmpty , "No event should have been emitted" ) . to . be . true ;
747+ } ;
748+
672749module . exports = {
673750 mineAndSync,
674751 waitForBlock,
@@ -697,4 +774,9 @@ module.exports = {
697774 compressPublicKey,
698775 waitForRskMempoolToGetThisCountOfAddSignatureTxs,
699776 waitForRskMempoolToGetThisCountOfRegisterBtcTx,
777+ importAccounts,
778+ decodeLogs,
779+ assertContractCallFails,
780+ findEventInTx,
781+ assertNoEventWasEmitted,
700782} ;
0 commit comments