Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ TokenEnitity on RMRK #274

Merged
merged 5 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions db/migrations/1694954140600-Data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = class Data1694954140600 {
name = 'Data1694954140600'

async up(db) {
await db.query(`CREATE TABLE "token_entity" ("id" character varying NOT NULL, "block_number" numeric, "hash" text NOT NULL, "image" text, "media" text, "name" text, "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, "count" integer NOT NULL, "collection_id" character varying, CONSTRAINT "PK_687443f2a51af49b5472e2c5ddc" PRIMARY KEY ("id"))`)
await db.query(`CREATE INDEX "IDX_0eb2ed7929c3e81941fa1b51b3" ON "token_entity" ("collection_id") `)
await db.query(`CREATE INDEX "IDX_40d6049fd30532dada71922792" ON "token_entity" ("hash") `)
await db.query(`CREATE INDEX "IDX_47b385945a425667b9e690bc02" ON "token_entity" ("name") `)
await db.query(`ALTER TABLE "nft_entity" ADD "token_id" character varying`)
await db.query(`CREATE INDEX "IDX_060d0f515d293fac1d81ee61a7" ON "nft_entity" ("token_id") `)
await db.query(`ALTER TABLE "token_entity" ADD CONSTRAINT "FK_0eb2ed7929c3e81941fa1b51b35" FOREIGN KEY ("collection_id") REFERENCES "collection_entity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
await db.query(`ALTER TABLE "nft_entity" ADD CONSTRAINT "FK_060d0f515d293fac1d81ee61a79" FOREIGN KEY ("token_id") REFERENCES "token_entity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
}

async down(db) {
await db.query(`DROP TABLE "token_entity"`)
await db.query(`DROP INDEX "public"."IDX_0eb2ed7929c3e81941fa1b51b3"`)
await db.query(`DROP INDEX "public"."IDX_40d6049fd30532dada71922792"`)
await db.query(`DROP INDEX "public"."IDX_47b385945a425667b9e690bc02"`)
await db.query(`ALTER TABLE "nft_entity" DROP COLUMN "token_id"`)
await db.query(`DROP INDEX "public"."IDX_060d0f515d293fac1d81ee61a7"`)
await db.query(`ALTER TABLE "token_entity" DROP CONSTRAINT "FK_0eb2ed7929c3e81941fa1b51b35"`)
await db.query(`ALTER TABLE "nft_entity" DROP CONSTRAINT "FK_060d0f515d293fac1d81ee61a79"`)
}
}
15 changes: 15 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ type CollectionEntity @entity {
volume: BigInt!
}

type TokenEntity @entity {
id: ID!
blockNumber: BigInt
collection: CollectionEntity
nfts: [NFTEntity!] @derivedFrom(field: "token")
hash: String! @index
image: String
media: String
name: String @index
updatedAt: DateTime!
createdAt: DateTime!
count: Int!
}

type NFTEntity @entity {
blockNumber: BigInt
burned: Boolean!
Expand Down Expand Up @@ -58,6 +72,7 @@ type NFTEntity @entity {
transferable: Int
updatedAt: DateTime!
version: String!
token: TokenEntity!
}

type MetadataEntity @entity {
Expand Down
52 changes: 52 additions & 0 deletions src/mappings/shared/handleTokenEntity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { create, getOptional } from '@kodadot1/metasquid/entity'
import md5 from 'md5'
import { CollectionEntity as CE, NFTEntity as NE, TokenEntity as TE } from '../../model'
import { warn } from '../utils/logger'
import { Context } from '../utils/types'

const OPERATION = 'TokenEntity' as any

export async function handleTokenEntity(context: Context, collection: CE, nft: NE): Promise<TE | undefined> {
const nftMedia =
nft.image ??
nft.media ??
nft.meta?.image ??
nft.meta?.animationUrl ??
nft.resources[0].src ??
nft.resources[0].thumb
if (!nftMedia || nftMedia === '') {
warn(OPERATION, `MISSING NFT MEDIA ${nft.id}`)
await new Promise((resolve) => setTimeout(resolve, 5000))
vikiival marked this conversation as resolved.
Show resolved Hide resolved

return
}

const tokenId = `${collection.id}-${md5(nftMedia)}`
let token = await getOptional<TE>(context.store, TE, tokenId)

if (!token) {
const tokenName = typeof nft.name === 'string' ? nft.name?.replace(/([#_]\d+$)/g, '').trim() : ''

token = create(TE, tokenId, {
createdAt: nft.createdAt,
collection,
name: tokenName,
count: 1,
hash: md5(tokenId),
image: nft.image,
media: nft.media,
blockNumber: nft.blockNumber,
updatedAt: nft.updatedAt,
id: tokenId,
})
} else {
token.count += 1
}

token.updatedAt = nft.updatedAt
token.blockNumber = nft.blockNumber

await context.store.save(token)

return token
}
6 changes: 6 additions & 0 deletions src/mappings/v1/mint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Action, Context, getNftId, NFT, Optional } from '../utils/types'
import { createEvent } from '../shared/event'
import { handleMetadata, isLewd } from '../shared/metadata'
import { calculateCollectionOwnerCountAndDistribution } from '../utils/helper'
import { handleTokenEntity } from '../shared/handleTokenEntity'

const OPERATION = Action.MINT

Expand Down Expand Up @@ -69,6 +70,11 @@ export async function mintItem(context: Context): Promise<void> {
}
}

const token = await handleTokenEntity(context, collection, final)
if (token) {
final.token = token
}
vikiival marked this conversation as resolved.
Show resolved Hide resolved

await context.store.save(final)
await context.store.save(collection)
success(OPERATION, `${final.id} from ${caller}`)
Expand Down
8 changes: 7 additions & 1 deletion src/mappings/v2/mint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import { CollectionEntity, NFTEntity, Property } from '../../model/generated'
import { createEvent } from '../shared/event'
import { handleMetadata, isLewd } from '../shared/metadata'
import { findRootItemById } from '../utils/entity'
import { calculateCollectionOwnerCountAndDistribution, isDummyAddress } from '../utils/helper'
import { isDummyAddress } from '../utils/helper'
daiagi marked this conversation as resolved.
Show resolved Hide resolved
import logger, { error, success } from '../utils/logger'
import { Action, Context, Optional, getNftId } from '../utils/types'
import { handleTokenEntity } from '../shared/handleTokenEntity'
import { getCreateToken } from './getters'

const OPERATION = Action.MINT
Expand Down Expand Up @@ -88,6 +89,11 @@ export async function mintItem(context: Context): Promise<void> {
final.pending = false
}

const token = await handleTokenEntity(context, collection, final)
if (token) {
final.token = token
}

await context.store.save(final)
await context.store.save(collection)
success(OPERATION, `${final.id} from ${caller}`)
Expand Down
1 change: 1 addition & 0 deletions src/model/generated/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from "./collectionEntity.model"
export * from "./_collectionEvent"
export * from "./tokenEntity.model"
export * from "./nftEntity.model"
export * from "./metadataEntity.model"
export * from "./_attribute"
Expand Down
5 changes: 5 additions & 0 deletions src/model/generated/nftEntity.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {Part} from "./part.model"
import {MetadataEntity} from "./metadataEntity.model"
import {Property} from "./property.model"
import {Resource} from "./resource.model"
import {TokenEntity} from "./tokenEntity.model"

@Entity_()
export class NFTEntity {
Expand Down Expand Up @@ -110,4 +111,8 @@ export class NFTEntity {

@Column_("text", {nullable: false})
version!: string

@Index_()
@ManyToOne_(() => TokenEntity, {nullable: true})
token!: TokenEntity
}
47 changes: 47 additions & 0 deletions src/model/generated/tokenEntity.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_, OneToMany as OneToMany_} from "typeorm"
import * as marshal from "./marshal"
import {CollectionEntity} from "./collectionEntity.model"
import {NFTEntity} from "./nftEntity.model"

@Entity_()
export class TokenEntity {
constructor(props?: Partial<TokenEntity>) {
Object.assign(this, props)
}

@PrimaryColumn_()
id!: string

@Column_("numeric", {transformer: marshal.bigintTransformer, nullable: true})
blockNumber!: bigint | undefined | null

@Index_()
@ManyToOne_(() => CollectionEntity, {nullable: true})
collection!: CollectionEntity | undefined | null

@OneToMany_(() => NFTEntity, e => e.token)
nfts!: NFTEntity[]

@Index_()
@Column_("text", {nullable: false})
hash!: string

@Column_("text", {nullable: true})
image!: string | undefined | null

@Column_("text", {nullable: true})
media!: string | undefined | null

@Index_()
@Column_("text", {nullable: true})
name!: string | undefined | null

@Column_("timestamp with time zone", {nullable: false})
updatedAt!: Date

@Column_("timestamp with time zone", {nullable: false})
createdAt!: Date

@Column_("int4", {nullable: false})
count!: number
}