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

Vik #2

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
30 changes: 5 additions & 25 deletions lib/api/api.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,12 @@
import { Marketplace } from "../marketplace";
import express from 'express'
import bodyParser from 'body-parser'
import { OrderFront } from "../types/common";
import { graphqlHTTP } from "express-graphql";
import { schema } from "./schema";
import { ApolloServer} from "apollo-server";


export async function start(marketplace: Marketplace) {

const app = express()
const jsonParser = bodyParser.json()

app.use(
"/graphql",
graphqlHTTP({
schema: schema(marketplace),
graphiql: true,
}));

app.post('/orders', jsonParser, async (req: any, res: any) => res.json(await marketplace.createOrder(OrderFront.fromJson(req.body))));
app.get('/orders', async (req: any, res: any) => res.json(await marketplace.getOrders()));
app.get('/orders/:orderId', async (req: any, res: any) => res.json(await marketplace.getOrder(req.params.orderId)));
app.get('/tokens', async (req: any, res: any) => res.json(await marketplace.getTokens()));
app.post('/asset/create', async (req: any, res: any) => res.set('Status Code', 202));


console.log("starting")
app.listen(8080);

const server = new ApolloServer({ schema: schema(marketplace) })
server.listen({port: 8080}).then(
() => { console.log("ready at 8080") }
).catch((err) => {console.log(err)});
}

96 changes: 77 additions & 19 deletions lib/api/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,32 @@ import {
GraphQLString
} from "graphql";

import {Order, TokensCollection} from "../types/mongo";
import {Order, TokensCollection, Tokens} from "../types/mongo";
import {OrderFront} from "../types/common";
import {Marketplace} from "../marketplace";
// import {util} from "prettier";
// import skip = util.skip;


export function schema(marketplace: Marketplace): GraphQLSchema {
const PageInfoType = new GraphQLObjectType({
name: "PageInfo",
fields: () => ({
hasNext: {type: GraphQLBoolean},
nextCursor: {type: GraphQLString}
})
});


const Page = (itemType: any, pageName: any) => {
return new GraphQLObjectType({
name: pageName,
fields: () => ({
results: {type: new GraphQLList(itemType)},
pageInfo: {type: PageInfoType}
})
});
}


const TokenOwnersType = new GraphQLScalarType({
Expand All @@ -37,13 +57,27 @@ export function schema(marketplace: Marketplace): GraphQLSchema {
})
});

const EventType = new GraphQLObjectType({
name: "Event",
fields: () => ({
from: {type: GraphQLString},
to: {type: GraphQLString},
quantity: {type: GraphQLInt},
timestamp: {type: GraphQLInt},
txHash: {type: GraphQLString},
})
});

const TokenType = new GraphQLObjectType({
name: "Token",
fields: () => ({
collectionObjectId: {type: GraphQLString},
tokenId: {type: GraphQLString},
metadata_uri: {type: GraphQLString},
metadata: {type: MetadataType},
last_update: {type: GraphQLInt},
owners: {type: TokenOwnersType},
events: {type: new GraphQLList(EventType)}
})
});

Expand All @@ -54,7 +88,6 @@ export function schema(marketplace: Marketplace): GraphQLSchema {
contractAddress: {type: GraphQLString},
tokenType: {type: GraphQLInt},
owner: {type: GraphQLString},
tokens: {type: new GraphQLList(TokenType),}
})
});

