From 2c7a556205b22f0d73ec3df56a6f7b357ba18e6d Mon Sep 17 00:00:00 2001 From: KoKo Date: Mon, 23 May 2022 15:52:14 +0800 Subject: [PATCH 1/8] feat: model of flipping nft --- src/server-extension/model/nft.model.ts | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/server-extension/model/nft.model.ts diff --git a/src/server-extension/model/nft.model.ts b/src/server-extension/model/nft.model.ts new file mode 100644 index 00000000..6637cf4e --- /dev/null +++ b/src/server-extension/model/nft.model.ts @@ -0,0 +1,35 @@ +import { Field, ObjectType } from 'type-graphql'; + +@ObjectType() +export class FlippingNFT { + @Field(() => String, { nullable: false, name: 'nftId' }) + nft_id!: string + + @Field(() => String, { nullable: false }) + author!: string + + @Field(() => Date, { nullable: false }) + date!: Date + + // @Field(() => String) + // previous!: BigInt + + @Field(() => String, { nullable: false }) + current!: BigInt + + @Field(() => BigInt, { nullable: true, defaultValue: 0n, name: 'floorPrice' }) + floor_price!: bigint + + @Field(() => Number, { nullable: false }) + total!: number + + @Field(() => Number, { nullable: false, name: 'owners' }) + unique_collectors!: number + + @Field(() => BigInt, { name: 'emotes' }) + emote_count!: number + + constructor(props: Partial) { + Object.assign(this, props); + } +} \ No newline at end of file From 23998ae29838860be52c0f87b49be24596896685 Mon Sep 17 00:00:00 2001 From: KoKo Date: Mon, 23 May 2022 16:22:11 +0800 Subject: [PATCH 2/8] feat: resolver --- src/server-extension/query/nft.ts | 28 ++++++++++++++++++- .../resolvers/flippingNfts.ts | 18 ++++++++++++ src/server-extension/resolvers/index.ts | 2 ++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/server-extension/resolvers/flippingNfts.ts diff --git a/src/server-extension/query/nft.ts b/src/server-extension/query/nft.ts index 94e0eaf8..22775b6e 100644 --- a/src/server-extension/query/nft.ts +++ b/src/server-extension/query/nft.ts @@ -1,4 +1,30 @@ export const passionQuery = `SELECT DISTINCT ne.issuer as id FROM nft_entity ne WHERE ne.current_owner = $1 -AND ne.current_owner != ne.issuer` \ No newline at end of file +AND ne.current_owner != ne.issuer` + +export const flippingQuery = `select +ne.issuer as author, +e.nft_id, +ne.created_at as date, +ne.price as current, +count(e.*), +s.floor_price, +s.total, +s.unique_collectors, +s.emote_count +from event e +left join nft_entity ne on e.nft_id = ne.id +left join series s on s.id = ne.collection_id +where e.interaction = 'BUY' and ne.burned = 'false' +group by +author, +e.nft_id, +date, +current, +floor_price, +s.total, +s.unique_collectors, +s.emote_count +order by count desc +limit 20` \ No newline at end of file diff --git a/src/server-extension/resolvers/flippingNfts.ts b/src/server-extension/resolvers/flippingNfts.ts new file mode 100644 index 00000000..9e7123c1 --- /dev/null +++ b/src/server-extension/resolvers/flippingNfts.ts @@ -0,0 +1,18 @@ +import { Query, Resolver, } from 'type-graphql' +import type { EntityManager } from 'typeorm' +import { NFTEntity } from '../../model/generated' +import { FlippingNFT } from '../model/nft.model' +import { flippingQuery } from "../query/nft"; +import { makeQuery } from "../utils"; + +@Resolver() +export class FlippingNFTsResolver { + constructor(private tx: () => Promise) { } + + @Query(() => [FlippingNFT]) + async flippingNFTs(): Promise<[FlippingNFT]> { + const result: [FlippingNFT] = await makeQuery(this.tx, NFTEntity, flippingQuery) + + return result + } +} \ No newline at end of file diff --git a/src/server-extension/resolvers/index.ts b/src/server-extension/resolvers/index.ts index e32db8a9..ad36b555 100644 --- a/src/server-extension/resolvers/index.ts +++ b/src/server-extension/resolvers/index.ts @@ -6,6 +6,7 @@ import { SpotlightResolver } from './spotlight' import { CollectionChartResolver } from './collectionChart' import { CollectionEventResolver } from './collectionEvent' import { PassionFeedResolver } from "./passionFeed"; +import { FlippingNFTsResolver } from "./flippingNfts"; @ObjectType() export class Hello { @@ -37,4 +38,5 @@ export { SpotlightResolver, CollectionEventResolver, PassionFeedResolver, + FlippingNFTsResolver, } From 0b26edab5f353608c4df784d30203daff27dfff4 Mon Sep 17 00:00:00 2001 From: KoKo Date: Tue, 24 May 2022 00:58:57 +0800 Subject: [PATCH 3/8] feat: lint sql and add params --- src/server-extension/query/nft.ts | 43 ++++++++----------- .../resolvers/flippingNfts.ts | 9 ++-- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/src/server-extension/query/nft.ts b/src/server-extension/query/nft.ts index 22775b6e..88f3ff0f 100644 --- a/src/server-extension/query/nft.ts +++ b/src/server-extension/query/nft.ts @@ -3,28 +3,21 @@ FROM nft_entity ne WHERE ne.current_owner = $1 AND ne.current_owner != ne.issuer` -export const flippingQuery = `select -ne.issuer as author, -e.nft_id, -ne.created_at as date, -ne.price as current, -count(e.*), -s.floor_price, -s.total, -s.unique_collectors, -s.emote_count -from event e -left join nft_entity ne on e.nft_id = ne.id -left join series s on s.id = ne.collection_id -where e.interaction = 'BUY' and ne.burned = 'false' -group by -author, -e.nft_id, -date, -current, -floor_price, -s.total, -s.unique_collectors, -s.emote_count -order by count desc -limit 20` \ No newline at end of file +export const flippingQuery = `SELECT + ne.issuer AS author, + e.nft_id, + ne.created_at AS date, + ne.price AS current, + COUNT(e.*), + s.floor_price, + s.total, + s.unique_collectors, + s.emote_count +FROM event e +LEFT JOIN nft_entity ne ON e.nft_id = ne.id +LEFT JOIN series s ON s.id = ne.collection_id +WHERE e.interaction = 'BUY' AND ne.burned = 'false' +GROUP BY author, e.nft_id, date, current, floor_price, s.total, s.unique_collectors, s.emote_count +ORDER BY count DESC +LIMIT $1 +OFFSET $2` \ No newline at end of file diff --git a/src/server-extension/resolvers/flippingNfts.ts b/src/server-extension/resolvers/flippingNfts.ts index 9e7123c1..182727d4 100644 --- a/src/server-extension/resolvers/flippingNfts.ts +++ b/src/server-extension/resolvers/flippingNfts.ts @@ -1,4 +1,4 @@ -import { Query, Resolver, } from 'type-graphql' +import { Query, Resolver, Arg } from 'type-graphql' import type { EntityManager } from 'typeorm' import { NFTEntity } from '../../model/generated' import { FlippingNFT } from '../model/nft.model' @@ -10,8 +10,11 @@ export class FlippingNFTsResolver { constructor(private tx: () => Promise) { } @Query(() => [FlippingNFT]) - async flippingNFTs(): Promise<[FlippingNFT]> { - const result: [FlippingNFT] = await makeQuery(this.tx, NFTEntity, flippingQuery) + async flippingNFTs( + @Arg('limit', { nullable: true, defaultValue: 20 }) limit: number, + @Arg('offset', { nullable: true, defaultValue: 0 }) offset: number, + ): Promise<[FlippingNFT]> { + const result: [FlippingNFT] = await makeQuery(this.tx, NFTEntity, flippingQuery, [limit, offset]) return result } From 66259ada0fb594e8a49549dc3694704997aa5287 Mon Sep 17 00:00:00 2001 From: KoKo Date: Tue, 24 May 2022 12:33:28 +0800 Subject: [PATCH 4/8] feat: previous price --- src/server-extension/model/nft.model.ts | 9 ++++--- src/server-extension/query/nft.ts | 23 +++++++++++++++- .../resolvers/flippingNfts.ts | 27 ++++++++++++++++--- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/server-extension/model/nft.model.ts b/src/server-extension/model/nft.model.ts index 6637cf4e..b35baeba 100644 --- a/src/server-extension/model/nft.model.ts +++ b/src/server-extension/model/nft.model.ts @@ -1,4 +1,5 @@ import { Field, ObjectType } from 'type-graphql'; +import {string} from '../../model/generated/marshal'; @ObjectType() export class FlippingNFT { @@ -11,11 +12,11 @@ export class FlippingNFT { @Field(() => Date, { nullable: false }) date!: Date - // @Field(() => String) - // previous!: BigInt + @Field(() => String) + previous!: string @Field(() => String, { nullable: false }) - current!: BigInt + current!: string @Field(() => BigInt, { nullable: true, defaultValue: 0n, name: 'floorPrice' }) floor_price!: bigint @@ -32,4 +33,4 @@ export class FlippingNFT { constructor(props: Partial) { Object.assign(this, props); } -} \ No newline at end of file +} diff --git a/src/server-extension/query/nft.ts b/src/server-extension/query/nft.ts index 88f3ff0f..3d7b6a45 100644 --- a/src/server-extension/query/nft.ts +++ b/src/server-extension/query/nft.ts @@ -20,4 +20,25 @@ WHERE e.interaction = 'BUY' AND ne.burned = 'false' GROUP BY author, e.nft_id, date, current, floor_price, s.total, s.unique_collectors, s.emote_count ORDER BY count DESC LIMIT $1 -OFFSET $2` \ No newline at end of file +OFFSET $2` + +export const previousPriceQuery = (idList: string) => `WITH ranking AS ( + SELECT + nft_id, + meta, + Rank() OVER ( + partition BY nft_id + ORDER BY + e.timestamp DESC + ) AS rank + FROM + event e + WHERE + e.nft_id IN (${idList}) + ) + SELECT + * + FROM + ranking + WHERE + rank IN (2);` \ No newline at end of file diff --git a/src/server-extension/resolvers/flippingNfts.ts b/src/server-extension/resolvers/flippingNfts.ts index 182727d4..0ffd08d8 100644 --- a/src/server-extension/resolvers/flippingNfts.ts +++ b/src/server-extension/resolvers/flippingNfts.ts @@ -2,8 +2,14 @@ import { Query, Resolver, Arg } from 'type-graphql' import type { EntityManager } from 'typeorm' import { NFTEntity } from '../../model/generated' import { FlippingNFT } from '../model/nft.model' -import { flippingQuery } from "../query/nft"; -import { makeQuery } from "../utils"; +import { flippingQuery, previousPriceQuery } from "../query/nft"; +import { makeQuery, toSqlInParams } from "../utils"; + +type previousNft = { + nft_id: string, + meta: string, + rank: number, +} @Resolver() export class FlippingNFTsResolver { @@ -16,6 +22,21 @@ export class FlippingNFTsResolver { ): Promise<[FlippingNFT]> { const result: [FlippingNFT] = await makeQuery(this.tx, NFTEntity, flippingQuery, [limit, offset]) + const nfts = result.map(item => item.nft_id) + + const prevNFTs: [previousNft] = (await makeQuery( + this.tx, + NFTEntity, + previousPriceQuery(toSqlInParams(nfts)))) + + result.forEach(nft => { + const { nft_id } = nft + const previousNft = prevNFTs.find((nft) => nft.nft_id === nft_id) || { meta: "0" } + // handle LIST meta is not money + const previous = Number(previousNft.meta) + nft.previous = Number.isNaN(previous) ? "0" : String(previous) + }) + return result } -} \ No newline at end of file +} From 46db70b43b8835dc0e71ce5be56b2a9b30b876b0 Mon Sep 17 00:00:00 2001 From: KoKo Date: Tue, 24 May 2022 14:57:24 +0800 Subject: [PATCH 5/8] feat: prev owners --- src/server-extension/model/nft.model.ts | 3 +++ src/server-extension/query/nft.ts | 21 +++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/server-extension/model/nft.model.ts b/src/server-extension/model/nft.model.ts index b35baeba..da2ccf95 100644 --- a/src/server-extension/model/nft.model.ts +++ b/src/server-extension/model/nft.model.ts @@ -21,6 +21,9 @@ export class FlippingNFT { @Field(() => BigInt, { nullable: true, defaultValue: 0n, name: 'floorPrice' }) floor_price!: bigint + @Field(() => Number, { name: 'prevOwners' }) + prev_owners!: number + @Field(() => Number, { nullable: false }) total!: number diff --git a/src/server-extension/query/nft.ts b/src/server-extension/query/nft.ts index 3d7b6a45..9a574b8f 100644 --- a/src/server-extension/query/nft.ts +++ b/src/server-extension/query/nft.ts @@ -4,21 +4,22 @@ WHERE ne.current_owner = $1 AND ne.current_owner != ne.issuer` export const flippingQuery = `SELECT - ne.issuer AS author, - e.nft_id, - ne.created_at AS date, - ne.price AS current, - COUNT(e.*), - s.floor_price, - s.total, - s.unique_collectors, - s.emote_count +ne.issuer AS author, +e.nft_id, +ne.created_at AS date, +ne.price AS current, +COUNT(e.*) AS total_flip, +COUNT(DISTINCT e.current_owner) AS prev_owners, +s.floor_price, +s.total, +s.unique_collectors, +s.emote_count FROM event e LEFT JOIN nft_entity ne ON e.nft_id = ne.id LEFT JOIN series s ON s.id = ne.collection_id WHERE e.interaction = 'BUY' AND ne.burned = 'false' GROUP BY author, e.nft_id, date, current, floor_price, s.total, s.unique_collectors, s.emote_count -ORDER BY count DESC +ORDER BY total_flip DESC LIMIT $1 OFFSET $2` From e3caba4af0a606bed0b63336e3bb92a75d8c0289 Mon Sep 17 00:00:00 2001 From: KoKo Date: Fri, 27 May 2022 14:44:29 +0800 Subject: [PATCH 6/8] feat: distribution --- src/server-extension/model/nft.model.ts | 7 ++++- src/server-extension/query/nft.ts | 3 +- .../resolvers/flippingNfts.ts | 31 ++++++++++++++----- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/server-extension/model/nft.model.ts b/src/server-extension/model/nft.model.ts index da2ccf95..44bb687b 100644 --- a/src/server-extension/model/nft.model.ts +++ b/src/server-extension/model/nft.model.ts @@ -1,11 +1,13 @@ import { Field, ObjectType } from 'type-graphql'; -import {string} from '../../model/generated/marshal'; @ObjectType() export class FlippingNFT { @Field(() => String, { nullable: false, name: 'nftId' }) nft_id!: string + @Field(() => String, { nullable: false, name: 'collectionId' }) + collection_id!: string + @Field(() => String, { nullable: false }) author!: string @@ -30,6 +32,9 @@ export class FlippingNFT { @Field(() => Number, { nullable: false, name: 'owners' }) unique_collectors!: number + @Field(() => String, { nullable: false }) + distribution!: string + @Field(() => BigInt, { name: 'emotes' }) emote_count!: number diff --git a/src/server-extension/query/nft.ts b/src/server-extension/query/nft.ts index b10e97d4..a6416c85 100644 --- a/src/server-extension/query/nft.ts +++ b/src/server-extension/query/nft.ts @@ -12,6 +12,7 @@ ne.price AS current, COUNT(e.*) AS total_flip, COUNT(DISTINCT e.current_owner) AS prev_owners, s.floor_price, +s.id as collection_id, s.total, s.unique_collectors, s.emote_count @@ -19,7 +20,7 @@ FROM event e LEFT JOIN nft_entity ne ON e.nft_id = ne.id LEFT JOIN series s ON s.id = ne.collection_id WHERE e.interaction = 'BUY' AND ne.burned = 'false' -GROUP BY author, e.nft_id, date, current, floor_price, s.total, s.unique_collectors, s.emote_count +GROUP BY author, e.nft_id, date, current, floor_price, s.id, s.total, s.unique_collectors, s.emote_count ORDER BY total_flip DESC LIMIT $1 OFFSET $2` diff --git a/src/server-extension/resolvers/flippingNfts.ts b/src/server-extension/resolvers/flippingNfts.ts index 0ffd08d8..182e75ff 100644 --- a/src/server-extension/resolvers/flippingNfts.ts +++ b/src/server-extension/resolvers/flippingNfts.ts @@ -3,6 +3,7 @@ import type { EntityManager } from 'typeorm' import { NFTEntity } from '../../model/generated' import { FlippingNFT } from '../model/nft.model' import { flippingQuery, previousPriceQuery } from "../query/nft"; +import { collectionsDistribution } from "../query/collection" import { makeQuery, toSqlInParams } from "../utils"; type previousNft = { @@ -11,6 +12,12 @@ type previousNft = { rank: number, } +type CollectionDistribution = { + id: string + owners: number + unique_owner: number +} + @Resolver() export class FlippingNFTsResolver { constructor(private tx: () => Promise) { } @@ -19,8 +26,8 @@ export class FlippingNFTsResolver { async flippingNFTs( @Arg('limit', { nullable: true, defaultValue: 20 }) limit: number, @Arg('offset', { nullable: true, defaultValue: 0 }) offset: number, - ): Promise<[FlippingNFT]> { - const result: [FlippingNFT] = await makeQuery(this.tx, NFTEntity, flippingQuery, [limit, offset]) + ): Promise> { + const result: Array = await makeQuery(this.tx, NFTEntity, flippingQuery, [limit, offset]) const nfts = result.map(item => item.nft_id) @@ -29,14 +36,24 @@ export class FlippingNFTsResolver { NFTEntity, previousPriceQuery(toSqlInParams(nfts)))) - result.forEach(nft => { - const { nft_id } = nft + const collections: CollectionDistribution[] = await makeQuery( + this.tx, + NFTEntity, + collectionsDistribution(toSqlInParams(result.map(item => item.collection_id)))) + + return result.map(nft => { + const { nft_id, collection_id } = nft const previousNft = prevNFTs.find((nft) => nft.nft_id === nft_id) || { meta: "0" } // handle LIST meta is not money const previous = Number(previousNft.meta) - nft.previous = Number.isNaN(previous) ? "0" : String(previous) - }) + const { owners = 0, unique_owner = 0} = collections.find(col => col.id === collection_id) || {} - return result + return { + ...nft, + previous: Number.isNaN(previous) ? "0" : String(previous), + distribution: (owners / unique_owner).toFixed(2), + } + + }) } } From 605bb372f512154e6954a94b01a8f8fdc5bab6bd Mon Sep 17 00:00:00 2001 From: KoKo Date: Fri, 27 May 2022 14:44:29 +0800 Subject: [PATCH 7/8] feat: distribution --- src/server-extension/model/nft.model.ts | 7 ++++- src/server-extension/query/collection.ts | 8 +++++ src/server-extension/query/nft.ts | 3 +- .../resolvers/flippingNfts.ts | 31 ++++++++++++++----- 4 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 src/server-extension/query/collection.ts diff --git a/src/server-extension/model/nft.model.ts b/src/server-extension/model/nft.model.ts index da2ccf95..44bb687b 100644 --- a/src/server-extension/model/nft.model.ts +++ b/src/server-extension/model/nft.model.ts @@ -1,11 +1,13 @@ import { Field, ObjectType } from 'type-graphql'; -import {string} from '../../model/generated/marshal'; @ObjectType() export class FlippingNFT { @Field(() => String, { nullable: false, name: 'nftId' }) nft_id!: string + @Field(() => String, { nullable: false, name: 'collectionId' }) + collection_id!: string + @Field(() => String, { nullable: false }) author!: string @@ -30,6 +32,9 @@ export class FlippingNFT { @Field(() => Number, { nullable: false, name: 'owners' }) unique_collectors!: number + @Field(() => String, { nullable: false }) + distribution!: string + @Field(() => BigInt, { name: 'emotes' }) emote_count!: number diff --git a/src/server-extension/query/collection.ts b/src/server-extension/query/collection.ts new file mode 100644 index 00000000..ff922fca --- /dev/null +++ b/src/server-extension/query/collection.ts @@ -0,0 +1,8 @@ +export const collectionsDistribution = (idList: string): string => +`SELECT ce.id, + COUNT(ne.current_owner) AS owners, + COUNT (DISTINCT ne.current_owner) AS unique_owner +FROM collection_entity ce +LEFT JOIN nft_entity ne ON ne.collection_id = ce.id +WHERE ce.id in (${idList}) +GROUP BY ce.id` \ No newline at end of file diff --git a/src/server-extension/query/nft.ts b/src/server-extension/query/nft.ts index b10e97d4..a6416c85 100644 --- a/src/server-extension/query/nft.ts +++ b/src/server-extension/query/nft.ts @@ -12,6 +12,7 @@ ne.price AS current, COUNT(e.*) AS total_flip, COUNT(DISTINCT e.current_owner) AS prev_owners, s.floor_price, +s.id as collection_id, s.total, s.unique_collectors, s.emote_count @@ -19,7 +20,7 @@ FROM event e LEFT JOIN nft_entity ne ON e.nft_id = ne.id LEFT JOIN series s ON s.id = ne.collection_id WHERE e.interaction = 'BUY' AND ne.burned = 'false' -GROUP BY author, e.nft_id, date, current, floor_price, s.total, s.unique_collectors, s.emote_count +GROUP BY author, e.nft_id, date, current, floor_price, s.id, s.total, s.unique_collectors, s.emote_count ORDER BY total_flip DESC LIMIT $1 OFFSET $2` diff --git a/src/server-extension/resolvers/flippingNfts.ts b/src/server-extension/resolvers/flippingNfts.ts index 0ffd08d8..182e75ff 100644 --- a/src/server-extension/resolvers/flippingNfts.ts +++ b/src/server-extension/resolvers/flippingNfts.ts @@ -3,6 +3,7 @@ import type { EntityManager } from 'typeorm' import { NFTEntity } from '../../model/generated' import { FlippingNFT } from '../model/nft.model' import { flippingQuery, previousPriceQuery } from "../query/nft"; +import { collectionsDistribution } from "../query/collection" import { makeQuery, toSqlInParams } from "../utils"; type previousNft = { @@ -11,6 +12,12 @@ type previousNft = { rank: number, } +type CollectionDistribution = { + id: string + owners: number + unique_owner: number +} + @Resolver() export class FlippingNFTsResolver { constructor(private tx: () => Promise) { } @@ -19,8 +26,8 @@ export class FlippingNFTsResolver { async flippingNFTs( @Arg('limit', { nullable: true, defaultValue: 20 }) limit: number, @Arg('offset', { nullable: true, defaultValue: 0 }) offset: number, - ): Promise<[FlippingNFT]> { - const result: [FlippingNFT] = await makeQuery(this.tx, NFTEntity, flippingQuery, [limit, offset]) + ): Promise> { + const result: Array = await makeQuery(this.tx, NFTEntity, flippingQuery, [limit, offset]) const nfts = result.map(item => item.nft_id) @@ -29,14 +36,24 @@ export class FlippingNFTsResolver { NFTEntity, previousPriceQuery(toSqlInParams(nfts)))) - result.forEach(nft => { - const { nft_id } = nft + const collections: CollectionDistribution[] = await makeQuery( + this.tx, + NFTEntity, + collectionsDistribution(toSqlInParams(result.map(item => item.collection_id)))) + + return result.map(nft => { + const { nft_id, collection_id } = nft const previousNft = prevNFTs.find((nft) => nft.nft_id === nft_id) || { meta: "0" } // handle LIST meta is not money const previous = Number(previousNft.meta) - nft.previous = Number.isNaN(previous) ? "0" : String(previous) - }) + const { owners = 0, unique_owner = 0} = collections.find(col => col.id === collection_id) || {} - return result + return { + ...nft, + previous: Number.isNaN(previous) ? "0" : String(previous), + distribution: (owners / unique_owner).toFixed(2), + } + + }) } } From a4c392226ab25e1860428f2fb39152951b527f04 Mon Sep 17 00:00:00 2001 From: KoKo Date: Mon, 30 May 2022 11:39:01 +0800 Subject: [PATCH 8/8] feat: rename and beautify sql code --- src/server-extension/model/nft.model.ts | 4 +- src/server-extension/query/nft.ts | 44 ++++++++++++------- .../resolvers/flippingNfts.ts | 4 +- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/server-extension/model/nft.model.ts b/src/server-extension/model/nft.model.ts index 44bb687b..2ccce6cd 100644 --- a/src/server-extension/model/nft.model.ts +++ b/src/server-extension/model/nft.model.ts @@ -23,8 +23,8 @@ export class FlippingNFT { @Field(() => BigInt, { nullable: true, defaultValue: 0n, name: 'floorPrice' }) floor_price!: bigint - @Field(() => Number, { name: 'prevOwners' }) - prev_owners!: number + @Field(() => Number, { name: 'previousOwner' }) + previous_owners!: number @Field(() => Number, { nullable: false }) total!: number diff --git a/src/server-extension/query/nft.ts b/src/server-extension/query/nft.ts index a6416c85..e26f0160 100644 --- a/src/server-extension/query/nft.ts +++ b/src/server-extension/query/nft.ts @@ -5,22 +5,34 @@ AND ne.current_owner != ne.issuer` export const flippingQuery = `SELECT -ne.issuer AS author, -e.nft_id, -ne.created_at AS date, -ne.price AS current, -COUNT(e.*) AS total_flip, -COUNT(DISTINCT e.current_owner) AS prev_owners, -s.floor_price, -s.id as collection_id, -s.total, -s.unique_collectors, -s.emote_count -FROM event e -LEFT JOIN nft_entity ne ON e.nft_id = ne.id -LEFT JOIN series s ON s.id = ne.collection_id -WHERE e.interaction = 'BUY' AND ne.burned = 'false' -GROUP BY author, e.nft_id, date, current, floor_price, s.id, s.total, s.unique_collectors, s.emote_count + ne.issuer AS author, + e.nft_id, + ne.created_at AS date, + ne.price AS current, + COUNT(e.*) AS total_flip, + COUNT(DISTINCT e.current_owner) AS previous_owners, + s.floor_price, + s.id as collection_id, + s.total, + s.unique_collectors, + s.emote_count +FROM + event e + LEFT JOIN nft_entity ne ON e.nft_id = ne.id + LEFT JOIN series s ON s.id = ne.collection_id +WHERE + e.interaction = 'BUY' + AND ne.burned = 'false' +GROUP BY + author, + e.nft_id, + date, + current, + floor_price, + s.id, + s.total, + s.unique_collectors, + s.emote_count ORDER BY total_flip DESC LIMIT $1 OFFSET $2` diff --git a/src/server-extension/resolvers/flippingNfts.ts b/src/server-extension/resolvers/flippingNfts.ts index 182e75ff..138fc7a3 100644 --- a/src/server-extension/resolvers/flippingNfts.ts +++ b/src/server-extension/resolvers/flippingNfts.ts @@ -6,7 +6,7 @@ import { flippingQuery, previousPriceQuery } from "../query/nft"; import { collectionsDistribution } from "../query/collection" import { makeQuery, toSqlInParams } from "../utils"; -type previousNft = { +type PreviousNft = { nft_id: string, meta: string, rank: number, @@ -31,7 +31,7 @@ export class FlippingNFTsResolver { const nfts = result.map(item => item.nft_id) - const prevNFTs: [previousNft] = (await makeQuery( + const prevNFTs: [PreviousNft] = (await makeQuery( this.tx, NFTEntity, previousPriceQuery(toSqlInParams(nfts))))