Skip to content

Commit

Permalink
Merge branch 'master' into feat-add-leaderboard
Browse files Browse the repository at this point in the history
  • Loading branch information
wa0x6e committed Jul 10, 2024
2 parents 84f8836 + 79564e8 commit 8e46846
Show file tree
Hide file tree
Showing 15 changed files with 144 additions and 43 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ NETWORK=testnet
HUB_DATABASE_URL=mysql://...
SEQ_DATABASE_URL=mysql://
SEQUENCER_URL=https://testnet.seq.snapshot.org
STAMP_URL=https://stamp.fyi
KEYCARD_URL=https://keycard.snapshot.org
KEYCARD_SECRET=
SCORE_API_URL=https://score.snapshot.org
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
},
"prettier": "@snapshot-labs/prettier-config",
"dependencies": {
"@ethersproject/address": "^5.7.0",
"@graphql-tools/schema": "^10.0.0",
"@snapshot-labs/keycard": "^0.5.1",
"@snapshot-labs/snapshot-metrics": "^1.4.1",
"@snapshot-labs/snapshot-sentry": "^1.5.5",
"@snapshot-labs/snapshot.js": "^0.11.17",
"@snapshot-labs/snapshot.js": "^0.11.38",
"bluebird": "^3.7.2",
"connection-string": "^1.0.1",
"cors": "^2.8.5",
Expand All @@ -39,6 +40,7 @@
"graphql-query-count-limit": "^1.0.0",
"lodash": "^4.17.21",
"mysql": "^2.18.1",
"node-fetch": "2",
"rate-limit-redis": "^3.1.0",
"redis": "^4.6.8",
"ts-node": "^10.9.1",
Expand All @@ -55,7 +57,6 @@
"eslint": "^8.28.0",
"jest": "^29.6.1",
"jest-environment-node-single-context": "^29.1.0",
"node-fetch": "^2.7",
"nodemon": "^2.0.19",
"prettier": "^3.0.3",
"start-server-and-test": "^2.0.0",
Expand Down
68 changes: 68 additions & 0 deletions src/graphql/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { getAddress } from '@ethersproject/address';
import graphqlFields from 'graphql-fields';
import fetch from 'node-fetch';
import { jsonParse } from '../helpers/utils';
import { spacesMetadata } from '../helpers/spaces';
import db from '../helpers/mysql';
Expand All @@ -25,6 +27,15 @@ const ARG_LIMITS = {
}
};

export function formatAddress(address: string): string {
try {
return getAddress(address);
} catch (error) {
// return same address for now, but return error in the future, if address is not EVM or sn address
return address;
}
}