Expand Down Expand Up @@ -86,26 +119,51 @@ export function schema(marketplace: Marketplace): GraphQLSchema {
fields: () => ({
tokensCollection: {
type: new GraphQLList(TokensCollectionType),
resolve: () => {
resolve: async () => {
return TokensCollection
.find({tokenType: {$ne: null}})
.sort({'tokens.last_update': 1});
.find({tokenType: {$ne: null}})
.sort({'tokens.last_update': 1});
}
},

getTokens: {
type: Page(TokenType, "AllTokensPage"),
args: {
first: {type: GraphQLInt},
cursor: {type: GraphQLString }
},
resolve: async (_, args) => {
args.cursor = args.cursor === null ? undefined : args.cursor;

return Tokens
.find({})
.sort({last_update: -1})
.limit(args.first)
.paginate(args.cursor) // If IDE lights this as error - all ok
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// noinspection

}
},

getTokensByOwner: {
type: new GraphQLList(TokensCollectionType),
args: {owner: {type: GraphQLString}},
resolve: (_, args) => {
return TokensCollection.find({
tokenType: {$ne: null},
tokens: {$elemMatch: {[`owners.${args.owner}`]: {$gt: 0}}}
})
type: Page(TokenType, "TokensByOwnerPage"),
args: {
owner: {type: GraphQLString},
first: {type: GraphQLInt},
cursor: {type: GraphQLString }
},
resolve: async (_, args) => {
args.cursor = args.cursor === null ? undefined : args.cursor;

return Tokens
.find({[`owners.${args.owner}`]: {$gt: 0}})
.sort({last_update: -1})
.limit(args.first)
.paginate(args.cursor) // If IDE lights this as error - all ok
}
},

orders: {
type: new GraphQLList(OrderType),
resolve: () => {
resolve: async () => {
return Order.find({}).sort({createTime: 1})
}
},
Expand All @@ -116,15 +174,15 @@ export function schema(marketplace: Marketplace): GraphQLSchema {
contractAddress: {type: GraphQLString},
tokenId: {type: GraphQLString},
},
resolve: (_, args) => {
resolve: async (_, args) => {
const {contractAddress, tokenId} = args
const filter = {contractAddress, tokens: {tokenId}}
return Order
.find({$or: [
{left: {filter}},
{right: {filter}},
]})
.sort({createTime: 1})
.find({$or: [
{left: {filter}},
{right: {filter}},
]})
.sort({createTime: 1})
}
},

Expand Down
9 changes: 6 additions & 3 deletions lib/types/mongo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { model, Schema } from 'mongoose';
const paginationPlugin = require('@mother/mongoose-cursor-pagination')

// todo https://mongoosejs.com/docs/typescript.html

Expand Down Expand Up @@ -27,6 +28,8 @@ const TokenTransferEventSchema = new Schema({
}, { _id: false });

const TokenSchema = new Schema({
collectionObjectId: String,

tokenId: String,

metadata_uri: String,
Expand All @@ -35,15 +38,15 @@ const TokenSchema = new Schema({
last_update: Number,
owners: { type: Map, of: Number },
events: [TokenTransferEventSchema],
}, { _id: false })
}).plugin(paginationPlugin);

export const Tokens = model("Tokens", TokenSchema);

export const TokensCollection = model('TokensCollection', new Schema({
contractAddress: String,
tokenType: Number,
name: String,
owner: String,

tokens: [TokenSchema],
}));


Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@
},
"dependencies": {
"@gnosis.pm/safe-deployments": "^1.1.0",
"@mother/mongoose-cursor-pagination": "^0.0.5",
"@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"@openzeppelin/contracts": "^4.1.0",
"@pinata/sdk": "^1.1.23",
"@types/dotenv": "^8.2.0",
"@types/mongoose": "^5.11.97",
"apollo-server": "^3.5.0",
"dotenv": "^9.0.2",
"ethereum-waffle": "^3.2.0",
"ethers": "^5.5.1",
Expand Down
44 changes: 29 additions & 15 deletions test/utils/gen_fake_tokens.ts → scripts/gen_fake_tokens.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,42 @@
import {TokensCollection} from "../../lib/types/mongo";
import {TokensCollection, Tokens} from "../lib/types/mongo";
import {ethers} from "ethers";
import {zero} from "./utils";
import {TokenType} from "../../lib/types/common";
import {zero} from "../test/utils/utils";
import {TokenType} from "../lib/types/common";
import amongus from "mongoose";

amongus.connect('mongodb://root:example@localhost:27017/admin');

randomCollection()

generateFakeData();

function randomCollection() {
const tokens = [];
for (let i=0; i<10; i++)
tokens.push(randomToken())

function generateFakeData() {
let collectionObjId;
new TokensCollection({
contractAddress: randomAddress(),
tokenType: randomChoice([TokenType.ERC1155, TokenType.ERC721]),
owner: randomAddress(),
tokens: []
}).save().then((r:any) => console.log(r));
}).save().then((r:any) => {
collectionObjId = r._id
const tokens = [];
for (let i=0; i<5; i++)
tokens.push(randomToken(collectionObjId));
console.log(collectionObjId);

tokens.forEach(value => {
new Tokens(value).save().then((r:any) => {});
});
});
}


function randomToken() {
function randomToken(collectionObjId: any) {
const tokenId = randomFrom0To(1000).toString();
const quantity = randomFrom0To(100)
const addr = randomAddress()
const quantity = randomFrom0To(100);
const addr = randomAddress();

return {
collectionObjectId: collectionObjId,
tokenId: tokenId,
metadata_uri: `http://localhost/${tokenId}`,
metadata:
Expand Down Expand Up @@ -55,11 +65,15 @@ function randomToken() {
}
}

function toHex(d: any) {
return ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}
function randomAddress() {
return "0x" + ethers.utils.keccak256(randomFrom0To(100000).toString()).toString().slice(0, 40)
let st = `0x${toHex(randomFrom0To(100000))}`;
return ethers.utils.keccak256(st).toString().slice(0, 40)
}
function randomHash() {
return "0x" + ethers.utils.keccak256(randomFrom0To(100000).toString()).toString().slice(0, 64)
return ethers.utils.keccak256(`0x${toHex(randomFrom0To(100000))}`).toString().slice(0, 64)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    function randomAddress() {
      return randomHash().slice(0, 42)
    }
    function randomHash() {
      return ethers.utils.hashMessage(randomFrom0To(100000).toString())
    }

}
function randomChoice(items: any[]) {
return items[randomFrom0To(items.length)];
Expand Down