-
Notifications
You must be signed in to change notification settings - Fork 11
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
Add missing fields #110
Add missing fields #110
Changes from 13 commits
0defebc
2456fc3
3ec22b8
0bcaafc
e470451
3ae7031
88a43f1
0a93e90
0db457c
2917612
ef65343
7e6e5dc
cd0de70
810718e
6559ba3
9a4aa70
4578868
96036d3
3a97b0d
cbeda90
8402c5e
9eae7d8
eb9a4dd
b5963dc
c684a66
7060884
789ff7b
6671e29
d858519
40a43d4
23ac70a
76692c8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,58 @@ | ||
module.exports = class Data1689623692588 { | ||
name = 'Data1689623692588' | ||
name = 'Data1689623692588' | ||
|
||
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 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(`ALTER TABLE "token_entity" ADD "total_count" integer NOT NULL`) | ||
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"`) | ||
} | ||
// Commands from Data1696428349370 | ||
await db.query(`ALTER TABLE "token_entity" ADD "cheapest_nft_id" character varying`) | ||
await db.query(`CREATE INDEX "IDX_6d56119ac99ab53644b1b21a6e" ON "token_entity" ("cheapest_nft_id") `) | ||
await db.query( | ||
`ALTER TABLE "token_entity" ADD CONSTRAINT "FK_6d56119ac99ab53644b1b21a6ef" FOREIGN KEY ("cheapest_nft_id") REFERENCES "nft_entity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION` | ||
) | ||
|
||
// Commands from Data1696576165016 | ||
await db.query(`ALTER TABLE "token_entity" ADD "metadata" text`) | ||
await db.query(`ALTER TABLE "token_entity" ADD "meta_id" character varying`) | ||
await db.query(`CREATE INDEX "IDX_ae4ff3b28e3fec72aa14124d1e" ON "token_entity" ("meta_id") `) | ||
await db.query( | ||
`ALTER TABLE "token_entity" ADD CONSTRAINT "FK_ae4ff3b28e3fec72aa14124d1e1" FOREIGN KEY ("meta_id") REFERENCES "metadata_entity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION` | ||
) | ||
} | ||
|
||
async down(db) { | ||
// Rollback commands from Data1696576165016 | ||
await db.query(`ALTER TABLE "token_entity" DROP COLUMN "metadata"`) | ||
await db.query(`ALTER TABLE "token_entity" DROP COLUMN "meta_id"`) | ||
await db.query(`DROP INDEX "public"."IDX_ae4ff3b28e3fec72aa14124d1e"`) | ||
await db.query(`ALTER TABLE "token_entity" DROP CONSTRAINT "FK_ae4ff3b28e3fec72aa14124d1e1"`) | ||
|
||
// Rollback commands from Data1696428349370 | ||
await db.query(`ALTER TABLE "token_entity" DROP COLUMN "cheapest_nft_id"`) | ||
await db.query(`DROP INDEX "public"."IDX_6d56119ac99ab53644b1b21a6e"`) | ||
await db.query(`ALTER TABLE "token_entity" DROP CONSTRAINT "FK_6d56119ac99ab53644b1b21a6ef"`) | ||
|
||
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"`) | ||
} | ||
} |
daiagi marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,44 +1,166 @@ | ||||||
import { create, getOptional } from '@kodadot1/metasquid/entity' | ||||||
import { create, getOptional, getWith } 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 { debug, 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 | ||||||
function generateTokenId(collectionId: string, nftMedia: string): string { | ||||||
return `${collectionId}-${md5(nftMedia)}` | ||||||
} | ||||||
|
||||||
daiagi marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
async function createToken(context: Context, collection: CE, nft: NE): Promise<TE | undefined> { | ||||||
const nftMedia = nft.image ?? nft.media | ||||||
if (!nftMedia || nftMedia === '') { | ||||||
warn(OPERATION, `MISSING NFT MEDIA ${nft.id}`) | ||||||
return | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
const tokenId = generateTokenId(collection.id, nftMedia) | ||||||
debug(OPERATION, { createToken: `Create TOKEN ${tokenId} for NFT ${nft.id}` }) | ||||||
const tokenName = typeof nft.name === 'string' ? nft.name?.replace(/([#_]\d+$)/g, '').trim() : '' | ||||||
daiagi marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
const tokenId = `${collection.id}-${md5(nftMedia)}` | ||||||
let token = await getOptional<TE>(context.store, TE, tokenId) | ||||||
const token = create(TE, tokenId, { | ||||||
createdAt: nft.createdAt, | ||||||
collection, | ||||||
name: tokenName, | ||||||
count: 1, | ||||||
totalCount: 1, | ||||||
hash: md5(tokenId), | ||||||
image: nft.image, | ||||||
media: nft.media, | ||||||
metadata: nft.metadata, | ||||||
meta: nft.meta, | ||||||
blockNumber: nft.blockNumber, | ||||||
updatedAt: nft.updatedAt, | ||||||
id: 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 | ||||||
} | ||||||
nft.token = token | ||||||
await context.store.save(token) | ||||||
await context.store.save(nft) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. any particular reason to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it needs to be updated with new token |
||||||
|
||||||
token.updatedAt = nft.updatedAt | ||||||
token.blockNumber = nft.blockNumber | ||||||
return token | ||||||
} | ||||||
|
||||||
async function addNftToToken(context: Context, nft: NE, token: TE): Promise<TE> { | ||||||
debug(OPERATION, { updateToken: `Add NFT ${nft.id} to TOKEN ${token.id} for ` }) | ||||||
token.count += 1 | ||||||
token.totalCount += 1 | ||||||
token.updatedAt = nft.updatedAt | ||||||
nft.token = token | ||||||
await context.store.save(token) | ||||||
await context.store.save(nft) | ||||||
|
||||||
return token | ||||||
} | ||||||
|
||||||
async function removeNftFromToken(context: Context, nft: NE, token: TE): Promise<void> { | ||||||
if (!token) { | ||||||
return | ||||||
} | ||||||
debug(OPERATION, { removeNftFromToken: `Unlink NFT ${nft.id} from TOKEN ${token.id}` }) | ||||||
|
||||||
await context.store.update(NE, nft.id, { token: null }) | ||||||
const updatedTotalCount = token.totalCount - 1 | ||||||
await context.store.update(TE, token.id, { count: token.count - 1, totalCount: updatedTotalCount , updatedAt: nft.updatedAt }) | ||||||
|
||||||
if (updatedTotalCount === 0) { | ||||||
debug(OPERATION, { deleteEmptyToken: `delete empty token ${token.id}` }) | ||||||
|
||||||
await context.store.delete(TE, token.id) | ||||||
} | ||||||
} | ||||||
|
||||||
async function mintHandler(context: Context, collection: CE, nft: NE): Promise<TE | undefined> { | ||||||
const nftMedia = nft.image ?? nft.media | ||||||
daiagi marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
debug(OPERATION, { mintHandler: `Handle mint for NFT ${nft.id}` }) | ||||||
|
||||||
if (!nftMedia || nftMedia === '') { | ||||||
warn(OPERATION, `MISSING NFT MEDIA ${nft.id}`) | ||||||
return | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
|
||||||
const existingToken = await getOptional<TE>(context.store, TE, generateTokenId(collection.id, nftMedia)) | ||||||
return await (existingToken ? addNftToToken(context, nft, existingToken) : createToken(context, collection, nft)) | ||||||
} | ||||||
|
||||||
async function handleMetadataSet(context: Context, collection: CE, nft: NE): Promise<TE | undefined> { | ||||||
debug(OPERATION, { handleMetadataSet: `Handle set metadata for NFT ${nft.id}` }) | ||||||
const nftMedia = nft.image ?? nft.media | ||||||
|
||||||
if (!nftMedia || nftMedia === '') { | ||||||
daiagi marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
warn(OPERATION, `MISSING NFT MEDIA ${nft.id}`) | ||||||
return | ||||||
} | ||||||
|
||||||
let nftWithToken, existingToken | ||||||
try { | ||||||
[nftWithToken, existingToken] = await Promise.all([ | ||||||
getWith(context.store, NE, nft.id, { token: true }), | ||||||
getOptional<TE>(context.store, TE, generateTokenId(collection.id, nftMedia)), | ||||||
]) | ||||||
} catch (error) { | ||||||
warn(OPERATION, `ERROR ${error}`) | ||||||
return | ||||||
} | ||||||
if (nftWithToken.token) { | ||||||
await removeNftFromToken(context, nft, nftWithToken.token) | ||||||
} | ||||||
return await (existingToken ? addNftToToken(context, nft, existingToken) : createToken(context, collection, nft)) | ||||||
} | ||||||
|
||||||
async function handleBurn(context: Context, nft: NE): Promise<void> { | ||||||
debug(OPERATION, { handleBurn: `Handle Burn for NFT ${nft.id}` }) | ||||||
const nftMedia = nft.image ?? nft.media | ||||||
|
||||||
if (!nftMedia || nftMedia === '') { | ||||||
warn(OPERATION, `MISSING NFT MEDIA ${nft.id}`) | ||||||
return | ||||||
} | ||||||
|
||||||
const token = await getOptional<TE>(context.store, TE, generateTokenId(nft.collection.id, nftMedia)) | ||||||
|
||||||
if (!token) { | ||||||
return | ||||||
} | ||||||
|
||||||
debug(OPERATION, { BURN: `decrement Token's ${token.id} count` }) | ||||||
|
||||||
await context.store.update(TE, token.id, { count: token.count - 1, updatedAt: nft.updatedAt }) | ||||||
} | ||||||
|
||||||
async function listHandler(context: Context, nft: NE): Promise<TE | undefined> { | ||||||
daiagi marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
const nftMedia = nft.image ?? nft.media | ||||||
|
||||||
if (!nftMedia || nftMedia === '') { | ||||||
warn(OPERATION, `MISSING NFT MEDIA ${nft.id}`) | ||||||
return | ||||||
} | ||||||
daiagi marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
try { | ||||||
const nftWithToken = await getWith(context.store, NE, nft.id, { token: true }) | ||||||
if (!nftWithToken.token) { | ||||||
warn(OPERATION, `nft ${nft.id} is not linked to a token`) | ||||||
return | ||||||
} | ||||||
const cheapestNFT = nftWithToken.token.cheapestNFT | ||||||
if (!nft.price && !cheapestNFT?.price) { | ||||||
return; | ||||||
} | ||||||
|
||||||
if (!cheapestNFT?.price || (nft.price && nft.price < cheapestNFT.price)) { | ||||||
context.store.update(TE, nftWithToken.token.id, { cheapestNFT: nft, updatedAt: nft.updatedAt }) | ||||||
} | ||||||
} catch (error) { | ||||||
warn(OPERATION, `ERROR ${error}`) | ||||||
} | ||||||
} | ||||||
|
||||||
|
||||||
export const eventHandlers = { | ||||||
setMetadataHandler: handleMetadataSet, | ||||||
mintHandler, | ||||||
burnHandler: handleBurn, | ||||||
listHandler | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never alter migration pls
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok