Skip to content

Commit

Permalink
feat: fill wearables data (decentraland#22)
Browse files Browse the repository at this point in the history
* feat: finish indexer

* feat: index xmas

* feat: rename folders and ignore built files

* feat: add wearables to NFTs

* feat: finish adding wearables. prepare for other nfts

* fix: correctly check for xmas collection
  • Loading branch information
nicosantangelo authored and cazala committed Dec 26, 2019
1 parent 8237bfb commit cc56539
Show file tree
Hide file tree
Showing 23 changed files with 1,088 additions and 2,697 deletions.
11 changes: 9 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ pids
*.seed
*.pid.lock

# Mac
*DS_Store

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

Expand Down Expand Up @@ -60,6 +63,10 @@ typings/
# next.js build output
.next

# Built files
dist
build
*DS_Store

# Indexer
indexer/build
indexer/src/entities

3 changes: 1 addition & 2 deletions indexer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
"name": "testing",
"version": "0.1.0",
"scripts": {
"build-contract": "solc contracts/Gravity.sol --abi -o abis --overwrite && solc contracts/Gravity.sol --bin -o bin --overwrite",
"create": "graph create nicosantangelo/testing --node https://api.thegraph.com/deploy/",
"create-local": "graph create nicosantangelo/testing --node http://127.0.0.1:8020",
"codegen": "graph codegen --debug --output-dir src/types/",
"codegen": "graph codegen --debug --output-dir src/entities/",
"build": "graph build",
"deploy": "graph deploy nicosantangelo/testing --ipfs https://api.thegraph.com/ipfs/ --node https://api.thegraph.com/deploy/",
"deploy-local": "graph deploy nicosantangelo/testing --ipfs http://localhost:5001 --node http://127.0.0.1:8020"
Expand Down
79 changes: 71 additions & 8 deletions indexer/schema.graphql
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
type Metric @entity {
id: ID!
parcel: Int!
estate: Int!
wearable_halloween_2019: Int!
wearable_exclusive_masks: Int!
parcels: Int!
estates: Int!
orders: Int!
wearables_halloween_2019: Int!
wearables_exclusive_masks: Int!
wearables_xmas_2019: Int!
}

type Order @entity {
Expand All @@ -22,21 +24,82 @@ type Order @entity {
updatedAt: BigInt!
}

# TODO: createdAt/updatedAt
# TODO: custom data for each type of NFT or metadata prop
# aka LAND
type Parcel @entity {
id: ID!
tokenId: BigInt!
owner: Wallet!
x: BigInt!
y: BigInt!
estate: Estate
data: Data
rawData: String
operator: Bytes
updateOperator: Bytes
}

type Estate @entity {
id: ID!
tokenId: BigInt!
owner: Wallet!
parcels: [Parcel!]
size: Int
data: Data
rawData: String
operator: Bytes
updateOperator: Bytes
}

type Data @entity {
id: ID!
parcel: Parcel
estate: Estate
version: String!
name: String
description: String
ipns: String
}

type Wearable @entity {
id: ID!
name: String!
description: String!
category: String!
rarity: String!
}

type NFT @entity {
id: ID!
tokenId: BigInt!
contractAddress: Bytes!
category: Category!
owner: Bytes!
owner: Wallet!
tokenURI: String

orders: [Order!] @derivedFrom(field: "nft") # History of all orders. should only ever be ONE open order. all others must be closed or sold
activeOrder: Order

parcel: Parcel
estate: Estate
wearable: Wearable
createdAt: BigInt!
updatedAt: BigInt!
}

# TODO: User entity?
type Authorization @entity {
id: ID!
type: String!
tokenAddress: Bytes!
owner: Wallet!
operator: Bytes!
}

type Wallet @entity {
id: ID! # ETH addr
nfts: [NFT!] @derivedFrom(field: "owner")
authorizations: [Authorization!] @derivedFrom(field: "owner")
mana: BigInt # Amount of mana owned
}

enum Category @entity {
parcel
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { Address } from '@graphprotocol/graph-ts'

import { Finalized } from '../types/MANACrowdsale/MANACrowdsale'
import { ERC721 } from '../types/templates'
import { Finalized } from '../entities/MANACrowdsale/MANACrowdsale'
import { ERC721 } from '../entities/templates'
import {
LANDRegistry,
EstateRegistry,
ERC721Collection_halloween_2019,
ERC721Collection_exclusive_masks
ERC721Collection_exclusive_masks,
ERC721Collection_xmas_2019
} from '../modules/contract/addresses'

export function handleFinalized(_: Finalized): void {
ERC721.create(Address.fromString(LANDRegistry))
ERC721.create(Address.fromString(EstateRegistry))
ERC721.create(Address.fromString(ERC721Collection_halloween_2019))
ERC721.create(Address.fromString(ERC721Collection_exclusive_masks))
ERC721.create(Address.fromString(ERC721Collection_xmas_2019))
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import {
OrderCreated,
OrderSuccessful,
OrderCancelled
} from '../types/Marketplace/Marketplace'
import { Order, NFT } from '../types/schema'
} from '../entities/Marketplace/Marketplace'
import { Order, NFT } from '../entities/schema'
import { buildId } from '../modules/nft'
import { getCategory } from '../modules/category'
import { upsertMetric } from '../modules/metric'
import * as status from '../modules/order/status'
import * as addresses from '../modules/contract/addresses'

export function handleOrderCreated(event: OrderCreated): void {
let category = getCategory(event.params.nftAddress.toHexString())
Expand All @@ -29,7 +31,6 @@ export function handleOrderCreated(event: OrderCreated): void {
order.save()

let nft = NFT.load(nftId)

if (nft == null) {
log.error('Undefined NFT {} for order {}', [nftId, orderId])
throw new Error('Undefined NFT')
Expand All @@ -47,6 +48,8 @@ export function handleOrderCreated(event: OrderCreated): void {

nft.activeOrder = orderId
nft.save()

upsertMetric(addresses.Marketplace)
}

export function handleOrderSuccessful(event: OrderSuccessful): void {
Expand All @@ -63,7 +66,7 @@ export function handleOrderSuccessful(event: OrderSuccessful): void {
order.save()

let nft = new NFT(nftId)
nft.owner = event.params.buyer
nft.owner = event.params.buyer.toHex()
nft.activeOrder = null
nft.save()
}
Expand Down
51 changes: 51 additions & 0 deletions indexer/src/handlers/nft.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Transfer } from '../entities/templates/ERC721/ERC721'
import { NFT, Parcel, Estate } from '../entities/schema'
import { isMint, buildId, getTokenURI } from '../modules/nft'
import { getCategory } from '../modules/category'
import { buildData, DataType } from '../modules/data'
import { upsertMetric } from '../modules/metric'
import { decodeTokenId } from '../modules/parcel'
import { upsertWearable } from '../modules/wearable'
import { createWallet } from '../modules/wallet'
import * as addresses from '../modules/contract/addresses'
import * as categories from '../modules/category/categories'

export function handleTransfer(event: Transfer): void {
if (event.params.tokenId.toString() == '') {
return
}

let contractAddress = event.address.toHexString()
let category = getCategory(contractAddress)
let id = buildId(event.params.tokenId.toString(), category)

let nft = new NFT(id)

nft.tokenId = event.params.tokenId
nft.owner = event.params.to.toHex()
nft.contractAddress = event.address
nft.category = category

if (contractAddress != addresses.LANDRegistry) {
// The LANDRegistry contract does not have a tokenURI method
nft.tokenURI = getTokenURI(event)
}

if (category == categories.WEARABLE) {
let wearableId = upsertWearable(nft.tokenURI)
if (wearableId != '') {
nft.wearable = wearableId
}
}

if (isMint(event)) {
upsertMetric(contractAddress)
nft.createdAt = event.block.timestamp
} else {
nft.updatedAt = event.block.timestamp
}

createWallet(event.params.to.toHex())

nft.save()
}
34 changes: 0 additions & 34 deletions indexer/src/mappings/nft.ts

This file was deleted.

3 changes: 2 additions & 1 deletion indexer/src/modules/category/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export function getCategory(contractAddress: string): string {
category = categories.ESTATE
} else if (
contractAddress == addresses.ERC721Collection_exclusive_masks ||
contractAddress == addresses.ERC721Collection_halloween_2019
contractAddress == addresses.ERC721Collection_halloween_2019 ||
contractAddress == addresses.ERC721Collection_xmas_2019
) {
category = categories.WEARABLE
} else {
Expand Down
2 changes: 2 additions & 0 deletions indexer/src/modules/contract/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ export const ERC721Collection_halloween_2019 =
'0xc1f4b0eea2bd6690930e6c66efd3e197d620b9c2'
export const ERC721Collection_exclusive_masks =
'0xc04528c14c8ffd84c7c1fb6719b4a89853035cdd'
export const ERC721Collection_xmas_2019 =
'0x34a4a5631a263823025e55a5c6ad068732e07a37'

export const Marketplace = '0x8e5660b4Ab70168b5a6fEeA0e0315cb49c8Cd539'
34 changes: 20 additions & 14 deletions indexer/src/modules/metric/index.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,40 @@
import { Metric } from '../../types/schema'
import { Metric } from '../../entities/schema'
import * as addresses from '../contract/addresses'

export const DEFAULT_ID = 'all'

export function getMetricEntity(): Metric {
export function buildMetric(): Metric {
let metric = Metric.load(DEFAULT_ID)

if (metric == null) {
metric = new Metric(DEFAULT_ID)
metric.parcel = 0
metric.estate = 0
metric.wearable_halloween_2019 = 0
metric.wearable_exclusive_masks = 0
metric.parcels = 0
metric.estates = 0
metric.orders = 0
metric.wearables_halloween_2019 = 0
metric.wearables_exclusive_masks = 0
metric.wearables_xmas_2019 = 0
}

return metric as Metric
}

export function getUpdatedMetricEntity(contractAddress: string): Metric {
let metric = getMetricEntity()
export function upsertMetric(contractAddress: string): void {
let metric = buildMetric()

if (contractAddress == addresses.LANDRegistry) {
metric.parcel += 1
metric.parcels += 1
} else if (contractAddress == addresses.EstateRegistry) {
metric.estate += 1
} else if (contractAddress == addresses.ERC721Collection_exclusive_masks) {
metric.wearable_exclusive_masks += 1
metric.estates += 1
} else if (contractAddress == addresses.Marketplace) {
metric.orders += 1
} else if (contractAddress == addresses.ERC721Collection_halloween_2019) {
metric.wearable_halloween_2019 += 1
metric.wearables_halloween_2019 += 1
} else if (contractAddress == addresses.ERC721Collection_exclusive_masks) {
metric.wearables_exclusive_masks += 1
} else if (contractAddress == addresses.ERC721Collection_xmas_2019) {
metric.wearables_xmas_2019 += 1
}

return metric
metric.save()
}
2 changes: 1 addition & 1 deletion indexer/src/modules/nft/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { log } from '@graphprotocol/graph-ts'
import { ERC721, Transfer } from '../../types/templates/ERC721/ERC721'
import { ERC721, Transfer } from '../../entities/templates/ERC721/ERC721'
import * as addresses from '../contract/addresses'

export function isMint(event: Transfer): boolean {
Expand Down
21 changes: 21 additions & 0 deletions indexer/src/modules/wearable/Wearable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export class Wearable {
id: string
name: string
description: string
category: string
rarity: string

constructor(
id: string,
name: string,
description: string,
category: string,
rarity: string
) {
this.id = id
this.name = name
this.description = description
this.category = category
this.rarity = rarity
}
}
Loading

0 comments on commit cc56539

Please sign in to comment.