|
| 1 | +--- |
| 2 | +title: Categorize NFT Marketplaces Using Enums |
| 3 | +--- |
| 4 | + |
| 5 | +Use Enums to make your code cleaner and less error-prone. Here's a full example of using Enums on NFT marketplaces. |
| 6 | + |
| 7 | +## What are Enums? |
| 8 | + |
| 9 | +Enums, or enumeration types, are a specific data type that allows you to define a set of specific, allowed values. |
| 10 | + |
| 11 | +### Example of Enums in Your Schema |
| 12 | + |
| 13 | +If you're building a subgraph to track the ownership history of tokens on a marketplace, each token might go through different ownerships, such as `OriginalOwner`, `SecondOwner`, and `ThirdOwner`. By using enums, you can define these specific ownerships, ensuring only predefined values are assigned. |
| 14 | + |
| 15 | +You can define enums in your schema, and once defined, you can use the string representation of the enum values to set an enum field on an entity. |
| 16 | + |
| 17 | +Here's what an enum definition might look like in your schema, based on the example above: |
| 18 | + |
| 19 | +```graphql |
| 20 | +enum TokenStatus { |
| 21 | + OriginalOwner |
| 22 | + SecondOwner |
| 23 | + ThirdOwner |
| 24 | +} |
| 25 | +``` |
| 26 | + |
| 27 | +This means that when you use the `TokenStatus` type in your schema, you expect it to be exactly one of predefined values: `OriginalOwner`, `SecondOwner`, or `ThirdOwner`, ensuring consistency and validity. |
| 28 | + |
| 29 | +To learn more about enums, check out [Creating a Subgraph](/developing/creating-a-subgraph/#enums) and [GraphQL documentation](https://graphql.org/learn/schema/#enumeration-types). |
| 30 | + |
| 31 | +## Benefits of Using Enums |
| 32 | + |
| 33 | +- **Clarity:** Enums provide meaningful names for values, making data easier to understand. |
| 34 | +- **Validation:** Enums enforce strict value definitions, preventing invalid data entries. |
| 35 | +- **Maintainability:** When you need to change or add new categories, enums allow you to do this in a focused manner. |
| 36 | + |
| 37 | +### Without Enums |
| 38 | + |
| 39 | +If you choose to define the type as a string instead of using an Enum, your code might look like this: |
| 40 | + |
| 41 | +```graphql |
| 42 | +type Token @entity { |
| 43 | + id: ID! |
| 44 | + tokenId: BigInt! |
| 45 | + owner: Bytes! # Owner of the token |
| 46 | + tokenStatus: String! # String field to track token status |
| 47 | + timestamp: BigInt! |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | +In this schema, `TokenStatus` is a simple string with no specific, allowed values. |
| 52 | + |
| 53 | +#### Why is this a problem? |
| 54 | + |
| 55 | +- There's no restriction of `TokenStatus` values, so any string can be accidentally assigned. This makes it hard to ensure that only valid statuses like `OriginalOwner`, `SecondOwner`, or `ThirdOwner` are set. |
| 56 | +- It's easy to make typos such as `Orgnalowner` instead of `OriginalOwner`, making the data and potential queries unreliable. |
| 57 | + |
| 58 | +### With Enums |
| 59 | + |
| 60 | +Instead of assigning free-form strings, you can define an enum for `TokenStatus` with specific values: `OriginalOwner`, `SecondOwner`, or `ThirdOwner`. Using an enum ensures only allowed values are used. |
| 61 | + |
| 62 | +Enums provide type safety, minimize typo risks, and ensure consistent and reliable results. |
| 63 | + |
| 64 | +## Defining Enums for NFT Marketplaces |
| 65 | + |
| 66 | +> Note: The following guide uses the CryptoCoven NFT smart contract. |
| 67 | + |
| 68 | +To define enums for the various marketplaces where NFTs are traded, use the following in your subgraph schema: |
| 69 | + |
| 70 | +```gql |
| 71 | +# Enum for Marketplaces that the CryptoCoven contract interacted with(likely a Trade/Mint) |
| 72 | +enum Marketplace { |
| 73 | + OpenSeaV1 # Represents when a CryptoCoven NFT is traded on the marketplace |
| 74 | + OpenSeaV2 # Represents when a CryptoCoven NFT is traded on the OpenSeaV2 marketplace |
| 75 | + SeaPort # Represents when a CryptoCoven NFT is traded on the SeaPort marketplace |
| 76 | + LooksRare # Represents when a CryptoCoven NFT is traded on the LookRare marketplace |
| 77 | + # ...and other marketplaces |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +## Using Enums for NFT Marketplaces |
| 82 | + |
| 83 | +Once defined, enums can be used throughout your subgraph to categorize transactions or events. |
| 84 | + |
| 85 | +For example, when logging NFT sales, you can specify the marketplace involved in the trade using the enum. |
| 86 | + |
| 87 | +### Implementing a Function for NFT Marketplaces |
| 88 | + |
| 89 | +Here's how you can implement a function to retrieve the marketplace name from the enum as a string: |
| 90 | + |
| 91 | +```ts |
| 92 | +export function getMarketplaceName(marketplace: Marketplace): string { |
| 93 | + // Using if-else statements to map the enum value to a string |
| 94 | + if (marketplace === Marketplace.OpenSeaV1) { |
| 95 | + return 'OpenSeaV1' // If the marketplace is OpenSea, return its string representation |
| 96 | + } else if (marketplace === Marketplace.OpenSeaV2) { |
| 97 | + return 'OpenSeaV2' |
| 98 | + } else if (marketplace === Marketplace.SeaPort) { |
| 99 | + return 'SeaPort' // If the marketplace is SeaPort, return its string representation |
| 100 | + } else if (marketplace === Marketplace.LooksRare) { |
| 101 | + return 'LooksRare' // If the marketplace is LooksRare, return its string representation |
| 102 | + // ... and other market places |
| 103 | + } |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +## Best Practices for Using Enums |
| 108 | + |
| 109 | +- **Consistent Naming:** Use clear, descriptive names for enum values to improve readability. |
| 110 | +- **Centralized Management:** Keep enums in a single file for consistency. This makes enums easier to update and ensures they are the single source of truth. |
| 111 | +- **Documentation:** Add comments to enum to clarify their purpose and usage. |
| 112 | + |
| 113 | +## Using Enums in Queries |
| 114 | + |
| 115 | +Enums in queries help you improve data quality and make your results easier to interpret. They function as filters and response elements, ensuring consistency and reducing errors in marketplace values. |
| 116 | + |
| 117 | +**Specifics** |
| 118 | + |
| 119 | +- **Filtering with Enums:** Enums provide clear filters, allowing you to confidently include or exclude specific marketplaces. |
| 120 | +- **Enums in Responses:** Enums guarantee that only recognized marketplace names are returned, making the results standardized and accurate. |
| 121 | + |
| 122 | +### Sample Queries |
| 123 | + |
| 124 | +#### Query 1: Account With The Highest NFT Marketplace Interactions |
| 125 | + |
| 126 | +This query does the following: |
| 127 | + |
| 128 | +- It finds the account with the highest unique NFT marketplace interactions, which is great for analyzing cross-marketplace activity. |
| 129 | +- The marketplaces field uses the marketplace enum, ensuring consistent and validated marketplace values in the response. |
| 130 | + |
| 131 | +```gql |
| 132 | +{ |
| 133 | + accounts(first: 1, orderBy: uniqueMarketplacesCount, orderDirection: desc) { |
| 134 | + id |
| 135 | + sendCount |
| 136 | + receiveCount |
| 137 | + totalSpent |
| 138 | + uniqueMarketplacesCount |
| 139 | + marketplaces { |
| 140 | + marketplace # This field returns the enum value representing the marketplace |
| 141 | + } |
| 142 | + } |
| 143 | +} |
| 144 | +``` |
| 145 | + |
| 146 | +#### Returns |
| 147 | + |
| 148 | +This response provides account details and a list of unique marketplace interactions with enum values for standardized clarity: |
| 149 | + |
| 150 | +```gql |
| 151 | +{ |
| 152 | + "data": { |
| 153 | + "accounts": [ |
| 154 | + { |
| 155 | + "id": "0xb3abc96cb9a61576c03c955d75b703a890a14aa0", |
| 156 | + "sendCount": "44", |
| 157 | + "receiveCount": "44", |
| 158 | + "totalSpent": "1197500000000000000", |
| 159 | + "uniqueMarketplacesCount": "7", |
| 160 | + "marketplaces": [ |
| 161 | + { |
| 162 | + "marketplace": "OpenSeaV1" |
| 163 | + }, |
| 164 | + { |
| 165 | + "marketplace": "OpenSeaV2" |
| 166 | + }, |
| 167 | + { |
| 168 | + "marketplace": "GenieSwap" |
| 169 | + }, |
| 170 | + { |
| 171 | + "marketplace": "CryptoCoven" |
| 172 | + }, |
| 173 | + { |
| 174 | + "marketplace": "Unknown" |
| 175 | + }, |
| 176 | + { |
| 177 | + "marketplace": "LooksRare" |
| 178 | + }, |
| 179 | + { |
| 180 | + "marketplace": "NFTX" |
| 181 | + } |
| 182 | + ] |
| 183 | + } |
| 184 | + ] |
| 185 | + } |
| 186 | +} |
| 187 | +``` |
| 188 | + |
| 189 | +#### Query 2: Most Active Marketplace for CryptoCoven transactions |
| 190 | + |
| 191 | +This query does the following: |
| 192 | + |
| 193 | +- It identifies the marketplace with the highest volume of CryptoCoven transactions. |
| 194 | +- It uses the marketplace enum to ensure that only valid marketplace types appear in the response, adding reliability and consistency to your data. |
| 195 | + |
| 196 | +```gql |
| 197 | +{ |
| 198 | + marketplaceInteractions(first: 1, orderBy: transactionCount, orderDirection: desc) { |
| 199 | + marketplace |
| 200 | + transactionCount |
| 201 | + } |
| 202 | +} |
| 203 | +``` |
| 204 | + |
| 205 | +#### Result 2 |
| 206 | + |
| 207 | +The expected response includes the marketplace and the corresponding transaction count, using the enum to indicate the marketplace type: |
| 208 | + |
| 209 | +```gql |
| 210 | +{ |
| 211 | + "data": { |
| 212 | + "marketplaceInteractions": [ |
| 213 | + { |
| 214 | + "marketplace": "Unknown", |
| 215 | + "transactionCount": "222" |
| 216 | + } |
| 217 | + ] |
| 218 | + } |
| 219 | +} |
| 220 | +``` |
| 221 | + |
| 222 | +#### Query 3: Marketplace Interactions with High Transaction Counts |
| 223 | + |
| 224 | +This query does the following: |
| 225 | + |
| 226 | +- It retrieves the top four marketplaces with over 100 transactions, excluding "Unknown" marketplaces. |
| 227 | +- It uses enums as filters to ensure that only valid marketplace types are included, increasing accuracy. |
| 228 | + |
| 229 | +```gql |
| 230 | +{ |
| 231 | + marketplaceInteractions( |
| 232 | + first: 4 |
| 233 | + orderBy: transactionCount |
| 234 | + orderDirection: desc |
| 235 | + where: { transactionCount_gt: "100", marketplace_not: "Unknown" } |
| 236 | + ) { |
| 237 | + marketplace |
| 238 | + transactionCount |
| 239 | + } |
| 240 | +} |
| 241 | +``` |
| 242 | + |
| 243 | +#### Result 3 |
| 244 | + |
| 245 | +Expected output includes the marketplaces that meet the criteria, each represented by an enum value: |
| 246 | + |
| 247 | +```gql |
| 248 | +{ |
| 249 | + "data": { |
| 250 | + "marketplaceInteractions": [ |
| 251 | + { |
| 252 | + "marketplace": "NFTX", |
| 253 | + "transactionCount": "201" |
| 254 | + }, |
| 255 | + { |
| 256 | + "marketplace": "OpenSeaV1", |
| 257 | + "transactionCount": "148" |
| 258 | + }, |
| 259 | + { |
| 260 | + "marketplace": "CryptoCoven", |
| 261 | + "transactionCount": "117" |
| 262 | + }, |
| 263 | + { |
| 264 | + "marketplace": "OpenSeaV1", |
| 265 | + "transactionCount": "111" |
| 266 | + } |
| 267 | + ] |
| 268 | + } |
| 269 | +} |
| 270 | +``` |
| 271 | + |
| 272 | +## Additional Resources |
| 273 | + |
| 274 | +For additional information, check out this guide's [repo](https://github.com/chidubemokeke/Subgraph-Tutorial-Enums). |
0 commit comments