mirror of
https://github.com/cerc-io/watcher-ts
synced 2024-11-19 12:26: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",
|
||||
"dependencies": {
|
||||
"@types/lodash": "^4.14.168",
|
||||
"apollo-type-bigint": "^0.1.3",
|
||||
"express": "^4.17.1",
|
||||
"express-graphql": "^0.12.0",
|
||||
"graphql": "^15.5.0",
|
||||
|
@ -1,29 +1,100 @@
|
||||
type Author {
|
||||
id: Int!
|
||||
firstName: String
|
||||
lastName: String
|
||||
"""
|
||||
the list of Posts by this author
|
||||
"""
|
||||
posts: [Post]
|
||||
#
|
||||
# ERC20 GQL schema
|
||||
#
|
||||
|
||||
# Types
|
||||
|
||||
# Support uint256 values.
|
||||
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 {
|
||||
id: Int!
|
||||
title: String
|
||||
author: Author
|
||||
votes: Int
|
||||
# Result type, with proof, for uint256 method return values.
|
||||
type ResultUInt256 {
|
||||
value: BigInt!
|
||||
|
||||
# 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 {
|
||||
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 {
|
||||
upvotePost (
|
||||
postId: Int!
|
||||
): Post
|
||||
#
|
||||
# Subscriptions
|
||||
#
|
||||
type Subscription {
|
||||
|
||||
# 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 { find, filter } from 'lodash';
|
||||
import { makeExecutableSchema } from '@graphql-tools/schema';
|
||||
import BigInt from 'apollo-type-bigint';
|
||||
|
||||
import * as typeDefs from './erc20.graphql';
|
||||
import data from './mock-data';
|
||||
|
||||
const { posts, authors } = data;
|
||||
import { blocks } from './mock-data';
|
||||
|
||||
const resolvers = {
|
||||
Query: {
|
||||
posts: () => posts,
|
||||
author: (_, { id }) => find(authors, { id }),
|
||||
},
|
||||
BigInt: new BigInt('bigInt'),
|
||||
|
||||
Mutation: {
|
||||
upvotePost: (_, { postId }) => {
|
||||
const post = find(posts, { id: postId });
|
||||
if (!post) {
|
||||
throw new Error(`Couldn't find post with id ${postId}`);
|
||||
TokenEvent: {
|
||||
__resolveType: (obj) => {
|
||||
if (obj.owner) {
|
||||
return 'ApprovalEvent';
|
||||
}
|
||||
|
||||
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: {
|
||||
posts: author => filter(posts, { authorId: author.id }),
|
||||
},
|
||||
allowance: (_, { blockHash, token, owner, spender }) => {
|
||||
console.log('allowance', blockHash, token, owner, spender);
|
||||
|
||||
Post: {
|
||||
author: post => find(authors, { id: post.authorId }),
|
||||
},
|
||||
return {
|
||||
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({
|
||||
|
@ -1,17 +1,43 @@
|
||||
const authors = [
|
||||
{ id: 1, firstName: 'Tom', lastName: 'Coleman' },
|
||||
{ id: 2, firstName: 'Sashko', lastName: 'Stubailo' },
|
||||
{ id: 3, firstName: 'Mikhail', lastName: 'Novikov' },
|
||||
];
|
||||
// TODO: Pull mock data for 5 tokens from rinkeby.
|
||||
|
||||
const posts = [
|
||||
{ id: 1, authorId: 1, title: 'Introduction to GraphQL', votes: 2 },
|
||||
{ id: 2, authorId: 2, title: 'Welcome to Meteor', votes: 3 },
|
||||
{ id: 3, authorId: 2, title: 'Advanced GraphQL', votes: 1 },
|
||||
{ id: 4, authorId: 3, title: 'Launchpad is Cool', votes: 7 },
|
||||
];
|
||||
|
||||
export default {
|
||||
posts,
|
||||
authors
|
||||
export const tokens = {
|
||||
'0xd87fea54f506972e3267239ec8e159548892074a': {
|
||||
name: 'ChainLink Token',
|
||||
symbol: 'LINK',
|
||||
decimals: 18,
|
||||
totalSupply: '1000000'
|
||||
}
|
||||
};
|
||||
|
||||
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"
|
||||
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:
|
||||
version "14.1.3"
|
||||
resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-14.1.3.tgz#91f39011897bd08e99c0de0164e77ad2f3402247"
|
||||
|
Loading…
Reference in New Issue
Block a user