@@ -9,12 +9,10 @@ import { StacksEvent, StacksPayload } from '@hirosystems/chainhook-client';
99import { ENV } from '../../env' ;
1010import {
1111 NftMintEvent ,
12- SftMintEvent ,
1312 SmartContractDeployment ,
1413 TokenMetadataUpdateNotification ,
1514} from '../../token-processor/util/sip-validation' ;
16- import { ContractNotFoundError } from '../errors' ;
17- import { DbJob , DbSipNumber , DbSmartContractInsert , DbTokenType , DbSmartContract } from '../types' ;
15+ import { DbSmartContractInsert , DbTokenType , DbSmartContract } from '../types' ;
1816import { BlockCache , CachedEvent } from './block-cache' ;
1917import { dbSipNumberToDbTokenType } from '../../token-processor/util/helpers' ;
2018import BigNumber from 'bignumber.js' ;
@@ -322,25 +320,30 @@ export class ChainhookPgStore extends BasePgStoreModule {
322320 ) : Promise < void > {
323321 if ( mints . length == 0 ) return ;
324322 for await ( const batch of batchIterate ( mints , 500 ) ) {
325- const values = batch . map ( m => {
323+ const tokenValues = new Map < string , ( string | number ) [ ] > ( ) ;
324+ for ( const m of batch ) {
325+ // SFT tokens may mint one single token more than once given that it's an FT within an NFT.
326+ // This makes sure we only keep the first occurrence.
327+ const tokenKey = `${ m . event . contractId } -${ m . event . tokenId } ` ;
328+ if ( tokenValues . has ( tokenKey ) ) continue ;
326329 logger . info (
327330 `ChainhookPgStore apply ${ tokenType . toUpperCase ( ) } mint ${ m . event . contractId } (${
328331 m . event . tokenId
329332 } ) at block ${ cache . block . index } `
330333 ) ;
331- return [
334+ tokenValues . set ( tokenKey , [
332335 m . event . contractId ,
333336 tokenType ,
334337 m . event . tokenId . toString ( ) ,
335338 cache . block . index ,
336339 cache . block . hash ,
337340 m . tx_id ,
338341 m . tx_index ,
339- ] ;
340- } ) ;
342+ ] ) ;
343+ }
341344 await sql `
342345 WITH insert_values (principal, type, token_number, block_height, index_block_hash, tx_id,
343- tx_index) AS (VALUES ${ sql ( values ) } ),
346+ tx_index) AS (VALUES ${ sql ( [ ... tokenValues . values ( ) ] ) } ),
344347 filtered_values AS (
345348 SELECT s.id AS smart_contract_id, i.type::token_type, i.token_number::bigint,
346349 i.block_height::bigint, i.index_block_hash::text, i.tx_id::text, i.tx_index::int
0 commit comments