forked from snapshot-labs/snapshot-strategies
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutils.ts
135 lines (126 loc) · 3.62 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import fetch from 'cross-fetch';
import { Interface } from '@ethersproject/abi';
import { Contract } from '@ethersproject/contracts';
import { jsonToGraphQLQuery } from 'json-to-graphql-query';
import _strategies from './strategies';
import Multicaller from './utils/multicaller';
import getProvider from './utils/provider';
import { getBlockNumber } from './utils/web3';
import gateways from './gateways.json';
import networks from './networks.json';
export const SNAPSHOT_SUBGRAPH_URL = {
'1': 'https://api.thegraph.com/subgraphs/name/snapshot-labs/snapshot',
'4': 'https://api.thegraph.com/subgraphs/name/snapshot-labs/snapshot-rinkeby',
'42': 'https://api.thegraph.com/subgraphs/name/snapshot-labs/snapshot-kovan'
};
export async function call(provider, abi: any[], call: any[], options?) {
const contract = new Contract(call[0], abi, provider);
try {
const params = call[2] || [];
return await contract[call[1]](...params, options || {});
} catch (e) {
return Promise.reject(e);
}
}
export async function multicall(
network: string,
provider,
abi: any[],
calls: any[],
options?
) {
const multicallAbi = [
'function aggregate(tuple(address target, bytes callData)[] calls) view returns (uint256 blockNumber, bytes[] returnData)'
];
const multi = new Contract(
networks[network].multicall,
multicallAbi,
provider
);
const itf = new Interface(abi);
try {
const [, res] = await multi.aggregate(
calls.map((call) => [
call[0].toLowerCase(),
itf.encodeFunctionData(call[1], call[2])
]),
options || {}
);
return res.map((call, i) => itf.decodeFunctionResult(calls[i][1], call));
} catch (e) {
return Promise.reject(e);
}
}
export async function subgraphRequest(url: string, query, options: any = {}) {
const res = await fetch(url, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...options?.headers
},
body: JSON.stringify({ query: jsonToGraphQLQuery({ query }) })
});
const { data } = await res.json();
return data || {};
}
export function getUrl(uri, gateway = gateways[0]) {
const ipfsGateway = `https://${gateway}`;
if (!uri) return null;
if (!uri.includes('ipfs') && !uri.includes('ipns') && !uri.includes('http'))
return `${ipfsGateway}/ipfs/${uri}`;
const uriScheme = uri.split('://')[0];
if (uriScheme === 'ipfs')
return uri.replace('ipfs://', `${ipfsGateway}/ipfs/`);
if (uriScheme === 'ipns')
return uri.replace('ipns://', `${ipfsGateway}/ipns/`);
return uri;
}
export async function ipfsGet(
gateway: string,
ipfsHash: string,
protocolType = 'ipfs'
) {
const url = `https://${gateway}/${protocolType}/${ipfsHash}`;
return fetch(url).then((res) => res.json());
}
export async function getScoresDirect(
space: string,
strategies: any[],
network: string,
provider,
addresses: string[],
snapshot: number | string = 'latest'
) {
try {
return await Promise.all(
strategies.map((strategy) =>
(snapshot !== 'latest' && strategy.params?.start > snapshot) ||
(strategy.params?.end &&
(snapshot === 'latest' || snapshot > strategy.params?.end)) ||
addresses.length === 0
? {}
: _strategies[strategy.name].strategy(
space,
network,
provider,
addresses,
strategy.params,
snapshot
)
)
);
} catch (e) {
return Promise.reject(e);
}
}
export default {
call,
multicall,
subgraphRequest,
ipfsGet,
getScoresDirect,
getProvider,
getBlockNumber,
Multicaller
};