diff --git a/db/migrations/1649244965659-Data.js b/db/migrations/1649244965659-Data.js new file mode 100644 index 00000000..831297f8 --- /dev/null +++ b/db/migrations/1649244965659-Data.js @@ -0,0 +1,11 @@ +module.exports = class Data1649244965659 { + name = 'Data1649244965659' + + async up(db) { + await db.query(`ALTER TABLE "event" ADD "current_owner" text NOT NULL`) + } + + async down(db) { + await db.query(`ALTER TABLE "event" DROP COLUMN "current_owner"`) + } +} diff --git a/justfile b/justfile index dfb95297..710dd3f5 100644 --- a/justfile +++ b/justfile @@ -42,10 +42,10 @@ reset: npx sqd db:migrate migrate: - @npx sqd db:migrate + npx sqd db:migrate -update NAME: - npx sqd db:create-migration "{{NAME}}" +update-db: + npx sqd db:create-migration Data test: npm run test:unit @@ -60,4 +60,7 @@ kill TAG: npx sqd squid:kill "rubick@{{TAG}}" update-deps: - npx npm-check-updates -u + npx taze + +exec: + docker exec -it rubick-db-1 psql -U postgres -d squid diff --git a/schema.graphql b/schema.graphql index 59363928..1ced9504 100644 --- a/schema.graphql +++ b/schema.graphql @@ -71,6 +71,7 @@ interface EventType { blockNumber: BigInt timestamp: DateTime! caller: String! + currentOwner: String # currentOwner interaction: Interaction! meta: String! } @@ -80,6 +81,7 @@ type Event implements EventType @entity { blockNumber: BigInt timestamp: DateTime! caller: String! + currentOwner: String! # currentOwner interaction: Interaction! meta: String! nft: NFTEntity! @@ -104,6 +106,7 @@ enum Interaction { MINT MINTNFT LIST + UNLIST BUY SEND CONSUME diff --git a/src/mappings/index.ts b/src/mappings/index.ts index d854d80e..d17dcd5b 100644 --- a/src/mappings/index.ts +++ b/src/mappings/index.ts @@ -205,14 +205,14 @@ async function send(remark: RemarkResult, { store }: Context) { ) validateInteraction(nft, interaction) isOwnerOrElseError(nft, remark.caller) - + const originalOwner = nft.currentOwner ?? undefined nft.currentOwner = interaction.metadata nft.price = BigInt(0) nft.updatedAt = remark.timestamp logger.success(`[SEND] ${nft.id} to ${interaction.metadata}`) await store.save(nft) - await createEvent(nft, RmrkEvent.SEND, remark, interaction.metadata || '', store) + await createEvent(nft, RmrkEvent.SEND, remark, interaction.metadata || '', store, originalOwner) } catch (e) { logError(e, (e) => logger.error(`[SEND] ${e.message} ${JSON.stringify(interaction)}`) @@ -237,13 +237,14 @@ async function buy(remark: RemarkResult, { store }: Context) { isPositiveOrElseError(nft.price, true) isBuyLegalOrElseError(nft, remark.extra || []) const originalPrice = nft.price + const originalOwner = nft.currentOwner ?? undefined nft.currentOwner = remark.caller nft.price = BigInt(0) nft.updatedAt = remark.timestamp logger.success(`[BUY] ${nft.id} from ${remark.caller}`) await store.save(nft) - await createEvent(nft, RmrkEvent.BUY, remark, String(originalPrice), store) + await createEvent(nft, RmrkEvent.BUY, remark, String(originalPrice), store, originalOwner) } catch (e) { logError(e, (e) => logger.error(`[BUY] ${e.message} ${JSON.stringify(interaction)}`) @@ -299,7 +300,8 @@ async function list(remark: RemarkResult, { store }: Context) { logger.success(`[LIST] ${nft.id} from ${remark.caller}`) await store.save(nft) - await createEvent(nft, RmrkEvent.LIST, remark, String(price), store) + const event = nft.price === 0n ? RmrkEvent.UNLIST : RmrkEvent.LIST + await createEvent(nft, event, remark, String(price), store) } catch (e) { logError(e, (e) => logger.warn(`[LIST] ${e.message} ${JSON.stringify(interaction)}`) @@ -413,7 +415,7 @@ async function handleMetadata( } -async function createEvent(final: NFTEntity, interaction: RmrkEvent, remark: RemarkResult, meta: string, store: Store) { +async function createEvent(final: NFTEntity, interaction: RmrkEvent, remark: RemarkResult, meta: string, store: Store, currentOwner?: string) { try { const newEventId = eventId(final.id, interaction) const event = create(Event, newEventId, eventFrom(interaction, remark, meta)) diff --git a/src/mappings/utils/types.ts b/src/mappings/utils/types.ts index 524e76b3..d43f3919 100644 --- a/src/mappings/utils/types.ts +++ b/src/mappings/utils/types.ts @@ -20,11 +20,12 @@ export function collectionEventFrom(interaction: RmrkEvent.MINT | RmrkEvent.CHAN }) } -export function eventFrom(interaction: RmrkEvent, { blockNumber, caller, timestamp }: RemarkResult, meta: string): IEvent { +export function eventFrom(interaction: RmrkEvent, { blockNumber, caller, timestamp }: RemarkResult, meta: string, currentOwner?: string): IEvent { return { interaction, blockNumber: BigInt(blockNumber), caller, + currentOwner: currentOwner || caller, timestamp, meta } @@ -46,6 +47,7 @@ export interface IEvent { interaction: RmrkEvent; blockNumber: bigint, caller: string, + currentOwner: string, timestamp: Date, meta: string; } diff --git a/src/model/generated/_interaction.ts b/src/model/generated/_interaction.ts index 180be31a..f402dc8c 100644 --- a/src/model/generated/_interaction.ts +++ b/src/model/generated/_interaction.ts @@ -2,6 +2,7 @@ export enum Interaction { MINT = "MINT", MINTNFT = "MINTNFT", LIST = "LIST", + UNLIST = "UNLIST", BUY = "BUY", SEND = "SEND", CONSUME = "CONSUME", diff --git a/src/model/generated/event.model.ts b/src/model/generated/event.model.ts index b8283f13..3561cf76 100644 --- a/src/model/generated/event.model.ts +++ b/src/model/generated/event.model.ts @@ -21,6 +21,9 @@ export class Event { @Column_("text", {nullable: false}) caller!: string + @Column_("text", {nullable: false}) + currentOwner!: string + @Column_("varchar", {length: 12, nullable: false}) interaction!: Interaction