From 45f38dba543779e3663dd009a070fa04c99ee43c Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 15:29:51 +0200 Subject: [PATCH 01/14] :zap: check if issuer is address --- src/mappings/v2/change.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/mappings/v2/change.ts b/src/mappings/v2/change.ts index b2a824a5..9fa84960 100644 --- a/src/mappings/v2/change.ts +++ b/src/mappings/v2/change.ts @@ -6,9 +6,9 @@ import { ChangeIssuer } from '@kodadot1/minimark/v2' import { Base, CollectionEntity } from '../../model' import { unwrap } from '../utils' import { isOwnerOrElseError, withMeta } from '../utils/consolidator' +import { isDummyAddress } from '../utils/helper' import { error, success } from '../utils/logger' import { Action, Context } from '../utils/types' -import { calculateCollectionOwnerCountAndDistribution } from '../utils/helper' import { getChangeIssuer } from './getters' const OPERATION = Action.CHANGEISSUER @@ -26,14 +26,12 @@ export async function changeIssuer(context: Context) { ? await get(context.store, Base, interaction.id) : await get(context.store, CollectionEntity, interaction.id) isOwnerOrElseError(entity, caller) - entity.currentOwner = interaction.newissuer + entity.currentOwner = interaction.value - if (entity instanceof CollectionEntity) { - const { ownerCount, distribution } = await calculateCollectionOwnerCountAndDistribution(context.store, entity.id) - entity.ownerCount = ownerCount - entity.distribution = distribution + if (!isDummyAddress(interaction.value)) { + throw new Error(`Cannot change issuer to value that is not address address ${interaction.value}`) } - + await context.store.save(entity) success(OPERATION, `${entity.id} from ${caller}`) } catch (e) { From f3db88201a80e84d1eb03f9c1fd178db0f0e88ce Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 15:30:17 +0200 Subject: [PATCH 02/14] :zap: emit ACCEPT if NFT is not pending in src/mappings/v2/buy.ts --- src/mappings/v2/buy.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/mappings/v2/buy.ts b/src/mappings/v2/buy.ts index 49bf892d..f22992db 100644 --- a/src/mappings/v2/buy.ts +++ b/src/mappings/v2/buy.ts @@ -86,6 +86,17 @@ export async function buy(context: Context) { caller ) } + + if (nft.parent !== null && nft.pending === false) { + await createEvent( + nft.parent, + Action.ACCEPT, + { blockNumber, caller, timestamp, version }, + `NFT::${interaction.id}`, + context.store, + originalOwner + ) + } } catch (e) { error(e, OPERATION, JSON.stringify(interaction)) } From a8376f0fc2e9041e9f0f2567fa07c65ef374edbc Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 15:30:17 +0200 Subject: [PATCH 03/14] :zap: emit ACCEPT if NFT is not pending in src/mappings/v2/mint.ts --- src/mappings/v2/mint.ts | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/mappings/v2/mint.ts b/src/mappings/v2/mint.ts index ce88544d..2bb3876d 100644 --- a/src/mappings/v2/mint.ts +++ b/src/mappings/v2/mint.ts @@ -9,10 +9,9 @@ import { CollectionEntity, NFTEntity } from '../../model/generated' import { createEvent } from '../shared/event' import { handleMetadata } from '../shared/metadata' import { findRootItemById } from '../utils/entity' -import { isDummyAddress } from '../utils/helper' +import { calculateCollectionOwnerCountAndDistribution, isDummyAddress } from '../utils/helper' import logger, { error, success } from '../utils/logger' import { Action, Context, Optional, getNftId } from '../utils/types' -import { calculateCollectionOwnerCountAndDistribution } from '../utils/helper' import { getCreateToken } from './getters' const OPERATION = Action.MINT @@ -50,13 +49,6 @@ export async function mintItem(context: Context): Promise { collection.updatedAt = timestamp collection.nftCount += 1 collection.supply += 1 - const { ownerCount, distribution } = await calculateCollectionOwnerCountAndDistribution( - context.store, - collection.id, - final.currentOwner - ) - collection.ownerCount = ownerCount - collection.distribution = distribution if (final.metadata) { const metadata = await handleMetadata(final.metadata, '', context.store) @@ -91,6 +83,14 @@ export async function mintItem(context: Context): Promise { final.pending = false } + const { ownerCount, distribution } = await calculateCollectionOwnerCountAndDistribution( + context.store, + collection.id, + final.currentOwner || '' + ) + collection.ownerCount = ownerCount + collection.distribution = distribution + await context.store.save(final) await context.store.save(collection) success(OPERATION, `${final.id} from ${caller}`) @@ -116,6 +116,16 @@ export async function mintItem(context: Context): Promise { caller ) } + + if (final.parent !== null && final.pending === false) { + await createEvent( + final.parent, + Action.ACCEPT, + { blockNumber, caller, timestamp, version }, + `NFT::${final.id}`, + context.store, + ) + } } catch (e) { if (e instanceof Error) { logger.trace(e) From d7e5e4b2104ee135eb0629a4b753747eac585937 Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 15:30:17 +0200 Subject: [PATCH 04/14] :zap: emit ACCEPT if NFT is not pending in src/mappings/v2/send.ts --- src/mappings/v2/send.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mappings/v2/send.ts b/src/mappings/v2/send.ts index 94fb1ebc..7b0f4df3 100644 --- a/src/mappings/v2/send.ts +++ b/src/mappings/v2/send.ts @@ -68,6 +68,18 @@ export async function send(context: Context) { context.store, originalOwner ) + + + if (nft.parent !== null && nft.pending === false) { + await createEvent( + nft.parent, + Action.ACCEPT, + { blockNumber, caller, timestamp, version }, + `NFT::${interaction.id}`, + context.store, + originalOwner + ) + } } catch (e) { error(e, OPERATION, JSON.stringify(interaction)) } From 9138a1e01743018e93b0938a9eb8dc677774760d Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 15:30:46 +0200 Subject: [PATCH 05/14] :wastebasket: useless calculation of distribution --- src/mappings/v1/change.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/mappings/v1/change.ts b/src/mappings/v1/change.ts index 6ddc87b2..aef6b1ab 100644 --- a/src/mappings/v1/change.ts +++ b/src/mappings/v1/change.ts @@ -8,7 +8,6 @@ import { isOwnerOrElseError, withMeta } from '../utils/consolidator' import { getInteraction } from '../utils/getters' import { error, success } from '../utils/logger' import { Action, Context, RmrkInteraction } from '../utils/types' -import { calculateCollectionOwnerCountAndDistribution } from '../utils/helper' const OPERATION = Action.CHANGEISSUER @@ -24,12 +23,6 @@ export async function changeIssuer(context: Context) { plsBe(real, collection) isOwnerOrElseError(collection, caller) collection.currentOwner = interaction.value - const { ownerCount, distribution } = await calculateCollectionOwnerCountAndDistribution( - context.store, - collection.id, - ) - collection.ownerCount = ownerCount - collection.distribution = distribution await context.store.save(collection) success(OPERATION, `${collection.id} from ${caller}`) From 1aac9fc6302b93ad1e433ccb4d4b2b864891426f Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 15:32:04 +0200 Subject: [PATCH 06/14] :soap: prettier ; --- src/mappings/utils/entity.ts | 2 +- src/mappings/v2/addTheme.ts | 7 +++---- src/mappings/v2/buy.ts | 3 +-- src/mappings/v2/change.ts | 2 +- src/mappings/v2/equip.ts | 6 +++++- src/mappings/v2/mint.ts | 4 ++-- src/mappings/v2/send.ts | 3 +-- 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/mappings/utils/entity.ts b/src/mappings/utils/entity.ts index e1e42c05..effee80d 100644 --- a/src/mappings/utils/entity.ts +++ b/src/mappings/utils/entity.ts @@ -82,4 +82,4 @@ export async function findParentBaseResouce(store: Store, id: string, baseId: st } return result -} \ No newline at end of file +} diff --git a/src/mappings/v2/addTheme.ts b/src/mappings/v2/addTheme.ts index efed82c8..567aaf37 100644 --- a/src/mappings/v2/addTheme.ts +++ b/src/mappings/v2/addTheme.ts @@ -13,7 +13,7 @@ import { getThemeAdd } from './getters' const OPERATION = Action.THEMEADD -export async function addTheme(context: Context) { +export async function addTheme(context: Context) { let interaction: Optional = null try { @@ -26,10 +26,9 @@ export async function addTheme(context: Context) { const id = toThemeId(interaction.base_id, interaction.name) const final = await createUnlessNotExist(id, Theme, context) - final.name = interaction.name final.base = base - + const keys = ['theme_color_1', 'theme_color_2', 'theme_color_3', 'theme_color_4'] for (const key of keys) { @@ -37,8 +36,8 @@ export async function addTheme(context: Context) { if (value && key !== 'base') { const camelKey = camelCase(key) as keyof Omit final[camelKey] = value + } } - } // logger.success(`[${OPERATION}] NEW PRIORITY ${interaction.value} for ${nft.id} from ${caller}`) success(OPERATION, `< ${interaction.name}, ${interaction.value} > for ${interaction.base_id} from ${caller}`) diff --git a/src/mappings/v2/buy.ts b/src/mappings/v2/buy.ts index f22992db..f00c72e1 100644 --- a/src/mappings/v2/buy.ts +++ b/src/mappings/v2/buy.ts @@ -75,7 +75,6 @@ export async function buy(context: Context) { originalOwner ) - if (nft.currentOwner !== caller) { await createEvent( nft, @@ -95,7 +94,7 @@ export async function buy(context: Context) { `NFT::${interaction.id}`, context.store, originalOwner - ) + ) } } catch (e) { error(e, OPERATION, JSON.stringify(interaction)) diff --git a/src/mappings/v2/change.ts b/src/mappings/v2/change.ts index 9fa84960..5452509c 100644 --- a/src/mappings/v2/change.ts +++ b/src/mappings/v2/change.ts @@ -31,7 +31,7 @@ export async function changeIssuer(context: Context) { if (!isDummyAddress(interaction.value)) { throw new Error(`Cannot change issuer to value that is not address address ${interaction.value}`) } - + await context.store.save(entity) success(OPERATION, `${entity.id} from ${caller}`) } catch (e) { diff --git a/src/mappings/v2/equip.ts b/src/mappings/v2/equip.ts index f6cd886d..b30e6144 100644 --- a/src/mappings/v2/equip.ts +++ b/src/mappings/v2/equip.ts @@ -20,7 +20,11 @@ export async function equip(context: Context) { try { const { value: equip, caller, timestamp, blockNumber, version } = unwrap(context, getEquip) interaction = equip - const nft = await getWith(context.store, NFTEntity, interaction.id, { parent: true, equipped: true, collection: true }) + const nft = await getWith(context.store, NFTEntity, interaction.id, { + parent: true, + equipped: true, + collection: true, + }) plsNotBe(burned, nft) isOwnerOrElseError(nft, caller) plsBe(real, nft.parent) diff --git a/src/mappings/v2/mint.ts b/src/mappings/v2/mint.ts index 2bb3876d..f8cdd3d3 100644 --- a/src/mappings/v2/mint.ts +++ b/src/mappings/v2/mint.ts @@ -123,8 +123,8 @@ export async function mintItem(context: Context): Promise { Action.ACCEPT, { blockNumber, caller, timestamp, version }, `NFT::${final.id}`, - context.store, - ) + context.store + ) } } catch (e) { if (e instanceof Error) { diff --git a/src/mappings/v2/send.ts b/src/mappings/v2/send.ts index 7b0f4df3..71d1cc5b 100644 --- a/src/mappings/v2/send.ts +++ b/src/mappings/v2/send.ts @@ -69,7 +69,6 @@ export async function send(context: Context) { originalOwner ) - if (nft.parent !== null && nft.pending === false) { await createEvent( nft.parent, @@ -78,7 +77,7 @@ export async function send(context: Context) { `NFT::${interaction.id}`, context.store, originalOwner - ) + ) } } catch (e) { error(e, OPERATION, JSON.stringify(interaction)) From d7736d7b50b98b1facfd9568dfc3677193e8741f Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 15:51:17 +0200 Subject: [PATCH 07/14] :zap: add equip and equippable into process --- src/mappings/v2/index.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mappings/v2/index.ts b/src/mappings/v2/index.ts index 52e59899..b2a94ef4 100644 --- a/src/mappings/v2/index.ts +++ b/src/mappings/v2/index.ts @@ -16,6 +16,8 @@ import { mintItem } from './mint' import { send } from './send' import { setPriority } from './setpriority' import { addTheme } from './addTheme' +import { equip } from './equip' +import { equippable } from './equippable' export async function mainFrame(remark: string, context: Context): Promise { const base = unwrap(context, (_: Context) => ({ value: remark })) @@ -67,10 +69,14 @@ export async function mainFrame(remark: string, context: Context): Promise case Interaction.THEMEADD: await addTheme(context) break - case Interaction.DESTROY: + case Interaction.EQUIP: + await equip(context) + break case Interaction.EQUIPPABLE: + await equippable(context) + break + case Interaction.DESTROY: case Interaction.SETPROPERTY: - case Interaction.EQUIP: pending(event, `::${base.blockNumber}::${base.value}`) break default: From 0e0edea7cc73a8bb017f0e15f190644dd7d09b17 Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 16:17:03 +0200 Subject: [PATCH 08/14] :arrow_up: @kodadot1/minimark --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3464a498..c4c4e362 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.9", "dependencies": { "@kodadot1/metasquid": "^0.1.5-rc.0", - "@kodadot1/minimark": "0.1.7-rc.2", + "@kodadot1/minimark": "0.1.7-rc.3", "@kodadot1/minipfs": "^0.3.0-rc.0", "@subsquid/archive-registry": "2.1.10", "@subsquid/big-decimal": "^0.0.0", @@ -632,9 +632,9 @@ } }, "node_modules/@kodadot1/minimark": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@kodadot1/minimark/-/minimark-0.1.7-rc.2.tgz", - "integrity": "sha512-UZ/ATqFgBfakcdWakD0H+eZVHp14buAhe8EmsxBhxx0cvifZX65xkZIIX3ldywZJhEwP/6CiAElEimj1NAPKDg==", + "version": "0.1.7-rc.3", + "resolved": "https://registry.npmjs.org/@kodadot1/minimark/-/minimark-0.1.7-rc.3.tgz", + "integrity": "sha512-HztbWu3KzV/TBqyeSqyyKs0mleU/kdX1fhd4XCVQsle3sku/juUBX93BUb7x/MUCValyahqLVhoWs+gwbSgIvQ==", "dependencies": { "@polkadot/api": "10.1.4", "@polkadot/keyring": "11.1.1", @@ -13616,9 +13616,9 @@ } }, "@kodadot1/minimark": { - "version": "0.1.7-rc.2", - "resolved": "https://registry.npmjs.org/@kodadot1/minimark/-/minimark-0.1.7-rc.2.tgz", - "integrity": "sha512-UZ/ATqFgBfakcdWakD0H+eZVHp14buAhe8EmsxBhxx0cvifZX65xkZIIX3ldywZJhEwP/6CiAElEimj1NAPKDg==", + "version": "0.1.7-rc.3", + "resolved": "https://registry.npmjs.org/@kodadot1/minimark/-/minimark-0.1.7-rc.3.tgz", + "integrity": "sha512-HztbWu3KzV/TBqyeSqyyKs0mleU/kdX1fhd4XCVQsle3sku/juUBX93BUb7x/MUCValyahqLVhoWs+gwbSgIvQ==", "requires": { "@polkadot/api": "10.1.4", "@polkadot/keyring": "11.1.1", diff --git a/package.json b/package.json index 15fbfe48..7e4e17f5 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@kodadot1/metasquid": "^0.1.5-rc.0", - "@kodadot1/minimark": "0.1.7-rc.2", + "@kodadot1/minimark": "0.1.7-rc.3", "@kodadot1/minipfs": "^0.3.0-rc.0", "@subsquid/archive-registry": "2.1.10", "@subsquid/big-decimal": "^0.0.0", From 3807dc9f801687ace8b8bca95672344b604fc9bf Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 16:26:30 +0200 Subject: [PATCH 09/14] :alien: property --- schema.graphql | 15 +++++++++----- src/model/generated/index.ts | 1 + src/model/generated/nftEntity.model.ts | 4 ++++ src/model/generated/property.model.ts | 28 ++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 src/model/generated/property.model.ts diff --git a/schema.graphql b/schema.graphql index a5d703bc..baa4e9db 100644 --- a/schema.graphql +++ b/schema.graphql @@ -47,6 +47,7 @@ type NFTEntity @entity { parent: NFTEntity # = nft_id pending: Boolean! price: BigInt! + properties: [Property!] @derivedFrom (field: "nft") resources: [Resource!] @derivedFrom (field: "nft") royalty: Float recipient: String @@ -175,11 +176,6 @@ type Part @entity { z: Int! } -# type ResourcePart @entity { -# resource: Resource! -# part: Part! -# } - type Theme @entity { id: ID! @@ -220,6 +216,15 @@ enum PartType { slot } +type Property @entity { + id: ID! + key: String! + value: String! + type: String! + mutable: Boolean! + nft: NFTEntity! +} + # Cachce and tables type Series @entity { id: ID! diff --git a/src/model/generated/index.ts b/src/model/generated/index.ts index c1af1860..2f94c279 100644 --- a/src/model/generated/index.ts +++ b/src/model/generated/index.ts @@ -13,6 +13,7 @@ export * from "./part.model" export * from "./_partType" export * from "./theme.model" export * from "./resource.model" +export * from "./property.model" export * from "./series.model" export * from "./spotlight.model" export * from "./collector.model" diff --git a/src/model/generated/nftEntity.model.ts b/src/model/generated/nftEntity.model.ts index b22f527d..b847db43 100644 --- a/src/model/generated/nftEntity.model.ts +++ b/src/model/generated/nftEntity.model.ts @@ -5,6 +5,7 @@ import {Emote} from "./emote.model" import {Event} from "./event.model" import {Part} from "./part.model" import {MetadataEntity} from "./metadataEntity.model" +import {Property} from "./property.model" import {Resource} from "./resource.model" @Entity_() @@ -83,6 +84,9 @@ export class NFTEntity { @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) price!: bigint + @OneToMany_(() => Property, e => e.nft) + properties!: Property[] + @OneToMany_(() => Resource, e => e.nft) resources!: Resource[] diff --git a/src/model/generated/property.model.ts b/src/model/generated/property.model.ts new file mode 100644 index 00000000..f5199606 --- /dev/null +++ b/src/model/generated/property.model.ts @@ -0,0 +1,28 @@ +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_} from "typeorm" +import {NFTEntity} from "./nftEntity.model" + +@Entity_() +export class Property { + constructor(props?: Partial) { + Object.assign(this, props) + } + + @PrimaryColumn_() + id!: string + + @Column_("text", {nullable: false}) + key!: string + + @Column_("text", {nullable: false}) + value!: string + + @Column_("text", {nullable: false}) + type!: string + + @Column_("bool", {nullable: false}) + mutable!: boolean + + @Index_() + @ManyToOne_(() => NFTEntity, {nullable: true}) + nft!: NFTEntity +} From 1a4dce8a4148922b25c7260d7b2c09dab0c41d62 Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 16:32:08 +0200 Subject: [PATCH 10/14] :truck: magic renaming --- src/mappings/v2/setProperty2.ts | 46 +++++++++++++++++++++++++++++++++ src/mappings/v2/setproperty.ts | 28 -------------------- 2 files changed, 46 insertions(+), 28 deletions(-) create mode 100644 src/mappings/v2/setProperty2.ts delete mode 100644 src/mappings/v2/setproperty.ts diff --git a/src/mappings/v2/setProperty2.ts b/src/mappings/v2/setProperty2.ts new file mode 100644 index 00000000..00247ef4 --- /dev/null +++ b/src/mappings/v2/setProperty2.ts @@ -0,0 +1,46 @@ +import { Optional } from '@kodadot1/metasquid/types' +import { SetProperty, toPropertyId } from '@kodadot1/minimark/v2' + +import { burned, plsNotBe } from '@kodadot1/metasquid/consolidator' +import { getWith } from '@kodadot1/metasquid/entity' +import { Property } from '../../model' +import { createEvent } from '../shared' +import { unwrap } from '../utils' +import logger, { logError } from '../utils/logger' +import { Action, Context } from '../utils/types' +import { getSetProperty } from './getters' + +const OPERATION = Action.SETPROPERTY + +export async function setProperty(context: Context) { + let interaction: Optional = null + + try { + const getter = getSetProperty + const { value, caller, timestamp, blockNumber, version } = unwrap(context, getter) + interaction = value + + const id = toPropertyId(interaction.id, interaction.name, interaction.value) + + const property = await getWith(context.store, Property, id, { nft: true }) + plsNotBe(burned, property.nft) + + if (property.mutable === false || interaction.name === 'royaltyInfo') { + throw new Error(`Property ${interaction.name} is not mutable`) + } + + property.value = interaction.value + + logger.info(`[${OPERATION}] < ${interaction.name}, ${interaction.value} > for ${interaction.id} from ${caller}`) + await context.store.save(property) + await createEvent( + property.nft, + OPERATION, + { blockNumber, caller, timestamp, version }, + `${interaction.name}::${interaction.value}`, + context.store + ) + } catch (e) { + logError(e, (e) => logger.warn(`[${OPERATION}] ${e.message} ${JSON.stringify(interaction)}`)) + } +} diff --git a/src/mappings/v2/setproperty.ts b/src/mappings/v2/setproperty.ts deleted file mode 100644 index cfb339aa..00000000 --- a/src/mappings/v2/setproperty.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Optional } from '@kodadot1/metasquid/types' -import { SetProperty } from '@kodadot1/minimark/v2' - -import { unwrap } from '../utils' -import logger, { logError } from '../utils/logger' -import { Action, Context } from '../utils/types' -import { getSetProperty } from './getters' - -const OPERATION = Action.SETPROPERTY - -export async function setProperty(context: Context) { - let interaction: Optional = null - - try { - const getter = getSetProperty - const { value: interaction, caller, timestamp, blockNumber, version } = unwrap(context, getter) - - // logger.success(`[${OPERATION}] NEW PRIORITY ${interaction.value} for ${nft.id} from ${caller}`) - - // TODO: add logic for accepting resource - - logger.info(`[${OPERATION}] < ${interaction.name}, ${interaction.value} > for ${interaction.id} from ${caller}`) - // await context.store.save(nft) - // await createEvent(nft, OPERATION, { blockNumber, caller, timestamp, version }, `${interaction.value.at(0)}`, context.store) - } catch (e) { - logError(e, (e) => logger.warn(`[${OPERATION}] ${e.message} ${JSON.stringify(interaction)}`)) - } -} From 747f9b482e88bce2ecdda6ba92b369bef958ce0d Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 16:32:34 +0200 Subject: [PATCH 11/14] :truck: magic renaming --- src/mappings/v2/{setProperty2.ts => setProperty.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/mappings/v2/{setProperty2.ts => setProperty.ts} (100%) diff --git a/src/mappings/v2/setProperty2.ts b/src/mappings/v2/setProperty.ts similarity index 100% rename from src/mappings/v2/setProperty2.ts rename to src/mappings/v2/setProperty.ts From c88ce85279c7ce96e85e3a91598260996c6e5bf1 Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 16:37:42 +0200 Subject: [PATCH 12/14] :zap: having properties --- src/mappings/v2/mint.ts | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/mappings/v2/mint.ts b/src/mappings/v2/mint.ts index f8cdd3d3..96fe65f3 100644 --- a/src/mappings/v2/mint.ts +++ b/src/mappings/v2/mint.ts @@ -1,11 +1,11 @@ import { plsBe, real } from '@kodadot1/metasquid/consolidator' import { create, getOrFail as get } from '@kodadot1/metasquid/entity' -import { Mint, resolveRoyalty } from '@kodadot1/minimark/v2' +import { Mint, resolveRoyalty, toPropertyId } from '@kodadot1/minimark/v2' import md5 from 'md5' import { unwrap } from '../utils' import { isOwnerOrElseError } from '../utils/consolidator' -import { CollectionEntity, NFTEntity } from '../../model/generated' +import { CollectionEntity, NFTEntity, Property } from '../../model/generated' import { createEvent } from '../shared/event' import { handleMetadata } from '../shared/metadata' import { findRootItemById } from '../utils/entity' @@ -83,14 +83,6 @@ export async function mintItem(context: Context): Promise { final.pending = false } - const { ownerCount, distribution } = await calculateCollectionOwnerCountAndDistribution( - context.store, - collection.id, - final.currentOwner || '' - ) - collection.ownerCount = ownerCount - collection.distribution = distribution - await context.store.save(final) await context.store.save(collection) success(OPERATION, `${final.id} from ${caller}`) @@ -126,6 +118,26 @@ export async function mintItem(context: Context): Promise { context.store ) } + + if (nft.properties) { + const properties = Object.entries(nft.properties) + const saveList: Property[] = [] + for (const [key, value] of properties) { + if (!value.value) { + continue + } + const propertyId = toPropertyId(final.id, key, value.value) + const property = create(Property, propertyId, {}) + property.id = propertyId + property.key = key + property.value = value.value + property.nft = final + property.mutable = value._mutation?.allowed || false + saveList.push(property) + } + + await context.store.save(saveList) + } } catch (e) { if (e instanceof Error) { logger.trace(e) From 2e38bd87ae1a8a8489941e67307f72070dc043ff Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 16:38:43 +0200 Subject: [PATCH 13/14] :zap: enable setProperty --- src/mappings/v2/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mappings/v2/index.ts b/src/mappings/v2/index.ts index b2a94ef4..90971bf6 100644 --- a/src/mappings/v2/index.ts +++ b/src/mappings/v2/index.ts @@ -18,6 +18,7 @@ import { setPriority } from './setpriority' import { addTheme } from './addTheme' import { equip } from './equip' import { equippable } from './equippable' +import { setProperty } from './setProperty' export async function mainFrame(remark: string, context: Context): Promise { const base = unwrap(context, (_: Context) => ({ value: remark })) @@ -75,8 +76,10 @@ export async function mainFrame(remark: string, context: Context): Promise case Interaction.EQUIPPABLE: await equippable(context) break - case Interaction.DESTROY: case Interaction.SETPROPERTY: + await setProperty(context) + break + case Interaction.DESTROY: pending(event, `::${base.blockNumber}::${base.value}`) break default: From 87f0960d3a82636ef407375e2977eb91960f56b4 Mon Sep 17 00:00:00 2001 From: Viki Val Date: Sat, 15 Apr 2023 16:45:53 +0200 Subject: [PATCH 14/14] :construction: THEMES --- src/mappings/v2/base.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/mappings/v2/base.ts b/src/mappings/v2/base.ts index 3b849915..39bea0d7 100644 --- a/src/mappings/v2/base.ts +++ b/src/mappings/v2/base.ts @@ -1,5 +1,5 @@ import { Optional } from '@kodadot1/metasquid/types' -import { CreatedBase, toPartId } from '@kodadot1/minimark/v2' +import { CreatedBase, toPartId, toThemeId } from '@kodadot1/minimark/v2' import { Base, BaseType, Part, PartType } from '../../model' import { handleMetadata } from '../shared' @@ -52,9 +52,21 @@ export async function base(context: Context) { await context.store.save(part) } } - // TODO: themes - // if (base.themes) {} + // if (base.themes) { + // const keys = ['theme_color_1', 'theme_color_2', 'theme_color_3', 'theme_color_4'] + // const themes = Object.entries(base.themes) + // for (const [name, theme] of themes) { + // const themeId = toThemeId(id, name) + // for (const key of keys) { + // const value = theme[key] + // if (value && key !== 'base') { + // const camelKey = camelCase(key) as keyof Omit + // final[camelKey] = value + // } + // } + // } + // } } catch (e) { error(e, OPERATION, JSON.stringify(base)) }