GithubHelp home page GithubHelp logo

loligo's People

Contributors

matehoo avatar vikiival avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

matehoo

loligo's Issues

Introduce NSFW / lewd tag

We see a influx of porn ART on KodaDot

The task:
Introduce lewd boolean type into Collection / NFTs

read metadata of collection/item (attributes) and set the lewd attr accordingly.

The egde case:
It could happen that collection is not marked as nsfw but in reallity is.
so we must update the collection to lewd = true if at least one NFT is NSFW

Steps:

  • in schema introduce lewd attribute for both collection and NFT
  • in create/mint set it to false
  • check metadata if it does not contain lewd tag like this
  • Do PR to rubick, snek

definition of lewd attribute

Note: when you are minting new nft, and nft is lewd, updtate also collection to lewd

Fun:

video.mp4

Flip/Trade entity

To make some trading views easier the optional path is to make a Trade entity like following

type TradeEntity @entity {
  id: ID!
  nft: NFTEntity!
  createdAt: DateTime!
  closedAt: DateTime!
  initialPrice: BigInt!
  closingPrice: BigInt!
  realized: BigInt!
  percent: Int!
  profit: Boolean!
  issuer: String!
  buyer: String! 
}

May @daiagi can have more information since he was working on Flipper UI in Kodadot

Unify Schema across Squids

With #5 we should have unified schema across Squids

What that mean?

  • snek does not have Emotes - We will add it and will be always empty table
  • rubick does not have Offers - -||-

Distinct metadata of collection or nfts created after date

What I am currently missing in BAO is ability to logically fetch metadata of NFTs and Collections created under specific time. because we are running cron this time should be matched;

 SELECT DISTINCT metadata as id, image
 FROM nft_entity ne
 JOIN metadata_entity me on me.id = ne.meta_id
 WHERE ne.created_at >= NOW() - INTERVAL '$1';
 SELECT DISTINCT metadata as id, image
 FROM collection_entity ce
 JOIN metadata_entity me on me.id = ce.meta_id
 WHERE ce.created_at >= NOW() - INTERVAL '$1';

https://www.postgresql.org/docs/current/functions-datetime.html

let's say default interval should be 15 minutes

INTERVAL '15 minutes';

Listing entity

The current listing in events is nice but we need to extend NFT entity with listing

type Listing @entity {
  id: ID!
  nft: NFTEntity!
  collectionId: String!
  displayPrice: BigInt!
  royaltyAmount: BigInt!
  total: BigInt!
  updatedAt: DateTime!
  createdAt: DateTime!
}

Marketplace Metrics endpoint

As we want to gradually get listed here on these charts, we would need some kind of endpoint so we can get integrated to various dashboards

I think we need to show there Volume 1d & 7d, trades in 1d & 7d, TVL would be also nice.

I would split it by protocol, chain, NFT standard

https://defillama.com/nfts/marketplaces

Magiceden was ranking other places too back then, can't find it now, but they have at least this

image

Holding stats for NFT

Just a draft out of my head;

There should be a new Entity call Holding that tells us the stats about how each user holded the NFT.

type Holding @entity {
  id: ID!
  issuer: String!
  nft: NFTEntitity!
  obtainPrice: BigInt
  releasePrice: BigInt
  releasedTo: String!
  releasedVia: Interaction!
  obtainedAt: DateTime!
  releasedAt: DateTime!
  holdTime: BigInt! 
}

hold time Should be denominated in hours? or days?

ref:

Account/User entity

We are slowly getting to the tipping point where we need to replace user as String! with UserEntity

Would would it do?:

  • cache various metrics
  • calculating scores
  • Flips - what, price bought, price sold, date bought, date sold
    Users Activity -
    average sale ?
    Max sale
    Max flip

REF:

Add sequence to NFT

to NFTEntity add new field sequence that should be either BigInt or Int

type NFTEntity @entity {
sequence: BigInt! // or Int!
}

How to fill that?

Derive the number value from sn

sn = '00000000000008'
sequence = BigInt(sn)

Why

Because sorting based on SN is not correct (because sn is String)

Why Int or BigInt?

