mirror of
https://github.com/cerc-io/watcher-ts
synced 2024-11-19 20:36:19 +00:00
Schema, mock data and resolvers.
This commit is contained in:
parent
2b4e1ba315
commit
7133b3ab86
@ -19,6 +19,7 @@
|
|||||||
"homepage": "https://github.com/vulcanize/erc20-watcher#readme",
|
"homepage": "https://github.com/vulcanize/erc20-watcher#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/lodash": "^4.14.168",
|
"@types/lodash": "^4.14.168",
|
||||||
|
"apollo-type-bigint": "^0.1.3",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-graphql": "^0.12.0",
|
"express-graphql": "^0.12.0",
|
||||||
"graphql": "^15.5.0",
|
"graphql": "^15.5.0",
|
||||||
|
@ -1,29 +1,100 @@
|
|||||||
type Author {
|
#
|
||||||
id: Int!
|
# ERC20 GQL schema
|
||||||
firstName: String
|
#
|
||||||
lastName: String
|
|
||||||
"""
|
# Types
|
||||||
the list of Posts by this author
|
|
||||||
"""
|
# Support uint256 values.
|
||||||
posts: [Post]
|
scalar BigInt
|
||||||
|
|
||||||
|
# Proof for returned data. Serialized blob for now.
|
||||||
|
# Will be converted into a well defined structure later.
|
||||||
|
type Proof {
|
||||||
|
data: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Post {
|
# Result type, with proof, for uint256 method return values.
|
||||||
id: Int!
|
type ResultUInt256 {
|
||||||
title: String
|
value: BigInt!
|
||||||
author: Author
|
|
||||||
votes: Int
|
# Proof from state/storage trie.
|
||||||
|
proof: Proof
|
||||||
}
|
}
|
||||||
|
|
||||||
# the schema allows the following query:
|
# ERC20 Token https://eips.ethereum.org/EIPS/eip-20
|
||||||
|
# ABI: https://ethereumdev.io/abi-for-erc20-contract-on-ethereum/
|
||||||
|
type Token {
|
||||||
|
name: String!
|
||||||
|
symbol: String!
|
||||||
|
decimals: Int!
|
||||||
|
totalSupply: BigInt!
|
||||||
|
}
|
||||||
|
|
||||||
|
# Transfer Event
|
||||||
|
# Emitted by: `function transfer(address _to, uint256 _value) public returns (bool success)`
|
||||||
|
# Emitted by: `function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)`
|
||||||
|
type TransferEvent {
|
||||||
|
from: String!
|
||||||
|
to: String!
|
||||||
|
value: BigInt!
|
||||||
|
}
|
||||||
|
|
||||||
|
# Approval Event
|
||||||
|
# Emittted by: `function approve(address _spender, uint256 _value) public returns (bool success)`
|
||||||
|
type ApprovalEvent {
|
||||||
|
owner: String!
|
||||||
|
spender: String!
|
||||||
|
value: BigInt!
|
||||||
|
}
|
||||||
|
|
||||||
|
# All possible event types fired by an ERC20 contract.
|
||||||
|
union TokenEvent = TransferEvent | ApprovalEvent
|
||||||
|
|
||||||
|
# Result type, with proof, for event return values.
|
||||||
|
type ResultEvent {
|
||||||
|
event: TokenEvent!
|
||||||
|
|
||||||
|
# Proof from receipts trie.
|
||||||
|
proof: Proof
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Queries
|
||||||
|
#
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
posts: [Post]
|
|
||||||
author(id: Int!): Author
|
# `function balanceOf(address _owner) public view returns (uint256 balance)`
|
||||||
|
balanceOf(
|
||||||
|
blockHash: String!
|
||||||
|
token: String!
|
||||||
|
|
||||||
|
owner: String!
|
||||||
|
): ResultUInt256!
|
||||||
|
|
||||||
|
# `function allowance(address _owner, address _spender) public view returns (uint256 remaining)`
|
||||||
|
allowance(
|
||||||
|
blockHash: String!
|
||||||
|
token: String!
|
||||||
|
|
||||||
|
owner: String!
|
||||||
|
spender: String!
|
||||||
|
): ResultUInt256!
|
||||||
|
|
||||||
|
# Get token events at a certain block, optionally filter by event name.
|
||||||
|
events(
|
||||||
|
blockHash: String!
|
||||||
|
token: String!
|
||||||
|
name: String
|
||||||
|
): [ResultEvent!]
|
||||||
}
|
}
|
||||||
|
|
||||||
# this schema allows the following mutation:
|
#
|
||||||
type Mutation {
|
# Subscriptions
|
||||||
upvotePost (
|
#
|
||||||
postId: Int!
|
type Subscription {
|
||||||
): Post
|
|
||||||
|
# Watch for token events (at head of chain).
|
||||||
|
onTokenEvent(token: String!): ResultEvent!
|
||||||
}
|
}
|
||||||
|
59
src/gql.ts
59
src/gql.ts
@ -1,36 +1,51 @@
|
|||||||
|
import 'lodash';
|
||||||
import 'graphql-import-node';
|
import 'graphql-import-node';
|
||||||
import { find, filter } from 'lodash';
|
|
||||||
import { makeExecutableSchema } from '@graphql-tools/schema';
|
import { makeExecutableSchema } from '@graphql-tools/schema';
|
||||||
|
import BigInt from 'apollo-type-bigint';
|
||||||
|
|
||||||
import * as typeDefs from './erc20.graphql';
|
import * as typeDefs from './erc20.graphql';
|
||||||
import data from './mock-data';
|
import { blocks } from './mock-data';
|
||||||
|
|
||||||
const { posts, authors } = data;
|
|
||||||
|
|
||||||
const resolvers = {
|
const resolvers = {
|
||||||
Query: {
|
BigInt: new BigInt('bigInt'),
|
||||||
posts: () => posts,
|
|
||||||
author: (_, { id }) => find(authors, { id }),
|
|
||||||
},
|
|
||||||
|
|
||||||
Mutation: {
|
TokenEvent: {
|
||||||
upvotePost: (_, { postId }) => {
|
__resolveType: (obj) => {
|
||||||
const post = find(posts, { id: postId });
|
if (obj.owner) {
|
||||||
if (!post) {
|
return 'ApprovalEvent';
|
||||||
throw new Error(`Couldn't find post with id ${postId}`);
|
}
|
||||||
|
|
||||||
|
return 'TransferEvent';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
Query: {
|
||||||
|
|
||||||
|
balanceOf: (_, { blockHash, token, owner }) => {
|
||||||
|
console.log('balanceOf', blockHash, token, owner);
|
||||||
|
|
||||||
|
return {
|
||||||
|
value: blocks[blockHash][token].balanceOf[owner],
|
||||||
|
proof: { data: '' }
|
||||||
}
|
}
|
||||||
post.votes += 1;
|
|
||||||
return post;
|
|
||||||
},
|
},
|
||||||
},
|
|
||||||
|
|
||||||
Author: {
|
allowance: (_, { blockHash, token, owner, spender }) => {
|
||||||
posts: author => filter(posts, { authorId: author.id }),
|
console.log('allowance', blockHash, token, owner, spender);
|
||||||
},
|
|
||||||
|
|
||||||
Post: {
|
return {
|
||||||
author: post => find(authors, { id: post.authorId }),
|
value: blocks[blockHash][token].allowance[owner][spender],
|
||||||
},
|
proof: { data: '' }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
events: (_, { blockHash, token, name }) => {
|
||||||
|
console.log('events', blockHash, token, name);
|
||||||
|
return blocks[blockHash][token].events
|
||||||
|
.filter(e => !name || name === e.name)
|
||||||
|
.map(e => ({ 'event': e }));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const schema = makeExecutableSchema({
|
export const schema = makeExecutableSchema({
|
||||||
|
@ -1,17 +1,43 @@
|
|||||||
const authors = [
|
// TODO: Pull mock data for 5 tokens from rinkeby.
|
||||||
{ id: 1, firstName: 'Tom', lastName: 'Coleman' },
|
|
||||||
{ id: 2, firstName: 'Sashko', lastName: 'Stubailo' },
|
|
||||||
{ id: 3, firstName: 'Mikhail', lastName: 'Novikov' },
|
|
||||||
];
|
|
||||||
|
|
||||||
const posts = [
|
export const tokens = {
|
||||||
{ id: 1, authorId: 1, title: 'Introduction to GraphQL', votes: 2 },
|
'0xd87fea54f506972e3267239ec8e159548892074a': {
|
||||||
{ id: 2, authorId: 2, title: 'Welcome to Meteor', votes: 3 },
|
name: 'ChainLink Token',
|
||||||
{ id: 3, authorId: 2, title: 'Advanced GraphQL', votes: 1 },
|
symbol: 'LINK',
|
||||||
{ id: 4, authorId: 3, title: 'Launchpad is Cool', votes: 7 },
|
decimals: 18,
|
||||||
];
|
totalSupply: '1000000'
|
||||||
|
}
|
||||||
export default {
|
};
|
||||||
posts,
|
|
||||||
authors
|
export const blocks = {
|
||||||
|
// Block hash.
|
||||||
|
'0x77b5479a5856dd8ec63df6aabf9ce0913071a6dda3a3d54f3c9c940574bcb8ab': {
|
||||||
|
|
||||||
|
// ERC20 token address.
|
||||||
|
'0xd87fea54f506972e3267239ec8e159548892074a': {
|
||||||
|
balanceOf: {
|
||||||
|
'0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc': 10000,
|
||||||
|
'0xCA6D29232D1435D8198E3E5302495417dD073d61': 500
|
||||||
|
},
|
||||||
|
allowance: {
|
||||||
|
'0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc': {
|
||||||
|
'0xCA6D29232D1435D8198E3E5302495417dD073d61': 100
|
||||||
|
}
|
||||||
|
},
|
||||||
|
events: [
|
||||||
|
{
|
||||||
|
name: 'Transfer',
|
||||||
|
from: '0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc',
|
||||||
|
to: '0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||||
|
value: 500
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Approval',
|
||||||
|
owner: '0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc',
|
||||||
|
spender: '0xCA6D29232D1435D8198E3E5302495417dD073d61',
|
||||||
|
value: 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -943,6 +943,11 @@ anymatch@~3.1.1:
|
|||||||
normalize-path "^3.0.0"
|
normalize-path "^3.0.0"
|
||||||
picomatch "^2.0.4"
|
picomatch "^2.0.4"
|
||||||
|
|
||||||
|
apollo-type-bigint@^0.1.3:
|
||||||
|
version "0.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/apollo-type-bigint/-/apollo-type-bigint-0.1.3.tgz#9242115ca909b9467ba5c4bc6493a56a06984c0b"
|
||||||
|
integrity sha512-nyfwEWRZ+kon3Nnot20DufGm2EHZrkJoryYzw3soD+USdxhkcW434w1c/n+mjMLQDl86Z6EvlkvMX5Lordf2Wg==
|
||||||
|
|
||||||
apollo-upload-client@14.1.3:
|
apollo-upload-client@14.1.3:
|
||||||
version "14.1.3"
|
version "14.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-14.1.3.tgz#91f39011897bd08e99c0de0164e77ad2f3402247"
|
resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-14.1.3.tgz#91f39011897bd08e99c0de0164e77ad2f3402247"
|
||||||
|
Loading…
Reference in New Issue
Block a user