├── .gitmodules ├── tests ├── makeMockEventData.ts └── metadata.test.ts ├── abis ├── ZoraCreator1155Proxy.json ├── ZoraCreator1155FactoryProxy.json ├── Zora1155.json ├── Zora1155Factory.json ├── Zora1155PremintExecutor.json ├── copy-abis.sh ├── EditionMetadataRenderer.json ├── DropMetadataRenderer.json ├── ZoraCreatorRedeemMinterFactory.json ├── ZoraNFTCreator.json ├── ZoraCreatorMerkleMinterStrategy.json ├── ZoraCreatorFixedPriceSaleStrategy.json ├── ProtocolRewards.json └── ZoraNFTCreatorV1.json ├── tsconfig.json ├── src ├── constants │ ├── tokenStandard.ts │ ├── chainid.ts.template │ ├── salesConfigTypes.ts │ ├── metadataHistoryTypes.ts │ └── erc721RoleUtils.ts ├── common │ ├── getContractId.ts │ ├── getSaleId.ts │ ├── hasBit.ts │ ├── getIPFSHostFromURI.ts │ ├── getMintCommentId.ts │ ├── getOnChainMetadataKey.ts │ ├── getPermissionsKey.ts │ ├── getToken1155HolderId.ts │ ├── getTokenId.ts │ ├── getSalesConfigKey.ts │ ├── makeTransaction.ts │ └── metadata.ts ├── ERC1155Mappings │ ├── templates │ │ ├── ZoraCreatorRedeemMinterFactory.ts │ │ ├── ZoraMerkleMinterStrategyMappings.ts │ │ ├── ZoraCreatorFixedPriceSaleStrategyMappings.ts │ │ ├── ZoraCreatorRedeemMinterStrategy.ts │ │ └── ZoraCreator1155ImplMappings.ts │ ├── premintMappings.ts │ └── factoryMappings.ts ├── ipfs │ └── metadata.ts ├── ERC721Mappings │ ├── templates │ │ ├── DropMetadataRendererMappings.ts │ │ ├── EditionMetadataRendererMappings.ts │ │ └── ERC721DropMappings.ts │ └── ERC721FactoryMappings.ts ├── ReserveAuctionV3Mappings │ └── reserveAuctionV3Mappings.ts └── RewardsMappings │ └── rewardsMappings.ts ├── .gitignore ├── template_warning.md ├── scripts ├── remove-grafting-config.sh └── multideploy.sh ├── config ├── sepolia.yaml ├── publicgoods.yaml ├── arbitrum-one.yaml ├── arbitrum-sepolia.yaml ├── goerli.yaml ├── base-mainnet.yaml ├── optimism.yaml ├── base-goerli.yaml ├── optimism-goerli.yaml ├── zora-sepolia.yaml ├── zora-testnet.yaml ├── zora-mainnet.yaml └── mainnet.yaml ├── docs └── base-indexing-notes.md ├── package.json ├── README.md ├── schema.graphql └── subgraph.template.yaml /.gitmodules: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/makeMockEventData.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /abis/ZoraCreator1155Proxy.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /abis/ZoraCreator1155FactoryProxy.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@graphprotocol/graph-ts/types/tsconfig.base.json", 3 | "include": ["src"] 4 | } 5 | -------------------------------------------------------------------------------- /src/constants/tokenStandard.ts: -------------------------------------------------------------------------------- 1 | export const TOKEN_STANDARD_ERC721 = 'ERC721' 2 | export const TOKEN_STANDARD_ERC1155 = 'ERC1155' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | generated 2 | build 3 | node_modules 4 | .DS_Store 5 | subgraph.yaml 6 | tests/.bin/ 7 | yarn-error.log 8 | src/constants/chainid.ts 9 | -------------------------------------------------------------------------------- /template_warning.md: -------------------------------------------------------------------------------- 1 | # THIS IS A TEMPLATE FILE PLEASE DO NOT EDIT 2 | # 3 | # 4 | # 5 | # 6 | # 7 | # 8 | # 9 | # 10 | # 11 | # 12 | # Okayyyy... 13 | -------------------------------------------------------------------------------- /src/constants/chainid.ts.template: -------------------------------------------------------------------------------- 1 | import { BigInt } from "@graphprotocol/graph-ts"; 2 | 3 | export const chainid = BigInt.fromI32({{chainid}}); 4 | export const network = "{{network}}"; -------------------------------------------------------------------------------- /src/common/getContractId.ts: -------------------------------------------------------------------------------- 1 | import { Address } from "@graphprotocol/graph-ts" 2 | 3 | export function getContractId(contractAddress: Address): string { 4 | return contractAddress.toHex(); 5 | } -------------------------------------------------------------------------------- /src/constants/salesConfigTypes.ts: -------------------------------------------------------------------------------- 1 | export const SALE_CONFIG_PRESALE = 'PRESALE' 2 | export const SALE_CONFIG_FIXED_PRICE = 'FIXED_PRICE' 3 | export const SALE_CONFIG_REDEEM_STRATEGY = 'REDEEM_STRATEGY' -------------------------------------------------------------------------------- /src/constants/metadataHistoryTypes.ts: -------------------------------------------------------------------------------- 1 | export const METADATA_CUSTOM_RENDERER = 'CUSTOM_RENDERER' 2 | export const METADATA_ERC721_EDITION = "ERC721_EDITION"; 3 | export const METADATA_ERC721_DROP = "ERC721_DROP"; -------------------------------------------------------------------------------- /src/common/getSaleId.ts: -------------------------------------------------------------------------------- 1 | import { ethereum } from "@graphprotocol/graph-ts"; 2 | 3 | export function getSaleId(event: ethereum.Event): string { 4 | return `${event.transaction.hash.toHex()}-${event.logIndex}`; 5 | } 6 | -------------------------------------------------------------------------------- /src/common/hasBit.ts: -------------------------------------------------------------------------------- 1 | import { BigInt } from "@graphprotocol/graph-ts"; 2 | 3 | export function hasBit(bit: u8, permissions: BigInt): boolean { 4 | return permissions.bitAnd(BigInt.fromI64(2).pow(bit)).gt(BigInt.fromI64(0)); 5 | } -------------------------------------------------------------------------------- /src/common/getIPFSHostFromURI.ts: -------------------------------------------------------------------------------- 1 | export function getIPFSHostFromURI(uri: string | null): string | null { 2 | if (uri !== null && uri.startsWith("ipfs://")) { 3 | return uri.replace("ipfs://", ""); 4 | } 5 | return null; 6 | } -------------------------------------------------------------------------------- /src/common/getMintCommentId.ts: -------------------------------------------------------------------------------- 1 | import { ethereum } from "@graphprotocol/graph-ts"; 2 | 3 | export function getMintCommentId(event: ethereum.Event): string { 4 | return `${event.transaction.hash.toHex()}-${event.logIndex}`; 5 | } 6 | -------------------------------------------------------------------------------- /src/common/getOnChainMetadataKey.ts: -------------------------------------------------------------------------------- 1 | import { ethereum } from "@graphprotocol/graph-ts"; 2 | 3 | export const getOnChainMetadataKey = (event: ethereum.Event): string => 4 | `${event.transaction.hash.toHex()}-${event.logIndex.toString()}`; 5 | -------------------------------------------------------------------------------- /scripts/remove-grafting-config.sh: -------------------------------------------------------------------------------- 1 | # requirements: jq 2 | 3 | # enable errors 4 | set -e 5 | 6 | for configfile in ./config/* 7 | do 8 | newjson="$(jq -r 'del(.grafting)' $configfile)" 9 | echo "$newjson" 10 | echo "$newjson" > $configfile 11 | done 12 | -------------------------------------------------------------------------------- /src/common/getPermissionsKey.ts: -------------------------------------------------------------------------------- 1 | import { Address, BigInt } from "@graphprotocol/graph-ts"; 2 | 3 | export const getPermissionsKey = ( 4 | user: Address, 5 | address: Address, 6 | tokenId: BigInt 7 | ): string => `${user.toHex()}-${address.toHex()}-${tokenId.toString()}`; 8 | -------------------------------------------------------------------------------- /src/common/getToken1155HolderId.ts: -------------------------------------------------------------------------------- 1 | import {Address, BigInt} from '@graphprotocol/graph-ts' 2 | 3 | export function getToken1155HolderId(user: Address, tokenContract: Address, tokenId: BigInt): string { 4 | return `${user.toHex()}-${tokenContract.toHex()}-${tokenId.toString()}` 5 | } -------------------------------------------------------------------------------- /config/sepolia.yaml: -------------------------------------------------------------------------------- 1 | chainid: "11155111" 2 | network: sepolia 3 | factories1155: 4 | - address: "0x13dAA8E9e3f68deDE7b1386ACdc12eA98F2FB688" 5 | startBlock: "3354498" 6 | version: "1" 7 | factories721: 8 | - address: "0x87cfd516c5ea86e50b950678CA970a8a28de27ac" 9 | startBlock: "3354415" 10 | version: "1" 11 | -------------------------------------------------------------------------------- /config/publicgoods.yaml: -------------------------------------------------------------------------------- 1 | chainid: "424" 2 | network: publicgoods 3 | factories1155: 4 | - address: "0x6E742921602a5195f6439c8b8b827E85902E1B2D" 5 | startBlock: "404897" 6 | version: "1" 7 | factories721: 8 | - address: "0x48d8db63724444C6270749fEe80bBDB6CF33677f" 9 | startBlock: "389957" 10 | version: "1" 11 | -------------------------------------------------------------------------------- /src/common/getTokenId.ts: -------------------------------------------------------------------------------- 1 | import { Address, BigInt } from "@graphprotocol/graph-ts"; 2 | 3 | export const getTokenId = (contract: Address, tokenId: BigInt): string => 4 | `${contract.toHexString()}-${tokenId.toString()}`; 5 | 6 | export const getDefaultTokenId = (contract: Address): string => 7 | getTokenId(contract, BigInt.zero()); 8 | -------------------------------------------------------------------------------- /src/constants/erc721RoleUtils.ts: -------------------------------------------------------------------------------- 1 | export const KNOWN_TYPE_DEFAULT_ADMIN: string = 2 | "0x0000000000000000000000000000000000000000000000000000000000000000"; 3 | export const KNOWN_TYPE_MINTER_ROLE: string = 4 | "0xf0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc9"; 5 | 6 | export const KNOWN_TYPE_SALES_MANAGER_ROLE: string = 7 | "0x5ebbf78043a2215b522b1366a193ec74dd1f54e441e841a87b9653246a9c49a6"; 8 | -------------------------------------------------------------------------------- /config/arbitrum-one.yaml: -------------------------------------------------------------------------------- 1 | chainid: "42161" 2 | network: arbitrum-one 3 | factories1155: 4 | - address: "0x777777C338d93e2C7adf08D102d45CA7CC4Ed021" 5 | startBlock: "169120898" 6 | factories721: 7 | - address: "0xa5f8577cCA2eE9d5577E76385dB1Af51517c76bb" 8 | startBlock: "171408300" 9 | version: "1" 10 | protocolRewards: 11 | - address: "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" 12 | startBlock: "169101021" 13 | version: "1" 14 | -------------------------------------------------------------------------------- /config/arbitrum-sepolia.yaml: -------------------------------------------------------------------------------- 1 | chainid: "421614" 2 | network: arbitrum-sepolia 3 | factories1155: 4 | - address: "0x777777C338d93e2C7adf08D102d45CA7CC4Ed021" 5 | startBlock: "10708023" 6 | factories721: 7 | - address: "0x765FBfF9E400C55035a1180B78A9CBE12aC25414" 8 | startBlock: "11326180" 9 | version: "1" 10 | protocolRewards: 11 | - address: "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" 12 | startBlock: "10701645" 13 | version: "1" 14 | -------------------------------------------------------------------------------- /config/goerli.yaml: -------------------------------------------------------------------------------- 1 | chainid: "5" 2 | network: goerli 3 | factories1155: 4 | - address: "0x8732b4bCa198509bB9c40f9a24638Be1eaB7D30c" 5 | startBlock: "8667388" 6 | version: "1" 7 | - address: "0x777777C338d93e2C7adf08D102d45CA7CC4Ed021" 8 | startBlock: "9803733" 9 | version: "2" 10 | protocolRewards: 11 | - version: "1" 12 | address: "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" 13 | startBlock: "9423660" 14 | factories721: 15 | - address: "0xb9583D05Ba9ba8f7F14CCEe3Da10D2bc0A72f519" 16 | startBlock: "7412408" 17 | version: "1" 18 | -------------------------------------------------------------------------------- /src/common/getSalesConfigKey.ts: -------------------------------------------------------------------------------- 1 | import { Address, BigInt } from "@graphprotocol/graph-ts"; 2 | 3 | export const getSalesConfigKey = ( 4 | marketAddress: Address, 5 | mediaContractAddress: Address, 6 | tokenId: BigInt 7 | ): string => 8 | `${marketAddress.toHexString()}-${mediaContractAddress.toHexString()}-${tokenId.toString()}` 9 | 10 | export const getSalesConfigOnLegacyMarket = ( 11 | marketAddress: Address, 12 | postfix: string 13 | ): string => 14 | `${getSalesConfigKey( 15 | marketAddress, 16 | marketAddress, 17 | BigInt.zero() 18 | )}-${postfix}`; 19 | -------------------------------------------------------------------------------- /src/common/makeTransaction.ts: -------------------------------------------------------------------------------- 1 | import { BigInt, ethereum } from "@graphprotocol/graph-ts"; 2 | import { TransactionInfo } from "../../generated/schema"; 3 | import { chainid, network } from "../constants/chainid"; 4 | 5 | export function makeTransaction(event: ethereum.Event): string { 6 | const txn = new TransactionInfo(event.transaction.hash.toHex()); 7 | 8 | txn.block = event.block.number; 9 | txn.timestamp = event.block.timestamp; 10 | txn.logIndex = event.logIndex; 11 | txn.chainId = chainid; 12 | txn.address = event.address; 13 | txn.network = network; 14 | txn.save(); 15 | 16 | return txn.id; 17 | } 18 | -------------------------------------------------------------------------------- /src/common/metadata.ts: -------------------------------------------------------------------------------- 1 | import { ethereum } from "@graphprotocol/graph-ts"; 2 | import { getIPFSHostFromURI } from "./getIPFSHostFromURI"; 3 | import { MetadataInfo as MetadataInfoTemplate } from "../../generated/templates"; 4 | 5 | export function extractIPFSIDFromContract( 6 | result: ethereum.CallResult 7 | ): string | null { 8 | if (result.reverted) { 9 | return null; 10 | } 11 | return getIPFSHostFromURI(result.value); 12 | } 13 | 14 | export function loadMetadataInfoFromID(id: string | null): string | null { 15 | if (id !== null) { 16 | MetadataInfoTemplate.create(id); 17 | } 18 | 19 | return id; 20 | } 21 | -------------------------------------------------------------------------------- /config/base-mainnet.yaml: -------------------------------------------------------------------------------- 1 | chainid: "8453" 2 | network: base 3 | factories1155: 4 | - address: "0x9b24FD165a371042e5CA81e8d066d25CAD11EDE7" 5 | startBlock: "1496186" 6 | version: "1" 7 | - address: "0x777777C338d93e2C7adf08D102d45CA7CC4Ed021" 8 | startBlock: "4784084" 9 | version: "2" 10 | factories721: 11 | - address: "0x58C3ccB2dcb9384E5AB9111CD1a5DEA916B0f33c" 12 | startBlock: "1461362" 13 | version: "1" 14 | protocolRewards: 15 | - address: "0x7777777A456fF23D9b6851184472c08FBDa73e32" 16 | startBlock: "2123378" 17 | version: "1" 18 | - address: "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" 19 | startBlock: "2336418" 20 | version: "2" 21 | -------------------------------------------------------------------------------- /config/optimism.yaml: -------------------------------------------------------------------------------- 1 | chainid: "10" 2 | network: optimism 3 | factories1155: 4 | - address: "0x78b524931e9d847c40BcBf225c25e154a7B05fDA" 5 | startBlock: "97158995" 6 | version: "1" 7 | - address: "0x777777C338d93e2C7adf08D102d45CA7CC4Ed021" 8 | startBlock: "110378103" 9 | version: "2" 10 | factories721: 11 | - address: "0x7d1a46c6e614A0091c39E102F2798C27c1fA8892" 12 | startBlock: "97155865" 13 | version: "1" 14 | protocolRewards: 15 | - address: "0x7777777A456fF23D9b6851184472c08FBDa73e32" 16 | startBlock: "107718410" 17 | version: "1" 18 | - address: "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" 19 | startBlock: "107931668" 20 | version: "2" 21 | -------------------------------------------------------------------------------- /config/base-goerli.yaml: -------------------------------------------------------------------------------- 1 | chainid: "84531" 2 | network: base-goerli 3 | factories1155: 4 | - address: "0x9168C5ba5a0a76db8A1BF5b2eE5557f2A0ECA4f4" 5 | startBlock: "6948614" 6 | version: "1" 7 | - address: "0x777777C338d93e2C7adf08D102d45CA7CC4Ed021" 8 | startBlock: "10581134" 9 | version: "2" 10 | factories721: 11 | - address: "0x87cfd516c5ea86e50b950678CA970a8a28de27ac" 12 | startBlock: "3597035" 13 | version: "1" 14 | protocolRewards: 15 | - address: "0x7777777A456fF23D9b6851184472c08FBDa73e32" 16 | startBlock: "7920777" 17 | version: "1" 18 | - address: "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" 19 | startBlock: "8134033" 20 | version: "2" 21 | -------------------------------------------------------------------------------- /config/optimism-goerli.yaml: -------------------------------------------------------------------------------- 1 | chainid: "420" 2 | network: optimism-goerli 3 | factories1155: 4 | - address: "0xb0C56317E9cEBc6E0f7A59458a83D0A9ccC3e955" 5 | startBlock: "9127679" 6 | version: "1" 7 | - address: "0x777777C338d93e2C7adf08D102d45CA7CC4Ed021" 8 | startBlock: "15463356" 9 | version: "2" 10 | factories721: 11 | - address: "0x3C1ebcF36Ca9DD9371c9aA99c274e4988906c6E3" 12 | startBlock: "9120231" 13 | version: "1" 14 | protocolRewards: 15 | - address: "0x7777777A456fF23D9b6851184472c08FBDa73e32" 16 | startBlock: "12803376" 17 | version: "1" 18 | - address: "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" 19 | startBlock: "13016586" 20 | version: "2" 21 | -------------------------------------------------------------------------------- /config/zora-sepolia.yaml: -------------------------------------------------------------------------------- 1 | chainid: "999999999" 2 | network: zora-sepolia 3 | factories1155: 4 | - address: "0x777777C338d93e2C7adf08D102d45CA7CC4Ed021" 5 | startBlock: "309965" 6 | version: "1" 7 | factories721: 8 | - address: "0x6b28d7C2F8b2C2189e95b89B67886eEb16489a97" 9 | startBlock: "307400" 10 | version: "1" 11 | protocolRewards: 12 | - address: "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" 13 | startBlock: "298169" 14 | version: "1" 15 | preminter: 16 | - address: "0x7777773606e7e46C8Ba8B98C08f5cD218e31d340" 17 | startBlock: "309965" 18 | version: "1" 19 | reserveAuctionV3: 20 | - address: "0x0fbAB7302F9351dD1DB6674cc3bB855f0C55840B" 21 | startBlock: "992417" 22 | version: "1" 23 | -------------------------------------------------------------------------------- /config/zora-testnet.yaml: -------------------------------------------------------------------------------- 1 | chainid: "999" 2 | network: zora-testnet 3 | factories1155: 4 | - address: "0x6a357139C1bcDcf0B3AB9bC447932dDdcb956703" 5 | startBlock: "1" 6 | version: "1" 7 | - address: "0x777777C338d93e2C7adf08D102d45CA7CC4Ed021" 8 | startBlock: "1278602" 9 | version: "2" 10 | factories721: 11 | - address: "0x1Fc0BAE875C2CF2262BEc25B16d96814D37025AC" 12 | startBlock: "1" 13 | version: "1" 14 | - address: "0xeB29A4e5b84fef428c072debA2444e93c080CE87" 15 | startBlock: "587491" 16 | version: "2" 17 | protocolRewards: 18 | - address: "0x7777777A456fF23D9b6851184472c08FBDa73e32" 19 | startBlock: "780419" 20 | version: "1" 21 | - address: "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" 22 | startBlock: "823043" 23 | version: "2" 24 | preminter: 25 | - address: "0x7777773606e7e46C8Ba8B98C08f5cD218e31d340" 26 | startBlock: "1278602" 27 | version: "1" 28 | -------------------------------------------------------------------------------- /docs/base-indexing-notes.md: -------------------------------------------------------------------------------- 1 | # Base Indexing Notes for Zora Creator Subgraph 2 | 3 | This subgraph already does a solid job indexing creator contracts and rewards. 4 | From a Base builder’s perspective, a few small additions could make it even smoother to extend and operate. 5 | 6 | ## Chain Config Clarity 7 | A short example in `config/` showing how to add a new chain (naming, endpoints, start blocks) would help contributors avoid trial and error. 8 | 9 | ## Common Pitfalls 10 | - Mismatched network names between graph indexer and config 11 | - Metadata/IPFS timeouts during bursts 12 | - Start block selection causing long syncs 13 | 14 | ## Suggested Docs Snippet 15 | “Pick a start block near the first deployment of your target collection to shorten initial sync times. Validate the network name matches your indexer settings.” 16 | 17 | **Why this helps** 18 | Clear, reusable patterns reduce friction for multi-chain support on Base and beyond. 19 | -------------------------------------------------------------------------------- /config/zora-mainnet.yaml: -------------------------------------------------------------------------------- 1 | chainid: "7777777" 2 | network: zora-mainnet 3 | factories1155: 4 | - address: "0x35ca784918bf11692708c1D530691704AAcEA95E" 5 | startBlock: "45420" 6 | version: "1" 7 | - address: "0x777777C338d93e2C7adf08D102d45CA7CC4Ed021" 8 | startBlock: "4664191" 9 | version: "2" 10 | factories721: 11 | - address: "0xA2c2A96A232113Dd4993E8b048EEbc3371AE8d85" 12 | startBlock: "46799" 13 | version: "1" 14 | protocolRewards: 15 | - address: "0x7777777A456fF23D9b6851184472c08FBDa73e32" 16 | startBlock: "2171044" 17 | version: "1" 18 | - address: "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" 19 | startBlock: "2384107" 20 | version: "2" 21 | preminter: 22 | - address: "0x7777773606e7e46C8Ba8B98C08f5cD218e31d340" 23 | startBlock: "4664191" 24 | version: "1" 25 | reserveAuctionV3: 26 | - address: "0xA06262157905913f855573f53AD48DE2D4ba1F4A" 27 | startBlock: "6686902" 28 | version: "1" 29 | -------------------------------------------------------------------------------- /src/ERC1155Mappings/templates/ZoraCreatorRedeemMinterFactory.ts: -------------------------------------------------------------------------------- 1 | import { RedeemMinterDeployed } from "../../../generated/templates/ZoraCreatorRedeemMinterFactory/ZoraCreatorRedeemMinterFactory"; 2 | import { ZoraCreatorRedeemConfig } from "../../../generated/schema"; 3 | import { makeTransaction } from "../../common/makeTransaction"; 4 | import { ZoraCreatorRedeemMinterStrategy } from "../../../generated/templates"; 5 | 6 | export function handleRedeemMinterDeployed(event: RedeemMinterDeployed): void { 7 | let config = new ZoraCreatorRedeemConfig( 8 | `${event.address.toHex()}-${event.params.minterContract.toHex()}` 9 | ); 10 | config.creatorAddress = event.params.creatorContract; 11 | config.minterAddress = event.params.minterContract; 12 | 13 | const txn = makeTransaction(event); 14 | config.txn = txn; 15 | config.block = event.block.number; 16 | config.timestamp = event.block.timestamp; 17 | 18 | ZoraCreatorRedeemMinterStrategy.create(event.params.minterContract); 19 | 20 | config.save(); 21 | } 22 | -------------------------------------------------------------------------------- /config/mainnet.yaml: -------------------------------------------------------------------------------- 1 | chainid: "1" 2 | network: mainnet 3 | factories1155: 4 | # this factory unable to be controlled anymore 5 | - address: "0x784A410B891EE92612102521281a3e222a6E326D" 6 | startBlock: "16844200" 7 | version: "1" 8 | # previous versions of this factory hold the UpgradeGate and is non-deterministic 9 | - address: "0xA6C5f2DE915240270DaC655152C3f6A91748cb85" 10 | startBlock: "17126366" 11 | version: "2" 12 | # this factory is deterministic and does not include the UpgradeGate 13 | - address: "0x777777C338d93e2C7adf08D102d45CA7CC4Ed021" 14 | startBlock: "18272202" 15 | version: "3" 16 | factories721: 17 | - address: "0xF74B146ce44CC162b601deC3BE331784DB111DC1" 18 | startBlock: "14758780" 19 | version: "1" 20 | protocolRewards: 21 | # initial protocol rewards – only used by old NFT contracts 22 | - address: "0x7777777A456fF23D9b6851184472c08FBDa73e32" 23 | startBlock: "17831976" 24 | version: "1" 25 | # newer rewards used by more recent contracts. This adds `withdrawFor` 26 | - address: "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" 27 | startBlock: "17867249" 28 | version: "2" 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nft-creator-subgraph", 3 | "license": "MIT", 4 | "repository": "https://github.com/ourzora/zora-creator-subgraph", 5 | "scripts": { 6 | "copy-abis": "bash abis/copy-abis.sh", 7 | "codegen": "yarn gen-yaml-config && graph codegen && echo 'import { Address } from \"@graphprotocol/graph-ts\";' >> generated/templates.ts", 8 | "build": "yarn run codegen && graph build", 9 | "gen-yaml-config": "cat template_warning.md > subgraph.yaml && yaml2json config/${NETWORK:-zora-testnet}.yaml | mustache - subgraph.template.yaml >> subgraph.yaml && yaml2json config/${NETWORK:-zora-testnet}.yaml | mustache - src/constants/chainid.ts.template > src/constants/chainid.ts", 10 | "deploy-hosted": "graph deploy --node https://api.thegraph.com/deploy/ ${DEPLOYMENT_PATH}", 11 | "postinstall": "yarn run copy-abis", 12 | "test": "graph test . -v 0.5.4" 13 | }, 14 | "dependencies": { 15 | "@graphprotocol/graph-ts": "0.29.3", 16 | "@zoralabs/nft-drop-contracts": "1.12.0", 17 | "@zoralabs/protocol-rewards": "1.1.0", 18 | "@zoralabs/zora-1155-contracts": "2.6.0" 19 | }, 20 | "devDependencies": { 21 | "@goldskycom/cli": "^7.1.0", 22 | "@graphprotocol/graph-cli": "0.48.0", 23 | "matchstick-as": "^0.5.1", 24 | "yamljs": "^0.3.0", 25 | "mustache": "4.2.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /abis/Zora1155.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "constructor", 4 | "inputs": [ 5 | { 6 | "name": "_logic", 7 | "type": "address", 8 | "internalType": "address" 9 | } 10 | ], 11 | "stateMutability": "nonpayable" 12 | }, 13 | { 14 | "type": "fallback", 15 | "stateMutability": "payable" 16 | }, 17 | { 18 | "type": "receive", 19 | "stateMutability": "payable" 20 | }, 21 | { 22 | "type": "event", 23 | "name": "AdminChanged", 24 | "inputs": [ 25 | { 26 | "name": "previousAdmin", 27 | "type": "address", 28 | "indexed": false, 29 | "internalType": "address" 30 | }, 31 | { 32 | "name": "newAdmin", 33 | "type": "address", 34 | "indexed": false, 35 | "internalType": "address" 36 | } 37 | ], 38 | "anonymous": false 39 | }, 40 | { 41 | "type": "event", 42 | "name": "BeaconUpgraded", 43 | "inputs": [ 44 | { 45 | "name": "beacon", 46 | "type": "address", 47 | "indexed": true, 48 | "internalType": "address" 49 | } 50 | ], 51 | "anonymous": false 52 | }, 53 | { 54 | "type": "event", 55 | "name": "Upgraded", 56 | "inputs": [ 57 | { 58 | "name": "implementation", 59 | "type": "address", 60 | "indexed": true, 61 | "internalType": "address" 62 | } 63 | ], 64 | "anonymous": false 65 | } 66 | ] 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zora Creator Subgraph 2 | 3 | This subgraph indexes all Zora creator contracts (both 721 and 1155) along with creator rewards. 4 | 5 | Main entities can be found in `schema.graphql`. 6 | 7 | To add new chains, new configuration files can be added to the `config/` folder. The config chain name needs to match the network name in the graph indexer instance used. 8 | 9 | This subgraph uses metadata IPFS indexing and subgraph optional features. 10 | 11 | ## Installation 12 | 13 | The graph docs: https://thegraph.academy/developers/subgraph-development-guide/ 14 | 15 | After `git clone` run `yarn` to install dependencies. 16 | 17 | 18 | Steps to build: 19 | 20 | ```sh 21 | NETWORK=zora yarn run build 22 | 23 | ``` 24 | 25 | NETWORK needs to be a name of a valid network configuration file in `config/`. 26 | 27 | 28 | After building, you can use the graph cli or goldsky cli to deploy the built subgraph for the network specified above. 29 | 30 | 31 | ## Deployment shortcuts 32 | 33 | Only supports goldsky deploys for now: 34 | 35 | Grafts subgraph from FROM_VERSION: 36 | 37 | ./scripts/multideploy.sh NEW_VERSION NETWORKS FROM_VERSION 38 | 39 | ./scripts/multideploy.sh 1.10.0 zora-testnet,optimism-goerli,base-goerli 1.8.0 40 | 41 | Deploys without grafting: 42 | 43 | ./scripts/multideploy.sh NEW_VERSION NETWORKS 44 | 45 | ./scripts/multideploy.sh 1.10.0 zora-testnet,optimism-goerli,base-goerli 46 | 47 | Deploys a new version for _all_ networks without grafting: (not typical, indexing takes a long time in many cases.) 48 | 49 | ./scripts/multideploy.sh NEW_VERSION 50 | 51 | -------------------------------------------------------------------------------- /abis/Zora1155Factory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "constructor", 4 | "inputs": [ 5 | { 6 | "name": "_logic", 7 | "type": "address", 8 | "internalType": "address" 9 | }, 10 | { 11 | "name": "_data", 12 | "type": "bytes", 13 | "internalType": "bytes" 14 | } 15 | ], 16 | "stateMutability": "nonpayable" 17 | }, 18 | { 19 | "type": "fallback", 20 | "stateMutability": "payable" 21 | }, 22 | { 23 | "type": "receive", 24 | "stateMutability": "payable" 25 | }, 26 | { 27 | "type": "event", 28 | "name": "AdminChanged", 29 | "inputs": [ 30 | { 31 | "name": "previousAdmin", 32 | "type": "address", 33 | "indexed": false, 34 | "internalType": "address" 35 | }, 36 | { 37 | "name": "newAdmin", 38 | "type": "address", 39 | "indexed": false, 40 | "internalType": "address" 41 | } 42 | ], 43 | "anonymous": false 44 | }, 45 | { 46 | "type": "event", 47 | "name": "BeaconUpgraded", 48 | "inputs": [ 49 | { 50 | "name": "beacon", 51 | "type": "address", 52 | "indexed": true, 53 | "internalType": "address" 54 | } 55 | ], 56 | "anonymous": false 57 | }, 58 | { 59 | "type": "event", 60 | "name": "Upgraded", 61 | "inputs": [ 62 | { 63 | "name": "implementation", 64 | "type": "address", 65 | "indexed": true, 66 | "internalType": "address" 67 | } 68 | ], 69 | "anonymous": false 70 | } 71 | ] 72 | -------------------------------------------------------------------------------- /abis/Zora1155PremintExecutor.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "constructor", 4 | "inputs": [ 5 | { 6 | "name": "_logic", 7 | "type": "address", 8 | "internalType": "address" 9 | }, 10 | { 11 | "name": "_data", 12 | "type": "bytes", 13 | "internalType": "bytes" 14 | } 15 | ], 16 | "stateMutability": "nonpayable" 17 | }, 18 | { 19 | "type": "fallback", 20 | "stateMutability": "payable" 21 | }, 22 | { 23 | "type": "receive", 24 | "stateMutability": "payable" 25 | }, 26 | { 27 | "type": "event", 28 | "name": "AdminChanged", 29 | "inputs": [ 30 | { 31 | "name": "previousAdmin", 32 | "type": "address", 33 | "indexed": false, 34 | "internalType": "address" 35 | }, 36 | { 37 | "name": "newAdmin", 38 | "type": "address", 39 | "indexed": false, 40 | "internalType": "address" 41 | } 42 | ], 43 | "anonymous": false 44 | }, 45 | { 46 | "type": "event", 47 | "name": "BeaconUpgraded", 48 | "inputs": [ 49 | { 50 | "name": "beacon", 51 | "type": "address", 52 | "indexed": true, 53 | "internalType": "address" 54 | } 55 | ], 56 | "anonymous": false 57 | }, 58 | { 59 | "type": "event", 60 | "name": "Upgraded", 61 | "inputs": [ 62 | { 63 | "name": "implementation", 64 | "type": "address", 65 | "indexed": true, 66 | "internalType": "address" 67 | } 68 | ], 69 | "anonymous": false 70 | } 71 | ] 72 | -------------------------------------------------------------------------------- /src/ERC1155Mappings/premintMappings.ts: -------------------------------------------------------------------------------- 1 | import { Premint } from "../../generated/schema"; 2 | import { Preminted, PremintedV2 } from "../../generated/ZoraCreator1155PremintExecutorV1/ZoraCreator1155PremintExecutorImpl"; 3 | import { getTokenId } from "../common/getTokenId"; 4 | 5 | export function handlePreminted(event: Preminted): void { 6 | const premint = new Premint( 7 | `${event.params.contractAddress.toHex()}-${event.params.tokenId.toHex()}-${event.params.minter.toHex()}}` 8 | ); 9 | premint.uid = event.params.uid; 10 | premint.contractAddress = event.params.contractAddress; 11 | premint.tokenId = event.params.tokenId; 12 | premint.minter = event.params.minter; 13 | premint.tokenAndContract = getTokenId( 14 | event.params.contractAddress, 15 | event.params.tokenId 16 | ); 17 | premint.createdNewContract = event.params.createdNewContract; 18 | premint.quantityMinted = event.params.quantityMinted; 19 | 20 | premint.save(); 21 | } 22 | 23 | export function handlePremintedV2(event: PremintedV2): void { 24 | const premint = new Premint( 25 | `${event.params.contractAddress.toHex()}-${event.params.tokenId.toHex()}-${event.params.minter.toHex()}}` 26 | ); 27 | premint.uid = event.params.uid; 28 | premint.contractAddress = event.params.contractAddress; 29 | premint.tokenId = event.params.tokenId; 30 | premint.minter = event.params.minter; 31 | premint.tokenAndContract = getTokenId( 32 | event.params.contractAddress, 33 | event.params.tokenId 34 | ); 35 | premint.createdNewContract = event.params.createdNewContract; 36 | premint.quantityMinted = event.params.quantityMinted; 37 | 38 | premint.save(); 39 | } 40 | -------------------------------------------------------------------------------- /src/ipfs/metadata.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Bytes, 3 | JSONValueKind, 4 | dataSource, 5 | json, 6 | } from "@graphprotocol/graph-ts"; 7 | import { MetadataInfo } from "../../generated/schema"; 8 | 9 | export function handleJSONMetadataFetched(content: Bytes): void { 10 | const metadata = new MetadataInfo(dataSource.stringParam()); 11 | metadata.rawJson = content.toString(); 12 | const jsonType = json.try_fromBytes(content); 13 | if ( 14 | jsonType.isOk && 15 | !jsonType.value.isNull() && 16 | jsonType.value.kind === JSONValueKind.OBJECT 17 | ) { 18 | const value = jsonType.value.toObject(); 19 | if (value) { 20 | const name = value.get("name"); 21 | if (name && name.kind === JSONValueKind.STRING) { 22 | metadata.name = name.toString(); 23 | } 24 | const description = value.get("description"); 25 | if (description && description.kind === JSONValueKind.STRING) { 26 | metadata.description = description.toString(); 27 | } 28 | const image = value.get("image"); 29 | if (image && image.kind === JSONValueKind.STRING) { 30 | metadata.image = image.toString(); 31 | } 32 | const decimals = value.get("decimals"); 33 | if ( 34 | decimals && 35 | (decimals.kind === JSONValueKind.STRING || 36 | decimals.kind === JSONValueKind.NUMBER) 37 | ) { 38 | metadata.decimals = decimals.toString(); 39 | } 40 | const animation_url = value.get("animation_url"); 41 | if (animation_url && animation_url.kind === JSONValueKind.STRING) { 42 | metadata.animationUrl = animation_url.toString(); 43 | } 44 | } 45 | } 46 | 47 | metadata.save(); 48 | } 49 | -------------------------------------------------------------------------------- /abis/copy-abis.sh: -------------------------------------------------------------------------------- 1 | REL_BASE=$(dirname "$0") 2 | 3 | ERC721_ARTIFACTS_PATH=$REL_BASE/../node_modules/@zoralabs/nft-drop-contracts/dist/artifacts/ 4 | ERC1155_ARTIFACTS_PATH=$REL_BASE/../node_modules/@zoralabs/zora-1155-contracts/abis 5 | PROTOCOL_REWARDS_ARTIFACTS_PATH=$REL_BASE/../node_modules/@zoralabs/protocol-rewards/dist/artifacts/ 6 | 7 | get_contract () { 8 | node -e 'var fs = require("fs");console.log(JSON.stringify(JSON.parse(fs.readFileSync(process.argv[1])).abi, null, 2))' $1/$2.sol/$2.json > $REL_BASE/$2.json 9 | } 10 | 11 | get_contract_abi () { 12 | node -e 'var fs = require("fs");console.log(JSON.stringify(JSON.parse(fs.readFileSync(process.argv[1])), null, 2))' $1/$2.json > $REL_BASE/$2.json 13 | } 14 | 15 | # 721 drop contracts 16 | get_contract $ERC721_ARTIFACTS_PATH 'ERC721Drop' 17 | get_contract $ERC721_ARTIFACTS_PATH 'ZoraNFTCreatorV1' 18 | get_contract $ERC721_ARTIFACTS_PATH 'EditionMetadataRenderer' 19 | get_contract $ERC721_ARTIFACTS_PATH 'DropMetadataRenderer' 20 | 21 | # 1155 creator impl contracts 22 | get_contract_abi $ERC1155_ARTIFACTS_PATH 'ZoraCreator1155Impl' 23 | get_contract_abi $ERC1155_ARTIFACTS_PATH 'Zora1155' 24 | 25 | # 1155 creator factory contracts 26 | get_contract_abi $ERC1155_ARTIFACTS_PATH 'ZoraCreator1155FactoryImpl' 27 | get_contract_abi $ERC1155_ARTIFACTS_PATH 'Zora1155Factory' 28 | 29 | # minters 1155 30 | get_contract_abi $ERC1155_ARTIFACTS_PATH 'ZoraCreatorFixedPriceSaleStrategy' 31 | get_contract_abi $ERC1155_ARTIFACTS_PATH 'ZoraCreatorMerkleMinterStrategy' 32 | get_contract_abi $ERC1155_ARTIFACTS_PATH 'ZoraCreatorRedeemMinterFactory' 33 | get_contract_abi $ERC1155_ARTIFACTS_PATH 'ZoraCreatorRedeemMinterStrategy' 34 | get_contract_abi $ERC1155_ARTIFACTS_PATH 'Zora1155PremintExecutor' 35 | get_contract_abi $ERC1155_ARTIFACTS_PATH 'ZoraCreator1155PremintExecutorImpl' 36 | 37 | # protocol rewards contract 38 | get_contract $PROTOCOL_REWARDS_ARTIFACTS_PATH 'ProtocolRewards' -------------------------------------------------------------------------------- /src/ERC1155Mappings/templates/ZoraMerkleMinterStrategyMappings.ts: -------------------------------------------------------------------------------- 1 | import { BigInt } from "@graphprotocol/graph-ts"; 2 | import { 3 | SalesConfigMerkleMinterStrategy, 4 | SalesStrategyConfig, 5 | } from "../../../generated/schema"; 6 | import { SaleSet } from "../../../generated/templates/ZoraCreatorMerkleMinterStrategy/ZoraCreatorMerkleMinterStrategy"; 7 | import { getSalesConfigKey } from "../../common/getSalesConfigKey"; 8 | import { getTokenId } from "../../common/getTokenId"; 9 | import { makeTransaction } from "../../common/makeTransaction"; 10 | import { SALE_CONFIG_PRESALE } from "../../constants/salesConfigTypes"; 11 | import { getContractId } from "../../common/getContractId"; 12 | 13 | export function handleMerkleMinterStrategySaleSet(event: SaleSet): void { 14 | const id = getSalesConfigKey( 15 | event.address, 16 | event.params.mediaContract, 17 | event.params.tokenId 18 | ); 19 | let sale = new SalesConfigMerkleMinterStrategy(id); 20 | sale.configAddress = event.address; 21 | sale.presaleStart = event.params.merkleSaleSettings.presaleStart; 22 | sale.presaleEnd = event.params.merkleSaleSettings.presaleEnd; 23 | sale.fundsRecipient = event.params.merkleSaleSettings.fundsRecipient; 24 | sale.merkleRoot = event.params.merkleSaleSettings.merkleRoot; 25 | 26 | const txn = makeTransaction(event); 27 | sale.address = event.address; 28 | sale.block = event.block.number; 29 | sale.timestamp = event.block.timestamp; 30 | sale.txn = txn; 31 | sale.tokenId = event.params.tokenId; 32 | sale.contract = getContractId(event.params.mediaContract); 33 | 34 | sale.save(); 35 | 36 | // add join 37 | const saleJoin = new SalesStrategyConfig(id); 38 | if (event.params.tokenId.equals(BigInt.zero())) { 39 | saleJoin.contract = getContractId(event.params.mediaContract); 40 | } else { 41 | saleJoin.tokenAndContract = getTokenId( 42 | event.params.mediaContract, 43 | event.params.tokenId 44 | ); 45 | } 46 | 47 | saleJoin.block = event.block.number; 48 | saleJoin.address = event.address; 49 | saleJoin.timestamp = event.block.timestamp; 50 | 51 | saleJoin.presale = id; 52 | saleJoin.type = SALE_CONFIG_PRESALE; 53 | saleJoin.txn = txn; 54 | saleJoin.save(); 55 | } 56 | -------------------------------------------------------------------------------- /src/ERC721Mappings/templates/DropMetadataRendererMappings.ts: -------------------------------------------------------------------------------- 1 | import { MetadataUpdated } from "../../../generated/templates/DropMetadataRenderer/DropMetadataRenderer"; 2 | import { 3 | DropMetadata, 4 | OnChainMetadataHistory, 5 | ZoraCreateContract, 6 | } from "../../../generated/schema"; 7 | import { MetadataInfo as MetadataInfoTemplate } from "../../../generated/templates"; 8 | import { getDefaultTokenId } from "../../common/getTokenId"; 9 | import { makeTransaction } from "../../common/makeTransaction"; 10 | import { METADATA_ERC721_DROP } from "../../constants/metadataHistoryTypes"; 11 | import { getOnChainMetadataKey } from "../../common/getOnChainMetadataKey"; 12 | import { getIPFSHostFromURI } from "../../common/getIPFSHostFromURI"; 13 | 14 | export function handleMetadataUpdated(event: MetadataUpdated): void { 15 | const metadata = new DropMetadata(getOnChainMetadataKey(event)); 16 | metadata.contractURI = event.params.contractURI; 17 | metadata.extension = event.params.metadataExtension; 18 | metadata.base = event.params.metadataBase; 19 | metadata.freezeAt = event.params.freezeAt; 20 | metadata.save(); 21 | 22 | const metadataCompat = new DropMetadata(event.params.target.toHex()); 23 | metadataCompat.contractURI = event.params.contractURI; 24 | metadataCompat.extension = event.params.metadataExtension; 25 | metadataCompat.base = event.params.metadataBase; 26 | metadataCompat.freezeAt = event.params.freezeAt; 27 | metadataCompat.save(); 28 | 29 | const metadataLinkHistorical = new OnChainMetadataHistory( 30 | getOnChainMetadataKey(event) 31 | ); 32 | metadataLinkHistorical.rendererAddress = event.address; 33 | metadataLinkHistorical.createdAtBlock = event.block.number; 34 | metadataLinkHistorical.dropMetadata = metadata.id; 35 | metadataLinkHistorical.tokenAndContract = getDefaultTokenId( 36 | event.params.target 37 | ); 38 | 39 | const txn = makeTransaction(event); 40 | metadataLinkHistorical.txn = txn; 41 | metadataLinkHistorical.block = event.block.number; 42 | metadataLinkHistorical.timestamp = event.block.timestamp; 43 | metadataLinkHistorical.address = event.address; 44 | 45 | metadataLinkHistorical.knownType = METADATA_ERC721_DROP; 46 | metadataLinkHistorical.save(); 47 | 48 | // update contract uri 49 | const contract = ZoraCreateContract.load(event.params.target.toHex()); 50 | if (contract) { 51 | contract.contractURI = event.params.contractURI; 52 | 53 | // Update overall contract object uri from metadata path 54 | if (contract.contractURI) { 55 | const ipfsHostPath = getIPFSHostFromURI(contract.contractURI); 56 | if (ipfsHostPath !== null) { 57 | contract.metadata = ipfsHostPath; 58 | MetadataInfoTemplate.create(ipfsHostPath); 59 | } 60 | } 61 | 62 | contract.save(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /scripts/multideploy.sh: -------------------------------------------------------------------------------- 1 | # requirements: jq, curl, goldsky cli 2 | 3 | # enable errors 4 | set -e 5 | 6 | # arg 1 = version 7 | version=$1 8 | # arg 2 (optional) = networks 9 | networks=$2 10 | # arg 3 (optional) = fromversion 11 | fromversion=$3 12 | # arg 4 (optional) = fromcontract 13 | fromcontract=$4 14 | 15 | blockbuffer=10 16 | 17 | 18 | # production network tag 19 | prodtag=stable 20 | 21 | networkfiles=() 22 | if [[ -n $networks ]] 23 | then 24 | for p in ${networks//,/ }; do 25 | networkfiles+=("config/$p.json") 26 | done 27 | else 28 | for file in ./config/*.json; do 29 | networkfiles+=($file) 30 | done 31 | fi 32 | 33 | 34 | function getSubgraphQueryPath() { 35 | network=$1 36 | echo "https://api.goldsky.com/api/public/project_clhk16b61ay9t49vm6ntn4mkz/subgraphs/zora-create-$network/$fromversion/gn" 37 | } 38 | 39 | function getDeploymentBlock() { 40 | response=$(curl -sS $1 -X POST -H 'Accept: application/json' -H 'content-type: application/json' --data-raw '{"query":"{\n _meta{\n block {\n number\n }\n deployment\n }\n}"}') 41 | echo $response | jq '.data._meta.block.number' -r 42 | } 43 | 44 | function getDeploymentBase() { 45 | response=$(curl -sS $1 -X POST -H 'Accept: application/json' -H 'content-type: application/json' --data-raw '{"query":"{\n _meta{\n block {\n number\n }\n deployment\n }\n}"}') 46 | echo $response | jq '.data._meta.deployment' -r 47 | } 48 | 49 | function getNetworkDeploymentBlock() { 50 | startBlock=$(cat config/$1.json | jq "$fromcontract | map(.startBlock | tonumber) | max") 51 | echo $startBlock 52 | } 53 | 54 | 55 | for element in ${networkfiles[@]} 56 | do 57 | filename=$(basename $element) 58 | network="${filename%.*}" 59 | base=$(getSubgraphQueryPath $network) 60 | # newjson="" 61 | graft_flags="" 62 | if [[ -n $fromcontract ]]; then 63 | # newjson="$(jq '. + {"grafting": {"base": "'$(getDeploymentBase $base)'", "block": '$(($(getNetworkDeploymentBlock $network) - $blockbuffer))'}}' ./config/$network.json)" 64 | graft_flags="--graft-from zora-create-$network/$fromversion --start-block $(($(getNetworkDeploymentBlock $network) - $blockbuffer))" 65 | elif [[ -z $fromversion ]]; then 66 | echo 'skipping grafting' 67 | graft_flags="--remove-graft" 68 | # newjson="$(jq 'del(.grafting)' ./config/$network.json)" 69 | else 70 | # newjson="$(jq '. + {"grafting": {"base": "'$(getDeploymentBase $base)'", "block": '$(($(getDeploymentBlock $base) - $blockbuffer))'}}' ./config/$network.json)" 71 | graft_flags="--graft-from zora-create-$network/$fromversion --start-block $(($(getDeploymentBlock $base) - $blockbuffer))" 72 | fi 73 | # echo $newjson 74 | # echo "$newjson" > ./config/$network.json 75 | cat ./config/$network.json 76 | NETWORK=$network yarn run build 77 | echo goldsky subgraph deploy zora-create-$network/$version $graft_flags 78 | goldsky subgraph deploy zora-create-$network/$version $graft_flags 79 | done 80 | -------------------------------------------------------------------------------- /src/ERC1155Mappings/templates/ZoraCreatorFixedPriceSaleStrategyMappings.ts: -------------------------------------------------------------------------------- 1 | import { BigInt } from "@graphprotocol/graph-ts"; 2 | import { 3 | SalesConfigFixedPriceSaleStrategy, 4 | SalesStrategyConfig, 5 | MintComment 6 | } from "../../../generated/schema"; 7 | import { SaleSet } from "../../../generated/templates/ZoraCreatorFixedPriceSaleStrategy/ZoraCreatorFixedPriceSaleStrategy"; 8 | import { getSalesConfigKey } from "../../common/getSalesConfigKey"; 9 | import { getTokenId } from "../../common/getTokenId"; 10 | import { makeTransaction } from "../../common/makeTransaction"; 11 | import { SALE_CONFIG_FIXED_PRICE } from "../../constants/salesConfigTypes"; 12 | import { MintComment as Zora1155MintComment } from "../../../generated/templates/ZoraCreatorFixedPriceSaleStrategy/ZoraCreatorFixedPriceSaleStrategy"; 13 | import { getMintCommentId } from "../../common/getMintCommentId"; 14 | import { getContractId } from "../../common/getContractId"; 15 | 16 | export function handleFixedPriceStrategySaleSet(event: SaleSet): void { 17 | const id = getSalesConfigKey(event.address, event.params.mediaContract, event.params.tokenId) 18 | const sale = new SalesConfigFixedPriceSaleStrategy(id); 19 | sale.configAddress = event.address; 20 | sale.contract = getContractId(event.params.mediaContract); 21 | sale.fundsRecipient = event.params.salesConfig.fundsRecipient; 22 | sale.pricePerToken = event.params.salesConfig.pricePerToken; 23 | sale.saleStart = event.params.salesConfig.saleStart; 24 | sale.saleEnd = event.params.salesConfig.saleEnd; 25 | sale.maxTokensPerAddress = event.params.salesConfig.maxTokensPerAddress; 26 | 27 | const txn = makeTransaction(event); 28 | sale.txn = txn; 29 | sale.block = event.block.number; 30 | sale.timestamp = event.block.timestamp; 31 | sale.address = event.address; 32 | 33 | sale.tokenId = event.params.tokenId; 34 | sale.save(); 35 | 36 | // add join 37 | const saleJoin = new SalesStrategyConfig(id); 38 | if (event.params.tokenId.equals(BigInt.zero())) { 39 | saleJoin.contract = getContractId(event.params.mediaContract); 40 | } else { 41 | saleJoin.tokenAndContract = getTokenId(event.params.mediaContract, event.params.tokenId); 42 | } 43 | saleJoin.fixedPrice = id; 44 | saleJoin.type = SALE_CONFIG_FIXED_PRICE; 45 | saleJoin.txn = txn; 46 | saleJoin.block = event.block.number; 47 | saleJoin.timestamp = event.block.timestamp; 48 | saleJoin.address = event.address; 49 | saleJoin.save(); 50 | } 51 | 52 | export function handleMintedWithComment(event: Zora1155MintComment): void { 53 | const mintComment = new MintComment(getMintCommentId(event)); 54 | const tokenAndContract = getTokenId(event.params.tokenContract, event.params.tokenId); 55 | mintComment.tokenAndContract = tokenAndContract; 56 | mintComment.sender = event.params.sender; 57 | mintComment.comment = event.params.comment; 58 | mintComment.mintQuantity = event.params.quantity; 59 | mintComment.tokenId = event.params.tokenId; 60 | 61 | mintComment.txn = makeTransaction(event); 62 | mintComment.block = event.block.number; 63 | mintComment.timestamp = event.block.timestamp; 64 | mintComment.address = event.address; 65 | 66 | mintComment.save(); 67 | } -------------------------------------------------------------------------------- /tests/metadata.test.ts: -------------------------------------------------------------------------------- 1 | import { Address, BigInt, ethereum } from "@graphprotocol/graph-ts"; 2 | import { 3 | afterAll, 4 | assert, 5 | clearStore, 6 | describe, 7 | newMockEvent, 8 | test, 9 | } from "matchstick-as/assembly/index"; 10 | import { DropMetadata } from "../generated/schema"; 11 | import { MetadataUpdated } from "../generated/templates/DropMetadataRenderer/DropMetadataRenderer"; 12 | import { handleMetadataUpdated } from "../src/metadata"; 13 | 14 | describe("metadata", () => { 15 | afterAll(() => { 16 | clearStore(); 17 | }); 18 | describe("when entity does not exist", () => { 19 | test("handle creates new entity", () => { 20 | const mockEvent = newMockEvent(); 21 | mockEvent.parameters = [ 22 | new ethereum.EventParam( 23 | "target", 24 | ethereum.Value.fromAddress( 25 | Address.fromString("0xabcdefed93200601e1dfe26d6644758801d732e8") 26 | ) 27 | ), 28 | new ethereum.EventParam( 29 | "metadataBase", 30 | ethereum.Value.fromString("ipfs://bafy/") 31 | ), 32 | new ethereum.EventParam( 33 | "metadataExtension", 34 | ethereum.Value.fromString(".ipfs") 35 | ), 36 | new ethereum.EventParam( 37 | "contractURI", 38 | ethereum.Value.fromString("ipfs://bafy/contract.json") 39 | ), 40 | new ethereum.EventParam( 41 | "freezeAt", 42 | ethereum.Value.fromUnsignedBigInt(BigInt.fromString("2300230")) 43 | ), 44 | ]; 45 | handleMetadataUpdated(changetype(mockEvent)); 46 | const drop = DropMetadata.load(Address.fromString("0xabcdefed93200601e1dfe26d6644758801d732e8").toHex()) 47 | assert.stringEquals("ipfs://bafy/contract.json", drop!.contractURI); 48 | assert.stringEquals(".ipfs", drop!.extension); 49 | assert.stringEquals("ipfs://bafy/", drop!.base); 50 | assert.stringEquals("2300230", drop!.freezeAt.toString()); 51 | }); 52 | test("handles contract update", () => { 53 | const drop = new DropMetadata(Address.fromString("0xabcdefed93200601e1dfe26d6644758801d732e8").toHex()); 54 | drop.base = "WRONG"; 55 | drop.freezeAt = new BigInt(0); 56 | drop.save(); 57 | 58 | const mockEvent = newMockEvent(); 59 | mockEvent.parameters = [ 60 | new ethereum.EventParam( 61 | "target", 62 | ethereum.Value.fromAddress( 63 | Address.fromString("0xabcdefed93200601e1dfe26d6644758801d732e8") 64 | ) 65 | ), 66 | new ethereum.EventParam( 67 | "metadataBase", 68 | ethereum.Value.fromString("ipfs://bafy/") 69 | ), 70 | new ethereum.EventParam( 71 | "metadataExtension", 72 | ethereum.Value.fromString(".ipfs") 73 | ), 74 | new ethereum.EventParam( 75 | "contractURI", 76 | ethereum.Value.fromString("ipfs://bafy/contract.json") 77 | ), 78 | new ethereum.EventParam( 79 | "freezeAt", 80 | ethereum.Value.fromUnsignedBigInt(BigInt.fromString("2300230")) 81 | ), 82 | ]; 83 | handleMetadataUpdated(changetype(mockEvent)); 84 | const updatedDrop = DropMetadata.load(Address.fromString("0xabcdefed93200601e1dfe26d6644758801d732e8").toHex()) 85 | assert.stringEquals("ipfs://bafy/contract.json", updatedDrop!.contractURI); 86 | assert.stringEquals(".ipfs", updatedDrop!.extension); 87 | assert.stringEquals("ipfs://bafy/", updatedDrop!.base); 88 | assert.stringEquals("2300230", updatedDrop!.freezeAt.toString()); 89 | }); 90 | }); 91 | }); 92 | -------------------------------------------------------------------------------- /src/ReserveAuctionV3Mappings/reserveAuctionV3Mappings.ts: -------------------------------------------------------------------------------- 1 | import { Address, BigInt, Bytes, ethereum } from '@graphprotocol/graph-ts' 2 | import { Auction } from '../../generated/schema' 3 | import { 4 | AuctionCreated, 5 | AuctionBid, 6 | AuctionCanceled, 7 | AuctionEnded, 8 | AuctionReservePriceUpdated, 9 | } from '../../generated/ReserveAuctionV3/ReserveAuctionV3' 10 | import { makeTransaction } from '../common/makeTransaction' 11 | 12 | function getAuctionId(tokenContract: Address, tokenId: BigInt): string { 13 | return `${tokenContract.toHexString()}-${tokenId.toString()}` 14 | } 15 | 16 | export function handleAuctionCreated(event: AuctionCreated): void { 17 | const auctionId = getAuctionId( 18 | event.params.tokenContract, 19 | event.params.tokenId 20 | ) 21 | let auction = Auction.load(auctionId) 22 | if (!auction) { 23 | auction = new Auction(auctionId) 24 | } 25 | 26 | auction.address = event.address 27 | auction.block = event.block.number 28 | auction.timestamp = event.block.timestamp 29 | auction.txn = makeTransaction(event) 30 | 31 | auction.tokenContract = event.params.tokenContract 32 | auction.tokenId = event.params.tokenId 33 | auction.seller = event.params.auction.seller 34 | auction.sellerFundsRecipient = event.params.auction.sellerFundsRecipient 35 | auction.reservePrice = event.params.auction.reservePrice 36 | auction.highestBid = event.params.auction.highestBid 37 | auction.highestBidder = event.params.auction.highestBidder 38 | auction.startTime = event.params.auction.startTime 39 | auction.currency = event.params.auction.currency 40 | auction.firstBidTime = event.params.auction.firstBidTime 41 | auction.finder = event.params.auction.finder 42 | auction.duration = event.params.auction.duration 43 | auction.findersFeeBps = BigInt.fromI32(event.params.auction.findersFeeBps) 44 | 45 | auction.save() 46 | } 47 | 48 | export function handleAuctionReservePriceUpdated( 49 | event: AuctionReservePriceUpdated 50 | ): void { 51 | const auctionId = getAuctionId( 52 | event.params.tokenContract, 53 | event.params.tokenId 54 | ) 55 | let auction = Auction.load(auctionId) 56 | if (!auction) { 57 | return 58 | } 59 | 60 | auction.reservePrice = event.params.auction.reservePrice 61 | 62 | auction.save() 63 | } 64 | 65 | export function handleAuctionBid(event: AuctionBid): void { 66 | const auctionId = getAuctionId( 67 | event.params.tokenContract, 68 | event.params.tokenId 69 | ) 70 | let auction = Auction.load(auctionId) 71 | if (!auction) { 72 | return 73 | } 74 | 75 | auction.firstBidTime = event.params.auction.firstBidTime 76 | auction.highestBid = event.params.auction.highestBid 77 | auction.highestBidder = event.params.auction.highestBidder 78 | auction.finder = event.params.auction.finder 79 | auction.duration = event.params.auction.duration 80 | auction.extended = event.params.extended 81 | 82 | auction.save() 83 | } 84 | 85 | export function handleAuctionCanceled(event: AuctionCanceled): void { 86 | const auctionId = getAuctionId( 87 | event.params.tokenContract, 88 | event.params.tokenId 89 | ) 90 | let auction = Auction.load(auctionId) 91 | if (!auction) { 92 | return 93 | } 94 | 95 | auction.canceled = true 96 | 97 | auction.save() 98 | } 99 | 100 | export function handleAuctionEnded(event: AuctionEnded): void { 101 | const auctionId = getAuctionId(event.params.tokenContract, event.params.tokenId) 102 | let auction = Auction.load(auctionId) 103 | if (!auction) { 104 | return 105 | } 106 | 107 | auction.ended = true 108 | 109 | auction.save() 110 | } 111 | -------------------------------------------------------------------------------- /abis/EditionMetadataRenderer.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "Access_OnlyAdmin", 5 | "type": "error" 6 | }, 7 | { 8 | "anonymous": false, 9 | "inputs": [ 10 | { 11 | "indexed": true, 12 | "internalType": "address", 13 | "name": "target", 14 | "type": "address" 15 | }, 16 | { 17 | "indexed": false, 18 | "internalType": "address", 19 | "name": "sender", 20 | "type": "address" 21 | }, 22 | { 23 | "indexed": false, 24 | "internalType": "string", 25 | "name": "newDescription", 26 | "type": "string" 27 | } 28 | ], 29 | "name": "DescriptionUpdated", 30 | "type": "event" 31 | }, 32 | { 33 | "anonymous": false, 34 | "inputs": [ 35 | { 36 | "indexed": true, 37 | "internalType": "address", 38 | "name": "target", 39 | "type": "address" 40 | }, 41 | { 42 | "indexed": false, 43 | "internalType": "string", 44 | "name": "description", 45 | "type": "string" 46 | }, 47 | { 48 | "indexed": false, 49 | "internalType": "string", 50 | "name": "imageURI", 51 | "type": "string" 52 | }, 53 | { 54 | "indexed": false, 55 | "internalType": "string", 56 | "name": "animationURI", 57 | "type": "string" 58 | } 59 | ], 60 | "name": "EditionInitialized", 61 | "type": "event" 62 | }, 63 | { 64 | "anonymous": false, 65 | "inputs": [ 66 | { 67 | "indexed": true, 68 | "internalType": "address", 69 | "name": "target", 70 | "type": "address" 71 | }, 72 | { 73 | "indexed": false, 74 | "internalType": "address", 75 | "name": "sender", 76 | "type": "address" 77 | }, 78 | { 79 | "indexed": false, 80 | "internalType": "string", 81 | "name": "imageURI", 82 | "type": "string" 83 | }, 84 | { 85 | "indexed": false, 86 | "internalType": "string", 87 | "name": "animationURI", 88 | "type": "string" 89 | } 90 | ], 91 | "name": "MediaURIsUpdated", 92 | "type": "event" 93 | }, 94 | { 95 | "inputs": [], 96 | "name": "contractURI", 97 | "outputs": [ 98 | { 99 | "internalType": "string", 100 | "name": "", 101 | "type": "string" 102 | } 103 | ], 104 | "stateMutability": "view", 105 | "type": "function" 106 | }, 107 | { 108 | "inputs": [ 109 | { 110 | "internalType": "bytes", 111 | "name": "data", 112 | "type": "bytes" 113 | } 114 | ], 115 | "name": "initializeWithData", 116 | "outputs": [], 117 | "stateMutability": "nonpayable", 118 | "type": "function" 119 | }, 120 | { 121 | "inputs": [ 122 | { 123 | "internalType": "address", 124 | "name": "", 125 | "type": "address" 126 | } 127 | ], 128 | "name": "tokenInfos", 129 | "outputs": [ 130 | { 131 | "internalType": "string", 132 | "name": "description", 133 | "type": "string" 134 | }, 135 | { 136 | "internalType": "string", 137 | "name": "imageURI", 138 | "type": "string" 139 | }, 140 | { 141 | "internalType": "string", 142 | "name": "animationURI", 143 | "type": "string" 144 | } 145 | ], 146 | "stateMutability": "view", 147 | "type": "function" 148 | }, 149 | { 150 | "inputs": [ 151 | { 152 | "internalType": "uint256", 153 | "name": "tokenId", 154 | "type": "uint256" 155 | } 156 | ], 157 | "name": "tokenURI", 158 | "outputs": [ 159 | { 160 | "internalType": "string", 161 | "name": "", 162 | "type": "string" 163 | } 164 | ], 165 | "stateMutability": "view", 166 | "type": "function" 167 | }, 168 | { 169 | "inputs": [ 170 | { 171 | "internalType": "address", 172 | "name": "target", 173 | "type": "address" 174 | }, 175 | { 176 | "internalType": "string", 177 | "name": "newDescription", 178 | "type": "string" 179 | } 180 | ], 181 | "name": "updateDescription", 182 | "outputs": [], 183 | "stateMutability": "nonpayable", 184 | "type": "function" 185 | }, 186 | { 187 | "inputs": [ 188 | { 189 | "internalType": "address", 190 | "name": "target", 191 | "type": "address" 192 | }, 193 | { 194 | "internalType": "string", 195 | "name": "imageURI", 196 | "type": "string" 197 | }, 198 | { 199 | "internalType": "string", 200 | "name": "animationURI", 201 | "type": "string" 202 | } 203 | ], 204 | "name": "updateMediaURIs", 205 | "outputs": [], 206 | "stateMutability": "nonpayable", 207 | "type": "function" 208 | } 209 | ] 210 | -------------------------------------------------------------------------------- /src/ERC1155Mappings/factoryMappings.ts: -------------------------------------------------------------------------------- 1 | import { 2 | SetupNewContract, 3 | Upgraded, 4 | ZoraCreator1155FactoryImpl, 5 | } from "../../generated/ZoraNFTCreatorFactory1155V1/ZoraCreator1155FactoryImpl"; 6 | 7 | import { 8 | Upgrade, 9 | ZoraCreate1155Factory, 10 | ZoraCreateContract, 11 | } from "../../generated/schema"; 12 | import { 13 | ZoraCreator1155Impl as ZoraCreator1155ImplTemplate, 14 | MetadataInfo as MetadataInfoTemplate, 15 | ZoraCreatorFixedPriceSaleStrategy, 16 | ZoraCreatorMerkleMinterStrategy, 17 | ZoraCreatorRedeemMinterFactory, 18 | } from "../../generated/templates"; 19 | import { makeTransaction } from "../common/makeTransaction"; 20 | import { getIPFSHostFromURI } from "../common/getIPFSHostFromURI"; 21 | import { TOKEN_STANDARD_ERC1155 } from "../constants/tokenStandard"; 22 | import { ZoraCreator1155Impl } from "../../generated/templates/ZoraCreator1155Impl/ZoraCreator1155Impl"; 23 | import { getContractId } from "../common/getContractId"; 24 | import { 25 | extractIPFSIDFromContract, 26 | loadMetadataInfoFromID, 27 | } from "../common/metadata"; 28 | import { BigInt } from "@graphprotocol/graph-ts"; 29 | 30 | export function handleNewContractCreated(event: SetupNewContract): void { 31 | const createdContract = new ZoraCreateContract( 32 | getContractId(event.params.newContract) 33 | ); 34 | 35 | createdContract.address = event.params.newContract; 36 | createdContract.contractStandard = TOKEN_STANDARD_ERC1155; 37 | createdContract.contractURI = event.params.contractURI; 38 | 39 | // The creator being msg.sender cannot be guaranteed for premint 40 | createdContract.creator = event.params.defaultAdmin; 41 | 42 | createdContract.initialDefaultAdmin = event.params.defaultAdmin; 43 | createdContract.owner = event.params.defaultAdmin; 44 | createdContract.name = event.params.name; 45 | createdContract.symbol = null; 46 | createdContract.contractVersion = createdContract.contractVersion; 47 | createdContract.rendererContract = createdContract.rendererContract; 48 | 49 | const ipfsHostPath = getIPFSHostFromURI(event.params.contractURI); 50 | if (ipfsHostPath !== null) { 51 | createdContract.metadata = ipfsHostPath; 52 | MetadataInfoTemplate.create(ipfsHostPath); 53 | } 54 | 55 | const txn = makeTransaction(event); 56 | createdContract.txn = txn; 57 | createdContract.block = event.block.number; 58 | createdContract.address = event.params.newContract; 59 | createdContract.timestamp = event.block.timestamp; 60 | 61 | createdContract.createdAtBlock = event.block.number; 62 | 63 | // query for more information about contract 64 | const impl = ZoraCreator1155Impl.bind(event.params.newContract); 65 | 66 | // temporary fix: testnet deploy temporarily removed this function 67 | const attemptMintFee = impl.try_mintFee(); 68 | if (attemptMintFee.reverted) { 69 | createdContract.mintFeePerQuantity = BigInt.fromI64(777000000000000); 70 | } else { 71 | createdContract.mintFeePerQuantity = attemptMintFee.value; 72 | } 73 | createdContract.contractVersion = impl.contractVersion(); 74 | createdContract.contractStandard = TOKEN_STANDARD_ERC1155; 75 | 76 | createdContract.metadataIPFSID = extractIPFSIDFromContract( 77 | impl.try_contractURI() 78 | ); 79 | createdContract.metadata = loadMetadataInfoFromID( 80 | createdContract.metadataIPFSID 81 | ); 82 | 83 | createdContract.save(); 84 | 85 | ZoraCreator1155ImplTemplate.create(event.params.newContract); 86 | } 87 | 88 | export function handle1155FactoryUpgraded(event: Upgraded): void { 89 | const upgrade = new Upgrade( 90 | `${event.transaction.hash.toHex()}-${event.transactionLogIndex}` 91 | ); 92 | const factory = new ZoraCreate1155Factory(event.address.toHex()); 93 | const creator = ZoraCreator1155FactoryImpl.bind(event.address); 94 | 95 | // Handle bad upgrade, do not remove. 96 | if (creator.try_fixedPriceMinter().reverted) { 97 | return; 98 | } 99 | 100 | // Create child factory listeners 101 | ZoraCreatorFixedPriceSaleStrategy.create(creator.fixedPriceMinter()); 102 | ZoraCreatorMerkleMinterStrategy.create(creator.merkleMinter()); 103 | 104 | // Check if this version supports the redeem factory 105 | const redeemFactory = creator.try_redeemMinterFactory(); 106 | if (!redeemFactory.reverted) { 107 | ZoraCreatorRedeemMinterFactory.create(redeemFactory.value); 108 | factory.redeemMinterStrategyAddress = redeemFactory.value; 109 | } 110 | 111 | const txn = makeTransaction(event); 112 | upgrade.txn = txn; 113 | upgrade.block = event.block.number; 114 | upgrade.timestamp = event.block.timestamp; 115 | upgrade.impl = event.params.implementation; 116 | upgrade.address = event.address; 117 | upgrade.type = "1155Factory"; 118 | 119 | // Save required factories. 120 | factory.txn = txn; 121 | factory.block = event.block.number; 122 | factory.timestamp = event.block.timestamp; 123 | 124 | factory.fixedPriceSaleStrategyAddress = creator.fixedPriceMinter(); 125 | factory.merkleSaleStrategyAddress = creator.merkleMinter(); 126 | factory.implementation = event.params.implementation; 127 | factory.version = creator.contractVersion(); 128 | 129 | upgrade.save(); 130 | factory.save(); 131 | } 132 | -------------------------------------------------------------------------------- /src/ERC721Mappings/templates/EditionMetadataRendererMappings.ts: -------------------------------------------------------------------------------- 1 | import { 2 | EditionInitialized, 3 | MediaURIsUpdated, 4 | DescriptionUpdated, 5 | } from "../../../generated/templates/EditionMetadataRenderer/EditionMetadataRenderer"; 6 | import { 7 | EditionMetadata, 8 | OnChainMetadataHistory, 9 | ZoraCreateContract, 10 | } from "../../../generated/schema"; 11 | import { getDefaultTokenId } from "../../common/getTokenId"; 12 | import { makeTransaction } from "../../common/makeTransaction"; 13 | import { EditionMetadataRenderer } from "../../../generated/templates/EditionMetadataRenderer/EditionMetadataRenderer"; 14 | import { ERC721Drop as ERC721DropFactory } from "../../../generated/templates/ERC721Drop/ERC721Drop"; 15 | import { Address } from "@graphprotocol/graph-ts"; 16 | import { METADATA_ERC721_EDITION } from "../../constants/metadataHistoryTypes"; 17 | import { getOnChainMetadataKey } from "../../common/getOnChainMetadataKey"; 18 | import { 19 | extractIPFSIDFromContract, 20 | loadMetadataInfoFromID, 21 | } from "../../common/metadata"; 22 | 23 | export function handleCreatedEdition(event: EditionInitialized): void { 24 | const metadataRecord = new EditionMetadata(getOnChainMetadataKey(event)); 25 | metadataRecord.animationURI = event.params.animationURI; 26 | metadataRecord.description = event.params.description; 27 | metadataRecord.imageURI = event.params.imageURI; 28 | metadataRecord.save(); 29 | 30 | const metadataLinkHistory = new OnChainMetadataHistory( 31 | getOnChainMetadataKey(event) 32 | ); 33 | metadataLinkHistory.rendererAddress = event.address; 34 | metadataLinkHistory.createdAtBlock = event.block.number; 35 | metadataLinkHistory.editionMetadata = metadataRecord.id; 36 | metadataLinkHistory.tokenAndContract = getDefaultTokenId(event.params.target); 37 | 38 | const txn = makeTransaction(event); 39 | metadataLinkHistory.txn = txn; 40 | metadataLinkHistory.block = event.block.number; 41 | metadataLinkHistory.address = event.address; 42 | metadataLinkHistory.timestamp = event.block.timestamp; 43 | 44 | metadataLinkHistory.knownType = METADATA_ERC721_EDITION; 45 | metadataLinkHistory.save(); 46 | 47 | updateContractURI(event.params.target); 48 | } 49 | 50 | export function handleUpdateMediaURIs(event: MediaURIsUpdated): void { 51 | const metadataRenderer = EditionMetadataRenderer.bind(event.address); 52 | const tokenInfo = metadataRenderer.tokenInfos(event.params.target); 53 | 54 | const newMetadata = new EditionMetadata(getOnChainMetadataKey(event)); 55 | newMetadata.animationURI = event.params.animationURI; 56 | newMetadata.description = tokenInfo.getDescription(); 57 | newMetadata.imageURI = event.params.imageURI; 58 | newMetadata.save(); 59 | 60 | const metadataLinkHistory = new OnChainMetadataHistory( 61 | getOnChainMetadataKey(event) 62 | ); 63 | metadataLinkHistory.address = event.address; 64 | metadataLinkHistory.block = event.block.number; 65 | metadataLinkHistory.timestamp = event.block.timestamp; 66 | 67 | metadataLinkHistory.rendererAddress = event.address; 68 | metadataLinkHistory.createdAtBlock = event.block.number; 69 | metadataLinkHistory.editionMetadata = newMetadata.id; 70 | metadataLinkHistory.tokenAndContract = getDefaultTokenId(event.params.target); 71 | metadataLinkHistory.txn = makeTransaction(event); 72 | metadataLinkHistory.knownType = METADATA_ERC721_EDITION; 73 | metadataLinkHistory.save(); 74 | 75 | updateContractURI(event.params.target); 76 | } 77 | 78 | export function handleUpdateDescription(event: DescriptionUpdated): void { 79 | const metadataRenderer = EditionMetadataRenderer.bind(event.address); 80 | 81 | const tokenInfo = metadataRenderer.tokenInfos(event.params.target); 82 | 83 | const newMetadata = new EditionMetadata(getOnChainMetadataKey(event)); 84 | newMetadata.description = event.params.newDescription; 85 | newMetadata.imageURI = tokenInfo.getImageURI(); 86 | newMetadata.animationURI = tokenInfo.getAnimationURI(); 87 | newMetadata.save(); 88 | 89 | const metadataLinkHistory = new OnChainMetadataHistory( 90 | getOnChainMetadataKey(event) 91 | ); 92 | metadataLinkHistory.rendererAddress = event.address; 93 | metadataLinkHistory.createdAtBlock = event.block.number; 94 | metadataLinkHistory.editionMetadata = newMetadata.id; 95 | metadataLinkHistory.tokenAndContract = getDefaultTokenId(event.params.target); 96 | 97 | const txn = makeTransaction(event); 98 | metadataLinkHistory.txn = txn; 99 | metadataLinkHistory.address = event.address; 100 | metadataLinkHistory.block = event.block.number; 101 | metadataLinkHistory.timestamp = event.block.timestamp; 102 | 103 | metadataLinkHistory.knownType = METADATA_ERC721_EDITION; 104 | metadataLinkHistory.save(); 105 | 106 | updateContractURI(event.params.target); 107 | } 108 | 109 | function updateContractURI(target: Address): void { 110 | // update contract uri from drop string 111 | const contract = ZoraCreateContract.load(target.toHex()); 112 | if (contract) { 113 | const erc721Drop = ERC721DropFactory.bind(target); 114 | if (erc721Drop) { 115 | const attempt_contractURI = erc721Drop.try_contractURI(); 116 | if (!attempt_contractURI.reverted) { 117 | contract.contractURI = attempt_contractURI.value; 118 | } 119 | contract.metadataIPFSID = extractIPFSIDFromContract(attempt_contractURI); 120 | contract.metadata = loadMetadataInfoFromID(contract.metadataIPFSID); 121 | contract.save(); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /abis/DropMetadataRenderer.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "name": "Access_OnlyAdmin", 5 | "type": "error" 6 | }, 7 | { 8 | "inputs": [], 9 | "name": "MetadataFrozen", 10 | "type": "error" 11 | }, 12 | { 13 | "anonymous": false, 14 | "inputs": [ 15 | { 16 | "indexed": true, 17 | "internalType": "address", 18 | "name": "target", 19 | "type": "address" 20 | }, 21 | { 22 | "indexed": false, 23 | "internalType": "string", 24 | "name": "metadataBase", 25 | "type": "string" 26 | }, 27 | { 28 | "indexed": false, 29 | "internalType": "string", 30 | "name": "metadataExtension", 31 | "type": "string" 32 | }, 33 | { 34 | "indexed": false, 35 | "internalType": "string", 36 | "name": "contractURI", 37 | "type": "string" 38 | }, 39 | { 40 | "indexed": false, 41 | "internalType": "uint256", 42 | "name": "freezeAt", 43 | "type": "uint256" 44 | } 45 | ], 46 | "name": "MetadataUpdated", 47 | "type": "event" 48 | }, 49 | { 50 | "anonymous": false, 51 | "inputs": [ 52 | { 53 | "indexed": true, 54 | "internalType": "address", 55 | "name": "target", 56 | "type": "address" 57 | }, 58 | { 59 | "indexed": false, 60 | "internalType": "bytes32", 61 | "name": "provenanceHash", 62 | "type": "bytes32" 63 | } 64 | ], 65 | "name": "ProvenanceHashUpdated", 66 | "type": "event" 67 | }, 68 | { 69 | "inputs": [], 70 | "name": "contractURI", 71 | "outputs": [ 72 | { 73 | "internalType": "string", 74 | "name": "", 75 | "type": "string" 76 | } 77 | ], 78 | "stateMutability": "view", 79 | "type": "function" 80 | }, 81 | { 82 | "inputs": [ 83 | { 84 | "internalType": "bytes", 85 | "name": "data", 86 | "type": "bytes" 87 | } 88 | ], 89 | "name": "initializeWithData", 90 | "outputs": [], 91 | "stateMutability": "nonpayable", 92 | "type": "function" 93 | }, 94 | { 95 | "inputs": [ 96 | { 97 | "internalType": "address", 98 | "name": "", 99 | "type": "address" 100 | } 101 | ], 102 | "name": "metadataBaseByContract", 103 | "outputs": [ 104 | { 105 | "internalType": "string", 106 | "name": "base", 107 | "type": "string" 108 | }, 109 | { 110 | "internalType": "string", 111 | "name": "extension", 112 | "type": "string" 113 | }, 114 | { 115 | "internalType": "string", 116 | "name": "contractURI", 117 | "type": "string" 118 | }, 119 | { 120 | "internalType": "uint256", 121 | "name": "freezeAt", 122 | "type": "uint256" 123 | } 124 | ], 125 | "stateMutability": "view", 126 | "type": "function" 127 | }, 128 | { 129 | "inputs": [ 130 | { 131 | "internalType": "address", 132 | "name": "", 133 | "type": "address" 134 | } 135 | ], 136 | "name": "provenanceHashes", 137 | "outputs": [ 138 | { 139 | "internalType": "bytes32", 140 | "name": "", 141 | "type": "bytes32" 142 | } 143 | ], 144 | "stateMutability": "view", 145 | "type": "function" 146 | }, 147 | { 148 | "inputs": [ 149 | { 150 | "internalType": "uint256", 151 | "name": "tokenId", 152 | "type": "uint256" 153 | } 154 | ], 155 | "name": "tokenURI", 156 | "outputs": [ 157 | { 158 | "internalType": "string", 159 | "name": "", 160 | "type": "string" 161 | } 162 | ], 163 | "stateMutability": "view", 164 | "type": "function" 165 | }, 166 | { 167 | "inputs": [ 168 | { 169 | "internalType": "address", 170 | "name": "target", 171 | "type": "address" 172 | }, 173 | { 174 | "internalType": "string", 175 | "name": "baseUri", 176 | "type": "string" 177 | }, 178 | { 179 | "internalType": "string", 180 | "name": "newContractUri", 181 | "type": "string" 182 | } 183 | ], 184 | "name": "updateMetadataBase", 185 | "outputs": [], 186 | "stateMutability": "nonpayable", 187 | "type": "function" 188 | }, 189 | { 190 | "inputs": [ 191 | { 192 | "internalType": "address", 193 | "name": "target", 194 | "type": "address" 195 | }, 196 | { 197 | "internalType": "string", 198 | "name": "metadataBase", 199 | "type": "string" 200 | }, 201 | { 202 | "internalType": "string", 203 | "name": "metadataExtension", 204 | "type": "string" 205 | }, 206 | { 207 | "internalType": "string", 208 | "name": "newContractURI", 209 | "type": "string" 210 | }, 211 | { 212 | "internalType": "uint256", 213 | "name": "freezeAt", 214 | "type": "uint256" 215 | } 216 | ], 217 | "name": "updateMetadataBaseWithDetails", 218 | "outputs": [], 219 | "stateMutability": "nonpayable", 220 | "type": "function" 221 | }, 222 | { 223 | "inputs": [ 224 | { 225 | "internalType": "address", 226 | "name": "target", 227 | "type": "address" 228 | }, 229 | { 230 | "internalType": "bytes32", 231 | "name": "provenanceHash", 232 | "type": "bytes32" 233 | } 234 | ], 235 | "name": "updateProvenanceHash", 236 | "outputs": [], 237 | "stateMutability": "nonpayable", 238 | "type": "function" 239 | } 240 | ] 241 | -------------------------------------------------------------------------------- /src/ERC1155Mappings/templates/ZoraCreatorRedeemMinterStrategy.ts: -------------------------------------------------------------------------------- 1 | import { BigInt } from "@graphprotocol/graph-ts"; 2 | import { 3 | RedeemInstructions, 4 | RedeemMinterProcessed, 5 | RedeemMintToken, 6 | RedeemProcessedTokenPair, 7 | SalesConfigRedeemMinterStrategy, 8 | SalesStrategyConfig, 9 | } from "../../../generated/schema"; 10 | import { 11 | RedeemProcessed, 12 | RedeemsCleared, 13 | RedeemSet, 14 | } from "../../../generated/templates/ZoraCreatorRedeemMinterStrategy/ZoraCreatorRedeemMinterStrategy"; 15 | import { getTokenId } from "../../common/getTokenId"; 16 | import { makeTransaction } from "../../common/makeTransaction"; 17 | import { SALE_CONFIG_REDEEM_STRATEGY } from "../../constants/salesConfigTypes"; 18 | import { getContractId } from "../../common/getContractId"; 19 | 20 | export function handleRedeemCleared(event: RedeemsCleared): void { 21 | for (let i = 0; i < event.params.redeemInstructionsHashes.length; i++) { 22 | const redeem = SalesConfigRedeemMinterStrategy.load( 23 | `${event.params.redeemInstructionsHashes[i]}` 24 | ); 25 | 26 | if (redeem) { 27 | redeem.isActive = false; 28 | redeem.save(); 29 | } 30 | } 31 | } 32 | 33 | export function handleRedeemProcessed(event: RedeemProcessed): void { 34 | const id = `${event.transaction.hash.toHex()}`; 35 | const processed = new RedeemMinterProcessed(id); 36 | 37 | const txn = makeTransaction(event); 38 | processed.txn = txn; 39 | processed.block = event.block.number; 40 | processed.timestamp = event.block.timestamp; 41 | processed.address = event.address; 42 | 43 | processed.redeemMinter = event.params.redeemsInstructionsHash.toHex(); 44 | processed.target = event.params.target; 45 | processed.redeemsInstructionsHash = event.params.redeemsInstructionsHash; 46 | processed.sender = event.params.sender; 47 | 48 | for (let i = 0; i < event.params.amounts.length; i++) { 49 | const pair = new RedeemProcessedTokenPair(`${id}-redeemed-${i}`); 50 | pair.processed = id; 51 | pair.index = i; 52 | pair.amounts = event.params.amounts[i]; 53 | pair.tokenIds = event.params.tokenIds[i]; 54 | pair.save(); 55 | } 56 | 57 | processed.save(); 58 | } 59 | 60 | export function handleRedeemSet(event: RedeemSet): void { 61 | const transactionHash = event.transaction.hash.toHex(); 62 | const redemptionHash = event.params.redeemsInstructionsHash.toHex(); 63 | const txn = makeTransaction(event); 64 | 65 | let token = RedeemMintToken.load(redemptionHash); 66 | if (token === null) { 67 | token = new RedeemMintToken(redemptionHash); 68 | } 69 | 70 | token.tokenContract = event.params.data.mintToken.tokenContract; 71 | token.tokenId = event.params.data.mintToken.tokenId; 72 | token.amount = event.params.data.mintToken.amount; 73 | token.tokenType = event.params.data.mintToken.tokenType; 74 | token.save(); 75 | 76 | let strategy = SalesConfigRedeemMinterStrategy.load(redemptionHash); 77 | if (strategy === null) { 78 | strategy = new SalesConfigRedeemMinterStrategy(redemptionHash); 79 | } 80 | 81 | strategy.txn = txn; 82 | strategy.block = event.block.number; 83 | strategy.timestamp = event.block.timestamp; 84 | strategy.address = event.address; 85 | strategy.configAddress = event.address; 86 | strategy.target = event.params.target; 87 | strategy.redeemsInstructionsHash = event.params.redeemsInstructionsHash; 88 | strategy.saleStart = event.params.data.saleStart; 89 | strategy.saleEnd = event.params.data.saleEnd; 90 | strategy.ethAmount = event.params.data.ethAmount; 91 | strategy.ethRecipient = event.params.data.ethRecipient; 92 | strategy.isActive = true; 93 | strategy.redeemMintToken = token.id; 94 | strategy.save(); 95 | 96 | for (let i = 0; i < event.params.data.instructions.length; i++) { 97 | // This can fail for duplicate Redeem Instructions – while it doesn't make sense that the user can input this 98 | // the safest way to index these is by array index. Transaction hash added for uniqueness. 99 | const id = `${redemptionHash}-${i}-${transactionHash}` 100 | 101 | let redeemInstruction = RedeemInstructions.load(id); 102 | if (redeemInstruction === null) { 103 | redeemInstruction = new RedeemInstructions(id); 104 | } 105 | 106 | redeemInstruction.tokenType = event.params.data.instructions[i].tokenType; 107 | redeemInstruction.amount = event.params.data.instructions[i].amount; 108 | redeemInstruction.tokenIdStart = 109 | event.params.data.instructions[i].tokenIdStart; 110 | redeemInstruction.tokenIdEnd = event.params.data.instructions[i].tokenIdEnd; 111 | redeemInstruction.transferRecipient = 112 | event.params.data.instructions[i].transferRecipient; 113 | redeemInstruction.tokenContract = 114 | event.params.data.instructions[i].tokenContract; 115 | redeemInstruction.burnFunction = 116 | event.params.data.instructions[i].burnFunction; 117 | redeemInstruction.redeemMinter = strategy.id; 118 | redeemInstruction.save(); 119 | } 120 | 121 | // add join 122 | let saleJoin = SalesStrategyConfig.load(redemptionHash); 123 | if (saleJoin === null) { 124 | saleJoin = new SalesStrategyConfig(redemptionHash); 125 | } 126 | 127 | if (event.params.data.mintToken.tokenId.equals(BigInt.zero())) { 128 | saleJoin.contract = getContractId(event.params.data.mintToken.tokenContract); 129 | } else { 130 | saleJoin.tokenAndContract = getTokenId( 131 | event.params.data.mintToken.tokenContract, 132 | event.params.data.mintToken.tokenId 133 | ); 134 | } 135 | saleJoin.block = event.block.number; 136 | saleJoin.address = event.address; 137 | saleJoin.timestamp = event.block.timestamp; 138 | saleJoin.redeemMinter = strategy.id; 139 | saleJoin.type = SALE_CONFIG_REDEEM_STRATEGY; 140 | saleJoin.txn = txn; 141 | saleJoin.save(); 142 | } 143 | -------------------------------------------------------------------------------- /abis/ZoraCreatorRedeemMinterFactory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "constructor", 4 | "inputs": [], 5 | "stateMutability": "nonpayable" 6 | }, 7 | { 8 | "type": "function", 9 | "name": "CONTRACT_BASE_ID", 10 | "inputs": [], 11 | "outputs": [ 12 | { 13 | "name": "", 14 | "type": "uint256", 15 | "internalType": "uint256" 16 | } 17 | ], 18 | "stateMutability": "view" 19 | }, 20 | { 21 | "type": "function", 22 | "name": "contractName", 23 | "inputs": [], 24 | "outputs": [ 25 | { 26 | "name": "", 27 | "type": "string", 28 | "internalType": "string" 29 | } 30 | ], 31 | "stateMutability": "pure" 32 | }, 33 | { 34 | "type": "function", 35 | "name": "contractURI", 36 | "inputs": [], 37 | "outputs": [ 38 | { 39 | "name": "", 40 | "type": "string", 41 | "internalType": "string" 42 | } 43 | ], 44 | "stateMutability": "pure" 45 | }, 46 | { 47 | "type": "function", 48 | "name": "contractVersion", 49 | "inputs": [], 50 | "outputs": [ 51 | { 52 | "name": "", 53 | "type": "string", 54 | "internalType": "string" 55 | } 56 | ], 57 | "stateMutability": "pure" 58 | }, 59 | { 60 | "type": "function", 61 | "name": "createMinterIfNoneExists", 62 | "inputs": [], 63 | "outputs": [], 64 | "stateMutability": "nonpayable" 65 | }, 66 | { 67 | "type": "function", 68 | "name": "doesRedeemMinterExistForCreatorContract", 69 | "inputs": [ 70 | { 71 | "name": "_creatorContract", 72 | "type": "address", 73 | "internalType": "address" 74 | } 75 | ], 76 | "outputs": [ 77 | { 78 | "name": "", 79 | "type": "bool", 80 | "internalType": "bool" 81 | } 82 | ], 83 | "stateMutability": "view" 84 | }, 85 | { 86 | "type": "function", 87 | "name": "getDeployedRedeemMinterForCreatorContract", 88 | "inputs": [ 89 | { 90 | "name": "_creatorContract", 91 | "type": "address", 92 | "internalType": "address" 93 | } 94 | ], 95 | "outputs": [ 96 | { 97 | "name": "", 98 | "type": "address", 99 | "internalType": "address" 100 | } 101 | ], 102 | "stateMutability": "view" 103 | }, 104 | { 105 | "type": "function", 106 | "name": "predictMinterAddress", 107 | "inputs": [ 108 | { 109 | "name": "_creatorContract", 110 | "type": "address", 111 | "internalType": "address" 112 | } 113 | ], 114 | "outputs": [ 115 | { 116 | "name": "", 117 | "type": "address", 118 | "internalType": "address" 119 | } 120 | ], 121 | "stateMutability": "view" 122 | }, 123 | { 124 | "type": "function", 125 | "name": "requestMint", 126 | "inputs": [ 127 | { 128 | "name": "sender", 129 | "type": "address", 130 | "internalType": "address" 131 | }, 132 | { 133 | "name": "tokenId", 134 | "type": "uint256", 135 | "internalType": "uint256" 136 | }, 137 | { 138 | "name": "quantity", 139 | "type": "uint256", 140 | "internalType": "uint256" 141 | }, 142 | { 143 | "name": "ethValueSent", 144 | "type": "uint256", 145 | "internalType": "uint256" 146 | }, 147 | { 148 | "name": "minterArguments", 149 | "type": "bytes", 150 | "internalType": "bytes" 151 | } 152 | ], 153 | "outputs": [ 154 | { 155 | "name": "commands", 156 | "type": "tuple", 157 | "internalType": "struct ICreatorCommands.CommandSet", 158 | "components": [ 159 | { 160 | "name": "commands", 161 | "type": "tuple[]", 162 | "internalType": "struct ICreatorCommands.Command[]", 163 | "components": [ 164 | { 165 | "name": "method", 166 | "type": "uint8", 167 | "internalType": "enum ICreatorCommands.CreatorActions" 168 | }, 169 | { 170 | "name": "args", 171 | "type": "bytes", 172 | "internalType": "bytes" 173 | } 174 | ] 175 | }, 176 | { 177 | "name": "at", 178 | "type": "uint256", 179 | "internalType": "uint256" 180 | } 181 | ] 182 | } 183 | ], 184 | "stateMutability": "nonpayable" 185 | }, 186 | { 187 | "type": "function", 188 | "name": "supportsInterface", 189 | "inputs": [ 190 | { 191 | "name": "interfaceId", 192 | "type": "bytes4", 193 | "internalType": "bytes4" 194 | } 195 | ], 196 | "outputs": [ 197 | { 198 | "name": "", 199 | "type": "bool", 200 | "internalType": "bool" 201 | } 202 | ], 203 | "stateMutability": "pure" 204 | }, 205 | { 206 | "type": "function", 207 | "name": "zoraRedeemMinterImplementation", 208 | "inputs": [], 209 | "outputs": [ 210 | { 211 | "name": "", 212 | "type": "address", 213 | "internalType": "address" 214 | } 215 | ], 216 | "stateMutability": "view" 217 | }, 218 | { 219 | "type": "event", 220 | "name": "RedeemMinterDeployed", 221 | "inputs": [ 222 | { 223 | "name": "creatorContract", 224 | "type": "address", 225 | "indexed": true, 226 | "internalType": "address" 227 | }, 228 | { 229 | "name": "minterContract", 230 | "type": "address", 231 | "indexed": true, 232 | "internalType": "address" 233 | } 234 | ], 235 | "anonymous": false 236 | }, 237 | { 238 | "type": "error", 239 | "name": "CallerNotZoraCreator1155", 240 | "inputs": [] 241 | }, 242 | { 243 | "type": "error", 244 | "name": "InvalidMerkleProof", 245 | "inputs": [ 246 | { 247 | "name": "mintTo", 248 | "type": "address", 249 | "internalType": "address" 250 | }, 251 | { 252 | "name": "merkleProof", 253 | "type": "bytes32[]", 254 | "internalType": "bytes32[]" 255 | }, 256 | { 257 | "name": "merkleRoot", 258 | "type": "bytes32", 259 | "internalType": "bytes32" 260 | } 261 | ] 262 | }, 263 | { 264 | "type": "error", 265 | "name": "MinterContractAlreadyExists", 266 | "inputs": [] 267 | }, 268 | { 269 | "type": "error", 270 | "name": "MinterContractDoesNotExist", 271 | "inputs": [] 272 | }, 273 | { 274 | "type": "error", 275 | "name": "SaleEnded", 276 | "inputs": [] 277 | }, 278 | { 279 | "type": "error", 280 | "name": "SaleHasNotStarted", 281 | "inputs": [] 282 | }, 283 | { 284 | "type": "error", 285 | "name": "WrongValueSent", 286 | "inputs": [] 287 | } 288 | ] 289 | -------------------------------------------------------------------------------- /src/ERC721Mappings/ERC721FactoryMappings.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DropMetadataRenderer as DropMetadataRendererFactory, 3 | EditionMetadataRenderer as EditionMetadataRendererFactory, 4 | } from "../../generated/templates"; 5 | 6 | import { 7 | Upgrade, 8 | ZoraCreateContract, 9 | ZoraCreate721Factory, 10 | ZoraCreateToken, 11 | RoyaltyConfig, 12 | KnownRenderer, 13 | } from "../../generated/schema"; 14 | 15 | import { 16 | CreatedDrop, 17 | Upgraded, 18 | ZoraNFTCreatorV1, 19 | } from "../../generated/Zora721V1/ZoraNFTCreatorV1"; 20 | 21 | import { makeTransaction } from "../common/makeTransaction"; 22 | 23 | import { ERC721Drop as ERC721DropContract } from "../../generated/templates/ERC721Drop/ERC721Drop"; 24 | import { getIPFSHostFromURI } from "../common/getIPFSHostFromURI"; 25 | import { ERC721Drop as ERC721DropTemplate } from "../../generated/templates"; 26 | import { BigInt } from "@graphprotocol/graph-ts"; 27 | import { getDefaultTokenId } from "../common/getTokenId"; 28 | import { TOKEN_STANDARD_ERC721 } from "../constants/tokenStandard"; 29 | import { getContractId } from "../common/getContractId"; 30 | import { 31 | extractIPFSIDFromContract, 32 | loadMetadataInfoFromID, 33 | } from "../common/metadata"; 34 | 35 | export function handleFactoryUpgraded(event: Upgraded): void { 36 | const upgrade = new Upgrade( 37 | `${event.transaction.hash.toHex()}-${event.transactionLogIndex}` 38 | ); 39 | const factory = new ZoraCreate721Factory(event.address.toHex()); 40 | const creator = ZoraNFTCreatorV1.bind(event.address); 41 | 42 | if (creator.try_dropMetadataRenderer().reverted) { 43 | return; 44 | } 45 | const dropRendererAddress = creator.dropMetadataRenderer(); 46 | 47 | if (creator.try_editionMetadataRenderer().reverted) { 48 | return; 49 | } 50 | const editionRendererAddress = creator.editionMetadataRenderer(); 51 | 52 | DropMetadataRendererFactory.create(dropRendererAddress); 53 | EditionMetadataRendererFactory.create(editionRendererAddress); 54 | 55 | if (!KnownRenderer.load(dropRendererAddress.toHex())) { 56 | const knownDropRenderer = new KnownRenderer(dropRendererAddress.toHex()); 57 | const txn = makeTransaction(event); 58 | knownDropRenderer.txn = txn; 59 | knownDropRenderer.address = dropRendererAddress; 60 | knownDropRenderer.block = event.block.number; 61 | knownDropRenderer.timestamp = event.block.timestamp; 62 | knownDropRenderer.isEdition = false; 63 | 64 | knownDropRenderer.save(); 65 | } 66 | 67 | if (!KnownRenderer.load(editionRendererAddress.toHex())) { 68 | const knownEditionRenderer = new KnownRenderer( 69 | editionRendererAddress.toHex() 70 | ); 71 | const txn = makeTransaction(event); 72 | 73 | knownEditionRenderer.txn = txn; 74 | knownEditionRenderer.address = dropRendererAddress; 75 | knownEditionRenderer.block = event.block.number; 76 | knownEditionRenderer.timestamp = event.block.timestamp; 77 | knownEditionRenderer.address = editionRendererAddress; 78 | 79 | knownEditionRenderer.isEdition = true; 80 | knownEditionRenderer.save(); 81 | } 82 | 83 | const txn = makeTransaction(event); 84 | 85 | upgrade.txn = txn; 86 | upgrade.block = event.block.number; 87 | upgrade.timestamp = event.block.timestamp; 88 | upgrade.impl = event.params.implementation; 89 | upgrade.address = event.address; 90 | upgrade.type = "721Factory"; 91 | 92 | factory.txn = txn; 93 | factory.block = event.block.number; 94 | factory.timestamp = event.block.timestamp; 95 | factory.address = event.address; 96 | 97 | factory.dropMetadataRendererFactory = creator.dropMetadataRenderer(); 98 | factory.editionMetadataRendererFactory = creator.editionMetadataRenderer(); 99 | factory.implementation = event.params.implementation; 100 | factory.version = creator.contractVersion().toString(); 101 | 102 | upgrade.save(); 103 | factory.save(); 104 | } 105 | 106 | export function handleCreatedDrop(event: CreatedDrop): void { 107 | const dropAddress = event.params.editionContractAddress; 108 | const dropContract = ERC721DropContract.bind(dropAddress); 109 | 110 | const createdContract = new ZoraCreateContract(getContractId(dropAddress)); 111 | createdContract.contractVersion = dropContract.contractVersion().toString(); 112 | const dropConfig = dropContract.config(); 113 | 114 | // setup royalties 115 | const royalties = new RoyaltyConfig(dropAddress.toHex()); 116 | royalties.royaltyRecipient = dropConfig.getFundsRecipient(); 117 | royalties.royaltyMintSchedule = BigInt.zero(); 118 | royalties.contract = getContractId(dropAddress); 119 | royalties.tokenId = BigInt.zero(); 120 | royalties.royaltyBPS = BigInt.fromU64(dropConfig.getRoyaltyBPS()); 121 | royalties.user = event.params.creator; 122 | royalties.save(); 123 | 124 | createdContract.contractStandard = TOKEN_STANDARD_ERC721; 125 | const contractURIResponse = dropContract.try_contractURI(); 126 | if (!contractURIResponse.reverted) { 127 | createdContract.contractURI = contractURIResponse.value; 128 | } 129 | createdContract.creator = event.params.creator; 130 | createdContract.initialDefaultAdmin = event.params.creator; 131 | createdContract.owner = dropContract.owner(); 132 | createdContract.name = dropContract.name(); 133 | createdContract.symbol = dropContract.symbol(); 134 | createdContract.contractVersion = dropContract.contractVersion().toString(); 135 | createdContract.rendererContract = dropContract.metadataRenderer(); 136 | 137 | const knownRenderer = KnownRenderer.load( 138 | dropConfig.getMetadataRenderer().toHex() 139 | ); 140 | if (knownRenderer) { 141 | createdContract.likelyIsEdition = knownRenderer.isEdition; 142 | } 143 | 144 | const feePerAmount = dropContract.try_zoraFeeForAmount(BigInt.fromI64(1)); 145 | if (feePerAmount.reverted) { 146 | createdContract.mintFeePerQuantity = BigInt.zero(); 147 | } 148 | createdContract.mintFeePerQuantity = feePerAmount.value.getFee(); 149 | 150 | createdContract.metadataIPFSID = 151 | extractIPFSIDFromContract(contractURIResponse); 152 | createdContract.metadata = loadMetadataInfoFromID( 153 | createdContract.metadataIPFSID 154 | ); 155 | 156 | if (!contractURIResponse.reverted) { 157 | const ipfsHostPath = getIPFSHostFromURI(contractURIResponse.value); 158 | if (ipfsHostPath !== null) { 159 | createdContract.metadata = ipfsHostPath; 160 | } 161 | } 162 | const txn = makeTransaction(event); 163 | createdContract.timestamp = event.block.timestamp; 164 | createdContract.block = event.block.number; 165 | createdContract.address = dropAddress; 166 | createdContract.txn = txn; 167 | createdContract.createdAtBlock = event.block.number; 168 | 169 | createdContract.save(); 170 | 171 | // create token from contract 172 | const createTokenId = getDefaultTokenId(dropAddress); 173 | const newToken = new ZoraCreateToken(createTokenId); 174 | 175 | newToken.holders1155Number = new BigInt(0); 176 | newToken.address = dropAddress; 177 | newToken.rendererContract = createdContract.rendererContract; 178 | newToken.totalSupply = BigInt.zero(); 179 | newToken.maxSupply = event.params.editionSize; 180 | newToken.totalMinted = BigInt.zero(); 181 | newToken.contract = getContractId(dropAddress); 182 | newToken.tokenId = BigInt.zero(); 183 | newToken.creator = event.params.creator; 184 | 185 | newToken.txn = txn; 186 | newToken.timestamp = event.block.timestamp; 187 | newToken.address = event.address; 188 | newToken.block = event.block.number; 189 | 190 | newToken.createdAtBlock = event.block.number; 191 | newToken.tokenStandard = TOKEN_STANDARD_ERC721; 192 | newToken.save(); 193 | 194 | ERC721DropTemplate.create(dropAddress); 195 | } 196 | -------------------------------------------------------------------------------- /src/RewardsMappings/rewardsMappings.ts: -------------------------------------------------------------------------------- 1 | import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; 2 | import { 3 | RewardsPerUser, 4 | RewardsPerUserPerDay, 5 | RewardsSingleDeposit, 6 | RewardsDeposit, 7 | RewardsWithdraw, 8 | RewardsPerUserPerSource, 9 | RewardsAggregate, 10 | RewardsPerSource, 11 | RewardsPerUserPerType, 12 | } from "../../generated/schema"; 13 | import { 14 | Deposit as DepositEvent, 15 | RewardsDeposit as RewardsDepositEvent, 16 | Withdraw as WithdrawEvent, 17 | } from "../../generated/ProtocolRewardsV2/ProtocolRewards"; 18 | import { makeTransaction } from "../common/makeTransaction"; 19 | 20 | function addRewardInfoToUser( 21 | from: Address, 22 | user: Address, 23 | amount: BigInt, 24 | timestamp: BigInt, 25 | type: string | null 26 | ): void { 27 | let creatorRewards = RewardsPerUser.load(user); 28 | if (!creatorRewards) { 29 | creatorRewards = new RewardsPerUser(user); 30 | creatorRewards.address = user; 31 | creatorRewards.amount = BigInt.zero(); 32 | creatorRewards.withdrawn = BigInt.zero(); 33 | } 34 | creatorRewards.amount = creatorRewards.amount.plus(amount); 35 | 36 | creatorRewards.save(); 37 | 38 | /* 39 | 40 | const isoString = new Date(timestamp.toI64() * 1000) 41 | .toISOString() 42 | .substring(0, 10); 43 | const rewardsPerUserPerDayKey = `${user.toHex()}-${isoString}`; 44 | let rewardsPerUserPerDay = RewardsPerUserPerDay.load(rewardsPerUserPerDayKey); 45 | if (!rewardsPerUserPerDay) { 46 | rewardsPerUserPerDay = new RewardsPerUserPerDay(rewardsPerUserPerDayKey); 47 | rewardsPerUserPerDay.amount = BigInt.zero(); 48 | } 49 | rewardsPerUserPerDay.amount = rewardsPerUserPerDay.amount.plus(amount); 50 | rewardsPerUserPerDay.to = user; 51 | const date = new Date(timestamp.toU64() * 1000); 52 | rewardsPerUserPerDay.date = date.toISOString().substring(0, 10); 53 | rewardsPerUserPerDay.timestamp = BigInt.fromU64( 54 | timestamp.toU64() % (24 * 60 * 60) 55 | ); 56 | rewardsPerUserPerDay.save(); 57 | 58 | const rewardsPerUserPerSourceKey = `${from.toHex()}-${user.toHex()}`; 59 | let rewardsPerUserPerSource = RewardsPerUserPerSource.load( 60 | rewardsPerUserPerSourceKey 61 | ); 62 | if (!rewardsPerUserPerSource) { 63 | rewardsPerUserPerSource = new RewardsPerUserPerSource( 64 | rewardsPerUserPerSourceKey 65 | ); 66 | rewardsPerUserPerSource.amount = BigInt.zero(); 67 | rewardsPerUserPerSource.from = from; 68 | rewardsPerUserPerSource.to = user; 69 | } 70 | rewardsPerUserPerSource.amount = rewardsPerUserPerSource.amount.plus(amount); 71 | rewardsPerUserPerSource.save(); 72 | 73 | let rewardsPerSource = RewardsPerSource.load(from); 74 | if (!rewardsPerSource) { 75 | rewardsPerSource = new RewardsPerSource(from); 76 | rewardsPerSource.amount = BigInt.zero(); 77 | rewardsPerSource.from = from; 78 | } 79 | rewardsPerSource.amount = rewardsPerSource.amount.plus(amount); 80 | rewardsPerSource.save(); 81 | 82 | let typeString = type === null ? 'null' : type.toString(); 83 | 84 | const rewardsPerUserPerTypeKey = `${user.toHex()}-${typeString}`; 85 | let rewardsPerUserPerType = RewardsPerUserPerType.load(rewardsPerUserPerTypeKey); 86 | if (!rewardsPerUserPerType) { 87 | rewardsPerUserPerType = new RewardsPerUserPerType(rewardsPerUserPerTypeKey); 88 | rewardsPerUserPerType.type = type; 89 | rewardsPerUserPerType.amount = BigInt.zero(); 90 | rewardsPerUserPerType.from = user; 91 | } 92 | rewardsPerUserPerType.amount = rewardsPerUserPerType.amount.plus(amount); 93 | rewardsPerUserPerType.save(); 94 | 95 | let rewardsTotal = RewardsAggregate.load("AGGREGATE"); 96 | if (!rewardsTotal) { 97 | rewardsTotal = new RewardsAggregate("AGGREGATE"); 98 | rewardsTotal.amount = BigInt.zero(); 99 | rewardsTotal.withdrawn = BigInt.zero(); 100 | } 101 | rewardsTotal.amount = rewardsTotal.amount.plus(amount); 102 | rewardsTotal.save(); 103 | 104 | */ 105 | } 106 | 107 | function addSingleDeposit( 108 | event: ethereum.Event, 109 | from: Address, 110 | to: Address, 111 | amount: BigInt, 112 | comment: string 113 | ): void { 114 | const customDeposit = new RewardsSingleDeposit( 115 | `${event.transaction.hash.toHex()}-${event.transactionLogIndex}-${comment}` 116 | ); 117 | customDeposit.txn = makeTransaction(event); 118 | customDeposit.block = event.block.number; 119 | customDeposit.address = event.address; 120 | customDeposit.timestamp = event.block.timestamp; 121 | 122 | customDeposit.from = from; 123 | customDeposit.to = to; 124 | customDeposit.amount = amount; 125 | customDeposit.comment = comment; 126 | customDeposit.reason = Bytes.empty(); 127 | customDeposit.save(); 128 | 129 | addRewardInfoToUser(from, to, amount, event.block.timestamp, comment); 130 | } 131 | 132 | export function handleRewardsDeposit(event: RewardsDepositEvent): void { 133 | const rewardsDeposit = new RewardsDeposit( 134 | `${event.transaction.hash.toHex()}-${event.transactionLogIndex}` 135 | ); 136 | rewardsDeposit.address = event.address; 137 | rewardsDeposit.block = event.block.number; 138 | rewardsDeposit.timestamp = event.block.timestamp; 139 | rewardsDeposit.txn = makeTransaction(event); 140 | 141 | rewardsDeposit.from = event.params.from; 142 | rewardsDeposit.creator = event.params.creator; 143 | rewardsDeposit.creatorReward = event.params.creatorReward; 144 | rewardsDeposit.createReferral = event.params.createReferral; 145 | rewardsDeposit.createReferralReward = event.params.createReferralReward; 146 | rewardsDeposit.mintReferral = event.params.mintReferral; 147 | rewardsDeposit.mintReferralReward = event.params.mintReferralReward; 148 | rewardsDeposit.firstMinter = event.params.firstMinter; 149 | rewardsDeposit.firstMinterReward = event.params.firstMinterReward; 150 | rewardsDeposit.zora = event.params.zora; 151 | rewardsDeposit.zoraReward = event.params.zoraReward; 152 | 153 | rewardsDeposit.save(); 154 | 155 | // create referral 156 | if (event.params.createReferralReward.gt(BigInt.zero())) { 157 | addSingleDeposit( 158 | event, 159 | event.params.from, 160 | event.params.createReferral, 161 | event.params.createReferralReward, 162 | "create_referral" 163 | ); 164 | } 165 | 166 | addSingleDeposit( 167 | event, 168 | event.params.from, 169 | event.params.creator, 170 | event.params.creatorReward, 171 | "creator" 172 | ); 173 | 174 | if (event.params.firstMinterReward.gt(BigInt.zero())) { 175 | addSingleDeposit( 176 | event, 177 | event.params.from, 178 | event.params.firstMinter, 179 | event.params.firstMinterReward, 180 | "first_minter" 181 | ); 182 | } 183 | 184 | if (event.params.mintReferralReward.gt(BigInt.zero())) { 185 | addSingleDeposit( 186 | event, 187 | event.params.from, 188 | event.params.mintReferral, 189 | event.params.mintReferralReward, 190 | "mint_referral" 191 | ); 192 | } 193 | 194 | addSingleDeposit( 195 | event, 196 | event.params.from, 197 | event.params.zora, 198 | event.params.zoraReward, 199 | "zora" 200 | ); 201 | 202 | rewardsDeposit.save(); 203 | } 204 | 205 | export function handleWithdraw(event: WithdrawEvent): void { 206 | const withdraw = new RewardsWithdraw( 207 | `${event.transaction.hash.toHex()}-${event.transactionLogIndex}` 208 | ); 209 | withdraw.address = event.address; 210 | withdraw.amount = event.params.amount; 211 | withdraw.from = event.params.from; 212 | withdraw.to = event.params.to; 213 | withdraw.timestamp = event.block.timestamp; 214 | withdraw.block = event.block.number; 215 | withdraw.txn = event.transaction.hash.toHex(); 216 | withdraw.save(); 217 | 218 | const rewards = RewardsPerUser.load(event.params.from); 219 | if (rewards) { 220 | rewards.withdrawn = rewards.withdrawn.plus(event.params.amount); 221 | rewards.save(); 222 | } 223 | const rewardsTotal = RewardsAggregate.load("AGGREGATE"); 224 | if (rewardsTotal) { 225 | rewardsTotal.withdrawn = rewardsTotal.withdrawn.plus(event.params.amount); 226 | rewardsTotal.save(); 227 | } 228 | } 229 | 230 | export function handleDeposit(event: DepositEvent): void { 231 | const deposit = new RewardsSingleDeposit(getEventId(event)); 232 | 233 | deposit.address = event.address; 234 | deposit.block = event.block.number; 235 | deposit.timestamp = event.block.timestamp; 236 | deposit.txn = makeTransaction(event); 237 | 238 | deposit.from = event.params.from; 239 | deposit.to = event.params.to; 240 | deposit.amount = event.params.amount; 241 | deposit.reason = event.params.reason; 242 | deposit.comment = event.params.comment; 243 | 244 | addRewardInfoToUser( 245 | event.params.from, 246 | event.params.to, 247 | event.params.amount, 248 | event.block.timestamp, 249 | null 250 | ); 251 | 252 | deposit.save(); 253 | } 254 | 255 | function getEventId(event: ethereum.Event): string { 256 | return `${event.transaction.hash.toHex()}-${event.logIndex}`; 257 | } 258 | -------------------------------------------------------------------------------- /abis/ZoraNFTCreator.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_implementation", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "contract EditionMetadataRenderer", 11 | "name": "_editionMetadataRenderer", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "contract DropMetadataRenderer", 16 | "name": "_dropMetadataRenderer", 17 | "type": "address" 18 | } 19 | ], 20 | "stateMutability": "nonpayable", 21 | "type": "constructor" 22 | }, 23 | { 24 | "anonymous": false, 25 | "inputs": [ 26 | { 27 | "indexed": false, 28 | "internalType": "address", 29 | "name": "previousAdmin", 30 | "type": "address" 31 | }, 32 | { 33 | "indexed": false, 34 | "internalType": "address", 35 | "name": "newAdmin", 36 | "type": "address" 37 | } 38 | ], 39 | "name": "AdminChanged", 40 | "type": "event" 41 | }, 42 | { 43 | "anonymous": false, 44 | "inputs": [ 45 | { 46 | "indexed": true, 47 | "internalType": "address", 48 | "name": "beacon", 49 | "type": "address" 50 | } 51 | ], 52 | "name": "BeaconUpgraded", 53 | "type": "event" 54 | }, 55 | { 56 | "anonymous": false, 57 | "inputs": [ 58 | { 59 | "indexed": true, 60 | "internalType": "uint256", 61 | "name": "editionId", 62 | "type": "uint256" 63 | }, 64 | { 65 | "indexed": true, 66 | "internalType": "address", 67 | "name": "creator", 68 | "type": "address" 69 | }, 70 | { 71 | "indexed": false, 72 | "internalType": "uint256", 73 | "name": "editionSize", 74 | "type": "uint256" 75 | }, 76 | { 77 | "indexed": false, 78 | "internalType": "address", 79 | "name": "editionContractAddress", 80 | "type": "address" 81 | } 82 | ], 83 | "name": "CreatedEdition", 84 | "type": "event" 85 | }, 86 | { 87 | "anonymous": false, 88 | "inputs": [ 89 | { 90 | "indexed": false, 91 | "internalType": "uint8", 92 | "name": "version", 93 | "type": "uint8" 94 | } 95 | ], 96 | "name": "Initialized", 97 | "type": "event" 98 | }, 99 | { 100 | "anonymous": false, 101 | "inputs": [ 102 | { 103 | "indexed": true, 104 | "internalType": "address", 105 | "name": "previousOwner", 106 | "type": "address" 107 | }, 108 | { 109 | "indexed": true, 110 | "internalType": "address", 111 | "name": "newOwner", 112 | "type": "address" 113 | } 114 | ], 115 | "name": "OwnershipTransferred", 116 | "type": "event" 117 | }, 118 | { 119 | "anonymous": false, 120 | "inputs": [ 121 | { 122 | "indexed": true, 123 | "internalType": "address", 124 | "name": "implementation", 125 | "type": "address" 126 | } 127 | ], 128 | "name": "Upgraded", 129 | "type": "event" 130 | }, 131 | { 132 | "inputs": [ 133 | { 134 | "internalType": "string", 135 | "name": "name", 136 | "type": "string" 137 | }, 138 | { 139 | "internalType": "string", 140 | "name": "symbol", 141 | "type": "string" 142 | }, 143 | { 144 | "internalType": "uint64", 145 | "name": "editionSize", 146 | "type": "uint64" 147 | }, 148 | { 149 | "internalType": "uint16", 150 | "name": "royaltyBPS", 151 | "type": "uint16" 152 | }, 153 | { 154 | "internalType": "address payable", 155 | "name": "fundsRecipient", 156 | "type": "address" 157 | }, 158 | { 159 | "internalType": "string", 160 | "name": "metadataURIBase", 161 | "type": "string" 162 | }, 163 | { 164 | "internalType": "string", 165 | "name": "metadataContractURI", 166 | "type": "string" 167 | } 168 | ], 169 | "name": "createDrop", 170 | "outputs": [ 171 | { 172 | "internalType": "uint256", 173 | "name": "", 174 | "type": "uint256" 175 | } 176 | ], 177 | "stateMutability": "nonpayable", 178 | "type": "function" 179 | }, 180 | { 181 | "inputs": [ 182 | { 183 | "internalType": "string", 184 | "name": "name", 185 | "type": "string" 186 | }, 187 | { 188 | "internalType": "string", 189 | "name": "symbol", 190 | "type": "string" 191 | }, 192 | { 193 | "internalType": "uint64", 194 | "name": "editionSize", 195 | "type": "uint64" 196 | }, 197 | { 198 | "internalType": "uint16", 199 | "name": "royaltyBPS", 200 | "type": "uint16" 201 | }, 202 | { 203 | "internalType": "address payable", 204 | "name": "fundsRecipient", 205 | "type": "address" 206 | }, 207 | { 208 | "internalType": "string", 209 | "name": "description", 210 | "type": "string" 211 | }, 212 | { 213 | "internalType": "string", 214 | "name": "animationURI", 215 | "type": "string" 216 | }, 217 | { 218 | "internalType": "bytes32", 219 | "name": "animationHash", 220 | "type": "bytes32" 221 | }, 222 | { 223 | "internalType": "string", 224 | "name": "imageURI", 225 | "type": "string" 226 | }, 227 | { 228 | "internalType": "bytes32", 229 | "name": "imageHash", 230 | "type": "bytes32" 231 | } 232 | ], 233 | "name": "createEdition", 234 | "outputs": [ 235 | { 236 | "internalType": "uint256", 237 | "name": "", 238 | "type": "uint256" 239 | } 240 | ], 241 | "stateMutability": "nonpayable", 242 | "type": "function" 243 | }, 244 | { 245 | "inputs": [], 246 | "name": "dropMetadataRenderer", 247 | "outputs": [ 248 | { 249 | "internalType": "contract DropMetadataRenderer", 250 | "name": "", 251 | "type": "address" 252 | } 253 | ], 254 | "stateMutability": "view", 255 | "type": "function" 256 | }, 257 | { 258 | "inputs": [], 259 | "name": "editionMetadataRenderer", 260 | "outputs": [ 261 | { 262 | "internalType": "contract EditionMetadataRenderer", 263 | "name": "", 264 | "type": "address" 265 | } 266 | ], 267 | "stateMutability": "view", 268 | "type": "function" 269 | }, 270 | { 271 | "inputs": [ 272 | { 273 | "internalType": "uint256", 274 | "name": "editionId", 275 | "type": "uint256" 276 | } 277 | ], 278 | "name": "getEditionAtId", 279 | "outputs": [ 280 | { 281 | "internalType": "contract ERC721Drop", 282 | "name": "", 283 | "type": "address" 284 | } 285 | ], 286 | "stateMutability": "view", 287 | "type": "function" 288 | }, 289 | { 290 | "inputs": [], 291 | "name": "implementation", 292 | "outputs": [ 293 | { 294 | "internalType": "address", 295 | "name": "", 296 | "type": "address" 297 | } 298 | ], 299 | "stateMutability": "view", 300 | "type": "function" 301 | }, 302 | { 303 | "inputs": [], 304 | "name": "initialize", 305 | "outputs": [], 306 | "stateMutability": "nonpayable", 307 | "type": "function" 308 | }, 309 | { 310 | "inputs": [], 311 | "name": "owner", 312 | "outputs": [ 313 | { 314 | "internalType": "address", 315 | "name": "", 316 | "type": "address" 317 | } 318 | ], 319 | "stateMutability": "view", 320 | "type": "function" 321 | }, 322 | { 323 | "inputs": [], 324 | "name": "proxiableUUID", 325 | "outputs": [ 326 | { 327 | "internalType": "bytes32", 328 | "name": "", 329 | "type": "bytes32" 330 | } 331 | ], 332 | "stateMutability": "view", 333 | "type": "function" 334 | }, 335 | { 336 | "inputs": [], 337 | "name": "renounceOwnership", 338 | "outputs": [], 339 | "stateMutability": "nonpayable", 340 | "type": "function" 341 | }, 342 | { 343 | "inputs": [ 344 | { 345 | "internalType": "address", 346 | "name": "newOwner", 347 | "type": "address" 348 | } 349 | ], 350 | "name": "transferOwnership", 351 | "outputs": [], 352 | "stateMutability": "nonpayable", 353 | "type": "function" 354 | }, 355 | { 356 | "inputs": [ 357 | { 358 | "internalType": "address", 359 | "name": "newImplementation", 360 | "type": "address" 361 | } 362 | ], 363 | "name": "upgradeTo", 364 | "outputs": [], 365 | "stateMutability": "nonpayable", 366 | "type": "function" 367 | }, 368 | { 369 | "inputs": [ 370 | { 371 | "internalType": "address", 372 | "name": "newImplementation", 373 | "type": "address" 374 | }, 375 | { 376 | "internalType": "bytes", 377 | "name": "data", 378 | "type": "bytes" 379 | } 380 | ], 381 | "name": "upgradeToAndCall", 382 | "outputs": [], 383 | "stateMutability": "payable", 384 | "type": "function" 385 | } 386 | ] 387 | -------------------------------------------------------------------------------- /abis/ZoraCreatorMerkleMinterStrategy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "function", 4 | "name": "allowedMerkles", 5 | "inputs": [ 6 | { 7 | "name": "", 8 | "type": "address", 9 | "internalType": "address" 10 | }, 11 | { 12 | "name": "", 13 | "type": "uint256", 14 | "internalType": "uint256" 15 | } 16 | ], 17 | "outputs": [ 18 | { 19 | "name": "presaleStart", 20 | "type": "uint64", 21 | "internalType": "uint64" 22 | }, 23 | { 24 | "name": "presaleEnd", 25 | "type": "uint64", 26 | "internalType": "uint64" 27 | }, 28 | { 29 | "name": "fundsRecipient", 30 | "type": "address", 31 | "internalType": "address" 32 | }, 33 | { 34 | "name": "merkleRoot", 35 | "type": "bytes32", 36 | "internalType": "bytes32" 37 | } 38 | ], 39 | "stateMutability": "view" 40 | }, 41 | { 42 | "type": "function", 43 | "name": "contractName", 44 | "inputs": [], 45 | "outputs": [ 46 | { 47 | "name": "", 48 | "type": "string", 49 | "internalType": "string" 50 | } 51 | ], 52 | "stateMutability": "pure" 53 | }, 54 | { 55 | "type": "function", 56 | "name": "contractURI", 57 | "inputs": [], 58 | "outputs": [ 59 | { 60 | "name": "", 61 | "type": "string", 62 | "internalType": "string" 63 | } 64 | ], 65 | "stateMutability": "pure" 66 | }, 67 | { 68 | "type": "function", 69 | "name": "contractVersion", 70 | "inputs": [], 71 | "outputs": [ 72 | { 73 | "name": "", 74 | "type": "string", 75 | "internalType": "string" 76 | } 77 | ], 78 | "stateMutability": "pure" 79 | }, 80 | { 81 | "type": "function", 82 | "name": "getMintedPerWallet", 83 | "inputs": [ 84 | { 85 | "name": "tokenContract", 86 | "type": "address", 87 | "internalType": "address" 88 | }, 89 | { 90 | "name": "tokenId", 91 | "type": "uint256", 92 | "internalType": "uint256" 93 | }, 94 | { 95 | "name": "wallet", 96 | "type": "address", 97 | "internalType": "address" 98 | } 99 | ], 100 | "outputs": [ 101 | { 102 | "name": "", 103 | "type": "uint256", 104 | "internalType": "uint256" 105 | } 106 | ], 107 | "stateMutability": "view" 108 | }, 109 | { 110 | "type": "function", 111 | "name": "requestMint", 112 | "inputs": [ 113 | { 114 | "name": "", 115 | "type": "address", 116 | "internalType": "address" 117 | }, 118 | { 119 | "name": "tokenId", 120 | "type": "uint256", 121 | "internalType": "uint256" 122 | }, 123 | { 124 | "name": "quantity", 125 | "type": "uint256", 126 | "internalType": "uint256" 127 | }, 128 | { 129 | "name": "ethValueSent", 130 | "type": "uint256", 131 | "internalType": "uint256" 132 | }, 133 | { 134 | "name": "minterArguments", 135 | "type": "bytes", 136 | "internalType": "bytes" 137 | } 138 | ], 139 | "outputs": [ 140 | { 141 | "name": "commands", 142 | "type": "tuple", 143 | "internalType": "struct ICreatorCommands.CommandSet", 144 | "components": [ 145 | { 146 | "name": "commands", 147 | "type": "tuple[]", 148 | "internalType": "struct ICreatorCommands.Command[]", 149 | "components": [ 150 | { 151 | "name": "method", 152 | "type": "uint8", 153 | "internalType": "enum ICreatorCommands.CreatorActions" 154 | }, 155 | { 156 | "name": "args", 157 | "type": "bytes", 158 | "internalType": "bytes" 159 | } 160 | ] 161 | }, 162 | { 163 | "name": "at", 164 | "type": "uint256", 165 | "internalType": "uint256" 166 | } 167 | ] 168 | } 169 | ], 170 | "stateMutability": "nonpayable" 171 | }, 172 | { 173 | "type": "function", 174 | "name": "resetSale", 175 | "inputs": [ 176 | { 177 | "name": "tokenId", 178 | "type": "uint256", 179 | "internalType": "uint256" 180 | } 181 | ], 182 | "outputs": [], 183 | "stateMutability": "nonpayable" 184 | }, 185 | { 186 | "type": "function", 187 | "name": "sale", 188 | "inputs": [ 189 | { 190 | "name": "tokenContract", 191 | "type": "address", 192 | "internalType": "address" 193 | }, 194 | { 195 | "name": "tokenId", 196 | "type": "uint256", 197 | "internalType": "uint256" 198 | } 199 | ], 200 | "outputs": [ 201 | { 202 | "name": "", 203 | "type": "tuple", 204 | "internalType": "struct ZoraCreatorMerkleMinterStrategy.MerkleSaleSettings", 205 | "components": [ 206 | { 207 | "name": "presaleStart", 208 | "type": "uint64", 209 | "internalType": "uint64" 210 | }, 211 | { 212 | "name": "presaleEnd", 213 | "type": "uint64", 214 | "internalType": "uint64" 215 | }, 216 | { 217 | "name": "fundsRecipient", 218 | "type": "address", 219 | "internalType": "address" 220 | }, 221 | { 222 | "name": "merkleRoot", 223 | "type": "bytes32", 224 | "internalType": "bytes32" 225 | } 226 | ] 227 | } 228 | ], 229 | "stateMutability": "view" 230 | }, 231 | { 232 | "type": "function", 233 | "name": "setSale", 234 | "inputs": [ 235 | { 236 | "name": "tokenId", 237 | "type": "uint256", 238 | "internalType": "uint256" 239 | }, 240 | { 241 | "name": "merkleSaleSettings", 242 | "type": "tuple", 243 | "internalType": "struct ZoraCreatorMerkleMinterStrategy.MerkleSaleSettings", 244 | "components": [ 245 | { 246 | "name": "presaleStart", 247 | "type": "uint64", 248 | "internalType": "uint64" 249 | }, 250 | { 251 | "name": "presaleEnd", 252 | "type": "uint64", 253 | "internalType": "uint64" 254 | }, 255 | { 256 | "name": "fundsRecipient", 257 | "type": "address", 258 | "internalType": "address" 259 | }, 260 | { 261 | "name": "merkleRoot", 262 | "type": "bytes32", 263 | "internalType": "bytes32" 264 | } 265 | ] 266 | } 267 | ], 268 | "outputs": [], 269 | "stateMutability": "nonpayable" 270 | }, 271 | { 272 | "type": "function", 273 | "name": "supportsInterface", 274 | "inputs": [ 275 | { 276 | "name": "interfaceId", 277 | "type": "bytes4", 278 | "internalType": "bytes4" 279 | } 280 | ], 281 | "outputs": [ 282 | { 283 | "name": "", 284 | "type": "bool", 285 | "internalType": "bool" 286 | } 287 | ], 288 | "stateMutability": "pure" 289 | }, 290 | { 291 | "type": "event", 292 | "name": "SaleSet", 293 | "inputs": [ 294 | { 295 | "name": "mediaContract", 296 | "type": "address", 297 | "indexed": true, 298 | "internalType": "address" 299 | }, 300 | { 301 | "name": "tokenId", 302 | "type": "uint256", 303 | "indexed": true, 304 | "internalType": "uint256" 305 | }, 306 | { 307 | "name": "merkleSaleSettings", 308 | "type": "tuple", 309 | "indexed": false, 310 | "internalType": "struct ZoraCreatorMerkleMinterStrategy.MerkleSaleSettings", 311 | "components": [ 312 | { 313 | "name": "presaleStart", 314 | "type": "uint64", 315 | "internalType": "uint64" 316 | }, 317 | { 318 | "name": "presaleEnd", 319 | "type": "uint64", 320 | "internalType": "uint64" 321 | }, 322 | { 323 | "name": "fundsRecipient", 324 | "type": "address", 325 | "internalType": "address" 326 | }, 327 | { 328 | "name": "merkleRoot", 329 | "type": "bytes32", 330 | "internalType": "bytes32" 331 | } 332 | ] 333 | } 334 | ], 335 | "anonymous": false 336 | }, 337 | { 338 | "type": "error", 339 | "name": "CallerNotZoraCreator1155", 340 | "inputs": [] 341 | }, 342 | { 343 | "type": "error", 344 | "name": "InvalidMerkleProof", 345 | "inputs": [ 346 | { 347 | "name": "mintTo", 348 | "type": "address", 349 | "internalType": "address" 350 | }, 351 | { 352 | "name": "merkleProof", 353 | "type": "bytes32[]", 354 | "internalType": "bytes32[]" 355 | }, 356 | { 357 | "name": "merkleRoot", 358 | "type": "bytes32", 359 | "internalType": "bytes32" 360 | } 361 | ] 362 | }, 363 | { 364 | "type": "error", 365 | "name": "MerkleClaimsExceeded", 366 | "inputs": [] 367 | }, 368 | { 369 | "type": "error", 370 | "name": "MinterContractAlreadyExists", 371 | "inputs": [] 372 | }, 373 | { 374 | "type": "error", 375 | "name": "MinterContractDoesNotExist", 376 | "inputs": [] 377 | }, 378 | { 379 | "type": "error", 380 | "name": "SaleEnded", 381 | "inputs": [] 382 | }, 383 | { 384 | "type": "error", 385 | "name": "SaleHasNotStarted", 386 | "inputs": [] 387 | }, 388 | { 389 | "type": "error", 390 | "name": "UserExceedsMintLimit", 391 | "inputs": [ 392 | { 393 | "name": "user", 394 | "type": "address", 395 | "internalType": "address" 396 | }, 397 | { 398 | "name": "limit", 399 | "type": "uint256", 400 | "internalType": "uint256" 401 | }, 402 | { 403 | "name": "requestedAmount", 404 | "type": "uint256", 405 | "internalType": "uint256" 406 | } 407 | ] 408 | }, 409 | { 410 | "type": "error", 411 | "name": "WrongValueSent", 412 | "inputs": [] 413 | } 414 | ] 415 | -------------------------------------------------------------------------------- /abis/ZoraCreatorFixedPriceSaleStrategy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "function", 4 | "name": "contractName", 5 | "inputs": [], 6 | "outputs": [ 7 | { 8 | "name": "", 9 | "type": "string", 10 | "internalType": "string" 11 | } 12 | ], 13 | "stateMutability": "pure" 14 | }, 15 | { 16 | "type": "function", 17 | "name": "contractURI", 18 | "inputs": [], 19 | "outputs": [ 20 | { 21 | "name": "", 22 | "type": "string", 23 | "internalType": "string" 24 | } 25 | ], 26 | "stateMutability": "pure" 27 | }, 28 | { 29 | "type": "function", 30 | "name": "contractVersion", 31 | "inputs": [], 32 | "outputs": [ 33 | { 34 | "name": "", 35 | "type": "string", 36 | "internalType": "string" 37 | } 38 | ], 39 | "stateMutability": "pure" 40 | }, 41 | { 42 | "type": "function", 43 | "name": "getMintedPerWallet", 44 | "inputs": [ 45 | { 46 | "name": "tokenContract", 47 | "type": "address", 48 | "internalType": "address" 49 | }, 50 | { 51 | "name": "tokenId", 52 | "type": "uint256", 53 | "internalType": "uint256" 54 | }, 55 | { 56 | "name": "wallet", 57 | "type": "address", 58 | "internalType": "address" 59 | } 60 | ], 61 | "outputs": [ 62 | { 63 | "name": "", 64 | "type": "uint256", 65 | "internalType": "uint256" 66 | } 67 | ], 68 | "stateMutability": "view" 69 | }, 70 | { 71 | "type": "function", 72 | "name": "requestMint", 73 | "inputs": [ 74 | { 75 | "name": "", 76 | "type": "address", 77 | "internalType": "address" 78 | }, 79 | { 80 | "name": "tokenId", 81 | "type": "uint256", 82 | "internalType": "uint256" 83 | }, 84 | { 85 | "name": "quantity", 86 | "type": "uint256", 87 | "internalType": "uint256" 88 | }, 89 | { 90 | "name": "ethValueSent", 91 | "type": "uint256", 92 | "internalType": "uint256" 93 | }, 94 | { 95 | "name": "minterArguments", 96 | "type": "bytes", 97 | "internalType": "bytes" 98 | } 99 | ], 100 | "outputs": [ 101 | { 102 | "name": "commands", 103 | "type": "tuple", 104 | "internalType": "struct ICreatorCommands.CommandSet", 105 | "components": [ 106 | { 107 | "name": "commands", 108 | "type": "tuple[]", 109 | "internalType": "struct ICreatorCommands.Command[]", 110 | "components": [ 111 | { 112 | "name": "method", 113 | "type": "uint8", 114 | "internalType": "enum ICreatorCommands.CreatorActions" 115 | }, 116 | { 117 | "name": "args", 118 | "type": "bytes", 119 | "internalType": "bytes" 120 | } 121 | ] 122 | }, 123 | { 124 | "name": "at", 125 | "type": "uint256", 126 | "internalType": "uint256" 127 | } 128 | ] 129 | } 130 | ], 131 | "stateMutability": "nonpayable" 132 | }, 133 | { 134 | "type": "function", 135 | "name": "resetSale", 136 | "inputs": [ 137 | { 138 | "name": "tokenId", 139 | "type": "uint256", 140 | "internalType": "uint256" 141 | } 142 | ], 143 | "outputs": [], 144 | "stateMutability": "nonpayable" 145 | }, 146 | { 147 | "type": "function", 148 | "name": "sale", 149 | "inputs": [ 150 | { 151 | "name": "tokenContract", 152 | "type": "address", 153 | "internalType": "address" 154 | }, 155 | { 156 | "name": "tokenId", 157 | "type": "uint256", 158 | "internalType": "uint256" 159 | } 160 | ], 161 | "outputs": [ 162 | { 163 | "name": "", 164 | "type": "tuple", 165 | "internalType": "struct ZoraCreatorFixedPriceSaleStrategy.SalesConfig", 166 | "components": [ 167 | { 168 | "name": "saleStart", 169 | "type": "uint64", 170 | "internalType": "uint64" 171 | }, 172 | { 173 | "name": "saleEnd", 174 | "type": "uint64", 175 | "internalType": "uint64" 176 | }, 177 | { 178 | "name": "maxTokensPerAddress", 179 | "type": "uint64", 180 | "internalType": "uint64" 181 | }, 182 | { 183 | "name": "pricePerToken", 184 | "type": "uint96", 185 | "internalType": "uint96" 186 | }, 187 | { 188 | "name": "fundsRecipient", 189 | "type": "address", 190 | "internalType": "address" 191 | } 192 | ] 193 | } 194 | ], 195 | "stateMutability": "view" 196 | }, 197 | { 198 | "type": "function", 199 | "name": "setSale", 200 | "inputs": [ 201 | { 202 | "name": "tokenId", 203 | "type": "uint256", 204 | "internalType": "uint256" 205 | }, 206 | { 207 | "name": "salesConfig", 208 | "type": "tuple", 209 | "internalType": "struct ZoraCreatorFixedPriceSaleStrategy.SalesConfig", 210 | "components": [ 211 | { 212 | "name": "saleStart", 213 | "type": "uint64", 214 | "internalType": "uint64" 215 | }, 216 | { 217 | "name": "saleEnd", 218 | "type": "uint64", 219 | "internalType": "uint64" 220 | }, 221 | { 222 | "name": "maxTokensPerAddress", 223 | "type": "uint64", 224 | "internalType": "uint64" 225 | }, 226 | { 227 | "name": "pricePerToken", 228 | "type": "uint96", 229 | "internalType": "uint96" 230 | }, 231 | { 232 | "name": "fundsRecipient", 233 | "type": "address", 234 | "internalType": "address" 235 | } 236 | ] 237 | } 238 | ], 239 | "outputs": [], 240 | "stateMutability": "nonpayable" 241 | }, 242 | { 243 | "type": "function", 244 | "name": "supportsInterface", 245 | "inputs": [ 246 | { 247 | "name": "interfaceId", 248 | "type": "bytes4", 249 | "internalType": "bytes4" 250 | } 251 | ], 252 | "outputs": [ 253 | { 254 | "name": "", 255 | "type": "bool", 256 | "internalType": "bool" 257 | } 258 | ], 259 | "stateMutability": "pure" 260 | }, 261 | { 262 | "type": "event", 263 | "name": "MintComment", 264 | "inputs": [ 265 | { 266 | "name": "sender", 267 | "type": "address", 268 | "indexed": true, 269 | "internalType": "address" 270 | }, 271 | { 272 | "name": "tokenContract", 273 | "type": "address", 274 | "indexed": true, 275 | "internalType": "address" 276 | }, 277 | { 278 | "name": "tokenId", 279 | "type": "uint256", 280 | "indexed": true, 281 | "internalType": "uint256" 282 | }, 283 | { 284 | "name": "quantity", 285 | "type": "uint256", 286 | "indexed": false, 287 | "internalType": "uint256" 288 | }, 289 | { 290 | "name": "comment", 291 | "type": "string", 292 | "indexed": false, 293 | "internalType": "string" 294 | } 295 | ], 296 | "anonymous": false 297 | }, 298 | { 299 | "type": "event", 300 | "name": "SaleSet", 301 | "inputs": [ 302 | { 303 | "name": "mediaContract", 304 | "type": "address", 305 | "indexed": true, 306 | "internalType": "address" 307 | }, 308 | { 309 | "name": "tokenId", 310 | "type": "uint256", 311 | "indexed": true, 312 | "internalType": "uint256" 313 | }, 314 | { 315 | "name": "salesConfig", 316 | "type": "tuple", 317 | "indexed": false, 318 | "internalType": "struct ZoraCreatorFixedPriceSaleStrategy.SalesConfig", 319 | "components": [ 320 | { 321 | "name": "saleStart", 322 | "type": "uint64", 323 | "internalType": "uint64" 324 | }, 325 | { 326 | "name": "saleEnd", 327 | "type": "uint64", 328 | "internalType": "uint64" 329 | }, 330 | { 331 | "name": "maxTokensPerAddress", 332 | "type": "uint64", 333 | "internalType": "uint64" 334 | }, 335 | { 336 | "name": "pricePerToken", 337 | "type": "uint96", 338 | "internalType": "uint96" 339 | }, 340 | { 341 | "name": "fundsRecipient", 342 | "type": "address", 343 | "internalType": "address" 344 | } 345 | ] 346 | } 347 | ], 348 | "anonymous": false 349 | }, 350 | { 351 | "type": "error", 352 | "name": "CallerNotZoraCreator1155", 353 | "inputs": [] 354 | }, 355 | { 356 | "type": "error", 357 | "name": "InvalidMerkleProof", 358 | "inputs": [ 359 | { 360 | "name": "mintTo", 361 | "type": "address", 362 | "internalType": "address" 363 | }, 364 | { 365 | "name": "merkleProof", 366 | "type": "bytes32[]", 367 | "internalType": "bytes32[]" 368 | }, 369 | { 370 | "name": "merkleRoot", 371 | "type": "bytes32", 372 | "internalType": "bytes32" 373 | } 374 | ] 375 | }, 376 | { 377 | "type": "error", 378 | "name": "MinterContractAlreadyExists", 379 | "inputs": [] 380 | }, 381 | { 382 | "type": "error", 383 | "name": "MinterContractDoesNotExist", 384 | "inputs": [] 385 | }, 386 | { 387 | "type": "error", 388 | "name": "SaleEnded", 389 | "inputs": [] 390 | }, 391 | { 392 | "type": "error", 393 | "name": "SaleHasNotStarted", 394 | "inputs": [] 395 | }, 396 | { 397 | "type": "error", 398 | "name": "UserExceedsMintLimit", 399 | "inputs": [ 400 | { 401 | "name": "user", 402 | "type": "address", 403 | "internalType": "address" 404 | }, 405 | { 406 | "name": "limit", 407 | "type": "uint256", 408 | "internalType": "uint256" 409 | }, 410 | { 411 | "name": "requestedAmount", 412 | "type": "uint256", 413 | "internalType": "uint256" 414 | } 415 | ] 416 | }, 417 | { 418 | "type": "error", 419 | "name": "WrongValueSent", 420 | "inputs": [] 421 | } 422 | ] 423 | -------------------------------------------------------------------------------- /abis/ProtocolRewards.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "stateMutability": "payable", 5 | "type": "constructor" 6 | }, 7 | { 8 | "inputs": [], 9 | "name": "ADDRESS_ZERO", 10 | "type": "error" 11 | }, 12 | { 13 | "inputs": [], 14 | "name": "ARRAY_LENGTH_MISMATCH", 15 | "type": "error" 16 | }, 17 | { 18 | "inputs": [], 19 | "name": "INVALID_DEPOSIT", 20 | "type": "error" 21 | }, 22 | { 23 | "inputs": [], 24 | "name": "INVALID_SIGNATURE", 25 | "type": "error" 26 | }, 27 | { 28 | "inputs": [], 29 | "name": "INVALID_WITHDRAW", 30 | "type": "error" 31 | }, 32 | { 33 | "inputs": [], 34 | "name": "InvalidShortString", 35 | "type": "error" 36 | }, 37 | { 38 | "inputs": [], 39 | "name": "SIGNATURE_DEADLINE_EXPIRED", 40 | "type": "error" 41 | }, 42 | { 43 | "inputs": [ 44 | { 45 | "internalType": "string", 46 | "name": "str", 47 | "type": "string" 48 | } 49 | ], 50 | "name": "StringTooLong", 51 | "type": "error" 52 | }, 53 | { 54 | "inputs": [], 55 | "name": "TRANSFER_FAILED", 56 | "type": "error" 57 | }, 58 | { 59 | "anonymous": false, 60 | "inputs": [ 61 | { 62 | "indexed": true, 63 | "internalType": "address", 64 | "name": "from", 65 | "type": "address" 66 | }, 67 | { 68 | "indexed": true, 69 | "internalType": "address", 70 | "name": "to", 71 | "type": "address" 72 | }, 73 | { 74 | "indexed": true, 75 | "internalType": "bytes4", 76 | "name": "reason", 77 | "type": "bytes4" 78 | }, 79 | { 80 | "indexed": false, 81 | "internalType": "uint256", 82 | "name": "amount", 83 | "type": "uint256" 84 | }, 85 | { 86 | "indexed": false, 87 | "internalType": "string", 88 | "name": "comment", 89 | "type": "string" 90 | } 91 | ], 92 | "name": "Deposit", 93 | "type": "event" 94 | }, 95 | { 96 | "anonymous": false, 97 | "inputs": [], 98 | "name": "EIP712DomainChanged", 99 | "type": "event" 100 | }, 101 | { 102 | "anonymous": false, 103 | "inputs": [ 104 | { 105 | "indexed": true, 106 | "internalType": "address", 107 | "name": "creator", 108 | "type": "address" 109 | }, 110 | { 111 | "indexed": true, 112 | "internalType": "address", 113 | "name": "createReferral", 114 | "type": "address" 115 | }, 116 | { 117 | "indexed": true, 118 | "internalType": "address", 119 | "name": "mintReferral", 120 | "type": "address" 121 | }, 122 | { 123 | "indexed": false, 124 | "internalType": "address", 125 | "name": "firstMinter", 126 | "type": "address" 127 | }, 128 | { 129 | "indexed": false, 130 | "internalType": "address", 131 | "name": "zora", 132 | "type": "address" 133 | }, 134 | { 135 | "indexed": false, 136 | "internalType": "address", 137 | "name": "from", 138 | "type": "address" 139 | }, 140 | { 141 | "indexed": false, 142 | "internalType": "uint256", 143 | "name": "creatorReward", 144 | "type": "uint256" 145 | }, 146 | { 147 | "indexed": false, 148 | "internalType": "uint256", 149 | "name": "createReferralReward", 150 | "type": "uint256" 151 | }, 152 | { 153 | "indexed": false, 154 | "internalType": "uint256", 155 | "name": "mintReferralReward", 156 | "type": "uint256" 157 | }, 158 | { 159 | "indexed": false, 160 | "internalType": "uint256", 161 | "name": "firstMinterReward", 162 | "type": "uint256" 163 | }, 164 | { 165 | "indexed": false, 166 | "internalType": "uint256", 167 | "name": "zoraReward", 168 | "type": "uint256" 169 | } 170 | ], 171 | "name": "RewardsDeposit", 172 | "type": "event" 173 | }, 174 | { 175 | "anonymous": false, 176 | "inputs": [ 177 | { 178 | "indexed": true, 179 | "internalType": "address", 180 | "name": "from", 181 | "type": "address" 182 | }, 183 | { 184 | "indexed": true, 185 | "internalType": "address", 186 | "name": "to", 187 | "type": "address" 188 | }, 189 | { 190 | "indexed": false, 191 | "internalType": "uint256", 192 | "name": "amount", 193 | "type": "uint256" 194 | } 195 | ], 196 | "name": "Withdraw", 197 | "type": "event" 198 | }, 199 | { 200 | "inputs": [], 201 | "name": "WITHDRAW_TYPEHASH", 202 | "outputs": [ 203 | { 204 | "internalType": "bytes32", 205 | "name": "", 206 | "type": "bytes32" 207 | } 208 | ], 209 | "stateMutability": "view", 210 | "type": "function" 211 | }, 212 | { 213 | "inputs": [ 214 | { 215 | "internalType": "address", 216 | "name": "", 217 | "type": "address" 218 | } 219 | ], 220 | "name": "balanceOf", 221 | "outputs": [ 222 | { 223 | "internalType": "uint256", 224 | "name": "", 225 | "type": "uint256" 226 | } 227 | ], 228 | "stateMutability": "view", 229 | "type": "function" 230 | }, 231 | { 232 | "inputs": [ 233 | { 234 | "internalType": "address", 235 | "name": "to", 236 | "type": "address" 237 | }, 238 | { 239 | "internalType": "bytes4", 240 | "name": "reason", 241 | "type": "bytes4" 242 | }, 243 | { 244 | "internalType": "string", 245 | "name": "comment", 246 | "type": "string" 247 | } 248 | ], 249 | "name": "deposit", 250 | "outputs": [], 251 | "stateMutability": "payable", 252 | "type": "function" 253 | }, 254 | { 255 | "inputs": [ 256 | { 257 | "internalType": "address[]", 258 | "name": "recipients", 259 | "type": "address[]" 260 | }, 261 | { 262 | "internalType": "uint256[]", 263 | "name": "amounts", 264 | "type": "uint256[]" 265 | }, 266 | { 267 | "internalType": "bytes4[]", 268 | "name": "reasons", 269 | "type": "bytes4[]" 270 | }, 271 | { 272 | "internalType": "string", 273 | "name": "comment", 274 | "type": "string" 275 | } 276 | ], 277 | "name": "depositBatch", 278 | "outputs": [], 279 | "stateMutability": "payable", 280 | "type": "function" 281 | }, 282 | { 283 | "inputs": [ 284 | { 285 | "internalType": "address", 286 | "name": "creator", 287 | "type": "address" 288 | }, 289 | { 290 | "internalType": "uint256", 291 | "name": "creatorReward", 292 | "type": "uint256" 293 | }, 294 | { 295 | "internalType": "address", 296 | "name": "createReferral", 297 | "type": "address" 298 | }, 299 | { 300 | "internalType": "uint256", 301 | "name": "createReferralReward", 302 | "type": "uint256" 303 | }, 304 | { 305 | "internalType": "address", 306 | "name": "mintReferral", 307 | "type": "address" 308 | }, 309 | { 310 | "internalType": "uint256", 311 | "name": "mintReferralReward", 312 | "type": "uint256" 313 | }, 314 | { 315 | "internalType": "address", 316 | "name": "firstMinter", 317 | "type": "address" 318 | }, 319 | { 320 | "internalType": "uint256", 321 | "name": "firstMinterReward", 322 | "type": "uint256" 323 | }, 324 | { 325 | "internalType": "address", 326 | "name": "zora", 327 | "type": "address" 328 | }, 329 | { 330 | "internalType": "uint256", 331 | "name": "zoraReward", 332 | "type": "uint256" 333 | } 334 | ], 335 | "name": "depositRewards", 336 | "outputs": [], 337 | "stateMutability": "payable", 338 | "type": "function" 339 | }, 340 | { 341 | "inputs": [], 342 | "name": "eip712Domain", 343 | "outputs": [ 344 | { 345 | "internalType": "bytes1", 346 | "name": "fields", 347 | "type": "bytes1" 348 | }, 349 | { 350 | "internalType": "string", 351 | "name": "name", 352 | "type": "string" 353 | }, 354 | { 355 | "internalType": "string", 356 | "name": "version", 357 | "type": "string" 358 | }, 359 | { 360 | "internalType": "uint256", 361 | "name": "chainId", 362 | "type": "uint256" 363 | }, 364 | { 365 | "internalType": "address", 366 | "name": "verifyingContract", 367 | "type": "address" 368 | }, 369 | { 370 | "internalType": "bytes32", 371 | "name": "salt", 372 | "type": "bytes32" 373 | }, 374 | { 375 | "internalType": "uint256[]", 376 | "name": "extensions", 377 | "type": "uint256[]" 378 | } 379 | ], 380 | "stateMutability": "view", 381 | "type": "function" 382 | }, 383 | { 384 | "inputs": [ 385 | { 386 | "internalType": "address", 387 | "name": "", 388 | "type": "address" 389 | } 390 | ], 391 | "name": "nonces", 392 | "outputs": [ 393 | { 394 | "internalType": "uint256", 395 | "name": "", 396 | "type": "uint256" 397 | } 398 | ], 399 | "stateMutability": "view", 400 | "type": "function" 401 | }, 402 | { 403 | "inputs": [], 404 | "name": "totalSupply", 405 | "outputs": [ 406 | { 407 | "internalType": "uint256", 408 | "name": "", 409 | "type": "uint256" 410 | } 411 | ], 412 | "stateMutability": "view", 413 | "type": "function" 414 | }, 415 | { 416 | "inputs": [ 417 | { 418 | "internalType": "address", 419 | "name": "to", 420 | "type": "address" 421 | }, 422 | { 423 | "internalType": "uint256", 424 | "name": "amount", 425 | "type": "uint256" 426 | } 427 | ], 428 | "name": "withdraw", 429 | "outputs": [], 430 | "stateMutability": "nonpayable", 431 | "type": "function" 432 | }, 433 | { 434 | "inputs": [ 435 | { 436 | "internalType": "address", 437 | "name": "to", 438 | "type": "address" 439 | }, 440 | { 441 | "internalType": "uint256", 442 | "name": "amount", 443 | "type": "uint256" 444 | } 445 | ], 446 | "name": "withdrawFor", 447 | "outputs": [], 448 | "stateMutability": "nonpayable", 449 | "type": "function" 450 | }, 451 | { 452 | "inputs": [ 453 | { 454 | "internalType": "address", 455 | "name": "from", 456 | "type": "address" 457 | }, 458 | { 459 | "internalType": "address", 460 | "name": "to", 461 | "type": "address" 462 | }, 463 | { 464 | "internalType": "uint256", 465 | "name": "amount", 466 | "type": "uint256" 467 | }, 468 | { 469 | "internalType": "uint256", 470 | "name": "deadline", 471 | "type": "uint256" 472 | }, 473 | { 474 | "internalType": "uint8", 475 | "name": "v", 476 | "type": "uint8" 477 | }, 478 | { 479 | "internalType": "bytes32", 480 | "name": "r", 481 | "type": "bytes32" 482 | }, 483 | { 484 | "internalType": "bytes32", 485 | "name": "s", 486 | "type": "bytes32" 487 | } 488 | ], 489 | "name": "withdrawWithSig", 490 | "outputs": [], 491 | "stateMutability": "nonpayable", 492 | "type": "function" 493 | } 494 | ] 495 | -------------------------------------------------------------------------------- /schema.graphql: -------------------------------------------------------------------------------- 1 | type TransactionInfo @entity { 2 | id: ID! 3 | chainId: BigInt! 4 | network: String! 5 | block: BigInt! 6 | logIndex: BigInt! 7 | address: Bytes! 8 | timestamp: BigInt! 9 | } 10 | 11 | # TODO: 12 | # * add chainid & root parameters 13 | # * ensure contractVersion works 14 | 15 | 16 | # **ERC721** 17 | 18 | type SalesConfig @entity(immutable: true) { 19 | id: ID! 20 | 21 | publicSalePrice: BigInt! 22 | maxSalePurchasePerAddress: BigInt! 23 | publicSaleStart: BigInt! 24 | publicSaleEnd: BigInt! 25 | presaleStart: BigInt! 26 | presaleEnd: BigInt! 27 | presaleMerkleRoot: Bytes! 28 | } 29 | 30 | type ZoraCreate721Factory @entity { 31 | # Begin – default data block 32 | id: ID! 33 | txn: TransactionInfo! 34 | address: Bytes! 35 | block: BigInt! 36 | timestamp: BigInt! 37 | # End – default data block 38 | 39 | implementation: Bytes! 40 | version: String! 41 | dropMetadataRendererFactory: Bytes! 42 | editionMetadataRendererFactory: Bytes! 43 | } 44 | 45 | type MintComment @entity @immutable { 46 | # Begin – default data block 47 | id: ID! 48 | txn: TransactionInfo! 49 | address: Bytes! 50 | block: BigInt! 51 | timestamp: BigInt! 52 | # End – default data block 53 | 54 | tokenAndContract: ZoraCreateToken! 55 | sender: Bytes! 56 | comment: String! 57 | mintQuantity: BigInt! 58 | tokenId: BigInt! 59 | } 60 | 61 | type TokenSale @entity { 62 | # Begin – default data block 63 | id: ID! 64 | txn: TransactionInfo! 65 | address: Bytes! 66 | block: BigInt! 67 | timestamp: BigInt! 68 | # End – default data block 69 | 70 | tokenAndContract: ZoraCreateToken! 71 | 72 | quantity: BigInt! 73 | pricePerToken: BigInt! 74 | mintRecipient: Bytes! 75 | 76 | # 721-specific data 77 | firstPurchasedTokenId: BigInt! 78 | } 79 | 80 | # type DropRole @entity { 81 | # # user-role 82 | # id: ID! 83 | # account: Bytes! 84 | # sender: Bytes! 85 | # roleHash: Bytes! 86 | # role: String! 87 | # updated: BigInt! 88 | # granted: Boolean! 89 | 90 | # drop: ERC721Drop! 91 | # } 92 | 93 | type Upgrade @entity { 94 | # Begin – default data block 95 | id: ID! 96 | txn: TransactionInfo! 97 | block: BigInt! 98 | address: Bytes! 99 | timestamp: BigInt! 100 | # End – default data block 101 | 102 | impl: Bytes 103 | type: String 104 | } 105 | 106 | type EditionMetadata @entity { 107 | id: ID! 108 | 109 | description: String! 110 | imageURI: String! 111 | animationURI: String! 112 | } 113 | 114 | type DropMetadata @entity { 115 | id: ID! 116 | 117 | base: String! 118 | extension: String! 119 | freezeAt: BigInt! 120 | contractURI: String! 121 | } 122 | 123 | ### ERC1155 124 | 125 | # 1155 Records 126 | 127 | type ZoraCreate1155Factory @entity { 128 | # Begin – default data block 129 | id: ID! 130 | txn: TransactionInfo! 131 | block: BigInt! 132 | timestamp: BigInt! 133 | # End – default data block 134 | 135 | 136 | fixedPriceSaleStrategyAddress: Bytes! 137 | redeemMinterStrategyAddress: Bytes 138 | implementation: Bytes! 139 | merkleSaleStrategyAddress: Bytes! 140 | version: String! 141 | } 142 | 143 | type ZoraCreateContract @entity { 144 | # Begin – default data block 145 | id: ID! 146 | txn: TransactionInfo! 147 | block: BigInt! 148 | timestamp: BigInt! 149 | # End – default data block 150 | 151 | 152 | address: Bytes! 153 | 154 | name: String 155 | symbol: String 156 | 157 | # Set if this contract likely is an edition 158 | likelyIsEdition: Boolean 159 | 160 | contractURI: String 161 | contractStandard: String! 162 | contractVersion: String 163 | metadata: MetadataInfo 164 | metadataIPFSID: String 165 | 166 | mintFeePerQuantity: BigInt! 167 | 168 | rendererContract: Bytes 169 | 170 | creator: Bytes! 171 | initialDefaultAdmin: Bytes 172 | owner: Bytes! 173 | 174 | tokens: [ZoraCreateToken!]! @derivedFrom(field: "contract") 175 | permissions: [ZoraCreatorPermission!]! @derivedFrom(field: "contract") 176 | royalties: RoyaltyConfig @derivedFrom(field: "contract") 177 | salesStrategies: [SalesStrategyConfig!]! @derivedFrom(field: "contract") 178 | 179 | createdAtBlock: BigInt! 180 | } 181 | 182 | type ZoraCreatorPermission @entity { 183 | # Begin – default data block 184 | id: ID! 185 | txn: TransactionInfo! 186 | block: BigInt! 187 | timestamp: BigInt! 188 | # End – default data block 189 | 190 | user: Bytes! 191 | contract: ZoraCreateContract 192 | tokenAndContract: ZoraCreateToken 193 | 194 | tokenId: BigInt! 195 | 196 | isAdmin: Boolean! 197 | isMinter: Boolean! 198 | isSalesManager: Boolean! 199 | isMetadataManager: Boolean! 200 | isFundsManager: Boolean! 201 | } 202 | 203 | type ZoraCreateToken @entity { 204 | # Begin – default data block 205 | id: ID! 206 | txn: TransactionInfo! 207 | block: BigInt! 208 | timestamp: BigInt! 209 | # End – default data block 210 | 211 | 212 | address: Bytes! 213 | 214 | creator: Bytes! 215 | 216 | uri: String 217 | totalSupply: BigInt! 218 | maxSupply: BigInt! 219 | totalMinted: BigInt! 220 | 221 | rendererContract: Bytes 222 | 223 | contract: ZoraCreateContract! 224 | tokenId: BigInt! 225 | tokenStandard: String! 226 | 227 | metadata: MetadataInfo 228 | metadataIPFSID: String 229 | 230 | onChainMetadataHistory: [OnChainMetadataHistory!]! 231 | @derivedFrom(field: "tokenAndContract") 232 | 233 | holders1155Number: BigInt! 234 | holders1155: [Token1155Holder!]! @derivedFrom(field: "tokenAndContract") 235 | 236 | mintComments: [MintComment!]! @derivedFrom(field: "tokenAndContract") 237 | sales: [TokenSale!]! @derivedFrom(field: "tokenAndContract") 238 | 239 | permissions: [ZoraCreatorPermission!]! @derivedFrom(field: "tokenAndContract") 240 | royalties: [RoyaltyConfig!]! @derivedFrom(field: "tokenAndContract") 241 | salesStrategies: [SalesStrategyConfig!]! 242 | @derivedFrom(field: "tokenAndContract") 243 | createdAtBlock: BigInt! 244 | premint: Premint @derivedFrom(field: "tokenAndContract") 245 | } 246 | 247 | type KnownRenderer @entity(immutable: true) { 248 | # Begin – default data block 249 | id: ID! 250 | txn: TransactionInfo! 251 | block: BigInt! 252 | address: Bytes! 253 | timestamp: BigInt! 254 | # End – default data block 255 | 256 | isEdition: Boolean 257 | } 258 | 259 | type OnChainMetadataHistory @entity(immutable: true) { 260 | # Begin – default data block 261 | id: ID! 262 | txn: TransactionInfo! 263 | block: BigInt! 264 | address: Bytes! 265 | timestamp: BigInt! 266 | # End – default data block 267 | 268 | tokenAndContract: ZoraCreateToken! 269 | 270 | rendererAddress: Bytes! 271 | 272 | createdAtBlock: BigInt! 273 | 274 | editionMetadata: EditionMetadata 275 | dropMetadata: DropMetadata 276 | directURI: String 277 | directURIMetadata: MetadataInfo 278 | 279 | knownType: String! 280 | } 281 | 282 | type SalesConfigFixedPriceSaleStrategy @entity { 283 | # Begin – default data block 284 | id: ID! 285 | txn: TransactionInfo! 286 | block: BigInt! 287 | address: Bytes! 288 | timestamp: BigInt! 289 | # End – default data block 290 | 291 | 292 | configAddress: Bytes! 293 | 294 | tokenId: BigInt! 295 | contract: ZoraCreateContract! 296 | saleStart: BigInt! 297 | saleEnd: BigInt! 298 | maxTokensPerAddress: BigInt! 299 | pricePerToken: BigInt! 300 | 301 | fundsRecipient: Bytes 302 | } 303 | 304 | type ZoraCreatorRedeemConfig @entity { 305 | # Begin – default data block 306 | id: ID! 307 | txn: TransactionInfo! 308 | block: BigInt! 309 | timestamp: BigInt! 310 | # End – default data block 311 | 312 | creatorAddress: Bytes! 313 | minterAddress: Bytes! 314 | } 315 | 316 | type RedeemMintToken @entity(immutable: true) { 317 | id: ID! 318 | tokenContract: Bytes! 319 | tokenId: BigInt! 320 | amount: BigInt! 321 | tokenType: Int! 322 | } 323 | 324 | type RedeemInstructions @entity(immutable: true) { 325 | id: ID! 326 | 327 | redeemMinter: SalesConfigRedeemMinterStrategy! 328 | tokenType: Int! 329 | amount: BigInt! 330 | tokenIdStart: BigInt! 331 | tokenIdEnd: BigInt! 332 | tokenContract: Bytes! 333 | transferRecipient: Bytes! 334 | burnFunction: Bytes! 335 | } 336 | 337 | type RedeemMinterProcessed @entity { 338 | # Begin – default data block 339 | id: ID! 340 | txn: TransactionInfo! 341 | block: BigInt! 342 | address: Bytes! 343 | timestamp: BigInt! 344 | # End – default data block 345 | 346 | redeemMinter: SalesConfigRedeemMinterStrategy! 347 | 348 | target: Bytes! 349 | redeemsInstructionsHash: Bytes! 350 | sender: Bytes! 351 | tokenPairs: [RedeemProcessedTokenPair!]! @derivedFrom(field: "processed") 352 | } 353 | 354 | type RedeemProcessedTokenPair @entity(immutable: true) { 355 | id: ID! 356 | processed: RedeemMinterProcessed! 357 | 358 | amounts: [BigInt!]! 359 | tokenIds: [BigInt!]! 360 | index: Int! 361 | } 362 | 363 | type SalesConfigRedeemMinterStrategy @entity { 364 | # Begin – default data block 365 | id: ID! 366 | txn: TransactionInfo! 367 | block: BigInt! 368 | address: Bytes! 369 | timestamp: BigInt! 370 | # End – default data block 371 | 372 | 373 | configAddress: Bytes! 374 | target: Bytes! 375 | # isActive tells if the redeem has been cleared or not 376 | isActive: Boolean! 377 | redeemsInstructionsHash: Bytes! 378 | redeemMintToken: RedeemMintToken! 379 | redeemInstructions: [RedeemInstructions!]! @derivedFrom(field: "redeemMinter") 380 | saleStart: BigInt! 381 | saleEnd: BigInt! 382 | ethAmount: BigInt! 383 | ethRecipient: Bytes! 384 | } 385 | 386 | type SalesConfigMerkleMinterStrategy @entity { 387 | # Begin – default data block 388 | id: ID! 389 | txn: TransactionInfo! 390 | block: BigInt! 391 | address: Bytes! 392 | timestamp: BigInt! 393 | # End – default data block 394 | 395 | 396 | configAddress: Bytes! 397 | 398 | tokenId: BigInt! 399 | contract: ZoraCreateContract! 400 | presaleStart: BigInt! 401 | presaleEnd: BigInt! 402 | merkleRoot: Bytes! 403 | 404 | fundsRecipient: Bytes 405 | } 406 | 407 | type SalesStrategyConfig @entity { 408 | # Begin – default data block 409 | id: ID! 410 | txn: TransactionInfo! 411 | block: BigInt! 412 | address: Bytes! 413 | timestamp: BigInt! 414 | # End – default data block 415 | 416 | 417 | tokenAndContract: ZoraCreateToken 418 | contract: ZoraCreateContract 419 | 420 | presale: SalesConfigMerkleMinterStrategy 421 | fixedPrice: SalesConfigFixedPriceSaleStrategy 422 | redeemMinter: SalesConfigRedeemMinterStrategy 423 | type: String! 424 | } 425 | 426 | type MetadataInfo @entity { 427 | id: ID! 428 | name: String 429 | description: String 430 | image: String 431 | animationUrl: String 432 | decimals: String 433 | 434 | rawJson: String 435 | } 436 | 437 | type RoyaltyConfig @entity { 438 | id: ID! 439 | 440 | tokenId: BigInt! 441 | user: Bytes! 442 | royaltyBPS: BigInt! 443 | royaltyRecipient: Bytes! 444 | royaltyMintSchedule: BigInt! 445 | contract: ZoraCreateContract 446 | tokenAndContract: ZoraCreateToken 447 | } 448 | 449 | type Token1155Holder @entity { 450 | # id is (contract, token, user) 451 | id: ID! 452 | 453 | user: Bytes! 454 | lastUpdatedBlock: BigInt! 455 | tokenAndContract: ZoraCreateToken! 456 | balance: BigInt! 457 | } 458 | 459 | ### Protocol Rewards 460 | 461 | type RewardsPerUserPerDay @entity { 462 | id: ID! 463 | 464 | to: Bytes! 465 | date: String! 466 | timestamp: BigInt! 467 | amount: BigInt! 468 | } 469 | 470 | type RewardsPerUserPerSource @entity { 471 | id: ID! 472 | 473 | from: Bytes! 474 | to: Bytes! 475 | amount: BigInt! 476 | } 477 | 478 | type RewardsPerUser @entity { 479 | id: Bytes! 480 | 481 | address: Bytes! 482 | amount: BigInt! 483 | withdrawn: BigInt! 484 | } 485 | 486 | type RewardsAggregate @entity { 487 | id: ID! 488 | 489 | amount: BigInt! 490 | withdrawn: BigInt! 491 | } 492 | 493 | type RewardsPerSource @entity { 494 | id: Bytes! 495 | 496 | from: Bytes! 497 | amount: BigInt! 498 | } 499 | 500 | type RewardsPerUserPerType @entity { 501 | id: ID! 502 | 503 | from: Bytes! 504 | type: String 505 | amount: BigInt! 506 | } 507 | 508 | 509 | type RewardsDeposit @entity @immutable { 510 | # Begin – default data block 511 | id: ID! 512 | txn: TransactionInfo! 513 | block: BigInt! 514 | address: Bytes! 515 | timestamp: BigInt! 516 | # End – default data block 517 | 518 | from: Bytes! 519 | creator: Bytes! 520 | creatorReward: BigInt! 521 | mintReferral: Bytes! 522 | mintReferralReward: BigInt! 523 | createReferral: Bytes! 524 | createReferralReward: BigInt! 525 | firstMinter: Bytes! 526 | firstMinterReward: BigInt! 527 | zora: Bytes! 528 | zoraReward: BigInt! 529 | } 530 | 531 | type RewardsSingleDeposit @entity @immutable { 532 | # Begin – default data block 533 | id: ID! 534 | txn: TransactionInfo! 535 | block: BigInt! 536 | address: Bytes! 537 | timestamp: BigInt! 538 | # End – default data block 539 | 540 | from: Bytes! 541 | to: Bytes! 542 | reason: Bytes! 543 | amount: BigInt! 544 | comment: String 545 | } 546 | 547 | type RewardsWithdraw @entity @immutable { 548 | # Begin – default data block 549 | id: ID! 550 | txn: TransactionInfo! 551 | block: BigInt! 552 | address: Bytes! 553 | timestamp: BigInt! 554 | # End – default data block 555 | 556 | from: Bytes! 557 | to: Bytes! 558 | amount: BigInt! 559 | reason: String 560 | } 561 | 562 | type Premint @entity { 563 | id: ID! 564 | uid: BigInt! 565 | contractAddress: Bytes! 566 | tokenId: BigInt! 567 | minter: Bytes! 568 | createdNewContract: Boolean! 569 | quantityMinted: BigInt 570 | tokenAndContract: ZoraCreateToken 571 | } 572 | 573 | ### Reserve Auctions V3 574 | 575 | type Auction @entity { 576 | id: ID! 577 | txn: TransactionInfo! 578 | block: BigInt! 579 | address: Bytes! 580 | timestamp: BigInt! 581 | 582 | tokenContract: Bytes! 583 | tokenId: BigInt! 584 | seller: Bytes 585 | sellerFundsRecipient: Bytes 586 | reservePrice: BigInt 587 | highestBid: BigInt 588 | highestBidder: Bytes 589 | startTime: BigInt 590 | currency: Bytes 591 | firstBidTime: BigInt 592 | finder: Bytes 593 | duration: BigInt 594 | findersFeeBps: BigInt 595 | extended: Boolean 596 | canceled: Boolean 597 | ended: Boolean 598 | } -------------------------------------------------------------------------------- /src/ERC721Mappings/templates/ERC721DropMappings.ts: -------------------------------------------------------------------------------- 1 | import { Address, BigInt, Bytes, ethereum } from "@graphprotocol/graph-ts"; 2 | import { makeTransaction } from "../../common/makeTransaction"; 3 | 4 | import { 5 | ZoraCreateContract, 6 | SalesConfigMerkleMinterStrategy, 7 | SalesStrategyConfig, 8 | SalesConfigFixedPriceSaleStrategy, 9 | ZoraCreatorPermission, 10 | ZoraCreateToken, 11 | RoyaltyConfig, 12 | OnChainMetadataHistory, 13 | KnownRenderer, 14 | MintComment, 15 | TokenSale, 16 | } from "../../../generated/schema"; 17 | 18 | import { 19 | ERC721Drop as ERC721DropContract, 20 | FundsRecipientChanged, 21 | MintComment as ERC721DropMintComment, 22 | Sale as ERC721DropSale, 23 | OpenMintFinalized, 24 | OwnershipTransferred, 25 | RoleGranted, 26 | RoleRevoked, 27 | SalesConfigChanged, 28 | Transfer, 29 | UpdatedMetadataRenderer, 30 | Upgraded, 31 | } from "../../../generated/templates/ERC721Drop/ERC721Drop"; 32 | import { getSalesConfigOnLegacyMarket } from "../../common/getSalesConfigKey"; 33 | import { 34 | SALE_CONFIG_PRESALE, 35 | SALE_CONFIG_FIXED_PRICE, 36 | } from "../../constants/salesConfigTypes"; 37 | import { getPermissionsKey } from "../../common/getPermissionsKey"; 38 | import { 39 | KNOWN_TYPE_DEFAULT_ADMIN, 40 | KNOWN_TYPE_MINTER_ROLE, 41 | KNOWN_TYPE_SALES_MANAGER_ROLE, 42 | } from "../../constants/erc721RoleUtils"; 43 | import { getDefaultTokenId, getTokenId } from "../../common/getTokenId"; 44 | import { METADATA_CUSTOM_RENDERER } from "../../constants/metadataHistoryTypes"; 45 | import { getOnChainMetadataKey } from "../../common/getOnChainMetadataKey"; 46 | import { getMintCommentId } from "../../common/getMintCommentId"; 47 | import { getSaleId } from "../../common/getSaleId"; 48 | import { getContractId } from "../../common/getContractId"; 49 | import { 50 | extractIPFSIDFromContract, 51 | loadMetadataInfoFromID, 52 | } from "../../common/metadata"; 53 | 54 | 55 | const EMPTY_PRESALE_CONFIG = Bytes.fromHexString( 56 | "0x0000000000000000000000000000000000000000000000000000000000000000" 57 | ); 58 | 59 | /* sales config updated */ 60 | export function handleSalesConfigChanged(event: ethereum.Event): void { 61 | const dropContract = ERC721DropContract.bind( 62 | Address.fromString(event.address.toHex()) 63 | ); 64 | 65 | const salesConfigObject = dropContract.salesConfig(); 66 | 67 | if ( 68 | salesConfigObject.getPresaleMerkleRoot().notEqual(EMPTY_PRESALE_CONFIG) && 69 | salesConfigObject.getPresaleStart().gt(BigInt.zero()) 70 | ) { 71 | const presaleConfigId = getSalesConfigOnLegacyMarket( 72 | // market is the same as media contract for this impl 73 | // token ID for 721 is 0 74 | event.address, 75 | SALE_CONFIG_PRESALE 76 | ); 77 | const strategyPresale = new SalesConfigMerkleMinterStrategy( 78 | presaleConfigId 79 | ); 80 | strategyPresale.configAddress = event.address; 81 | strategyPresale.tokenId = BigInt.zero(); 82 | strategyPresale.contract = getContractId(event.address); 83 | strategyPresale.presaleStart = salesConfigObject.getPresaleStart(); 84 | strategyPresale.presaleEnd = salesConfigObject.getPresaleEnd(); 85 | strategyPresale.merkleRoot = salesConfigObject.getPresaleMerkleRoot(); 86 | 87 | const txn = makeTransaction(event); 88 | strategyPresale.address = event.address; 89 | strategyPresale.block = event.block.number; 90 | strategyPresale.timestamp = event.block.timestamp; 91 | strategyPresale.txn = txn; 92 | strategyPresale.save(); 93 | 94 | // make a join table 95 | const presaleJoin = new SalesStrategyConfig(presaleConfigId); 96 | presaleJoin.contract = getContractId(event.address); 97 | 98 | presaleJoin.txn = txn; 99 | presaleJoin.address = event.address; 100 | presaleJoin.block = event.block.number; 101 | presaleJoin.timestamp = event.block.timestamp; 102 | 103 | presaleJoin.presale = presaleConfigId; 104 | presaleJoin.type = SALE_CONFIG_PRESALE; 105 | presaleJoin.save(); 106 | } 107 | 108 | if (salesConfigObject.getPublicSaleEnd() != BigInt.zero()) { 109 | const publicSaleConfigId = getSalesConfigOnLegacyMarket( 110 | // market is the same as media contract for this impl 111 | // token ID for 721 is 0 112 | event.address, 113 | SALE_CONFIG_FIXED_PRICE 114 | ); 115 | 116 | const fixedPriceSaleStrategy = new SalesConfigFixedPriceSaleStrategy( 117 | publicSaleConfigId 118 | ); 119 | 120 | const txn = makeTransaction(event); 121 | fixedPriceSaleStrategy.txn = txn; 122 | fixedPriceSaleStrategy.block = event.block.number; 123 | fixedPriceSaleStrategy.timestamp = event.block.timestamp; 124 | fixedPriceSaleStrategy.address = event.address; 125 | 126 | fixedPriceSaleStrategy.tokenId = BigInt.zero(); 127 | fixedPriceSaleStrategy.configAddress = event.address; 128 | fixedPriceSaleStrategy.contract = getContractId(event.address); 129 | fixedPriceSaleStrategy.maxTokensPerAddress = 130 | salesConfigObject.getMaxSalePurchasePerAddress(); 131 | fixedPriceSaleStrategy.saleStart = salesConfigObject.getPublicSaleStart(); 132 | fixedPriceSaleStrategy.saleEnd = salesConfigObject.getPublicSaleEnd(); 133 | fixedPriceSaleStrategy.pricePerToken = 134 | salesConfigObject.getPublicSalePrice(); 135 | fixedPriceSaleStrategy.save(); 136 | 137 | // make a join table 138 | const fixedPriceSaleJoin = new SalesStrategyConfig(publicSaleConfigId); 139 | fixedPriceSaleJoin.contract = getContractId(event.address); 140 | 141 | fixedPriceSaleJoin.txn = txn; 142 | fixedPriceSaleJoin.address = event.address; 143 | fixedPriceSaleJoin.block = event.block.number; 144 | fixedPriceSaleJoin.timestamp = event.block.timestamp; 145 | 146 | fixedPriceSaleJoin.fixedPrice = publicSaleConfigId; 147 | fixedPriceSaleJoin.type = SALE_CONFIG_FIXED_PRICE; 148 | fixedPriceSaleJoin.save(); 149 | } 150 | } 151 | 152 | /* handle upgraded – updates contract version */ 153 | 154 | export function handleUpgraded(event: Upgraded): void { 155 | const drop = ERC721DropContract.bind(event.address); 156 | if (drop) { 157 | const version = drop.contractVersion(); 158 | const contractId = getContractId(event.address); 159 | const savedContract = ZoraCreateContract.load(contractId); 160 | if (savedContract) { 161 | savedContract.contractVersion = version.toString(); 162 | const dropConfig = drop.config(); 163 | const royalties = new RoyaltyConfig(event.address.toHexString()); 164 | royalties.royaltyRecipient = dropConfig.getFundsRecipient(); 165 | royalties.royaltyMintSchedule = BigInt.zero(); 166 | royalties.contract = contractId; 167 | royalties.tokenId = BigInt.zero(); 168 | royalties.royaltyBPS = BigInt.fromU64(dropConfig.getRoyaltyBPS()); 169 | royalties.save(); 170 | savedContract.save(); 171 | } 172 | handleSalesConfigChanged(event); 173 | } 174 | } 175 | 176 | /* role mappings */ 177 | 178 | export function handleRoleGranted(event: RoleGranted): void { 179 | const id = getPermissionsKey( 180 | event.params.account, 181 | event.address, 182 | BigInt.zero() 183 | ); 184 | 185 | let permissions = ZoraCreatorPermission.load(id); 186 | 187 | if (!permissions) { 188 | permissions = new ZoraCreatorPermission(id); 189 | permissions.isAdmin = false; 190 | permissions.isFundsManager = false; 191 | permissions.isMetadataManager = false; 192 | permissions.isSalesManager = false; 193 | permissions.isMinter = false; 194 | } 195 | permissions.block = event.block.number; 196 | permissions.timestamp = event.block.timestamp; 197 | 198 | permissions.user = event.params.account; 199 | permissions.tokenId = BigInt.zero(); 200 | 201 | if (event.params.role.equals(Bytes.fromHexString(KNOWN_TYPE_DEFAULT_ADMIN))) { 202 | permissions.isAdmin = true; 203 | } 204 | if (event.params.role.equals(Bytes.fromHexString(KNOWN_TYPE_MINTER_ROLE))) { 205 | permissions.isMinter = true; 206 | } 207 | if ( 208 | event.params.role.equals(Bytes.fromHexString(KNOWN_TYPE_SALES_MANAGER_ROLE)) 209 | ) { 210 | permissions.isSalesManager = true; 211 | } 212 | 213 | permissions.txn = makeTransaction(event); 214 | permissions.contract = getContractId(event.address); 215 | 216 | permissions.save(); 217 | } 218 | 219 | export function handleRoleRevoked(event: RoleRevoked): void { 220 | const id = getPermissionsKey( 221 | event.params.account, 222 | event.address, 223 | BigInt.zero() 224 | ); 225 | 226 | let permissions = ZoraCreatorPermission.load(id); 227 | if (!permissions) { 228 | return; 229 | } 230 | 231 | const role = event.params.role; 232 | if (role.equals(Bytes.fromHexString(KNOWN_TYPE_DEFAULT_ADMIN))) { 233 | permissions.isAdmin = false; 234 | } 235 | if (role.equals(Bytes.fromHexString(KNOWN_TYPE_MINTER_ROLE))) { 236 | permissions.isMinter = false; 237 | } 238 | if (role.equals(Bytes.fromHexString(KNOWN_TYPE_SALES_MANAGER_ROLE))) { 239 | permissions.isSalesManager = false; 240 | } 241 | 242 | permissions.txn = makeTransaction(event); 243 | permissions.contract = getContractId(event.address); 244 | permissions.user = event.params.account; 245 | 246 | permissions.save(); 247 | } 248 | 249 | /* finalized */ 250 | 251 | export function handleOpenMintFinalized(event: OpenMintFinalized): void { 252 | const id = getDefaultTokenId(event.address); 253 | 254 | const token = ZoraCreateToken.load(id); 255 | if (token) { 256 | token.maxSupply = event.params.numberOfMints; 257 | token.save(); 258 | } 259 | } 260 | 261 | /* funds recipient changed */ 262 | 263 | export function handleFundsRecipientChanged( 264 | event: FundsRecipientChanged 265 | ): void { 266 | const fixedPriceSale = SalesConfigFixedPriceSaleStrategy.load( 267 | getSalesConfigOnLegacyMarket(event.address, SALE_CONFIG_FIXED_PRICE) 268 | ); 269 | if (fixedPriceSale) { 270 | fixedPriceSale.fundsRecipient = event.params.newAddress; 271 | fixedPriceSale.save(); 272 | } 273 | 274 | const merkleStrategyPrice = SalesConfigMerkleMinterStrategy.load( 275 | getSalesConfigOnLegacyMarket(event.address, SALE_CONFIG_PRESALE) 276 | ); 277 | if (merkleStrategyPrice) { 278 | merkleStrategyPrice.fundsRecipient = event.params.newAddress; 279 | merkleStrategyPrice.save(); 280 | } 281 | 282 | const royaltyConfig = RoyaltyConfig.load(event.address.toHexString()); 283 | if (royaltyConfig) { 284 | royaltyConfig.royaltyRecipient = event.params.newAddress; 285 | royaltyConfig.save(); 286 | } 287 | } 288 | 289 | export function handleUpdatedMetadataRenderer( 290 | event: UpdatedMetadataRenderer 291 | ): void { 292 | const createContract = ZoraCreateContract.load(event.address.toHex()); 293 | if (createContract) { 294 | createContract.rendererContract = event.params.renderer; 295 | } 296 | 297 | const createToken = ZoraCreateToken.load(getDefaultTokenId(event.address)); 298 | if (!createToken) { 299 | return; 300 | } 301 | 302 | createToken.rendererContract = event.params.renderer; 303 | const drop = ERC721DropContract.bind(event.address); 304 | createToken.metadataIPFSID = extractIPFSIDFromContract( 305 | drop.try_contractURI() 306 | ); 307 | createToken.metadata = loadMetadataInfoFromID(createToken.metadataIPFSID); 308 | createToken.save(); 309 | 310 | if (!KnownRenderer.load(event.params.renderer.toHex())) { 311 | const history = new OnChainMetadataHistory(getOnChainMetadataKey(event)); 312 | history.tokenAndContract = getDefaultTokenId(event.address); 313 | history.knownType = METADATA_CUSTOM_RENDERER; 314 | history.createdAtBlock = event.block.timestamp; 315 | history.rendererAddress = event.params.renderer; 316 | 317 | history.txn = makeTransaction(event); 318 | history.block = event.block.number; 319 | history.address = event.address; 320 | history.timestamp = event.block.timestamp; 321 | 322 | history.save(); 323 | } 324 | } 325 | 326 | /* NFT transfer event */ 327 | 328 | export function handleNFTTransfer(event: Transfer): void { 329 | const createToken = ZoraCreateToken.load(getDefaultTokenId(event.address)); 330 | if (!createToken) { 331 | return; 332 | } 333 | if (event.params.from.equals(Address.zero())) { 334 | createToken.totalMinted = createToken.totalMinted.plus(BigInt.fromI32(1)); 335 | createToken.totalSupply = createToken.totalSupply.plus(BigInt.fromI32(1)); 336 | } 337 | if (event.params.to.equals(Address.zero())) { 338 | createToken.totalSupply = createToken.totalSupply.minus(BigInt.fromI32(1)); 339 | } 340 | createToken.save(); 341 | } 342 | 343 | /* handle ownership transfer */ 344 | 345 | export function handleOwnershipTransferred(event: OwnershipTransferred): void { 346 | const createContract = ZoraCreateContract.load(event.address.toHexString()); 347 | if (!createContract) { 348 | return; 349 | } 350 | createContract.owner = event.params.newOwner; 351 | createContract.save(); 352 | } 353 | 354 | export function handleMintComment(event: ERC721DropMintComment): void { 355 | const mintComment = new MintComment(getMintCommentId(event)); 356 | 357 | mintComment.comment = event.params.comment; 358 | mintComment.mintQuantity = event.params.quantity; 359 | mintComment.sender = event.params.sender; 360 | mintComment.tokenId = event.params.tokenId; 361 | mintComment.tokenAndContract = getTokenId( 362 | event.params.tokenContract, 363 | BigInt.zero() 364 | ); 365 | 366 | mintComment.txn = makeTransaction(event); 367 | mintComment.address = event.address; 368 | mintComment.block = event.block.number; 369 | mintComment.timestamp = event.block.timestamp; 370 | 371 | mintComment.save(); 372 | } 373 | 374 | export function handleSale(event: ERC721DropSale): void { 375 | const sale = new TokenSale(getSaleId(event)); 376 | 377 | sale.tokenAndContract = getTokenId(event.address, BigInt.zero()); 378 | sale.firstPurchasedTokenId = event.params.firstPurchasedTokenId; 379 | sale.pricePerToken = event.params.pricePerToken; 380 | sale.mintRecipient = event.params.to; 381 | sale.quantity = event.params.quantity; 382 | 383 | sale.txn = makeTransaction(event); 384 | sale.block = event.block.number; 385 | sale.timestamp = event.block.timestamp; 386 | sale.address = event.address; 387 | 388 | sale.save(); 389 | } 390 | -------------------------------------------------------------------------------- /abis/ZoraNFTCreatorV1.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_implementation", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "contract EditionMetadataRenderer", 11 | "name": "_editionMetadataRenderer", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "contract DropMetadataRenderer", 16 | "name": "_dropMetadataRenderer", 17 | "type": "address" 18 | } 19 | ], 20 | "stateMutability": "nonpayable", 21 | "type": "constructor" 22 | }, 23 | { 24 | "anonymous": false, 25 | "inputs": [ 26 | { 27 | "indexed": false, 28 | "internalType": "address", 29 | "name": "previousAdmin", 30 | "type": "address" 31 | }, 32 | { 33 | "indexed": false, 34 | "internalType": "address", 35 | "name": "newAdmin", 36 | "type": "address" 37 | } 38 | ], 39 | "name": "AdminChanged", 40 | "type": "event" 41 | }, 42 | { 43 | "anonymous": false, 44 | "inputs": [ 45 | { 46 | "indexed": true, 47 | "internalType": "address", 48 | "name": "beacon", 49 | "type": "address" 50 | } 51 | ], 52 | "name": "BeaconUpgraded", 53 | "type": "event" 54 | }, 55 | { 56 | "anonymous": false, 57 | "inputs": [ 58 | { 59 | "indexed": true, 60 | "internalType": "address", 61 | "name": "creator", 62 | "type": "address" 63 | }, 64 | { 65 | "indexed": true, 66 | "internalType": "address", 67 | "name": "editionContractAddress", 68 | "type": "address" 69 | }, 70 | { 71 | "indexed": false, 72 | "internalType": "uint256", 73 | "name": "editionSize", 74 | "type": "uint256" 75 | } 76 | ], 77 | "name": "CreatedDrop", 78 | "type": "event" 79 | }, 80 | { 81 | "anonymous": false, 82 | "inputs": [ 83 | { 84 | "indexed": true, 85 | "internalType": "address", 86 | "name": "previousOwner", 87 | "type": "address" 88 | }, 89 | { 90 | "indexed": true, 91 | "internalType": "address", 92 | "name": "newOwner", 93 | "type": "address" 94 | } 95 | ], 96 | "name": "OwnershipTransferred", 97 | "type": "event" 98 | }, 99 | { 100 | "anonymous": false, 101 | "inputs": [ 102 | { 103 | "indexed": true, 104 | "internalType": "address", 105 | "name": "implementation", 106 | "type": "address" 107 | } 108 | ], 109 | "name": "Upgraded", 110 | "type": "event" 111 | }, 112 | { 113 | "inputs": [], 114 | "name": "contractVersion", 115 | "outputs": [ 116 | { 117 | "internalType": "uint32", 118 | "name": "", 119 | "type": "uint32" 120 | } 121 | ], 122 | "stateMutability": "view", 123 | "type": "function" 124 | }, 125 | { 126 | "inputs": [ 127 | { 128 | "internalType": "string", 129 | "name": "name", 130 | "type": "string" 131 | }, 132 | { 133 | "internalType": "string", 134 | "name": "symbol", 135 | "type": "string" 136 | }, 137 | { 138 | "internalType": "address", 139 | "name": "defaultAdmin", 140 | "type": "address" 141 | }, 142 | { 143 | "internalType": "uint64", 144 | "name": "editionSize", 145 | "type": "uint64" 146 | }, 147 | { 148 | "internalType": "uint16", 149 | "name": "royaltyBPS", 150 | "type": "uint16" 151 | }, 152 | { 153 | "internalType": "address payable", 154 | "name": "fundsRecipient", 155 | "type": "address" 156 | }, 157 | { 158 | "internalType": "bytes[]", 159 | "name": "setupCalls", 160 | "type": "bytes[]" 161 | }, 162 | { 163 | "internalType": "contract IMetadataRenderer", 164 | "name": "metadataRenderer", 165 | "type": "address" 166 | }, 167 | { 168 | "internalType": "bytes", 169 | "name": "metadataInitializer", 170 | "type": "bytes" 171 | } 172 | ], 173 | "name": "createAndConfigureDrop", 174 | "outputs": [ 175 | { 176 | "internalType": "address payable", 177 | "name": "newDropAddress", 178 | "type": "address" 179 | } 180 | ], 181 | "stateMutability": "nonpayable", 182 | "type": "function" 183 | }, 184 | { 185 | "inputs": [ 186 | { 187 | "internalType": "string", 188 | "name": "name", 189 | "type": "string" 190 | }, 191 | { 192 | "internalType": "string", 193 | "name": "symbol", 194 | "type": "string" 195 | }, 196 | { 197 | "internalType": "address", 198 | "name": "defaultAdmin", 199 | "type": "address" 200 | }, 201 | { 202 | "internalType": "uint64", 203 | "name": "editionSize", 204 | "type": "uint64" 205 | }, 206 | { 207 | "internalType": "uint16", 208 | "name": "royaltyBPS", 209 | "type": "uint16" 210 | }, 211 | { 212 | "internalType": "address payable", 213 | "name": "fundsRecipient", 214 | "type": "address" 215 | }, 216 | { 217 | "components": [ 218 | { 219 | "internalType": "uint104", 220 | "name": "publicSalePrice", 221 | "type": "uint104" 222 | }, 223 | { 224 | "internalType": "uint32", 225 | "name": "maxSalePurchasePerAddress", 226 | "type": "uint32" 227 | }, 228 | { 229 | "internalType": "uint64", 230 | "name": "publicSaleStart", 231 | "type": "uint64" 232 | }, 233 | { 234 | "internalType": "uint64", 235 | "name": "publicSaleEnd", 236 | "type": "uint64" 237 | }, 238 | { 239 | "internalType": "uint64", 240 | "name": "presaleStart", 241 | "type": "uint64" 242 | }, 243 | { 244 | "internalType": "uint64", 245 | "name": "presaleEnd", 246 | "type": "uint64" 247 | }, 248 | { 249 | "internalType": "bytes32", 250 | "name": "presaleMerkleRoot", 251 | "type": "bytes32" 252 | } 253 | ], 254 | "internalType": "struct IERC721Drop.SalesConfiguration", 255 | "name": "saleConfig", 256 | "type": "tuple" 257 | }, 258 | { 259 | "internalType": "string", 260 | "name": "metadataURIBase", 261 | "type": "string" 262 | }, 263 | { 264 | "internalType": "string", 265 | "name": "metadataContractURI", 266 | "type": "string" 267 | } 268 | ], 269 | "name": "createDrop", 270 | "outputs": [ 271 | { 272 | "internalType": "address", 273 | "name": "", 274 | "type": "address" 275 | } 276 | ], 277 | "stateMutability": "nonpayable", 278 | "type": "function" 279 | }, 280 | { 281 | "inputs": [ 282 | { 283 | "internalType": "string", 284 | "name": "name", 285 | "type": "string" 286 | }, 287 | { 288 | "internalType": "string", 289 | "name": "symbol", 290 | "type": "string" 291 | }, 292 | { 293 | "internalType": "uint64", 294 | "name": "editionSize", 295 | "type": "uint64" 296 | }, 297 | { 298 | "internalType": "uint16", 299 | "name": "royaltyBPS", 300 | "type": "uint16" 301 | }, 302 | { 303 | "internalType": "address payable", 304 | "name": "fundsRecipient", 305 | "type": "address" 306 | }, 307 | { 308 | "internalType": "address", 309 | "name": "defaultAdmin", 310 | "type": "address" 311 | }, 312 | { 313 | "components": [ 314 | { 315 | "internalType": "uint104", 316 | "name": "publicSalePrice", 317 | "type": "uint104" 318 | }, 319 | { 320 | "internalType": "uint32", 321 | "name": "maxSalePurchasePerAddress", 322 | "type": "uint32" 323 | }, 324 | { 325 | "internalType": "uint64", 326 | "name": "publicSaleStart", 327 | "type": "uint64" 328 | }, 329 | { 330 | "internalType": "uint64", 331 | "name": "publicSaleEnd", 332 | "type": "uint64" 333 | }, 334 | { 335 | "internalType": "uint64", 336 | "name": "presaleStart", 337 | "type": "uint64" 338 | }, 339 | { 340 | "internalType": "uint64", 341 | "name": "presaleEnd", 342 | "type": "uint64" 343 | }, 344 | { 345 | "internalType": "bytes32", 346 | "name": "presaleMerkleRoot", 347 | "type": "bytes32" 348 | } 349 | ], 350 | "internalType": "struct IERC721Drop.SalesConfiguration", 351 | "name": "saleConfig", 352 | "type": "tuple" 353 | }, 354 | { 355 | "internalType": "string", 356 | "name": "description", 357 | "type": "string" 358 | }, 359 | { 360 | "internalType": "string", 361 | "name": "animationURI", 362 | "type": "string" 363 | }, 364 | { 365 | "internalType": "string", 366 | "name": "imageURI", 367 | "type": "string" 368 | } 369 | ], 370 | "name": "createEdition", 371 | "outputs": [ 372 | { 373 | "internalType": "address", 374 | "name": "", 375 | "type": "address" 376 | } 377 | ], 378 | "stateMutability": "nonpayable", 379 | "type": "function" 380 | }, 381 | { 382 | "inputs": [], 383 | "name": "dropMetadataRenderer", 384 | "outputs": [ 385 | { 386 | "internalType": "contract DropMetadataRenderer", 387 | "name": "", 388 | "type": "address" 389 | } 390 | ], 391 | "stateMutability": "view", 392 | "type": "function" 393 | }, 394 | { 395 | "inputs": [], 396 | "name": "editionMetadataRenderer", 397 | "outputs": [ 398 | { 399 | "internalType": "contract EditionMetadataRenderer", 400 | "name": "", 401 | "type": "address" 402 | } 403 | ], 404 | "stateMutability": "view", 405 | "type": "function" 406 | }, 407 | { 408 | "inputs": [], 409 | "name": "implementation", 410 | "outputs": [ 411 | { 412 | "internalType": "address", 413 | "name": "", 414 | "type": "address" 415 | } 416 | ], 417 | "stateMutability": "view", 418 | "type": "function" 419 | }, 420 | { 421 | "inputs": [], 422 | "name": "initialize", 423 | "outputs": [], 424 | "stateMutability": "nonpayable", 425 | "type": "function" 426 | }, 427 | { 428 | "inputs": [], 429 | "name": "owner", 430 | "outputs": [ 431 | { 432 | "internalType": "address", 433 | "name": "", 434 | "type": "address" 435 | } 436 | ], 437 | "stateMutability": "view", 438 | "type": "function" 439 | }, 440 | { 441 | "inputs": [], 442 | "name": "proxiableUUID", 443 | "outputs": [ 444 | { 445 | "internalType": "bytes32", 446 | "name": "", 447 | "type": "bytes32" 448 | } 449 | ], 450 | "stateMutability": "view", 451 | "type": "function" 452 | }, 453 | { 454 | "inputs": [], 455 | "name": "renounceOwnership", 456 | "outputs": [], 457 | "stateMutability": "nonpayable", 458 | "type": "function" 459 | }, 460 | { 461 | "inputs": [ 462 | { 463 | "internalType": "string", 464 | "name": "name", 465 | "type": "string" 466 | }, 467 | { 468 | "internalType": "string", 469 | "name": "symbol", 470 | "type": "string" 471 | }, 472 | { 473 | "internalType": "address", 474 | "name": "defaultAdmin", 475 | "type": "address" 476 | }, 477 | { 478 | "internalType": "uint64", 479 | "name": "editionSize", 480 | "type": "uint64" 481 | }, 482 | { 483 | "internalType": "uint16", 484 | "name": "royaltyBPS", 485 | "type": "uint16" 486 | }, 487 | { 488 | "internalType": "address payable", 489 | "name": "fundsRecipient", 490 | "type": "address" 491 | }, 492 | { 493 | "components": [ 494 | { 495 | "internalType": "uint104", 496 | "name": "publicSalePrice", 497 | "type": "uint104" 498 | }, 499 | { 500 | "internalType": "uint32", 501 | "name": "maxSalePurchasePerAddress", 502 | "type": "uint32" 503 | }, 504 | { 505 | "internalType": "uint64", 506 | "name": "publicSaleStart", 507 | "type": "uint64" 508 | }, 509 | { 510 | "internalType": "uint64", 511 | "name": "publicSaleEnd", 512 | "type": "uint64" 513 | }, 514 | { 515 | "internalType": "uint64", 516 | "name": "presaleStart", 517 | "type": "uint64" 518 | }, 519 | { 520 | "internalType": "uint64", 521 | "name": "presaleEnd", 522 | "type": "uint64" 523 | }, 524 | { 525 | "internalType": "bytes32", 526 | "name": "presaleMerkleRoot", 527 | "type": "bytes32" 528 | } 529 | ], 530 | "internalType": "struct IERC721Drop.SalesConfiguration", 531 | "name": "saleConfig", 532 | "type": "tuple" 533 | }, 534 | { 535 | "internalType": "contract IMetadataRenderer", 536 | "name": "metadataRenderer", 537 | "type": "address" 538 | }, 539 | { 540 | "internalType": "bytes", 541 | "name": "metadataInitializer", 542 | "type": "bytes" 543 | } 544 | ], 545 | "name": "setupDropsContract", 546 | "outputs": [ 547 | { 548 | "internalType": "address", 549 | "name": "", 550 | "type": "address" 551 | } 552 | ], 553 | "stateMutability": "nonpayable", 554 | "type": "function" 555 | }, 556 | { 557 | "inputs": [ 558 | { 559 | "internalType": "address", 560 | "name": "newOwner", 561 | "type": "address" 562 | } 563 | ], 564 | "name": "transferOwnership", 565 | "outputs": [], 566 | "stateMutability": "nonpayable", 567 | "type": "function" 568 | }, 569 | { 570 | "inputs": [ 571 | { 572 | "internalType": "address", 573 | "name": "newImplementation", 574 | "type": "address" 575 | } 576 | ], 577 | "name": "upgradeTo", 578 | "outputs": [], 579 | "stateMutability": "nonpayable", 580 | "type": "function" 581 | }, 582 | { 583 | "inputs": [ 584 | { 585 | "internalType": "address", 586 | "name": "newImplementation", 587 | "type": "address" 588 | }, 589 | { 590 | "internalType": "bytes", 591 | "name": "data", 592 | "type": "bytes" 593 | } 594 | ], 595 | "name": "upgradeToAndCall", 596 | "outputs": [], 597 | "stateMutability": "payable", 598 | "type": "function" 599 | } 600 | ] 601 | -------------------------------------------------------------------------------- /src/ERC1155Mappings/templates/ZoraCreator1155ImplMappings.ts: -------------------------------------------------------------------------------- 1 | import { Address, BigInt, Bytes } from "@graphprotocol/graph-ts"; 2 | import { 3 | ZoraCreateContract, 4 | ZoraCreateToken, 5 | ZoraCreatorPermission, 6 | RoyaltyConfig, 7 | Token1155Holder, 8 | OnChainMetadataHistory, 9 | } from "../../../generated/schema"; 10 | import { MetadataInfo as MetadataInfoTemplate } from "../../../generated/templates"; 11 | import { 12 | ContractRendererUpdated, 13 | OwnershipTransferred, 14 | TransferBatch, 15 | TransferSingle, 16 | UpdatedPermissions, 17 | UpdatedRoyalties, 18 | UpdatedToken, 19 | URI, 20 | ContractMetadataUpdated, 21 | SetupNewToken, 22 | ZoraCreator1155Impl, 23 | RendererUpdated, 24 | } from "../../../generated/templates/ZoraCreator1155Impl/ZoraCreator1155Impl"; 25 | import { Upgraded } from "../../../generated/ZoraNFTCreatorFactory1155V1/ZoraCreator1155FactoryImpl"; 26 | import { getOnChainMetadataKey } from "../../common/getOnChainMetadataKey"; 27 | import { getPermissionsKey } from "../../common/getPermissionsKey"; 28 | import { getToken1155HolderId } from "../../common/getToken1155HolderId"; 29 | import { getTokenId } from "../../common/getTokenId"; 30 | import { hasBit } from "../../common/hasBit"; 31 | import { makeTransaction } from "../../common/makeTransaction"; 32 | import { TOKEN_STANDARD_ERC1155 } from "../../constants/tokenStandard"; 33 | import { getContractId } from "../../common/getContractId"; 34 | import { 35 | extractIPFSIDFromContract, 36 | loadMetadataInfoFromID, 37 | } from "../../common/metadata"; 38 | 39 | export function handleUpgraded(event: Upgraded): void { 40 | const impl = ZoraCreator1155Impl.bind(event.address); 41 | const contract = ZoraCreateContract.load(event.address.toHex()); 42 | if (!impl || !contract) { 43 | return; 44 | } 45 | 46 | const mintFeeAttempt = impl.try_mintFee(); 47 | if (mintFeeAttempt.reverted) { 48 | contract.mintFeePerQuantity = BigInt.fromI64(777000000000000); 49 | } else { 50 | contract.mintFeePerQuantity = mintFeeAttempt.value; 51 | } 52 | contract.contractVersion = impl.contractVersion(); 53 | contract.contractStandard = TOKEN_STANDARD_ERC1155; 54 | 55 | contract.save(); 56 | } 57 | 58 | export function handleContractRendererUpdated( 59 | event: ContractRendererUpdated 60 | ): void { 61 | const contract = ZoraCreateContract.load(event.address.toHex()); 62 | if (!contract) { 63 | return; 64 | } 65 | 66 | contract.rendererContract = event.params.renderer; 67 | contract.save(); 68 | } 69 | 70 | export function handleRendererUpdated(event: RendererUpdated): void { 71 | const token = ZoraCreateToken.load( 72 | getTokenId(event.address, event.params.tokenId) 73 | ); 74 | if (!token) { 75 | return; 76 | } 77 | 78 | token.rendererContract = event.params.renderer; 79 | token.save(); 80 | } 81 | 82 | export function handleURI(event: URI): void { 83 | const id = getTokenId(event.address, event.params.id); 84 | const token = ZoraCreateToken.load(id); 85 | if (!token) { 86 | return; 87 | } 88 | 89 | const impl = ZoraCreator1155Impl.bind(event.address); 90 | const uri = impl.try_uri(event.params.id); 91 | token.metadataIPFSID = extractIPFSIDFromContract(uri); 92 | token.metadata = loadMetadataInfoFromID(token.metadataIPFSID); 93 | if (!uri.reverted) { 94 | token.uri = uri.value; 95 | } 96 | 97 | token.save(); 98 | 99 | const history = new OnChainMetadataHistory(getOnChainMetadataKey(event)); 100 | 101 | const txn = makeTransaction(event); 102 | history.txn = txn; 103 | history.block = event.block.number; 104 | history.timestamp = event.block.timestamp; 105 | history.address = event.address; 106 | 107 | history.tokenAndContract = id; 108 | history.rendererAddress = Bytes.fromHexString( 109 | "0x0000000000000000000000000000000000000000" 110 | ); 111 | history.createdAtBlock = event.block.number; 112 | history.directURI = event.params.value; 113 | history.directURIMetadata = token.metadataIPFSID; 114 | history.knownType = "DIRECT_URI"; 115 | history.save(); 116 | } 117 | 118 | export function handleUpdatedPermissions(event: UpdatedPermissions): void { 119 | const id = getPermissionsKey( 120 | event.params.user, 121 | event.address, 122 | event.params.tokenId 123 | ); 124 | let permissions = ZoraCreatorPermission.load(id); 125 | if (!permissions) { 126 | permissions = new ZoraCreatorPermission(id); 127 | } 128 | 129 | permissions.block = event.block.number; 130 | permissions.timestamp = event.block.timestamp; 131 | 132 | permissions.isAdmin = hasBit(1, event.params.permissions); 133 | permissions.isMinter = hasBit(2, event.params.permissions); 134 | permissions.isSalesManager = hasBit(3, event.params.permissions); 135 | permissions.isMetadataManager = hasBit(4, event.params.permissions); 136 | permissions.isFundsManager = hasBit(5, event.params.permissions); 137 | 138 | permissions.user = event.params.user; 139 | permissions.txn = makeTransaction(event); 140 | permissions.tokenId = event.params.tokenId; 141 | 142 | permissions.tokenId = event.params.tokenId; 143 | if (event.params.tokenId.equals(BigInt.zero())) { 144 | permissions.contract = getContractId(event.address); 145 | } else { 146 | permissions.tokenAndContract = getTokenId( 147 | event.address, 148 | event.params.tokenId 149 | ); 150 | } 151 | 152 | permissions.save(); 153 | } 154 | 155 | export function handleUpdatedRoyalties(event: UpdatedRoyalties): void { 156 | const id = event.params.tokenId.equals(BigInt.zero()) 157 | ? event.address.toHex() 158 | : getTokenId(event.address, event.params.tokenId); 159 | let royalties = new RoyaltyConfig(id); 160 | if (!royalties) { 161 | royalties = new RoyaltyConfig(id); 162 | } 163 | 164 | royalties.tokenId = event.params.tokenId; 165 | royalties.user = event.params.user; 166 | royalties.royaltyBPS = event.params.configuration.royaltyBPS; 167 | royalties.royaltyRecipient = event.params.configuration.royaltyRecipient; 168 | royalties.royaltyMintSchedule = 169 | event.params.configuration.royaltyMintSchedule; 170 | 171 | if (event.params.tokenId.equals(BigInt.zero())) { 172 | royalties.contract = getContractId(event.address); 173 | } else { 174 | royalties.tokenAndContract = getTokenId( 175 | event.address, 176 | event.params.tokenId 177 | ); 178 | } 179 | 180 | royalties.save(); 181 | } 182 | 183 | function _updateHolderTransfer( 184 | blockNumber: BigInt, 185 | contractAddress: Address, 186 | from: Address, 187 | to: Address, 188 | id: BigInt, 189 | value: BigInt 190 | ): BigInt { 191 | let tokenHolderCountChange = new BigInt(0); 192 | if (!to.equals(Address.zero())) { 193 | const holderId = getToken1155HolderId(to, contractAddress, id); 194 | let holder = Token1155Holder.load(holderId); 195 | if (!holder) { 196 | holder = new Token1155Holder(holderId); 197 | holder.balance = value; 198 | holder.tokenAndContract = getTokenId(contractAddress, id); 199 | holder.user = to; 200 | tokenHolderCountChange = tokenHolderCountChange.plus(new BigInt(1)); 201 | } else { 202 | holder.balance = holder.balance.plus(value); 203 | } 204 | holder.lastUpdatedBlock = blockNumber; 205 | holder.save(); 206 | } else { 207 | const fromHolder = Token1155Holder.load( 208 | getToken1155HolderId(from, contractAddress, id) 209 | ); 210 | if (fromHolder) { 211 | fromHolder.balance = fromHolder.balance.minus(value); 212 | fromHolder.lastUpdatedBlock = blockNumber; 213 | fromHolder.save(); 214 | if (fromHolder.balance.equals(BigInt.zero())) { 215 | tokenHolderCountChange = tokenHolderCountChange.minus(new BigInt(1)); 216 | } 217 | } 218 | } 219 | return tokenHolderCountChange; 220 | } 221 | 222 | function getTokenCreator(event: UpdatedToken): Bytes { 223 | const defaultFrom = event.params.from; 224 | if (event.receipt === null) { 225 | return defaultFrom; 226 | } 227 | 228 | for (let i = 0; i < event.receipt!.logs.length; i++) { 229 | if ( 230 | event.receipt!.logs[i].topics[0].equals( 231 | Bytes.fromHexString( 232 | // Event CreatorAttribution 233 | "0x06c5a80e592816bd4f60093568e69affa68b5e378a189b2f59a1121703de47de" 234 | ) 235 | ) 236 | ) { 237 | const newAddress = event 238 | .receipt!.logs[i].data.toHex() 239 | // Parse out the exact part of the event address since we didn't add topics for this event 240 | .slice(218, 218 + 40); 241 | if (newAddress && newAddress.length === 40) { 242 | return Address.fromHexString(newAddress); 243 | } 244 | } 245 | 246 | // SetupNewContract(address indexed newContract, address indexed creator, address indexed defaultAdmin, ...); 247 | if ( 248 | event.receipt!.logs[i].topics[0].equals( 249 | Bytes.fromHexString( 250 | "0xa45800684f65ae010ceb4385eceaed88dec7f6a6bcbe11f7ffd8bd24dd2653f4" 251 | ) 252 | ) 253 | ) { 254 | const newAddress = event 255 | .receipt!.logs[i].topics[3].toHexString() 256 | .slice(26); 257 | 258 | if (newAddress && newAddress.length === 40) { 259 | return Address.fromHexString(newAddress); 260 | } 261 | } 262 | } 263 | 264 | return defaultFrom; 265 | } 266 | 267 | export function handleUpdatedToken(event: UpdatedToken): void { 268 | const id = getTokenId(event.address, event.params.tokenId); 269 | let token = ZoraCreateToken.load(id); 270 | if (!token) { 271 | token = new ZoraCreateToken(id); 272 | token.holders1155Number = new BigInt(0); 273 | token.tokenStandard = TOKEN_STANDARD_ERC1155; 274 | token.address = event.address; 275 | token.createdAtBlock = event.block.number; 276 | token.totalMinted = BigInt.zero(); 277 | token.creator = getTokenCreator(event); 278 | } 279 | 280 | const txn = makeTransaction(event); 281 | token.txn = txn; 282 | token.block = event.block.number; 283 | token.timestamp = event.block.timestamp; 284 | 285 | token.contract = getContractId(event.address); 286 | token.tokenId = event.params.tokenId; 287 | token.uri = event.params.tokenData.uri; 288 | token.maxSupply = event.params.tokenData.maxSupply; 289 | token.totalMinted = event.params.tokenData.totalMinted; 290 | token.totalSupply = event.params.tokenData.totalMinted; 291 | 292 | token.save(); 293 | } 294 | 295 | // update the minted number and mx number 296 | export function handleTransferSingle(event: TransferSingle): void { 297 | const newHolderNumber = _updateHolderTransfer( 298 | event.block.number, 299 | event.address, 300 | event.params.from, 301 | event.params.to, 302 | event.params.id, 303 | event.params.value 304 | ); 305 | 306 | const token = ZoraCreateToken.load( 307 | getTokenId(event.address, event.params.id) 308 | ); 309 | 310 | if (!token) { 311 | return; 312 | } 313 | 314 | if (event.params.from.equals(Address.zero())) { 315 | token.totalSupply = token.totalSupply.plus(event.params.value); 316 | token.totalMinted = token.totalMinted.plus(event.params.value); 317 | token.holders1155Number = token.holders1155Number.plus(newHolderNumber); 318 | } else if (event.params.to.equals(Address.zero())) { 319 | token.totalSupply = token.totalSupply.minus(event.params.value); 320 | token.holders1155Number = token.holders1155Number.plus(newHolderNumber); 321 | } else if (newHolderNumber.gt(new BigInt(0))) { 322 | token.holders1155Number = token.holders1155Number.plus(newHolderNumber); 323 | } 324 | 325 | token.save(); 326 | } 327 | 328 | // update the minted number and max number 329 | export function handleTransferBatch(event: TransferBatch): void { 330 | if (event.params.from.equals(Address.zero())) { 331 | for (let i = 0; i < event.params.ids.length; i++) { 332 | const newTokenHolderBalance = _updateHolderTransfer( 333 | event.block.number, 334 | event.address, 335 | event.params.from, 336 | event.params.to, 337 | event.params.ids[i], 338 | event.params.values[i] 339 | ); 340 | const tokenId = getTokenId(event.address, event.params.ids[i]); 341 | const token = ZoraCreateToken.load(tokenId); 342 | if (token) { 343 | token.holders1155Number = token.holders1155Number.plus( 344 | newTokenHolderBalance 345 | ); 346 | token.totalSupply = token.totalSupply.plus(event.params.values[i]); 347 | token.totalMinted = token.totalMinted.plus(event.params.values[i]); 348 | token.save(); 349 | } 350 | } 351 | } else if (event.params.to.equals(Address.zero())) { 352 | for (let i = 0; i < event.params.ids.length; i++) { 353 | const newTokenHolderBalance = _updateHolderTransfer( 354 | event.block.number, 355 | event.address, 356 | event.params.from, 357 | event.params.to, 358 | event.params.ids[i], 359 | event.params.values[i] 360 | ); 361 | const tokenId = getTokenId(event.address, event.params.ids[i]); 362 | const token = ZoraCreateToken.load(tokenId); 363 | if (token) { 364 | token.holders1155Number = token.holders1155Number.plus( 365 | newTokenHolderBalance 366 | ); 367 | token.totalSupply = token.totalSupply.minus(event.params.values[i]); 368 | token.save(); 369 | } 370 | } 371 | } else { 372 | for (let i = 0; i < event.params.ids.length; i++) { 373 | const newTokenHolderBalance = _updateHolderTransfer( 374 | event.block.number, 375 | event.address, 376 | event.params.from, 377 | event.params.to, 378 | event.params.ids[i], 379 | event.params.values[i] 380 | ); 381 | const tokenId = getTokenId(event.address, event.params.ids[i]); 382 | const token = ZoraCreateToken.load(tokenId); 383 | if (token) { 384 | token.holders1155Number = token.holders1155Number.plus( 385 | newTokenHolderBalance 386 | ); 387 | token.save(); 388 | } 389 | } 390 | } 391 | } 392 | 393 | // Update ownership field when transferred 394 | export function handleOwnershipTransferred(event: OwnershipTransferred): void { 395 | const createContract = ZoraCreateContract.load(event.address.toHex()); 396 | if (createContract) { 397 | createContract.owner = event.params.newOwner; 398 | createContract.txn = makeTransaction(event); 399 | createContract.save(); 400 | } 401 | } 402 | 403 | export function handleContractMetadataUpdated( 404 | event: ContractMetadataUpdated 405 | ): void { 406 | const createContract = ZoraCreateContract.load(event.address.toHex()); 407 | if (createContract) { 408 | createContract.contractURI = event.params.uri; 409 | createContract.name = event.params.name; 410 | 411 | const impl = ZoraCreator1155Impl.bind(event.address); 412 | createContract.metadataIPFSID = extractIPFSIDFromContract( 413 | impl.try_contractURI() 414 | ); 415 | createContract.metadata = loadMetadataInfoFromID( 416 | createContract.metadataIPFSID 417 | ); 418 | 419 | createContract.save(); 420 | } 421 | } 422 | 423 | export function handleSetupNewToken(event: SetupNewToken): void { 424 | const token = new ZoraCreateToken( 425 | getTokenId(event.address, event.params.tokenId) 426 | ); 427 | 428 | token.holders1155Number = new BigInt(0); 429 | token.createdAtBlock = event.block.number; 430 | token.tokenId = event.params.tokenId; 431 | token.uri = event.params.newURI; 432 | token.maxSupply = event.params.maxSupply; 433 | 434 | const txn = makeTransaction(event); 435 | token.txn = txn; 436 | token.block = event.block.number; 437 | token.address = event.address; 438 | token.timestamp = event.block.timestamp; 439 | 440 | token.contract = getContractId(event.address); 441 | token.tokenStandard = TOKEN_STANDARD_ERC1155; 442 | 443 | const impl = ZoraCreator1155Impl.bind(event.address); 444 | token.metadataIPFSID = extractIPFSIDFromContract( 445 | impl.try_uri(event.params.tokenId) 446 | ); 447 | 448 | token.metadata = loadMetadataInfoFromID(token.metadataIPFSID); 449 | token.totalMinted = BigInt.zero(); 450 | token.totalSupply = BigInt.zero(); 451 | token.save(); 452 | } 453 | -------------------------------------------------------------------------------- /subgraph.template.yaml: -------------------------------------------------------------------------------- 1 | specVersion: 0.0.2 2 | schema: 3 | file: ./schema.graphql 4 | dataSources: 5 | {{#protocolRewards}} 6 | - name: ProtocolRewardsV{{version}} 7 | kind: ethereum/contract 8 | network: {{network}} 9 | source: 10 | abi: ProtocolRewards 11 | address: "{{address}}" 12 | startBlock: {{startBlock}} 13 | mapping: 14 | kind: ethereum/events 15 | apiVersion: 0.0.7 16 | entities: 17 | - RewardsPerUserPerDay 18 | - RewardsPerUser 19 | - RewardsStandardDeposit 20 | - RewardsCustomDeposit 21 | - RewardsWithdraw 22 | language: wasm/assemblyscript 23 | file: ./src/RewardsMappings/rewardsMappings.ts 24 | abis: 25 | - name: ProtocolRewards 26 | file: ./abis/ProtocolRewards.json 27 | eventHandlers: 28 | - event: Deposit(indexed address,indexed address,indexed bytes4,uint256,string) 29 | handler: handleDeposit 30 | - event: RewardsDeposit(indexed address,indexed address,indexed address,address,address,address,uint256,uint256,uint256,uint256,uint256) 31 | handler: handleRewardsDeposit 32 | - event: Withdraw(indexed address,indexed address,uint256) 33 | handler: handleWithdraw 34 | {{/protocolRewards}} 35 | {{#factories1155}} 36 | - kind: ethereum/contract 37 | name: ZoraNFTCreatorFactory1155V{{version}} 38 | network: {{network}} 39 | source: 40 | address: "{{address}}" 41 | abi: ZoraCreator1155FactoryImpl 42 | startBlock: {{startBlock}} 43 | mapping: 44 | kind: ethereum/events 45 | apiVersion: 0.0.7 46 | language: wasm/assemblyscript 47 | entities: 48 | - ERC1155Drop 49 | - MetadataInfo 50 | - ZoraCreateToken 51 | - ZoraCreateContract 52 | abis: 53 | - name: ZoraCreator1155FactoryImpl 54 | file: ./abis/ZoraCreator1155FactoryImpl.json 55 | - name: ZoraCreator1155Impl 56 | file: ./abis/ZoraCreator1155Impl.json 57 | eventHandlers: 58 | - event: SetupNewContract(indexed address,indexed address,indexed address,string,string,(uint32,uint32,address)) 59 | handler: handleNewContractCreated 60 | receipt: true 61 | - event: Upgraded(indexed address) 62 | handler: handle1155FactoryUpgraded 63 | file: ./src/ERC1155Mappings/factoryMappings.ts 64 | {{/factories1155}} 65 | {{#factories721}} 66 | - kind: ethereum/contract 67 | name: Zora721V{{version}} 68 | network: {{network}} 69 | source: 70 | address: "{{address}}" 71 | abi: ZoraNFTCreatorV1 72 | startBlock: {{startBlock}} 73 | mapping: 74 | kind: ethereum/events 75 | apiVersion: 0.0.7 76 | language: wasm/assemblyscript 77 | entities: 78 | - ZoraCreateContract 79 | - ZoraCreateToken 80 | - MetadataInfo 81 | abis: 82 | - name: ZoraNFTCreatorV1 83 | file: ./abis/ZoraNFTCreatorV1.json 84 | - name: ERC721Drop 85 | file: ./abis/ERC721Drop.json 86 | eventHandlers: 87 | - event: CreatedDrop(indexed address,indexed address,uint256) 88 | handler: handleCreatedDrop 89 | - event: Upgraded(indexed address) 90 | handler: handleFactoryUpgraded 91 | file: ./src/ERC721Mappings/ERC721FactoryMappings.ts 92 | {{/factories721}} 93 | {{#preminter}} 94 | - kind: ethereum/contract 95 | name: ZoraCreator1155PremintExecutorV{{version}} 96 | network: {{network}} 97 | source: 98 | address: "{{address}}" 99 | abi: ZoraCreator1155PremintExecutorImpl 100 | startBlock: {{startBlock}} 101 | mapping: 102 | kind: ethereum/events 103 | apiVersion: 0.0.7 104 | language: wasm/assemblyscript 105 | entities: 106 | - Premint 107 | file: ./src/ERC1155Mappings/premintMappings.ts 108 | abis: 109 | - name: ZoraCreator1155PremintExecutorImpl 110 | file: ./abis/ZoraCreator1155PremintExecutorImpl.json 111 | eventHandlers: 112 | - event: Preminted(indexed address,indexed uint256,indexed bool,uint32,(address,string,string),(string,uint256,uint64,uint96,uint64,uint64,uint32,uint32,address,address),address,uint256) 113 | handler: handlePreminted 114 | - event: PremintedV2(indexed address,indexed uint256,indexed bool,uint32,address,uint256) 115 | handler: handlePremintedV2 116 | {{/preminter}} 117 | {{#reserveAuctionV3}} 118 | - name: ReserveAuctionV3 119 | kind: ethereum/contract 120 | network: {{network}} 121 | source: 122 | abi: ReserveAuctionV3 123 | address: "{{address}}" 124 | startBlock: {{startBlock}} 125 | mapping: 126 | kind: ethereum/events 127 | apiVersion: 0.0.7 128 | entities: 129 | - Auction 130 | - AuctionBid 131 | language: wasm/assemblyscript 132 | file: ./src/ReserveAuctionV3Mappings/reserveAuctionV3Mappings.ts 133 | abis: 134 | - name: ReserveAuctionV3 135 | file: ./abis/ReserveAuctionV3.json 136 | eventHandlers: 137 | - event: AuctionCreated(indexed address,indexed uint256,(address,address,uint256,uint256,address,uint96,address,uint96,address,uint80,uint16)) 138 | handler: handleAuctionCreated 139 | - event: AuctionBid(indexed address,indexed uint256,bool,bool,(address,address,uint256,uint256,address,uint96,address,uint96,address,uint80,uint16)) 140 | handler: handleAuctionBid 141 | - event: AuctionCanceled(indexed address,indexed uint256,(address,address,uint256,uint256,address,uint96,address,uint96,address,uint80,uint16)) 142 | handler: handleAuctionCanceled 143 | - event: AuctionEnded(indexed address,indexed uint256,(address,address,uint256,uint256,address,uint96,address,uint96,address,uint80,uint16)) 144 | handler: handleAuctionEnded 145 | - event: AuctionReservePriceUpdated(indexed address,indexed uint256,(address,address,uint256,uint256,address,uint96,address,uint96,address,uint80,uint16)) 146 | handler: handleAuctionReservePriceUpdated 147 | {{/reserveAuctionV3}} 148 | templates: 149 | - name: MetadataInfo 150 | kind: file/ipfs 151 | mapping: 152 | apiVersion: 0.0.7 153 | language: wasm/assemblyscript 154 | file: ./src/ipfs/metadata.ts 155 | handler: handleJSONMetadataFetched 156 | entities: 157 | - MetadataInfo 158 | abis: 159 | - name: ZoraCreator1155Impl 160 | file: ./abis/ZoraCreator1155Impl.json 161 | - kind: ethereum/contract 162 | name: EditionMetadataRenderer 163 | network: {{network}} 164 | source: 165 | abi: EditionMetadataRenderer 166 | mapping: 167 | kind: ethereum/events 168 | apiVersion: 0.0.7 169 | language: wasm/assemblyscript 170 | entities: 171 | - EditionMetadata 172 | - ZoraCreateToken 173 | - OnChainMetadata 174 | - TransactionInfo 175 | abis: 176 | - name: EditionMetadataRenderer 177 | file: ./abis/EditionMetadataRenderer.json 178 | - name: ERC721Drop 179 | file: ./abis/ERC721Drop.json 180 | eventHandlers: 181 | - event: EditionInitialized(indexed address,string,string,string) 182 | handler: handleCreatedEdition 183 | - event: MediaURIsUpdated(indexed address,address,string,string) 184 | handler: handleUpdateMediaURIs 185 | - event: DescriptionUpdated(indexed address,address,string) 186 | handler: handleUpdateDescription 187 | file: ./src/ERC721Mappings/templates/EditionMetadataRendererMappings.ts 188 | - kind: ethereum/contract 189 | name: DropMetadataRenderer 190 | network: {{network}} 191 | source: 192 | abi: DropMetadataRenderer 193 | mapping: 194 | kind: ethereum/events 195 | apiVersion: 0.0.7 196 | language: wasm/assemblyscript 197 | entities: 198 | - DropMetadata 199 | - ZoraCreateToken 200 | - OnChainMetadata 201 | - TransactionInfo 202 | - MetadataInfo 203 | abis: 204 | - name: DropMetadataRenderer 205 | file: ./abis/DropMetadataRenderer.json 206 | - name: ERC721Drop 207 | file: ./abis/ERC721Drop.json 208 | eventHandlers: 209 | - event: MetadataUpdated(indexed address,string,string,string,uint256) 210 | handler: handleMetadataUpdated 211 | file: ./src/ERC721Mappings/templates/DropMetadataRendererMappings.ts 212 | - name: ZoraCreator1155Impl 213 | kind: ethereum/contract 214 | network: {{network}} 215 | source: 216 | abi: ZoraCreator1155Impl 217 | mapping: 218 | kind: ethereum/events 219 | apiVersion: 0.0.7 220 | entities: 221 | - ZoraCreateContract 222 | - ZoraCreateToken 223 | - ZoraCreatorPermission 224 | - Token1155Holder 225 | - OnChainMetadataHistory 226 | - RoyaltyConfig 227 | - MetadataInfo 228 | language: wasm/assemblyscript 229 | file: ./src/ERC1155Mappings/templates/ZoraCreator1155ImplMappings.ts 230 | abis: 231 | - name: ZoraCreator1155Impl 232 | file: ./abis/ZoraCreator1155Impl.json 233 | eventHandlers: 234 | - event: ContractRendererUpdated(address) 235 | handler: handleContractRendererUpdated 236 | - event: RendererUpdated(indexed uint256,indexed address,indexed address) 237 | handler: handleRendererUpdated 238 | - event: URI(string,indexed uint256) 239 | handler: handleURI 240 | - event: UpdatedPermissions(indexed uint256,indexed address,indexed uint256) 241 | handler: handleUpdatedPermissions 242 | - event: UpdatedRoyalties(indexed uint256,indexed address,(uint32,uint32,address)) 243 | handler: handleUpdatedRoyalties 244 | - event: UpdatedToken(indexed address,indexed uint256,(string,uint256,uint256)) 245 | handler: handleUpdatedToken 246 | receipt: true 247 | - event: TransferSingle(indexed address,indexed address,indexed address,uint256,uint256) 248 | handler: handleTransferSingle 249 | - event: TransferBatch(indexed address,indexed address,indexed address,uint256[],uint256[]) 250 | handler: handleTransferBatch 251 | - event: Upgraded(indexed address) 252 | handler: handleUpgraded 253 | - event: ContractMetadataUpdated(indexed address,string,string) 254 | handler: handleContractMetadataUpdated 255 | - event: SetupNewToken(indexed uint256,indexed address,string,uint256) 256 | handler: handleSetupNewToken 257 | - event: OwnershipTransferred(address,address) 258 | handler: handleOwnershipTransferred 259 | - name: ZoraCreatorFixedPriceSaleStrategy 260 | kind: ethereum/contract 261 | network: {{network}} 262 | source: 263 | abi: ZoraCreatorFixedPriceSaleStrategy 264 | mapping: 265 | kind: ethereum/events 266 | apiVersion: 0.0.7 267 | entities: 268 | - SalesConfigFixedPriceSaleStrategy 269 | language: wasm/assemblyscript 270 | file: ./src/ERC1155Mappings/templates/ZoraCreatorFixedPriceSaleStrategyMappings.ts 271 | abis: 272 | - name: ZoraCreatorFixedPriceSaleStrategy 273 | file: ./abis/ZoraCreatorFixedPriceSaleStrategy.json 274 | eventHandlers: 275 | - event: SaleSet(indexed address,indexed uint256,(uint64,uint64,uint64,uint96,address)) 276 | handler: handleFixedPriceStrategySaleSet 277 | - event: MintComment(indexed address,indexed address,indexed uint256,uint256,string) 278 | handler: handleMintedWithComment 279 | - name: ZoraCreatorRedeemMinterFactory 280 | kind: ethereum/contract 281 | network: {{network}} 282 | source: 283 | abi: ZoraCreatorRedeemMinterFactory 284 | mapping: 285 | kind: ethereum/events 286 | apiVersion: 0.0.7 287 | entities: 288 | - ZoraCreatorRedeemConfig 289 | language: wasm/assemblyscript 290 | file: ./src/ERC1155Mappings/templates/ZoraCreatorRedeemMinterFactory.ts 291 | abis: 292 | - name: ZoraCreatorRedeemMinterFactory 293 | file: ./abis/ZoraCreatorRedeemMinterFactory.json 294 | eventHandlers: 295 | - event: RedeemMinterDeployed(indexed address,indexed address) 296 | handler: handleRedeemMinterDeployed 297 | - name: ZoraCreatorRedeemMinterStrategy 298 | kind: ethereum/contract 299 | network: {{network}} 300 | source: 301 | abi: ZoraCreatorRedeemMinterStrategy 302 | mapping: 303 | kind: ethereum/events 304 | apiVersion: 0.0.7 305 | entities: 306 | - RedeemInstructions 307 | - RedeemMinterProcessed 308 | - RedeemMintToken 309 | - SalesConfigRedeemMinterStrategy 310 | language: wasm/assemblyscript 311 | file: ./src/ERC1155Mappings/templates/ZoraCreatorRedeemMinterStrategy.ts 312 | abis: 313 | - name: ZoraCreatorRedeemMinterStrategy 314 | file: ./abis/ZoraCreatorRedeemMinterStrategy.json 315 | eventHandlers: 316 | - event: RedeemsCleared(indexed address,indexed bytes32[]) 317 | handler: handleRedeemCleared 318 | - event: RedeemProcessed(indexed address,indexed bytes32,address,uint256[][],uint256[][]) 319 | handler: handleRedeemProcessed 320 | - event: RedeemSet(indexed address,indexed bytes32,((address,uint256,uint256,uint8),(uint8,uint256,uint256,uint256,address,address,bytes4)[],uint64,uint64,uint256,address)) 321 | handler: handleRedeemSet 322 | 323 | - name: ZoraCreatorMerkleMinterStrategy 324 | kind: ethereum/contract 325 | network: {{network}} 326 | source: 327 | abi: ZoraCreatorMerkleMinterStrategy 328 | mapping: 329 | kind: ethereum/events 330 | apiVersion: 0.0.7 331 | entities: 332 | - SalesConfigMerkleMinterStrategy 333 | language: wasm/assemblyscript 334 | file: ./src/ERC1155Mappings/templates/ZoraMerkleMinterStrategyMappings.ts 335 | abis: 336 | - name: ZoraCreatorMerkleMinterStrategy 337 | file: ./abis/ZoraCreatorMerkleMinterStrategy.json 338 | eventHandlers: 339 | - event: SaleSet(indexed address,indexed uint256,(uint64,uint64,address,bytes32)) 340 | handler: handleMerkleMinterStrategySaleSet 341 | # new mappings 342 | - name: ERC721Drop 343 | kind: ethereum/contract 344 | network: {{network}} 345 | source: 346 | abi: ERC721Drop 347 | mapping: 348 | kind: ethereum/events 349 | apiVersion: 0.0.7 350 | entities: 351 | - ZoraCreateContract 352 | - SalesConfigMerkleMinterStrategy 353 | - SalesStrategyConfig 354 | - SalesConfigFixedPriceSaleStrategy 355 | - ZoraCreatorPermission 356 | - ZoraCreateToken 357 | - RoyaltyConfig 358 | - OnChainMetadataHistory 359 | - KnownRenderer 360 | - MintComment 361 | - TokenSale 362 | language: wasm/assemblyscript 363 | file: ./src/ERC721Mappings/templates/ERC721DropMappings.ts 364 | abis: 365 | - name: ERC721Drop 366 | file: ./abis/ERC721Drop.json 367 | eventHandlers: 368 | - event: SalesConfigChanged(indexed address) 369 | handler: handleSalesConfigChanged 370 | - event: OpenMintFinalized(indexed address,uint256) 371 | handler: handleOpenMintFinalized 372 | - event: FundsRecipientChanged(indexed address,indexed address) 373 | handler: handleFundsRecipientChanged 374 | - event: Transfer(indexed address,indexed address,indexed uint256) 375 | handler: handleNFTTransfer 376 | - event: MintComment(indexed address,indexed address,indexed uint256,uint256,string) 377 | handler: handleMintComment 378 | - event: Sale(indexed address,indexed uint256,indexed uint256,uint256) 379 | handler: handleSale 380 | - event: Upgraded(indexed address) 381 | handler: handleUpgraded 382 | - event: RoleGranted(indexed bytes32,indexed address,indexed address) 383 | handler: handleRoleGranted 384 | - event: RoleRevoked(indexed bytes32,indexed address,indexed address) 385 | handler: handleRoleRevoked 386 | - event: OwnershipTransferred(indexed address,indexed address) 387 | handler: handleOwnershipTransferred 388 | - event: UpdatedMetadataRenderer(address,address) 389 | handler: handleUpdatedMetadataRenderer 390 | features: 391 | - grafting 392 | - nonFatalErrors 393 | {{#grafting}} 394 | graft: 395 | base: {{base}} # subgraph ID of base subgraph 396 | block: {{block}} # block number 397 | {{/grafting}} 398 | --------------------------------------------------------------------------------