I am not sure how bigint would behave in sort (maybe check first some ordering via blockNumber if it's correctly sorted)

Have you considered any alternatives?

Yeah the other alternative is to remap sn into BigInt or Int but I am not sure what will we break on frontend

Implement available collections to mint for user

Currently we are using a really ugly hack on frontend to determine if user can mint in the collection.

        totalCount: ce.nfts?.filter((nft) => !nft.burned).length,
       }))
       .filter(
         (ce: MintedCollectionKusama) =>
           (ce.max || Infinity) - ce.alreadyMinted > 0
       )

The task:

Implement a resolver that would take address as parameter and returns a list of collections that could be used for minting

Display price

The stuff should be that instead of saving price as 1e12 I would save it as 1

that means

const price = Float(BigInt(interaction.value || '0') / BigInt(`1e${decimals}`))

THE Task:

  • extend schema with
displayPrice: bigint!

Value of the displayPrice should be:

price + 3% of price (marketplace fee) + n% of royalty (if supported by chain)

I added the package label because fee calculation should be done there ideally

How to calculate stuff can be found in nft-gallery under name somePercentFromTx.

Property Entity

Thing is that RMRK2, Ajuna, Statemine has ability to add on-chain attributes.

type Property @jsonField {
  key: String!
  value: String!
}

Stats of collection

Requirement

  • extends collectionEntitiesConnection resolver or provide a new resolver
  • input:
{
    offset
    limit
    where
    orderBy
}
  • output:
{
   volume:  xxx, // Total trading turnover
   highestSale: xxx, // Maximum selling price
   totalCount: xxx     // count of nfts in this colleciton
}

image

Add indexes to sort fields

Screenshot 2023-09-05 at 13 10 14

What to do?

for collection fields add index to:

Screenshot 2023-09-05 at 13 12 24
type CollectionEntity @entity {
  createdAt: DateTime!
  distribution: Int!
  floor: BigInt!
  updatedAt: DateTime!
  nftCount: Int!
  supply: Int!
  volume: BigInt!
}

On NFT Entity

type NFTEntity @entity {
  burned: Boolean!
  createdAt: DateTime!
  name: String @index
  price: BigInt
  updatedAt: DateTime!
}

Tasks:

Insight entity

Current series insight

type Series @entity {
  id: ID!
  issuer: String
  unique: Int!
  uniqueCollectors: Int!
  sold: Int! @index
  total: Int!
  averagePrice: Float
  floorPrice: BigInt
  highestSale: BigInt
  buys: Int
  volume: BigInt
  name: String! @index
  metadata: String
  image: String
  emoteCount: Int
}

we can offload to like Insight entity

Add missing fields to TokenEntities

blockNumber

add the block when the tokenEntity has been created

updatedAt

update the date when the tokenEntity's count (#50) or price (#52) has been changed

createdAt

add the date when the tokenEntity has been created

Optimize stats queries

While reviewing kodadot/nft-gallery#5120 I found query that was added in 5f64a482a0e7cdcdb92341d314fdc89ba3eaf86e

query collectionStatsById($id: String!) {
  stats: collectionEntityById(id: $id) {
    id
    base: nfts(where: { burned_eq: false }) {
      id
      currentOwner
      issuer
    }
    listed: nfts(where: { price_gt: "0" }) {
      id
      price
  	}
    sales: nfts(where: { events_some: { interaction_eq: BUY } }) {
      id
      events(where: { interaction_eq: BUY }) {
        id,
        meta
      }
    }
  }
}

The reason is that when we returns this big chunks of data on frontend it creates more workload on frontend (to map it and parse)

Collection attributes resolver

To be able to show properties in sidebar we need to write a resolver.
resolver needs return list of attributes.

SELECT me.attributes from token_entity
left join  metadata_entity me on token_entity.meta_id = me.id
where token_entity.collection_id = ${id};

Deliverables:
I want to see a resolver that takes collection id as parameter and returns a list of attributes

Ref:

Blocked by?

infura?

Do we still have access to infura_kodadot1?

Fetch mime-type of media

Task is to fetch mime-type in indexer for animation_url if present

