Skip to content

Commit

Permalink
fix: 🐛 Handle NFT holders in case of nft.controller_transfer
Browse files Browse the repository at this point in the history
In case of `ControllerTransfer` as the reason for `NFTPortfolioUpdate`
event, asset transaction entry was being made but NFTHolder set of
nft_ids was not getting updated. This handles the logic to  update the
NFTHolders
  • Loading branch information
prashantasdeveloper authored and quinndiggitypolymath committed Jan 18, 2024
1 parent 3dc0dd4 commit 1d738d1
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 18 deletions.
20 changes: 20 additions & 0 deletions db/migrations/4_add_extrinsic_for_issued_txs.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- for older blocks, the extrinsic_idx in asset_transactions was not being populated. We use the events table to update the value for `Issued` event
update
asset_transactions ast
set
extrinsic_idx = e.extrinsic_idx
from
events e
where
e.block_id = ast.created_block_id
and e.event_idx = ast.event_idx
and ast.extrinsic_idx is null
and e.extrinsic_idx is not null;

-- extrinsic_id mapping in events was not being populated correctly. We use the block_id and extrinsic_idx to update the missing values
update
events
set
extrinsic_id = block_id || '/' || extrinsic_idx
where
extrinsic_id is null;
9 changes: 8 additions & 1 deletion src/mappings/entities/mapAsset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,13 @@ const handleDivisibilityChanged = async (blockId: string, params: Codec[]): Prom
await asset.save();
};

const handleIssued = async ({ blockId, params, eventIdx, block }: HandlerArgs): Promise<void> => {
const handleIssued = async ({
blockId,
params,
eventIdx,
block,
extrinsic,
}: HandlerArgs): Promise<void> => {
const [, rawTicker, rawBeneficiaryDid, rawAmount, rawFundingRound, rawTotalFundingAmount] =
params;

Expand All @@ -304,6 +310,7 @@ const handleIssued = async ({ blockId, params, eventIdx, block }: HandlerArgs):
eventIdx,
amount: issuedAmount,
fundingRound,
extrinsicIdx: extrinsic?.idx,
datetime: block.timestamp,
createdBlockId: blockId,
updatedBlockId: blockId,
Expand Down
6 changes: 6 additions & 0 deletions src/mappings/entities/mapEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ export function handleToolingEvent(

const { claimExpiry, claimIssuer, claimScope, claimType } = extractClaimInfo(harvesterLikeArgs);

let extrinsicId: string;
if (extrinsic) {
extrinsicId = `${blockId}/${extrinsic?.idx}`;
}

return Event.create({
id: `${blockId}/${eventIdx}`,
blockId,
Expand All @@ -85,6 +90,7 @@ export function handleToolingEvent(
corporateActionTicker: extractCorporateActionTicker(harvesterLikeArgs),
fundraiserOfferingAsset: extractOfferingAsset(harvesterLikeArgs),
transferTo: extractTransferTo(harvesterLikeArgs),
extrinsicId,
});
}

Expand Down
38 changes: 21 additions & 17 deletions src/mappings/entities/mapNfts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,15 @@ const handleNftPortfolioUpdates = async (
const nftHolder = await getNftHolder(ticker, did, blockId);
nftHolder.nftIds.push(...ids);
promises.push(nftHolder.save());
} else if (reason === 'transferred') {
eventId = EventIdEnum.Transfer;
} else if (reason === 'redeemed') {
eventId = EventIdEnum.RedeemedNFT;
asset.totalSupply -= BigInt(ids.length);

const nftHolder = await getNftHolder(ticker, did, blockId);
nftHolder.nftIds = nftHolder.nftIds.filter(heldId => !ids.includes(heldId));
nftHolder.updatedBlockId = blockId;
promises.push(nftHolder.save());
} else if (reason === 'transferred' || reason === 'controllerTransfer') {
const [fromHolder, toHolder] = await Promise.all([
getNftHolder(ticker, fromDid, blockId),
getNftHolder(ticker, toDid, blockId),
Expand All @@ -105,21 +112,18 @@ const handleNftPortfolioUpdates = async (

asset.totalTransfers += BigInt(1);

const details = value as unknown as {
readonly instructionId: Option<u64>;
readonly instructionMemo: Option<U8aFixed>;
};

instructionId = getTextValue(details.instructionId);
instructionMemo = bytesToString(details.instructionMemo);
} else if (reason === 'redeemed') {
eventId = EventIdEnum.RedeemedNFT;
asset.totalSupply -= BigInt(ids.length);

const nftHolder = await getNftHolder(ticker, did, blockId);
nftHolder.nftIds = nftHolder.nftIds.filter(heldId => !ids.includes(heldId));
nftHolder.updatedBlockId = blockId;
promises.push(nftHolder.save());
if (reason === 'transferred') {
eventId = EventIdEnum.Transfer;
const details = value as unknown as {
readonly instructionId: Option<u64>;
readonly instructionMemo: Option<U8aFixed>;
};

instructionId = getTextValue(details.instructionId);
instructionMemo = bytesToString(details.instructionMemo);
} else {
eventId = EventIdEnum.ControllerTransfer;
}
}

promises.push(
Expand Down

0 comments on commit 1d738d1

Please sign in to comment.