@stake-dao/reader 0.4.53 → 0.4.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/esm/index.js +2 -1
  2. package/dist/esm/index.js.map +1 -1
  3. package/dist/esm/prices.js +7 -0
  4. package/dist/esm/prices.js.map +1 -1
  5. package/dist/esm/strategies/curve/fetch/index.js +3 -1
  6. package/dist/esm/strategies/curve/fetch/index.js.map +1 -1
  7. package/dist/esm/strategies/curve/points.js +8 -0
  8. package/dist/esm/strategies/curve/points.js.map +1 -0
  9. package/dist/esm/strategies/pendle/fetch.js +2 -1
  10. package/dist/esm/strategies/pendle/fetch.js.map +1 -1
  11. package/dist/esm/strategies/pendle/pendlePoints.js +1 -48
  12. package/dist/esm/strategies/pendle/pendlePoints.js.map +1 -1
  13. package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
  14. package/dist/esm/utils/snapshot.js +92 -0
  15. package/dist/esm/utils/snapshot.js.map +1 -0
  16. package/dist/esm/votemarket/curve/config.js +1 -0
  17. package/dist/esm/votemarket/curve/config.js.map +1 -1
  18. package/dist/esm/votemarket/curve/fetchSnapshotUserData.js +2 -2
  19. package/dist/esm/votemarket/curve/fetchSnapshotUserData.js.map +1 -1
  20. package/dist/esm/votemarket/curve/fetchUserVlCvxClaimable.js +9 -15
  21. package/dist/esm/votemarket/curve/fetchUserVlCvxClaimable.js.map +1 -1
  22. package/dist/types/index.d.ts +2 -1
  23. package/dist/types/index.d.ts.map +1 -1
  24. package/dist/types/prices.d.ts +1 -0
  25. package/dist/types/prices.d.ts.map +1 -1
  26. package/dist/types/strategies/curve/fetch/index.d.ts.map +1 -1
  27. package/dist/types/strategies/curve/points.d.ts +20 -0
  28. package/dist/types/strategies/curve/points.d.ts.map +1 -0
  29. package/dist/types/strategies/pendle/fetch.d.ts +1 -0
  30. package/dist/types/strategies/pendle/fetch.d.ts.map +1 -1
  31. package/dist/types/strategies/pendle/pendlePoints.d.ts +1 -57
  32. package/dist/types/strategies/pendle/pendlePoints.d.ts.map +1 -1
  33. package/dist/types/utils/snapshot.d.ts +8 -0
  34. package/dist/types/utils/snapshot.d.ts.map +1 -0
  35. package/dist/types/votemarket/curve/config.d.ts +1 -0
  36. package/dist/types/votemarket/curve/config.d.ts.map +1 -1
  37. package/dist/types/votemarket/curve/fetchUserVlCvxClaimable.d.ts.map +1 -1
  38. package/package.json +1 -2
  39. package/src/index.ts +2 -1
  40. package/src/prices.ts +8 -0
  41. package/src/strategies/curve/fetch/index.ts +3 -1
  42. package/src/strategies/curve/points.ts +8 -0
  43. package/src/strategies/pendle/fetch.ts +2 -1
  44. package/src/strategies/pendle/pendlePoints.ts +1 -48
  45. package/src/utils/snapshot.ts +116 -0
  46. package/src/votemarket/curve/config.ts +1 -0
  47. package/src/votemarket/curve/fetchSnapshotUserData.ts +3 -3
  48. package/src/votemarket/curve/fetchUserVlCvxClaimable.ts +12 -19
