-
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
TokenEntity/fix count calculation #109
Changes from all commits
0defebc
2456fc3
3ec22b8
0bcaafc
3ae7031
2917612
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,44 +1,134 @@ | ||
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 { | ||
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. Use utils file 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. sure |
||
return `${collectionId}-${md5(nftMedia)}` | ||
} | ||
|
||
async function createToken(context: Context, collection: CE, nft: NE): Promise<TE | undefined> { | ||
const nftMedia = nft.image ?? nft.media | ||
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. as mentioned in #110 |
||
if (!nftMedia || nftMedia === '') { | ||
warn(OPERATION, `MISSING NFT MEDIA ${nft.id}`) | ||
return | ||
} | ||
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() : '' | ||
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. as mentioned in #110 |
||
|
||
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, | ||
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) | ||
|
||
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 | ||
debug(OPERATION, { mintHandler: `Handle mint for NFT ${nft.id}` }) | ||
|
||
if (!nftMedia || nftMedia === '') { | ||
warn(OPERATION, `MISSING NFT MEDIA ${nft.id}`) | ||
return | ||
} | ||
|
||
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 === '') { | ||
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 }) | ||
} | ||
|
||
export const eventHandlers = { | ||
setMetadataHandler: handleMetadataSet, | ||
mintHandler, | ||
burnHandler: handleBurn, | ||
} |
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.
please use same wording as collection has
count
for totalsupply
for availableThere 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
so supply is only not burned
count is all
yes?
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.
YES