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

Stick v9 #177

Merged
merged 21 commits into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kodadot1/stick",
"version": "0.0.2",
"version": "0.0.3",
"description": "GraphQL service for Uniques and Assets on Statemine",
"private": true,
"engines": {
Expand Down
2 changes: 1 addition & 1 deletion speck.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
manifestVersion: subsquid.io/v0.1
name: speck
version: 9
version: 10
description: 'SubSquid indexer for Uniques and Assets on Statemint'
build:
deploy:
Expand Down
2 changes: 1 addition & 1 deletion squid.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
manifestVersion: subsquid.io/v0.1
name: stick
version: 8
version: 9
description: 'SubSquid indexer for Uniques and Assets on Statemine'
build:
deploy:
Expand Down
9 changes: 6 additions & 3 deletions src/mappings/nfts/burn.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { getWith } from '@kodadot1/metasquid/entity'
import { getWith } from '@kodadot1/metasquid/entity'
import { NFTEntity as NE } from '../../model'
import { unwrap } from '../utils/extract'
import { debug, pending, success } from '../utils/logger'
import { Action, Context, createTokenId } from '../utils/types'
import { createEvent } from '../shared/event'
import { calculateCollectionOwnerCountAndDistribution } from '../utils/helper'
import { calculateCollectionFloor, calculateCollectionOwnerCountAndDistribution } from '../utils/helper'
import { burnHandler } from '../shared/token'
import { getBurnTokenEvent } from './getters'

Expand All @@ -18,6 +18,7 @@ export async function handleTokenBurn(context: Context): Promise<void> {
const id = createTokenId(event.collectionId, event.sn)
const entity = await getWith(context.store, NE, id, { collection: true })

const { floor } = await calculateCollectionFloor(context.store, entity.collection.id, id)
const { ownerCount, distribution } = await calculateCollectionOwnerCountAndDistribution(
context.store,
entity.collection.id,
Expand All @@ -27,15 +28,17 @@ export async function handleTokenBurn(context: Context): Promise<void> {
entity.burned = true
entity.updatedAt = event.timestamp

entity.collection.updatedAt = event.timestamp
entity.collection.supply -= 1
entity.collection.floor = floor
entity.collection.ownerCount = ownerCount
entity.collection.distribution = distribution
entity.collection.updatedAt = event.timestamp

await burnHandler(context, entity)

success(OPERATION, `${id} by ${event.caller}`)
await context.store.save(entity)
await context.store.save(entity.collection)
const meta = entity.metadata ?? ''
await createEvent(entity, OPERATION, event, meta, context.store)
}
29 changes: 16 additions & 13 deletions src/mappings/nfts/buy.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { getOrFail } from '@kodadot1/metasquid/entity'
import { CollectionEntity as CE, NFTEntity as NE } from '../../model'
import { getWith } from '@kodadot1/metasquid/entity'
import { NFTEntity as NE } from '../../model'
import { createEvent } from '../shared/event'
import { unwrap } from '../utils/extract'
import { debug, pending, success } from '../utils/logger'
import { Action, Context, createTokenId } from '../utils/types'
import { calculateCollectionOwnerCountAndDistribution } from '../utils/helper'
import { calculateCollectionFloor, calculateCollectionOwnerCountAndDistribution } from '../utils/helper'
import { getBuyTokenEvent } from './getters'

const OPERATION = Action.BUY
Expand All @@ -15,34 +15,37 @@ export async function handleTokenBuy(context: Context): Promise<void> {
debug(OPERATION, event, true)

const id = createTokenId(event.collectionId, event.sn)
const entity = await getOrFail<NE>(context.store, NE, id)
const collection = await getOrFail<CE>(context.store, CE, event.collectionId)
const entity = await getWith(context.store, NE, id, { collection: true })

const originalPrice = event.price
const originalOwner = entity.currentOwner ?? undefined

entity.price = BigInt(0)
entity.currentOwner = event.caller
entity.updatedAt = event.timestamp

if (originalPrice) {
collection.volume += originalPrice
if (originalPrice > collection.highestSale) {
collection.highestSale = originalPrice
entity.collection.volume += originalPrice
if (originalPrice > entity.collection.highestSale) {
entity.collection.highestSale = originalPrice
}
}

const { floor } = await calculateCollectionFloor(context.store, entity.collection.id, id)
const { ownerCount, distribution } = await calculateCollectionOwnerCountAndDistribution(
context.store,
collection.id,
entity.collection.id,
entity.currentOwner,
originalOwner
)
collection.ownerCount = ownerCount
collection.distribution = distribution
entity.collection.floor = floor
entity.collection.ownerCount = ownerCount
entity.collection.distribution = distribution
entity.collection.updatedAt = event.timestamp

success(OPERATION, `${id} by ${event.caller} for ${String(event.price)}`)
await context.store.save(entity)
await context.store.save(collection)
await context.store.save(entity.collection)
const meta = String(event.price || '')
await createEvent(entity, OPERATION, event, meta, context.store, event.currentOwner)
}
15 changes: 7 additions & 8 deletions src/mappings/nfts/list.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getOrFail } from '@kodadot1/metasquid/entity'
import { CollectionEntity as CE, NFTEntity as NE } from '../../model'
import { getWith } from '@kodadot1/metasquid/entity'
import { NFTEntity as NE } from '../../model'
import { unwrap } from '../utils/extract'
import { debug, pending, success } from '../utils/logger'
import { Action, Context, createTokenId } from '../utils/types'
Expand All @@ -15,18 +15,17 @@ export async function handleTokenList(context: Context): Promise<void> {
debug(OPERATION, event, true)

const id = createTokenId(event.collectionId, event.sn)
const entity = await getOrFail<NE>(context.store, NE, id)
const collection = await getOrFail<CE>(context.store, CE, event.collectionId)
const entity = await getWith(context.store, NE, id, { collection: true })

entity.price = event.price

if (event.price && (collection.floor === 0n || event.price < collection.floor)) {
collection.floor = event.price
if (event.price && (entity.collection.floor === 0n || event.price < entity.collection.floor)) {
entity.collection.floor = event.price
}

success(OPERATION, `${id} by ${event.caller}} for ${String(event.price)}`)
success(OPERATION, `${id} by ${event.caller} for ${String(event.price)}`)
await context.store.save(entity)
await context.store.save(collection)
await context.store.save(entity.collection)
const meta = String(event.price || '')
const interaction = event.price ? OPERATION : UNLIST
await createEvent(entity, interaction, event, meta, context.store)
Expand Down
35 changes: 18 additions & 17 deletions src/mappings/nfts/setAttribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { getOrFail as get } from '@kodadot1/metasquid/entity'
import { CollectionEntity, NFTEntity } from '../../model'
import { unwrap } from '../utils/extract'
import { Context, isNFT } from '../utils/types'
import { addressOf } from '../utils/helper'
// import { addressOf } from '../utils/helper'
import { getAttributeEvent } from './getters'
import { attributeFrom, tokenIdOf } from './types'
import { tokenIdOf } from './types'

export async function handleAttributeSet(context: Context): Promise<void> {
const event = unwrap(context, getAttributeEvent)
Expand All @@ -17,29 +17,30 @@ export async function handleAttributeSet(context: Context): Promise<void> {
final.attributes = []
}

if ('royalty' in final && event.trait === 'royalty') {
final.royalty = final.royalty ?? Number.parseFloat(event.value as string)
}
// if ('royalty' in final && event.trait === 'royalty') {
// final.royalty = final.royalty ?? Number.parseFloat(event.value as string)
// }

if ('recipient' in final && event.trait === 'recipient') {
try {
final.recipient = final.recipient ?? addressOf(event.value as string)
} catch (error) {
console.log(error)
final.recipient = final.recipient ?? (event.value as string)
}
}
// if ('recipient' in final && event.trait === 'recipient') {
// try {
// final.recipient = final.recipient ?? addressOf(event.value as string)
// } catch (error) {
// console.log(error)
// final.recipient = final.recipient ?? (event.value as string)
// }
// }

if (event.value === null) {
final.attributes = final.attributes?.filter((attr) => attr.trait !== event.trait)
} else {
const attribute = final.attributes?.find((attr) => attr.trait === event.trait)
if (attribute) {
attribute.value = String(event.value)
} else if (event.trait !== 'royalty' && event.trait !== 'recipient') {
const newAttribute = attributeFrom({ trait_type: event.trait, value: String(event.value) })
final.attributes?.push(newAttribute)
}
}
// else if (event.trait !== 'royalty' && event.trait !== 'recipient') {
// const newAttribute = attributeFrom({ trait_type: event.trait, value: String(event.value) })
// final.attributes?.push(newAttribute)
// }
}

await context.store.save(final)
Expand Down
1 change: 1 addition & 0 deletions src/mappings/nfts/transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ export async function handleTokenTransfer(context: Context): Promise<void> {

success(OPERATION, `${id} from ${event.caller} to ${event.to}`)
await context.store.save(entity)
await context.store.save(entity.collection)
await createEvent(entity, OPERATION, event, event.to, context.store, oldOwner)
}
7 changes: 5 additions & 2 deletions src/mappings/uniques/burn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { unwrap } from '../utils/extract'
import { debug, pending, success } from '../utils/logger'
import { Action, Context, createTokenId } from '../utils/types'
import { createEvent } from '../shared/event'
import { calculateCollectionOwnerCountAndDistribution } from '../utils/helper'
import { calculateCollectionFloor, calculateCollectionOwnerCountAndDistribution } from '../utils/helper'
import { burnHandler } from '../shared/token'
import { getBurnTokenEvent } from './getters'

Expand All @@ -18,6 +18,7 @@ export async function handleTokenBurn(context: Context): Promise<void> {
const id = createTokenId(event.collectionId, event.sn)
const entity = await getWith(context.store, NE, id, { collection: true })

const { floor } = await calculateCollectionFloor(context.store, entity.collection.id, id)
const { ownerCount, distribution } = await calculateCollectionOwnerCountAndDistribution(
context.store,
entity.collection.id,
Expand All @@ -27,15 +28,17 @@ export async function handleTokenBurn(context: Context): Promise<void> {
entity.burned = true
entity.updatedAt = event.timestamp

entity.collection.updatedAt = event.timestamp
entity.collection.supply -= 1
entity.collection.floor = floor
entity.collection.ownerCount = ownerCount
entity.collection.distribution = distribution
entity.collection.updatedAt = event.timestamp

await burnHandler(context, entity)

success(OPERATION, `${id} by ${event.caller}`)
await context.store.save(entity)
await context.store.save(entity.collection)
const meta = entity.metadata ?? ''
await createEvent(entity, OPERATION, event, meta, context.store)
}
11 changes: 8 additions & 3 deletions src/mappings/uniques/buy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createEvent } from '../shared/event'
import { unwrap } from '../utils/extract'
import { debug, pending, success } from '../utils/logger'
import { Action, Context, createTokenId } from '../utils/types'
import { calculateCollectionOwnerCountAndDistribution } from '../utils/helper'
import { calculateCollectionFloor, calculateCollectionOwnerCountAndDistribution } from '../utils/helper'
import { getBuyTokenEvent } from './getters'

const OPERATION = Action.BUY
Expand All @@ -17,30 +17,35 @@ export async function handleTokenBuy(context: Context): Promise<void> {
const id = createTokenId(event.collectionId, event.sn)
const entity = await getWith(context.store, NE, id, { collection: true })

const originalPrice = entity.price
const originalPrice = event.price
const originalOwner = entity.currentOwner ?? undefined

entity.price = BigInt(0)
entity.currentOwner = event.caller
entity.updatedAt = event.timestamp

if (originalPrice) {
entity.collection.volume += originalPrice
if (originalPrice > entity.collection.highestSale) {
entity.collection.highestSale = originalPrice
}
}

const { floor } = await calculateCollectionFloor(context.store, entity.collection.id, id)
const { ownerCount, distribution } = await calculateCollectionOwnerCountAndDistribution(
context.store,
entity.collection.id,
entity.currentOwner,
originalOwner
)
entity.collection.floor = floor
entity.collection.ownerCount = ownerCount
entity.collection.distribution = distribution

entity.collection.updatedAt = event.timestamp

success(OPERATION, `${id} by ${event.caller} for ${String(event.price)}`)
await context.store.save(entity)
await context.store.save(entity.collection)
const meta = String(event.price || '')
await createEvent(entity, OPERATION, event, meta, context.store, event.currentOwner)
}
7 changes: 4 additions & 3 deletions src/mappings/uniques/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ export async function handleTokenList(context: Context): Promise<void> {

entity.price = event.price

if (entity.price && (entity.collection.floor === 0n || entity.price < entity.collection.floor)) {
entity.collection.floor = entity.price
if (event.price && (entity.collection.floor === 0n || event.price < entity.collection.floor)) {
entity.collection.floor = event.price
}

success(OPERATION, `${id} by ${event.caller}} for ${String(event.price)}`)
success(OPERATION, `${id} by ${event.caller} for ${String(event.price)}`)
await context.store.save(entity)
await context.store.save(entity.collection)
const meta = String(event.price || '')
const interaction = event.price ? OPERATION : UNLIST
await createEvent(entity, interaction, event, meta, context.store)
Expand Down
1 change: 1 addition & 0 deletions src/mappings/uniques/transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ export async function handleTokenTransfer(context: Context): Promise<void> {

success(OPERATION, `${id} from ${event.caller} to ${event.to}`)
await context.store.save(entity)
await context.store.save(entity.collection)
await createEvent(entity, OPERATION, event, event.to, context.store, oldOwner)
}
18 changes: 18 additions & 0 deletions src/mappings/utils/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,21 @@ export async function calculateCollectionOwnerCountAndDistribution(

return adjustedResults
}

export async function calculateCollectionFloor(
store: Store,
collectionId: string,
nftId: string
): Promise<{ floor: bigint }> {
const query: string = `
SELECT MIN(NULLIF(nft_entity.price, 0)) as floor
FROM nft_entity
WHERE collection_id = '${collectionId}'
AND nft_entity.id <> '${nftId}'
`
const [result]: { floor: bigint; }[] = await store.query(query)

return {
floor: result.floor ?? BigInt(0)
}
}
2 changes: 1 addition & 1 deletion src/mappings/utils/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const fetchMetadata = async <T>(metadata: string): Promise<T> => {
}
return await $obtain<T>(metadata, ['rmrk', 'infura_kodadot1'], true)
} catch (e) {
logger.error(`[MINIPFS] ${e}}`)
logger.error(`[MINIPFS] ${e}`)
}

return ensure<T>({})
Expand Down