@@ -0,0 +1,116 @@
1
+ import { isAddress, zeroAddress } from 'viem'
2
+
3
+ interface Strategy {
4
+ name: string
5
+ network?: string
6
+ params: any
7
+ }
8
+
9
+ const DEFAULT_SCORE_API_URL = 'https://score.snapshot.org'
10
+
11
+ const NETWORKS = {
12
+ 1: { key: '1', name: 'Ethereum', start: 7929876 },
13
+ 10: { key: '10', name: 'Optimism', start: 657806 },
14
+ 56: { key: '56', name: 'BNB Smart Chain', start: 461230 },
15
+ 100: { key: '100', name: 'Gnosis Chain', start: 4108192 },
16
+ 137: { key: '137', name: 'Polygon PoS', start: 9834491 },
17
+ 146: { key: '146', name: 'Sonic', start: 60 },
18
+ 250: { key: '250', name: 'Fantom Opera', start: 2497732 },
19
+ 252: { key: '252', name: 'Fraxtal', start: 1 },
20
+ 324: { key: '324', name: 'zkSync Era', start: 3908235 },
21
+ 8453: { key: '8453', name: 'Base', start: 5022 },
22
+ 42161: { key: '42161', name: 'Arbitrum One', start: 256508 },
23
+ 42220: { key: '42220', name: 'Celo', start: 6599803 },
24
+ 43114: { key: '43114', name: 'Avalanche', start: 536483 },
25
+ 59144: { key: '59144', name: 'Linea', start: 42 },
26
+ 81457: { key: '81457', name: 'Blast', start: 88189 },
27
+ }
28
+
29
+ const inputError = (message: string) => Promise.reject(new Error(message))
30
+
31
+ function isValidNetwork(network: string) {
32
+ return !!NETWORKS[network]
33
+ }
34
+
35
+ function isValidAddress(address: string) {
36
+ return isAddress(address) && address !== zeroAddress
37
+ }
38
+
39
+ function isValidSnapshot(snapshot: number | string, network: string) {
40
+ return snapshot === 'latest' || (typeof snapshot === 'number' && snapshot >= NETWORKS[network].start)
41
+ }
42
+
43
+ const parseScoreAPIResponse = async (res: any) => {
44
+ let data: any = await res.text()
45
+
46
+ try {
47
+ data = JSON.parse(data)
48
+ } catch (_e: any) {
49
+ return Promise.reject({
50
+ code: res.status || 500,
51
+ message: 'Failed to parse response from score API',
52
+ data,
53
+ })
54
+ }
55
+
56
+ if (data.error) return Promise.reject(data.error)
57
+ return data
58
+ }
59
+
60
+ export const getSnapshotScores = async (
61
+ space: string,
62
+ strategies: Strategy[],
63
+ network: string,
64
+ addresses: string[],
65
+ snapshot: number | string = 'latest',
66
+ options: any = {},
67
+ ) => {
68
+ if (!Array.isArray(addresses)) {
69
+ return inputError('addresses should be an array of addresses')
70
+ }
71
+ if (addresses.length === 0) {
72
+ return inputError('addresses can not be empty')
73
+ }
74
+ const invalidAddress = addresses.find((address) => !isValidAddress(address))
75
+ if (invalidAddress) {
76
+ return inputError(`Invalid address: ${invalidAddress}`)
77
+ }
78
+ if (!isValidNetwork(network)) {
79
+ return inputError(`Invalid network: ${network}`)
80
+ }
81
+ const invalidStrategy = strategies.find((strategy) => strategy.network && !isValidNetwork(strategy.network))
82
+ if (invalidStrategy) {
83
+ return inputError(`Invalid network (${invalidStrategy.network}) in strategy ${invalidStrategy.name}`)
84
+ }
85
+ if (!isValidSnapshot(snapshot, network)) {
86
+ return inputError(
87
+ `Snapshot (${snapshot}) must be 'latest' or greater than network start block (${NETWORKS[network].start})`,
88
+ )
89
+ }
90
+
91
+ const url = `${DEFAULT_SCORE_API_URL}/api/scores`
92
+ const headers = { Accept: 'application/json', 'Content-Type': 'application/json' }
93
+
94
+ try {
95
+ const params = {
96
+ space,
97
+ network,
98
+ snapshot,
99
+ strategies,
100
+ addresses,
101
+ }
102
+ const res = await fetch(url, {
103
+ method: 'POST',
104
+ headers,
105
+ body: JSON.stringify({ params }),
106
+ })
107
+ const response = await parseScoreAPIResponse(res)
108
+
109
+ return options.returnValue === 'all' ? response.result : response.result[options.returnValue || 'scores']
110
+ } catch (e: any) {
111
+ if (e.errno) {
112
+ return Promise.reject({ code: e.errno, message: e.toString(), data: '' })
113
+ }
114
+ return Promise.reject(e)
115
+ }
116
+ }
@@ -6,6 +6,7 @@ export const GAUGES_METADATA_CHUNK_SIZE = {
6
6
  10: 10,
7
7
  100: 10,
8
8
  137: 10,
9
+ 146: 10,
9
10
  250: 10,
10
11
  252: 10,
11
12
  8453: 10,
@@ -1,8 +1,8 @@
1
- import snapshot from '@snapshot-labs/snapshot.js'
2
1
  import { gql } from 'graphql-request'
3
2
  import { isAddress } from 'viem'
4
3
  import { SNAPSHOT_HUB } from '../../endpoints.js'
5
4
  import { graphql } from '../../utils.js'
5
+ import { getSnapshotScores } from '../../utils/snapshot.js'
6
6
 
7
7
  interface SnapshotProposal {
8
8
  id: string
@@ -114,8 +114,8 @@ export const fetchSnapshotUserData = async (
114
114
  let vp = 0
115
115
  const userVotes = {}
116
116
  if (isAddress(userAddress)) {
117
- const fetchedVp = await (snapshot as any).utils.getScores(
118
- spaces[i],
117
+ const fetchedVp = await getSnapshotScores(
118
+ spaces[i]!,
119
119
  proposal.space.strategies,
120
120
  '1',
121
121
  [userAddress],
@@ -1,4 +1,4 @@
1
- import { ONE_WEEK, Zero, contract, tokenWithAddress } from '@stake-dao/constants'
1
+ import { Zero, contract, tokenWithAddress } from '@stake-dao/constants'
2
2
  import { type Address, formatUnits, parseAbi } from 'viem'
3
3
  import { mainnet } from 'viem/chains'
4
4
  import { GH_STAKE_DAO_BOUNTIES_REPORT } from '../../endpoints.js'
@@ -18,14 +18,14 @@ type UnknownToken = {
18
18
  chainId: number
19
19
  }
20
20
 
21
- const getMerkleData = async (epoch: number) => {
21
+ const getMerkleData = async () => {
22
22
  const [delegators, nonDelegators] = await Promise.all([
23
23
  fetch(
24
- `${GH_STAKE_DAO_BOUNTIES_REPORT}/refs/heads/main/bounties-reports/${epoch}/vlCVX/merkle_data_delegators.json`,
25
- ).then((res) => res.json()),
26
- fetch(
27
- `${GH_STAKE_DAO_BOUNTIES_REPORT}/refs/heads/main/bounties-reports/${epoch}/vlCVX/merkle_data_non_delegators.json`,
24
+ `${GH_STAKE_DAO_BOUNTIES_REPORT}/refs/heads/main/bounties-reports/latest/vlCVX/vlcvx_merkle_delegators.json`,
28
25
  ).then((res) => res.json()),
26
+ fetch(`${GH_STAKE_DAO_BOUNTIES_REPORT}/refs/heads/main/bounties-reports/latest/vlCVX/vlcvx_merkle.json`).then(
27
+ (res) => res.json(),
28
+ ),
29
29
  ])
30
30
 
31
31
  return { delegators, nonDelegators }
@@ -112,23 +112,16 @@ const getParsedData = (
112
112
  const ZERO_ROOT = '0x0000000000000000000000000000000000000000000000000000000000000000'
113
113
 
114
114
  export const fetchUserVlCvxClaimable = async (provider: any, rpc: Rpcs, user: string) => {
115
- const nowEpoch = Math.floor(Date.now() / 1000 / ONE_WEEK) * ONE_WEEK
116
- const prevEpoch = nowEpoch - ONE_WEEK
117
-
118
115
  const { delegatorRoot, nonDelegatorRoot } = await getMerkleRoots(provider)
119
116
 
120
117
  let vlCvxClaimable: any
121
118
 
122
- // Try current week, then previous week if needed
123
- for (const epoch of [nowEpoch, prevEpoch]) {
124
- try {
125
- const merkleData = await getMerkleData(epoch)
126
- if (validateMerkleRoots(delegatorRoot, nonDelegatorRoot, merkleData)) {
127
- vlCvxClaimable = merkleData
128
- break
129
- }
130
- } catch {}
131
- }
119
+ try {
120
+ const merkleData = await getMerkleData()
121
+ if (validateMerkleRoots(delegatorRoot, nonDelegatorRoot, merkleData)) {
122
+ vlCvxClaimable = merkleData
123
+ }
124
+ } catch {}
132
125
 
133
126
  if (!vlCvxClaimable) {
134
127
  throw new Error('Could not find valid merkle data')