# Zaap Subgraph ## diagram ![](https://i.imgur.com/4HQXxIQ.jpg) ``` proxy admin: 0xc738876019b4680fd8708831f90d0d47abf884cd zaap ERC721 Factory Impl: 0xe90e34323eb273fe518ff2d458b68521ef6eebb6 zaap ERC721 Factory Proxy: 0x63ce7eb9253038a3409835ae763d5c7f43d3ec50 zaap ERC721 Impl: 0xba9f130e6fd3e6ea24f880be98e4c4f9c60bf251 zaap Minter Factory Impl: 0xc12f0aaa2562ca2e639e090d511d6dc0b1acd46b zaap Minter Factory Proxy: 0xf8b705436fcdf1cde5663cd5bf089fdb57e4122b whitelist minter impl: 0x8f5f793097763c3da4b068270ceb6f0265bb7d37 raffle minter impl: 0xc0cb78d222299b28ac38b4d40132553380d236a4 public minter impl: 0x6fd18c1f46835e1f44b8381f5ec36e30d3a6ba3c zaap deployer: 0x0b4b996dbfc1cc12d20b180d4c974fe98573dd41 deployed nft: 0x5542fbf8c242084ff6bce757fdbf5e03c1752672 whitelist minter: 0xd73c0e6eb8997c84983b9f6a2257e2052ffa604e raffle minter: 0x6a156b3a2af62faec4e260891e295c6a7fbcf512 public minter: 0x51539ab152aeeaf0624379da06646e554b3220f2 ``` ## Schema ```graphql= type Minter @entity { "Minter address" id: ID! "Minter contract implementation address" implementation: Bytes! "Owner (Artist)" owner: Bytes! "Collection" collection: Collection "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } type Collection @entity { "ZaapERC721 address" id: ID! "List of minter contracts" minters: [Minter!]! @derivedFrom(field: "collection") "List of minter contracts that are whitelisted to mint NFTs " minterRoles: [Bytes!]! "ERC721 implementation address" implementation: Bytes! "Owner (Artist)" owner: Bytes! "Public price" publicPrice: BigInt! "List of collection's tokens" tokens: [Token!]! @derivedFrom(field: "collection") "Total supply of collection" totalSupply: BigInt! "Total sale amount (in ETH)" totalSaleAmount: BigInt! "Total sale amount only from minters (in ETH)" totalSaleAmountFromMinters: BigInt! "Mint transactions for ZaapERC721" erc721MintTransactions: [ERC721MintTransaction!]! @derivedFrom(field: "collection") "Mint transactions for ZaapMinter" minterMintTransactions: [MinterMintTransaction!]! @derivedFrom(field: "collection") "Withdraw ETH transactions" withdrawETHTransactions: [WithdrawETHTransaction!]! @derivedFrom(field: "collection") "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } type Token @entity { "ID {collectionAddress}-{tokenId}" id: ID! "Collection info" collection: Collection! "Token id" tokenID: BigInt! "Token URI" tokenURI: String "Owner (User's account)" owner: Owner! "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } """ Users """ type Owner @entity { "Owner address" id: ID! "List of Tokens" tokens: [Token!]! @derivedFrom(field: "owner") "Total tokens" totalTokens: BigInt! "Total tokens minted by owner" totalTokensMinted: BigInt! "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } type Artist @entity { "Artist address" id: ID! "Amount claimed (in ETH)" claimedAmount: BigInt! "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } """ Transactions """ type WithdrawETHTransaction @entity { "ID" id: ID! "Date (timestamp)" date: BigInt! "Block number" block: BigInt! "Collection" collection: Collection! "Receiver (Artist)" receiver: Bytes! "Fee receiver" feeReceiver: Bytes! "Amount (in ETH)" amount: BigInt! "Fee" fee: BigInt! } type ERC721MintTransaction @entity { "ID" id: ID! "Date (timestamp)" date: BigInt! "Block number" block: BigInt! "Collection" collection: Collection! "Price per NFT (in ETH)" price: BigInt! "NFT amount" nftAmount: BigInt! "Amount transfered (in ETH) -> nftAmount * price" amount: BigInt! "Buyer" buyer: Bytes! } type MinterMintTransaction @entity { "ID" id: ID! "Date (timestamp)" date: BigInt! "Block number" block: BigInt! "Collection" collection: Collection! "Price per NFT (in ETH)" price: BigInt! "NFT amount" nftAmount: BigInt! "Amount transfered (in ETH) -> nftAmount * price" amount: BigInt! "Buyer" buyer: Bytes! "Minter" minter: Minter! } """ Minters """ enum MintStatus { INACTIVE ACTIVE } type WhitelistMinter @entity { "ID" id: ID! "Price" price: BigInt! "Mint status" mintStatus: MintStatus! "Mint supply" mintSupply: BigInt! "Start timestamp" startTimestamp: BigInt! "End timestamp" endTimestamp: BigInt! "Total sale amount (in ETH)" totalSaleAmount: BigInt! "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } type RaffleMinter @entity { "ID" id: ID! "Price" price: BigInt! "Mint status" mintStatus: MintStatus! "Mint supply" mintSupply: BigInt! "Start timestamp" startTimestamp: BigInt! "End timestamp" endTimestamp: BigInt! "Register start timestamp" registerStartTimestamp: BigInt! "Register end timestamp" registerEndTimestamp: BigInt! "Total sale amount (in ETH)" totalSaleAmount: BigInt! "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } type PublicMinter @entity { "ID" id: ID! "Price" price: BigInt! "Mint status" mintStatus: MintStatus! "Mint supply" mintSupply: BigInt! "Start timestamp" startTimestamp: BigInt! "End timestamp" endTimestamp: BigInt! "Total sale amount (in ETH)" totalSaleAmount: BigInt! "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } ``` new updated schema (updated 28/6/2022 18.31) ```graphql= type Minter @entity { "Minter address" id: ID! "Minter contract implementation address" implementation: Bytes! "Owner (Artist)" owner: Bytes! "Collection" collection: Collection "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } type Collection @entity { "ZaapERC721 address" id: ID! "Base URI" baseURI: String! "List of minter contracts that reference this collection" minters: [Minter!]! @derivedFrom(field: "collection") "List of minter contracts that are whitelisted to mint NFTs " whitelistedMinters: [Bytes!]! "ERC721 implementation address" implementation: Bytes! "Owner (Artist)" owner: Bytes! "Public price" publicPrice: BigInt! "Total supply of collection" totalSupply: BigInt! "Total sale amount (in ETH)" totalSaleAmount: BigInt! "Total sale amount only from minters (in ETH)" totalSaleAmountFromMinters: BigInt! "List of collection's tokens" tokens: [Token!]! @derivedFrom(field: "collection") "Mint transactions" mintTransactions: [MintTransaction!]! @derivedFrom(field: "collection") "Withdraw ETH transactions" withdrawETHTransactions: [WithdrawETHTransaction!]! @derivedFrom(field: "collection") "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } type Token @entity { "ID {collectionAddress}-{tokenId}" id: ID! "Collection info" collection: Collection! "Token id" tokenID: BigInt! "Owner (User's account)" owner: Owner! "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } """ Users """ type Owner @entity { "Owner address" id: ID! "List of Tokens" tokens: [Token!]! @derivedFrom(field: "owner") "Total tokens" totalTokens: BigInt! "Total tokens minted by owner" totalTokensMinted: BigInt! "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } type Artist @entity { "Artist address" id: ID! "Amount claimed (in ETH)" claimedAmount: BigInt! "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } """ Transactions """ type WithdrawETHTransaction @entity { "{txHash}-{logIndex}" id: ID! "Date (timestamp)" date: BigInt! "Block number" block: BigInt! "Collection" collection: Collection! "Receiver (Artist)" receiver: Bytes! "Fee receiver" feeReceiver: Bytes! "Amount (in ETH)" amount: BigInt! "Fee" fee: BigInt! } type MintTransaction @entity { "{txHash}-{logIndex}" id: ID! "Date (timestamp)" date: BigInt! "Block number" block: BigInt! "Collection" collection: Collection! "Price per NFT (in ETH)" price: BigInt! "NFT amount" nftAmount: BigInt! "Amount transfered (in ETH) -> nftAmount * price" amount: BigInt! "Buyer" buyer: Bytes! "Minter" minter: Minter } """ Minters """ enum MintStatus { INACTIVE ACTIVE } type WhitelistMinter @entity { "ID" id: ID! "Price" price: BigInt! "Mint status" mintStatus: MintStatus! "Mint supply" mintSupply: BigInt! "Start timestamp" startTimestamp: BigInt! "End timestamp" endTimestamp: BigInt! "Total sale amount (in ETH)" totalSaleAmount: BigInt! "Minter" minter: Minter! "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } type RaffleMinter @entity { "ID" id: ID! "Price" price: BigInt! "Mint status" mintStatus: MintStatus! "Mint supply" mintSupply: BigInt! "Start timestamp" startTimestamp: BigInt! "End timestamp" endTimestamp: BigInt! "Register start timestamp" registerStartTimestamp: BigInt! "Register end timestamp" registerEndTimestamp: BigInt! "Total sale amount (in ETH)" totalSaleAmount: BigInt! "Minter" minter: Minter! "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } type PublicMinter @entity { "ID" id: ID! "Price" price: BigInt! "Mint status" mintStatus: MintStatus! "Mint supply" mintSupply: BigInt! "Start timestamp" startTimestamp: BigInt! "End timestamp" endTimestamp: BigInt! "Total sale amount (in ETH)" totalSaleAmount: BigInt! "Minter" minter: Minter! "Block number" block: BigInt! "Created At" createdAt: BigInt! "Updated At" updatedAt: BigInt! } ``` ## ZaapERC721Factory - handleCreateCollection ```solidity= event CreateCollection(address indexed collection, bytes32 salt, address implementation) ``` ```javascript= let collection = getOrCreateCollection(event.params.collection.toHexString()); collection.implementation = event.params.implementation; ZaapERC721Template.create(event.params.collection); collection.block = event.block.number; collection.createdAt = event.block.timestamp; collection.updatedAt = event.block.timestamp; collection.save(); ``` ## ZaapERC721 - handleRoleGranted (updated 28/6/2022 18.31) ```solidity= event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); ``` ```javascript= // load prev collection let collection = getOrCreateCollection(event.address.toHexString()); // add new adddress that added to minter roles if not let minterRoles = collection.whitelistedMinters; for (let i = 0; i < collection.whitelistedMinters.length; i++) { if (collection.whitelistedMinters[i] === event.params.account) { return; } } minterRoles.push(event.params.account); collection.whitelistedMinters = minterRoles; collection.updatedAt = event.block.timestamp; collection.save(); ``` - handleRoleRevoked (updated 28/6/2022 18.31) ```solidity= event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); ``` ```javascript= // check if it is minter_role if (MINTER_ROLE !== event.params.role.toHexString().toLowerCase()) { log.debug("not minter role.", []); return; } // load prev collection let collection = getOrCreateCollection(event.address.toHexString()); let minterRoles: Bytes[] = []; for (let i = 0; i < collection.whitelistedMinters.length; i++) { if (event.params.account !== collection.whitelistedMinters[i]) { minterRoles.push(collection.whitelistedMinters[i]); } } collection.whitelistedMinters = minterRoles; collection.updatedAt = event.block.timestamp; collection.save(); ``` - handleOwnershipTransferred ```solidity= event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); ``` ```javascript= let collection = getOrCreateCollection(event.address.toHexString()); // set collection owner collection.owner = event.params.newOwner; collection.updatedAt = event.block.timestamp; collection.save(); ``` - handlePublicMint (updated 29/6/2022 15.19) ```solidity= event PublicMint(address indexed minter, uint amount); ``` ```javascript= // update collection let collection = getOrCreateCollection( event.address.toHex(), event.block.number, event.block.timestamp ); let saleAmount = event.params.amount.times(collection.publicPrice); collection.totalSaleAmount = collection.totalSaleAmount.plus(saleAmount); collection.updatedAt = event.block.timestamp; collection.save(); // create new tranaction let transaction = getOrCreateMintTransaction( event.transaction.hash.toHexString() + "-" + event.logIndex.toString() ); transaction.date = event.block.timestamp; transaction.block = event.block.number; transaction.collection = collection.id; transaction.price = collection.publicPrice; transaction.nftAmount = event.params.amount; transaction.amount = saleAmount; transaction.buyer = event.params.minter; transaction.save(); ``` - handleTransfer (updated 28/6/2022 18.31) ```solidity= event Transfer(address indexed from, address indexed to, uint256 indexed tokenId) ``` ```javascript= let collection = getOrCreateCollection(event.address.toHex()); if (collection.createdAt.notEqual(BigInt.zero())) { collection.block = event.block.number; collection.createdAt = event.block.timestamp; } collection.updatedAt = event.block.timestamp; collection.save(); let fromId = event.params.from.toHex(); let from = getOrCreateOwner(fromId); from.totalTokens = event.params.from.equals(Address.zero()) ? from.totalTokens : from.totalTokens.minus(BigInt.fromI32(1)); if (from.totalTokens.equals(BigInt.zero())) { store.remove("Owner", fromId); } else { from.updatedAt = event.block.timestamp; from.save(); } let to = getOrCreateOwner(event.params.to.toHex()); to.totalTokens = to.totalTokens.plus(BigInt.fromI32(1)); to.save(); let token = getOrCreateToken( event.address.toHex() + "-" + event.params.tokenId.toString() ); if (event.params.from.equals(Address.zero())) { // Token token.collection = collection.id; token.tokenID = event.params.tokenId; token.owner = to.id; token.block = event.block.timestamp; token.createdAt = event.block.timestamp; token.save(); // Owner - as Receiver to.totalTokensMinted = to.totalTokensMinted.plus(BigInt.fromI32(1)); to.updatedAt = event.block.timestamp; to.save(); // Collection collection.totalSupply = collection.totalSupply.plus(BigInt.fromI32(1)); collection.updatedAt = event.block.timestamp; collection.save(); } token.owner = to.id; token.updatedAt = event.block.timestamp; token.save(); ``` - handleWithdrawETH ```solidity= event WithdrawETH(address indexed receiver, address indexed feeReceiver, uint amount, uint fee); ``` ```javascript= let collection = getOrCreateCollection(event.address.toHexString()); let transaction = getOrCreateWithdrawETHTransaction( event.transaction.hash.toHexString() ); transaction.date = event.block.timestamp; transaction.block = event.block.number; transaction.collection = collection.id; transaction.receiver = event.params.receiver; transaction.feeReceiver = event.params.feeReceiver; transaction.amount = event.params.amount; transaction.fee = event.params.fee; transaction.save(); let artist = getOrCreateArtist(event.params.receiver.toHexString()); if (artist.block.isZero()) { artist.block = event.block.number; artist.createdAt = event.block.timestamp; } artist.claimedAmount = artist.claimedAmount.plus(event.params.amount); artist.updatedAt = event.block.timestamp; artist.save(); ``` - handleSetPublicMintPrice ```solidity= event SetPublicMintPrice(uint price) ``` ```javascript= let collection = getOrCreateCollection(event.address.toHexString()); collection.publicPrice = event.params.price; collection.updatedAt = event.block.timestamp; collection.save(); ``` - handleSetBaseURI (updated 28/6/2022 18.31) ```solidity= event SetBaseURI(string baseURI); ``` ```javascript= let collection = getOrCreateCollection(event.address.toHexString()); collection.baseURI = event.params.baseURI; collection.updatedAt = event.block.timestamp; collection.save(); ``` ## ZaapMinterFactory - handleCreateMinter ```solidity= event CreateMinter(address indexed zaapMinter, address implementation); ``` ```javascript= let WHITELIST_MINTER_IMPLS = [ Address.fromString("0x8f5f793097763c3da4b068270ceb6f0265bb7d37"), ]; let RAFFLE_MINTER_IMPLS = [ Address.fromString("0xc0cb78d222299b28ac38b4d40132553380d236a4"), ]; let PUBLIC_MINTER_IMPLS = [ Address.fromString("0x6fd18c1f46835e1f44b8381f5ec36e30d3a6ba3c"), ]; let minter = new Minter(event.params.zaapMinter.toHexString()); minter.implementation = event.params.implementation; minter.block = event.block.number; minter.createdAt = event.block.timestamp; minter.updatedAt = event.block.timestamp; ZaapMinterTemplate.create(event.params.zaapMinter); let zaapImpl = event.params.implementation; if (WHITELIST_MINTER_IMPLS.includes(zaapImpl)) { ZaapWhitelistMinter.create(event.params.zaapMinter); } else if (RAFFLE_MINTER_IMPLS.includes(zaapImpl)) { ZaapRaffleMinter.create(event.params.zaapMinter); } else if (PUBLIC_MINTER_IMPLS.includes(zaapImpl)) { ZaapPublicMinter.create(event.params.zaapMinter); } else { log.error("Minter type not found, minter address: {}, implementation: {}", [ event.address.toHexString(), event.params.implementation.toHexString(), ]); } minter.save(); ``` ## BaseMinter - handleSetMintCollection ```solidity= event SetMintCollection(address nft); ``` ```javascript= // add minter into collection let minter = Minter.load(event.address.toHexString()); if (!minter) { log.debug("minter was null.", []); return; } // set minter minter.collection = getOrCreateCollection(event.params.nft.toHexString()).id; minter.updatedAt = event.block.timestamp; minter.save(); ``` - handleOwnershipTransferred ```solidity= event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); ``` ```javascript= let minter = getOrCreateMinter(event.address.toHexString()); minter.owner = event.params.newOwner; minter.updatedAt = event.block.timestamp; minter.save(); ``` ## ZaapWhitelistMinter - handleWhitelistMint ```solidity= event WhitelistMint(address indexed to, uint amount, address caller, uint maxClaimableAmount); ``` ```javascript= let minter = Minter.load(event.address.toHexString()); if (!minter) { log.error("failed to load minter address {}", [ event.address.toHexString(), ]); return; } let collection = Collection.load(minter.collection!); if (!collection) { log.error("failed to load collection {}", [minter.collection!]); return; } let whitelistMinter = WhitelistMinter.load(event.address.toHexString()); if (!whitelistMinter) { log.error("failed to load whitelist minter address {}", [ event.address.toHexString(), ]); return; } let transaction = getOrCreateMintTransaction( event.transaction.hash.toHexString() ); let saleAmount = event.params.amount.times(whitelistMinter.price); transaction.date = event.block.timestamp; transaction.block = event.block.number; transaction.collection = collection.id; transaction.price = whitelistMinter.price; transaction.nftAmount = event.params.amount; transaction.amount = saleAmount; transaction.buyer = event.params.to; collection.totalSaleAmount = collection.totalSaleAmount.plus(saleAmount); collection.totalSaleAmountFromMinters = collection.totalSaleAmountFromMinters.plus( saleAmount ); collection.updatedAt = event.block.timestamp; transaction.save(); collection.save(); ``` - handleSetPrice ```solidity= event SetPrice(uint price); ``` ```javascript= let minter = getOrCreateWhitelistMinter(event.address.toHexString()); minter.price = event.params.price; minter.updatedAt = event.block.timestamp; minter.save(); ``` - handleSetMintTimestamp ```solidity= event SetMintTimestamp(uint64 startTimestamp, uint64 endTimestamp); ``` ```javascript= let minter = getOrCreateWhitelistMinter(event.address.toHexString()); minter.startTimestamp = event.params.startTimestamp; minter.endTimestamp = event.params.endTimestamp; minter.updatedAt = event.block.timestamp; minter.save(); ``` - handleSetMintSupply ```solidity= event SetMintSupply(uint mintSupply); ``` ```javascript= let minter = getOrCreateWhitelistMinter(event.address.toHexString()); minter.mintSupply = event.params.mintSupply; minter.updatedAt = event.block.timestamp; minter.save(); ``` - handleSetMintStatus ```solidity= event SetMintStatus(MintStatus status); ``` ```javascript= let minter = getOrCreateWhitelistMinter(event.address.toHexString()); minter.mintStatus = event.params.status ? "ACTIVE" : "INACTIVE"; minter.updatedAt = event.block.timestamp; minter.save(); ``` ## ZaapRaffleMinter - handleRaffleMint ```solidity= event RaffleMint(address indexed to, uint amount, address caller, uint maxClaimableAmount); ``` ```javascript= let minter = Minter.load(event.address.toHexString()); if (!minter) { log.error("failed to load minter address {}", [ event.address.toHexString(), ]); return; } let collection = Collection.load(minter.collection!); if (!collection) { log.error("failed to load collection {}", [minter.collection!]); return; } let raffleMinter = RaffleMinter.load(event.address.toHexString()); if (!raffleMinter) { log.error("failed to load raffle minter address {}", [ event.address.toHexString(), ]); return; } let transaction = getOrCreateMintTransaction( event.transaction.hash.toHexString() ); let saleAmount = event.params.amount.times(raffleMinter.price); transaction.date = event.block.timestamp; transaction.block = event.block.number; transaction.collection = collection.id; transaction.price = raffleMinter.price; transaction.nftAmount = event.params.amount; transaction.amount = saleAmount; transaction.buyer = event.params.to; collection.totalSaleAmount = collection.totalSaleAmount.plus(saleAmount); collection.totalSaleAmountFromMinters = collection.totalSaleAmountFromMinters.plus( saleAmount ); collection.updatedAt = event.block.timestamp; transaction.save(); collection.save(); ``` - handleSetPrice ```solidity= event SetPrice(uint price); ``` ```javascript= let minter = getOrCreateWhitelistMinter(event.address.toHexString()); minter.price = event.params.price; minter.updatedAt = event.block.timestamp; minter.save(); ``` - handleSetMintTimestamp ```solidity= event SetMintTimestamp(uint64 startTimestamp, uint64 endTimestamp); ``` ```javascript= let minter = getOrCreateWhitelistMinter(event.address.toHexString()); minter.startTimestamp = event.params.startTimestamp; minter.endTimestamp = event.params.endTimestamp; minter.updatedAt = event.block.timestamp; minter.save(); ``` - handleSetMintSupply ```solidity= event SetMintSupply(uint mintSupply); ``` ```javascript= let minter = getOrCreateWhitelistMinter(event.address.toHexString()); minter.mintSupply = event.params.mintSupply; minter.updatedAt = event.block.timestamp; minter.save(); ``` - handleSetMintStatus ```solidity= event SetMintStatus(MintStatus status); ``` ```javascript= let minter = getOrCreateWhitelistMinter(event.address.toHexString()); minter.mintStatus = event.params.status ? "ACTIVE" : "INACTIVE"; minter.updatedAt = event.block.timestamp; minter.save(); ``` - handleSetRegisterTimestamp ```solidity= event SetRegisterTimestamp(uint64 registerStartTimestamp, uint64 registerEndTimestamp); ``` ```javascript= let minter = getOrCreateRaffleMinter(event.address.toHexString()); minter.registerStartTimestamp = event.params.registerStartTimestamp; minter.registerEndTimestamp = event.params.registerEndTimestamp; minter.updatedAt = event.block.timestamp; minter.save(); ``` ## ZaapPublicMinter - handlePublicMint ```solidity= event PublicMint(address indexed to, uint amount); ``` ```javascript= let minter = Minter.load(event.address.toHexString()); if (!minter) { log.error("failed to load minter address {}", [ event.address.toHexString(), ]); return; } let collection = Collection.load(minter.collection!); if (!collection) { log.error("failed to load collection {}", [minter.collection!]); return; } let publicMinter = PublicMinter.load(event.address.toHexString()); if (!publicMinter) { log.error("failed to load public minter address {}", [ event.address.toHexString(), ]); return; } let transaction = getOrCreateMintTransaction( event.transaction.hash.toHexString() ); let saleAmount = event.params.amount.times(publicMinter.price); transaction.date = event.block.timestamp; transaction.block = event.block.number; transaction.collection = collection.id; transaction.price = publicMinter.price; transaction.nftAmount = event.params.amount; transaction.amount = saleAmount; transaction.buyer = event.params.to; collection.totalSaleAmount = collection.totalSaleAmount.plus(saleAmount); collection.totalSaleAmountFromMinters = collection.totalSaleAmountFromMinters.plus( saleAmount ); collection.updatedAt = event.block.timestamp; transaction.save(); collection.save(); ``` - handleSetPrice ```solidity= event SetPrice(uint price); ``` ```javascript= let minter = getOrCreateWhitelistMinter(event.address.toHexString()); minter.price = event.params.price; minter.updatedAt = event.block.timestamp; minter.save(); ``` - handleSetMintTimestamp ```solidity= event SetMintTimestamp(uint64 startTimestamp, uint64 endTimestamp); ``` ```javascript= let minter = getOrCreateWhitelistMinter(event.address.toHexString()); minter.startTimestamp = event.params.startTimestamp; minter.endTimestamp = event.params.endTimestamp; minter.updatedAt = event.block.timestamp; minter.save(); ``` - handleSetMintSupply ```solidity= event SetMintSupply(uint mintSupply); ``` ```javascript= let minter = getOrCreateWhitelistMinter(event.address.toHexString()); minter.mintSupply = event.params.mintSupply; minter.updatedAt = event.block.timestamp; minter.save(); ``` - handleSetMintStatus ```solidity= event SetMintStatus(MintStatus status); ``` ```javascript= let minter = getOrCreateWhitelistMinter(event.address.toHexString()); minter.mintStatus = event.params.status ? "ACTIVE" : "INACTIVE"; minter.updatedAt = event.block.timestamp; minter.save(); ```