export function checkLimits(args: any = {}, type) {
const { where = {} } = args;
const typeLimits = { ...ARG_LIMITS.default, ...(ARG_LIMITS[type] || {}) };
Expand Down Expand Up @@ -116,7 +127,23 @@ export function formatSpace({
export function buildWhereQuery(fields, alias, where) {
let query: any = '';
const params: any[] = [];

Object.entries(fields).forEach(([field, type]) => {
if (type === 'EVMAddress') {
const conditions = ['', '_not', '_in', '_not_in'];
try {
conditions.forEach(condition => {
const key = `${field}${condition}`;
if (where[key]) {
where[key] = condition.includes('in')
? where[key].map(formatAddress)
: formatAddress(where[key]);
}
});
} catch (e) {
throw new PublicError(`Invalid ${field} address`);
}
}
if (where[field] !== undefined) {
query += `AND ${alias}.${field} = ? `;
params.push(where[field]);
Expand Down Expand Up @@ -178,6 +205,15 @@ export async function fetchSpaces(args) {
const { first = 20, skip = 0, where = {} } = args;

const fields = { id: 'string', created: 'number' };

if ('controller' in where) {
if (!where.controller) return [];

where.id_in = await getControllerDomains(where.controller);

delete where.controller;
}

const whereQuery = buildWhereQuery(fields, 's', where);
let queryStr = whereQuery.query;
const params: any[] = whereQuery.params;
Expand Down Expand Up @@ -375,3 +411,35 @@ export function formatSubscription(subscription) {
});
return subscription;
}

async function getControllerDomains(address: string): Promise<string[]> {
type JsonRpcResponse = {
result: string[];
error?: {
code: number;
message: string;
data: any;
};
};

try {
const response = await fetch(process.env.STAMP_URL ?? 'https://stamp.fyi', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
method: 'lookup_domains',
params: address
})
});
const { result, error } = (await response.json()) as JsonRpcResponse;

if (error) throw new PublicError("Failed to resolve controller's domains");

return result;
} catch (e) {
throw new PublicError("Failed to resolve controller's domains");
}
}
4 changes: 2 additions & 2 deletions src/graphql/operations/aliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export default async function (parent, args) {
const fields = {
id: 'string',
ipfs: 'string',
address: 'string',
alias: 'string',
address: 'EVMAddress',
alias: 'EVMAddress',
created: 'number'
};
const whereQuery = buildWhereQuery(fields, 'a', where);
Expand Down
13 changes: 6 additions & 7 deletions src/graphql/operations/follows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ export default async function (parent, args) {
const fields = {
id: 'string',
ipfs: 'string',
follower: 'string',
follower: 'EVMAddress',
space: 'string',
network: 'string',
created: 'number'
};
const whereQuery = buildWhereQuery(fields, 'f', where);
const queryStr = whereQuery.query;
const params: any[] = whereQuery.params;
const params = whereQuery.params.concat(skip, first);

let orderBy = args.orderBy || 'created';
let orderDirection = args.orderDirection || 'desc';
Expand All @@ -34,15 +35,13 @@ export default async function (parent, args) {
spaces.turbo as spaceTurbo,
spaces.hibernated as spaceHibernated
FROM follows f
INNER JOIN spaces ON spaces.id = f.space
WHERE spaces.settings IS NOT NULL ${queryStr}
LEFT JOIN spaces ON spaces.id = f.space
WHERE 1=1 ${queryStr}
ORDER BY ${orderBy} ${orderDirection} LIMIT ?, ?
`;
params.push(skip, first);

let follows: any[] = [];
try {
follows = await db.queryAsync(query, params);
const follows = await db.queryAsync(query, params);
return follows.map(follow => formatFollow(follow));
} catch (e: any) {
log.error(`[graphql] follows, ${JSON.stringify(e)}`);
Expand Down
2 changes: 1 addition & 1 deletion src/graphql/operations/proposals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default async function (parent, args) {
id: 'string',
ipfs: 'string',
space: 'string',
author: 'string',
author: 'EVMAddress',
network: 'string',
created: 'number',
updated: 'number',
Expand Down
6 changes: 3 additions & 3 deletions src/graphql/operations/ranking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export default async function (_parent, args, context, info) {
strategy = '',
plugin = ''
} = where;
const searchStr = search.toLowerCase();
let searchCategory = category.toLowerCase();
const searchStr = search?.toLowerCase() || '';
let searchCategory = category?.toLowerCase() || '';
if (searchCategory === 'all') searchCategory = '';

let filteredSpaces = rankedSpaces.filter((space: any) => {
Expand Down Expand Up @@ -74,7 +74,7 @@ export default async function (_parent, args, context, info) {
filteredSpaces.slice(skip, skip + first),
(space: any) => space.id
);
if (!filteredSpaces.length) return { spaces: [], metrics };
if (!filteredSpaces.length) return { items: [], metrics };

const query = `
SELECT s.* FROM spaces s WHERE s.deleted = 0
Expand Down
2 changes: 1 addition & 1 deletion src/graphql/operations/statements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default async function (parent, args) {
ipfs: 'string',
space: 'string',
created: 'number',
delegate: 'string'
delegate: 'EVMAddress'
};
const whereQuery = buildWhereQuery(fields, 's', where);
const queryStr = whereQuery.query;
Expand Down
2 changes: 1 addition & 1 deletion src/graphql/operations/subscriptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default async function (parent, args) {
const fields = {
id: 'string',
ipfs: 'string',
address: 'string',
address: 'EVMAddress',
space: 'string',
created: 'number'
};
Expand Down
4 changes: 2 additions & 2 deletions src/graphql/operations/user.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import db from '../../helpers/mysql';
import { formatUser } from '../helpers';
import { formatAddress, formatUser } from '../helpers';
import log from '../../helpers/log';
import { capture } from '@snapshot-labs/snapshot-sentry';

export default async function (parent, args) {
const id = args.id;
const id = formatAddress(args.id);
const query = `
SELECT
u.*,
Expand Down
2 changes: 1 addition & 1 deletion src/graphql/operations/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default async function (parent, args) {
checkLimits(args, 'users');

const fields = {
id: 'string',
id: 'EVMAddress',
ipfs: 'string',
created: 'number'
};
Expand Down
2 changes: 1 addition & 1 deletion src/graphql/operations/votes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ async function query(parent, args, context?, info?) {
id: 'string',
ipfs: 'string',
space: 'string',
voter: 'string',
voter: 'EVMAddress',
proposal: 'string',
reason: 'string',
app: 'string',
Expand Down
14 changes: 12 additions & 2 deletions src/graphql/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,10 @@ input SpaceWhere {
created_lte: Int
strategy: String
plugin: String
controller: String
}

input RankingWhere {
id: String
id_in: [String]
search: String
category: String
network: String
Expand Down Expand Up @@ -288,6 +287,8 @@ input FollowWhere {
follower_in: [String]
space: String
space_in: [String]
network: String
network_in: [String]
created: Int
created_in: [Int]
created_gt: Int
Expand Down Expand Up @@ -551,6 +552,7 @@ type Follow {
ipfs: String
follower: String!
space: Space!
network: String!
created: Int!
}

Expand All @@ -568,6 +570,11 @@ type User {
name: String
about: String
avatar: String
cover: String
github: String
twitter: String
lens: String
farcaster: String
created: Int!
votesCount: Int
proposalsCount: Int
Expand All @@ -578,9 +585,12 @@ type Statement {
id: String!
ipfs: String!
space: String!
network: String
about: String
delegate: String
statement: String
discourse: String
status: String
created: Int!
updated: Int!
}
Expand Down
Loading

0 comments on commit 8e46846

Please sign in to comment.