import { obtainMimeType } from '@kodadot1/minipfs'

const type = await obtainMimeType(metadata.image)
const animationType = await obtainMimeType(metadata.animationUrl)

Hot Table resolver

query hotNfts(
  $orderBy: [EventOrderByInput!] = timestamp_DESC
  $gte: DateTime!
) {
  result: events(
    where: { interaction_eq: BUY, timestamp_gte: $gte }
    orderBy: $orderBy
  ) {
    timestamp
    interaction
    nft {
      collection {
        name
        id
      }
    }
    meta
  }
}

data we calculate

  const collectionMap = groupBy(data, 'nft.collection.id')
   const sortOrder = [...new Set(data.map((e) => e.nft.collection.id))]
   const result = sortOrder.map((colId, idx) => {
     const collection = collectionMap[colId][0].nft.collection
     const nfts = sortBy(collectionMap[colId], 'timestamp').reverse()
     const totalVolume = toKSM(getVolume(nfts))
     const buys = nfts.length
     const latestSale = nfts[0]
     const medianIdx = Math.floor(buys / 2)
     return {
       id: idx + 1,
       collectionId: colId,
       name: collection.name,
       totalVolume,
       buys,
       latestSoldSize: toKSM(latestSale.meta),
       latestSoldTime: formatDistanceToNow(new Date(latestSale.timestamp)),
       medianDate: formatDistanceToNow(new Date(nfts[medianIdx].timestamp)),
       nfts,
     }

Add transaction hash to the event entity

Is your feature request related to a problem?

Currently we do not store any data about transaction hash.
Thus it make sometimes hard to reference something important.

Describe the solution you would like

Store variable hash in the Event on every indexer

Describe alternatives you have considered

Extend unwrap function :)

Screeenshots

No response

Are there opened related issues?

Yes! it's blocker for kodadot/nft-gallery#3931

Allowlist resolver

This is a simple resolver that should return

  • Array<string> of unique addresses
  • return if owner is in collection

Available Event resolver

we should dynamically decide which events should be visible based on schema

query availableEventsByNftId($id: String) {
   list: eventList(id: $id) 
}

SQL for this would look like

SELECT DISTINCT e.interaction FROM event e WHERE e.nft_id = $1

Add cheapest to TokenEntity

We want to know the floor price of the TokenEntity
However the current floor on CollectionEntity is not correct

Therefore we will try different approach:

type TokenEntity @entity {
  cheapest: NFTEntity
}

as I think would be easier to update :)

Sold

type CollectionEntity @entity {
  sold: Int!
}

When nft is bought for the first time #35 it should increate the value

Increase / decrease function

function inc(value: number | undefined) {
  return (value || 0) + ONE
}

function dec(value: number) {
  return value - ONE
}

Add Token/Item entity

type TokenEntity @entity {
  id: ID!
  blockNumber: BigInt
  collection: CollectionEntity
  nfts: [NFTEntity!] @derivedFrom(field: "token")
  hash: String! @index
  image: String
  media: String
  name: String @index
  updatedAt: DateTime!
  createdAt: DateTime!
  count: Int!
}

The point of TokenEntity is to natively group by NFTs from same collection And same image under one entity with this we can do search, filter super easy. However this require to rapidly change schema
Id should be generated as md5(collection-cid) ?
Name would be either taken from collection of first NFT name stripped from #{number} or _{number}

Also we need to add

type NFTEntity @entity {
  token: TokenEntity!
}

UserTally (Stats)

type UserTally @entity {
  id: ID!
  blockNumber: BigInt
  updatedAt: DateTime!
  createdAt: DateTime!
  created: Int!
  minted: Int!
  burned: Int!
  flipped: BigInt!
  transfers: Int!
  collected: Int!  
}

if we want to do something historical:

type TallyEntity @entity {
  id: ID!
  count: Int!
  createdAt: DateTime!
}

Ref

Implement first usable index for the collection

Now to get the first index we do another magic

const nextId = Math.max(lastIndexUsed + 1, collectionAlreadyMinted + 1)

it would be nice to return the index that could be used for particular collection

could be also part of #1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.