@net-protocol/score 0.1.0

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.
package/dist/react.js ADDED
@@ -0,0 +1,296 @@
1
+ 'use strict';
2
+
3
+ var wagmi = require('wagmi');
4
+ var react = require('react');
5
+ var viem = require('viem');
6
+ var storage = require('@net-protocol/storage');
7
+
8
+ // src/hooks/useUpvotes.ts
9
+
10
+ // src/abis/upvote-app.json
11
+ var upvote_app_default = [
12
+ { type: "constructor", inputs: [], stateMutability: "nonpayable" },
13
+ {
14
+ type: "function",
15
+ name: "CORE_CONTRACT",
16
+ inputs: [],
17
+ outputs: [
18
+ { name: "", type: "address", internalType: "contract Score" }
19
+ ],
20
+ stateMutability: "view"
21
+ },
22
+ {
23
+ type: "function",
24
+ name: "LEGACY_CONTRACT",
25
+ inputs: [],
26
+ outputs: [
27
+ {
28
+ name: "",
29
+ type: "address",
30
+ internalType: "contract ILegacyUpvoteContract"
31
+ }
32
+ ],
33
+ stateMutability: "view"
34
+ },
35
+ {
36
+ type: "function",
37
+ name: "getUpvotesWithLegacy",
38
+ inputs: [
39
+ {
40
+ name: "upvoteKeys",
41
+ type: "bytes32[]",
42
+ internalType: "bytes32[]"
43
+ },
44
+ {
45
+ name: "strategies",
46
+ type: "address[]",
47
+ internalType: "address[]"
48
+ }
49
+ ],
50
+ outputs: [
51
+ { name: "counts", type: "uint256[]", internalType: "uint256[]" }
52
+ ],
53
+ stateMutability: "view"
54
+ },
55
+ {
56
+ type: "function",
57
+ name: "name",
58
+ inputs: [],
59
+ outputs: [{ name: "", type: "string", internalType: "string" }],
60
+ stateMutability: "pure"
61
+ },
62
+ {
63
+ type: "function",
64
+ name: "owner",
65
+ inputs: [],
66
+ outputs: [{ name: "", type: "address", internalType: "address" }],
67
+ stateMutability: "view"
68
+ },
69
+ {
70
+ type: "function",
71
+ name: "renounceOwnership",
72
+ inputs: [],
73
+ outputs: [],
74
+ stateMutability: "nonpayable"
75
+ },
76
+ {
77
+ type: "function",
78
+ name: "transferOwnership",
79
+ inputs: [
80
+ { name: "newOwner", type: "address", internalType: "address" }
81
+ ],
82
+ outputs: [],
83
+ stateMutability: "nonpayable"
84
+ },
85
+ {
86
+ type: "function",
87
+ name: "upvote",
88
+ inputs: [
89
+ {
90
+ name: "strategy",
91
+ type: "address",
92
+ internalType: "contract IScoreStrategy"
93
+ },
94
+ { name: "scoreKey", type: "bytes32", internalType: "bytes32" },
95
+ { name: "scoreDelta", type: "uint256", internalType: "uint256" },
96
+ {
97
+ name: "scoreStoredContext",
98
+ type: "bytes",
99
+ internalType: "bytes"
100
+ },
101
+ {
102
+ name: "scoreUnstoredContext",
103
+ type: "bytes",
104
+ internalType: "bytes"
105
+ }
106
+ ],
107
+ outputs: [],
108
+ stateMutability: "payable"
109
+ },
110
+ {
111
+ type: "function",
112
+ name: "withdrawETH",
113
+ inputs: [{ name: "to", type: "address", internalType: "address" }],
114
+ outputs: [],
115
+ stateMutability: "nonpayable"
116
+ },
117
+ {
118
+ type: "function",
119
+ name: "withdrawErc20",
120
+ inputs: [
121
+ { name: "to", type: "address", internalType: "address" },
122
+ { name: "token", type: "address", internalType: "address" },
123
+ { name: "amount", type: "uint256", internalType: "uint256" }
124
+ ],
125
+ outputs: [],
126
+ stateMutability: "nonpayable"
127
+ },
128
+ {
129
+ type: "event",
130
+ name: "OwnershipTransferred",
131
+ inputs: [
132
+ {
133
+ name: "previousOwner",
134
+ type: "address",
135
+ indexed: true,
136
+ internalType: "address"
137
+ },
138
+ {
139
+ name: "newOwner",
140
+ type: "address",
141
+ indexed: true,
142
+ internalType: "address"
143
+ }
144
+ ],
145
+ anonymous: false
146
+ },
147
+ {
148
+ type: "error",
149
+ name: "OwnableInvalidOwner",
150
+ inputs: [
151
+ { name: "owner", type: "address", internalType: "address" }
152
+ ]
153
+ },
154
+ {
155
+ type: "error",
156
+ name: "OwnableUnauthorizedAccount",
157
+ inputs: [
158
+ { name: "account", type: "address", internalType: "address" }
159
+ ]
160
+ },
161
+ { type: "error", name: "WithdrawFailed", inputs: [] }
162
+ ];
163
+
164
+ // src/constants.ts
165
+ var UPVOTE_APP = {
166
+ address: "0x00000001f0b8173316a016a5067ad74e8cea47bf",
167
+ abi: upvote_app_default
168
+ };
169
+ var PURE_ALPHA_STRATEGY = {
170
+ address: "0x00000001b1bcdeddeafd5296aaf4f3f3e21ae876"};
171
+ var UNIV234_POOLS_STRATEGY = {
172
+ address: "0x000000063f84e07a3e7a7ee578b42704ee6d22c9"};
173
+ var DYNAMIC_SPLIT_STRATEGY = {
174
+ address: "0x0000000869160f0b2a213adefb46a7ea7e62ac7a"};
175
+ var ALL_STRATEGY_ADDRESSES = [
176
+ UNIV234_POOLS_STRATEGY.address,
177
+ PURE_ALPHA_STRATEGY.address,
178
+ DYNAMIC_SPLIT_STRATEGY.address
179
+ ];
180
+
181
+ // src/hooks/useUpvotes.ts
182
+ function useUpvotes({
183
+ chainId,
184
+ scoreKey,
185
+ strategies = ALL_STRATEGY_ADDRESSES,
186
+ enabled = true
187
+ }) {
188
+ const { data, isLoading, error, refetch } = wagmi.useReadContract({
189
+ address: UPVOTE_APP.address,
190
+ abi: UPVOTE_APP.abi,
191
+ functionName: "getUpvotesWithLegacy",
192
+ args: [[scoreKey], strategies],
193
+ chainId,
194
+ query: { enabled }
195
+ });
196
+ return {
197
+ upvotes: Array.isArray(data) && data.length > 0 ? Number(data[0]) : 0,
198
+ isLoading,
199
+ error,
200
+ refetch
201
+ };
202
+ }
203
+ var encodeUpvoteKey = (tokenAddress) => {
204
+ return `0x${BigInt(`0x${tokenAddress.slice(2)}`).toString(16).padStart(64, "0")}`;
205
+ };
206
+
207
+ // src/utils/scoreKeyUtils.ts
208
+ var getTokenScoreKey = (tokenAddress) => {
209
+ return encodeUpvoteKey(tokenAddress);
210
+ };
211
+ var getStorageScoreKey = (operatorAddress, storageKey) => {
212
+ const bytes32Key = storage.getStorageKeyBytes(storageKey);
213
+ return viem.keccak256(
214
+ viem.encodePacked(
215
+ ["bytes32", "address"],
216
+ [bytes32Key, operatorAddress]
217
+ )
218
+ );
219
+ };
220
+ var getFeedContentKey = (message) => {
221
+ return viem.keccak256(
222
+ viem.encodePacked(
223
+ ["address", "string", "address", "uint256", "string", "bytes"],
224
+ [
225
+ message.app,
226
+ message.topic,
227
+ message.sender,
228
+ message.timestamp,
229
+ message.text,
230
+ message.data
231
+ ]
232
+ )
233
+ );
234
+ };
235
+ var getScoreKey = (item) => {
236
+ switch (item.type) {
237
+ case "token":
238
+ return getTokenScoreKey(item.tokenAddress);
239
+ case "storage":
240
+ return getStorageScoreKey(item.operatorAddress, item.storageKey);
241
+ case "feed": {
242
+ const contentKey = getFeedContentKey(item.message);
243
+ return getStorageScoreKey(
244
+ item.message.sender,
245
+ contentKey
246
+ );
247
+ }
248
+ }
249
+ };
250
+
251
+ // src/hooks/useUpvotesBatch.ts
252
+ function useUpvotesBatch({
253
+ chainId,
254
+ items,
255
+ strategies = ALL_STRATEGY_ADDRESSES,
256
+ enabled = true
257
+ }) {
258
+ const scoreKeys = react.useMemo(
259
+ () => items.map((item) => getScoreKey(item)),
260
+ [items]
261
+ );
262
+ const { data, isLoading, error, refetch } = wagmi.useReadContract({
263
+ address: UPVOTE_APP.address,
264
+ abi: UPVOTE_APP.abi,
265
+ functionName: "getUpvotesWithLegacy",
266
+ args: [scoreKeys, strategies],
267
+ chainId,
268
+ query: { enabled: enabled && scoreKeys.length > 0 }
269
+ });
270
+ return {
271
+ upvoteCounts: Array.isArray(data) ? data.map(Number) : [],
272
+ isLoading,
273
+ error,
274
+ refetch
275
+ };
276
+ }
277
+ function useTokenUpvotes({
278
+ chainId,
279
+ tokenAddress,
280
+ enabled = true
281
+ }) {
282
+ const scoreKey = react.useMemo(
283
+ () => getTokenScoreKey(tokenAddress),
284
+ [tokenAddress]
285
+ );
286
+ return useUpvotes({ chainId, scoreKey, enabled });
287
+ }
288
+
289
+ exports.getScoreKey = getScoreKey;
290
+ exports.getStorageScoreKey = getStorageScoreKey;
291
+ exports.getTokenScoreKey = getTokenScoreKey;
292
+ exports.useTokenUpvotes = useTokenUpvotes;
293
+ exports.useUpvotes = useUpvotes;
294
+ exports.useUpvotesBatch = useUpvotesBatch;
295
+ //# sourceMappingURL=react.js.map
296
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/abis/upvote-app.json","../src/constants.ts","../src/hooks/useUpvotes.ts","../src/utils/strategyUtils.ts","../src/utils/scoreKeyUtils.ts","../src/hooks/useUpvotesBatch.ts","../src/hooks/useTokenUpvotes.ts"],"names":["useReadContract","getStorageKeyBytes","keccak256","encodePacked","useMemo"],"mappings":"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","file":"react.js","sourcesContent":["[\n { \"type\": \"constructor\", \"inputs\": [], \"stateMutability\": \"nonpayable\" },\n {\n \"type\": \"function\",\n \"name\": \"CORE_CONTRACT\",\n \"inputs\": [],\n \"outputs\": [\n { \"name\": \"\", \"type\": \"address\", \"internalType\": \"contract Score\" }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"LEGACY_CONTRACT\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contract ILegacyUpvoteContract\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getUpvotesWithLegacy\",\n \"inputs\": [\n {\n \"name\": \"upvoteKeys\",\n \"type\": \"bytes32[]\",\n \"internalType\": \"bytes32[]\"\n },\n {\n \"name\": \"strategies\",\n \"type\": \"address[]\",\n \"internalType\": \"address[]\"\n }\n ],\n \"outputs\": [\n { \"name\": \"counts\", \"type\": \"uint256[]\", \"internalType\": \"uint256[]\" }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"name\",\n \"inputs\": [],\n \"outputs\": [{ \"name\": \"\", \"type\": \"string\", \"internalType\": \"string\" }],\n \"stateMutability\": \"pure\"\n },\n {\n \"type\": \"function\",\n \"name\": \"owner\",\n \"inputs\": [],\n \"outputs\": [{ \"name\": \"\", \"type\": \"address\", \"internalType\": \"address\" }],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"renounceOwnership\",\n \"inputs\": [],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"transferOwnership\",\n \"inputs\": [\n { \"name\": \"newOwner\", \"type\": \"address\", \"internalType\": \"address\" }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"upvote\",\n \"inputs\": [\n {\n \"name\": \"strategy\",\n \"type\": \"address\",\n \"internalType\": \"contract IScoreStrategy\"\n },\n { \"name\": \"scoreKey\", \"type\": \"bytes32\", \"internalType\": \"bytes32\" },\n { \"name\": \"scoreDelta\", \"type\": \"uint256\", \"internalType\": \"uint256\" },\n {\n \"name\": \"scoreStoredContext\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"scoreUnstoredContext\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"payable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"withdrawETH\",\n \"inputs\": [{ \"name\": \"to\", \"type\": \"address\", \"internalType\": \"address\" }],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"withdrawErc20\",\n \"inputs\": [\n { \"name\": \"to\", \"type\": \"address\", \"internalType\": \"address\" },\n { \"name\": \"token\", \"type\": \"address\", \"internalType\": \"address\" },\n { \"name\": \"amount\", \"type\": \"uint256\", \"internalType\": \"uint256\" }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"event\",\n \"name\": \"OwnershipTransferred\",\n \"inputs\": [\n {\n \"name\": \"previousOwner\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"newOwner\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"error\",\n \"name\": \"OwnableInvalidOwner\",\n \"inputs\": [\n { \"name\": \"owner\", \"type\": \"address\", \"internalType\": \"address\" }\n ]\n },\n {\n \"type\": \"error\",\n \"name\": \"OwnableUnauthorizedAccount\",\n \"inputs\": [\n { \"name\": \"account\", \"type\": \"address\", \"internalType\": \"address\" }\n ]\n },\n { \"type\": \"error\", \"name\": \"WithdrawFailed\", \"inputs\": [] }\n]\n","import type { Abi, Address } from \"viem\";\nimport scoreAbi from \"./abis/score.json\";\nimport upvoteAppAbi from \"./abis/upvote-app.json\";\nimport upvoteStorageAppAbi from \"./abis/upvote-storage-app.json\";\nimport pureAlphaStrategyAbi from \"./abis/pure-alpha-strategy.json\";\nimport univ234PoolsStrategyAbi from \"./abis/univ234-pools-strategy.json\";\nimport dynamicSplitStrategyAbi from \"./abis/dynamic-split-strategy.json\";\n\n// Score core contract (v2 strategy)\nexport const SCORE_CONTRACT = {\n address: \"0x0000000fa09b022e5616e5a173b4b67fa2fbcf28\" as Address,\n abi: scoreAbi as Abi,\n} as const;\n\n// UpvoteApp contract\nexport const UPVOTE_APP = {\n address: \"0x00000001f0b8173316a016a5067ad74e8cea47bf\" as Address,\n abi: upvoteAppAbi as Abi,\n} as const;\n\n// UpvoteStorageApp contract\nexport const UPVOTE_STORAGE_APP = {\n address: \"0x000000060CEB69D023227DF64CfB75eC37c75B62\" as Address,\n abi: upvoteStorageAppAbi as Abi,\n} as const;\n\n// UpvotePureAlphaStrategy contract\nexport const PURE_ALPHA_STRATEGY = {\n address: \"0x00000001b1bcdeddeafd5296aaf4f3f3e21ae876\" as Address,\n abi: pureAlphaStrategyAbi as Abi,\n} as const;\n\n// UpvoteUniv234PoolsStrategy (handles Uniswap V2, V3, V4 pools)\nexport const UNIV234_POOLS_STRATEGY = {\n address: \"0x000000063f84e07a3e7a7ee578b42704ee6d22c9\" as Address,\n abi: univ234PoolsStrategyAbi as Abi,\n} as const;\n\n// UpvoteDynamicSplitUniv234PoolsStrategy (configurable token/alpha split for Uni V2/V3/V4 pools)\nexport const DYNAMIC_SPLIT_STRATEGY = {\n address: \"0x0000000869160f0b2a213adefb46a7ea7e62ac7a\" as Address,\n abi: dynamicSplitStrategyAbi as Abi,\n} as const;\n\n// All strategy addresses for batch queries\nexport const ALL_STRATEGY_ADDRESSES: Address[] = [\n UNIV234_POOLS_STRATEGY.address,\n PURE_ALPHA_STRATEGY.address,\n DYNAMIC_SPLIT_STRATEGY.address,\n];\n\n// Legacy upvote contract addresses (v1 and v2, before Score system)\nexport const LEGACY_UPVOTE_V1_ADDRESS =\n \"0x0ada882dbbdc12388a1f9ca85d2d847088f747df\" as Address;\n\nexport const LEGACY_UPVOTE_V2_ADDRESS =\n \"0x9027dcad0a3dca5835895e14fbc022a1e5ea909b\" as Address;\n\n// Chains where the Score system is deployed\nexport const SUPPORTED_SCORE_CHAINS = [8453] as const;\n","import { useReadContract } from \"wagmi\";\nimport { UPVOTE_APP, ALL_STRATEGY_ADDRESSES } from \"../constants\";\nimport type { UseUpvotesOptions } from \"../types\";\n\n/**\n * React hook for fetching the upvote count for a single score key.\n * Uses UpvoteApp.getUpvotesWithLegacy, which aggregates across legacy contracts and strategies.\n *\n * @param options - Upvote query options\n * @param options.chainId - Chain ID to query\n * @param options.scoreKey - The bytes32 score key to look up\n * @param options.strategies - Strategy addresses to include (default: all strategies)\n * @param options.enabled - Whether the query is enabled (default: true)\n * @returns Object with upvotes count, isLoading, error, and refetch\n *\n * @example\n * ```tsx\n * const { upvotes, isLoading } = useUpvotes({\n * chainId: 8453,\n * scoreKey: getTokenScoreKey(tokenAddress),\n * });\n * ```\n */\nexport function useUpvotes({\n chainId,\n scoreKey,\n strategies = ALL_STRATEGY_ADDRESSES,\n enabled = true,\n}: UseUpvotesOptions) {\n const { data, isLoading, error, refetch } = useReadContract({\n address: UPVOTE_APP.address,\n abi: UPVOTE_APP.abi,\n functionName: \"getUpvotesWithLegacy\",\n args: [[scoreKey], strategies],\n chainId,\n query: { enabled },\n });\n\n return {\n upvotes: Array.isArray(data) && data.length > 0 ? Number(data[0]) : 0,\n isLoading,\n error,\n refetch,\n };\n}\n","import { decodeAbiParameters, type Address } from \"viem\";\nimport {\n PURE_ALPHA_STRATEGY,\n UNIV234_POOLS_STRATEGY,\n DYNAMIC_SPLIT_STRATEGY,\n} from \"../constants\";\nimport type {\n PureAlphaMetadata,\n PoolStrategyMetadata,\n DecodedStrategyMetadata,\n PoolKey,\n} from \"../types\";\n\n/**\n * Convert token address to bytes32 upvote key.\n */\nexport const encodeUpvoteKey = (tokenAddress: string): `0x${string}` => {\n return `0x${BigInt(`0x${tokenAddress.slice(2)}`)\n .toString(16)\n .padStart(64, \"0\")}`;\n};\n\n/**\n * Convert token address to upvote key string format.\n * Strips leading zeros to match Solidity's Strings.toHexString(uint256(scoreKey)).\n */\nexport function tokenAddressToUpvoteKeyString(tokenAddress: string): string {\n const lower = tokenAddress.toLowerCase();\n const withoutPrefix = lower.slice(2);\n const stripped = withoutPrefix.replace(/^0+/, \"\") || \"0\";\n return \"0x\" + stripped;\n}\n\n/**\n * Check if a topic string represents a strategy message.\n */\nexport function isStrategyMessage(topic: string): boolean {\n return topic.startsWith(\"s\") && topic.length > 43;\n}\n\n/**\n * Check if a topic string represents a user upvote message.\n */\nexport function isUserUpvoteMessage(topic: string): boolean {\n return topic.startsWith(\"t\");\n}\n\n/**\n * Extracts strategy address from topic string.\n * Handles both new format and legacy format.\n */\nexport function extractStrategyAddress(topic: string): string {\n try {\n if (topic.startsWith(\"t\")) {\n return topic.slice(1);\n }\n\n if (topic.startsWith(\"s\")) {\n return topic.slice(1, 43);\n }\n\n if (topic.startsWith(\"t-\")) {\n return topic.slice(2);\n }\n\n const parts = topic.split(\"-\");\n if (parts.length >= 2) {\n return parts[0];\n }\n\n return \"\";\n } catch {\n return \"\";\n }\n}\n\nexport function isPureAlphaStrategy(strategyAddress: string): boolean {\n return (\n strategyAddress.toLowerCase() ===\n PURE_ALPHA_STRATEGY.address.toLowerCase()\n );\n}\n\nexport function isUniv234PoolsStrategy(strategyAddress: string): boolean {\n return (\n strategyAddress.toLowerCase() ===\n UNIV234_POOLS_STRATEGY.address.toLowerCase()\n );\n}\n\nexport function isDynamicSplitStrategy(strategyAddress: string): boolean {\n return (\n strategyAddress.toLowerCase() ===\n DYNAMIC_SPLIT_STRATEGY.address.toLowerCase()\n );\n}\n\n/**\n * Decode strategy-specific metadata from ABI-encoded bytes.\n */\nexport const decodeStrategyMetadata = (\n metadata: `0x${string}`,\n strategyAddress: string\n): DecodedStrategyMetadata => {\n try {\n if (isPureAlphaStrategy(strategyAddress)) {\n const [alphaAmount, alphaWethPrice, wethUsdcPrice, userAlphaBalance] =\n decodeAbiParameters(\n [\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n ],\n metadata\n );\n return {\n alphaAmount,\n alphaWethPrice,\n wethUsdcPrice,\n userAlphaBalance,\n } as PureAlphaMetadata;\n } else if (\n isUniv234PoolsStrategy(strategyAddress) ||\n isDynamicSplitStrategy(strategyAddress)\n ) {\n const [\n tokenAmount,\n tokenWethPrice,\n wethUsdcPrice,\n alphaWethPrice,\n userTokenBalance,\n ] = decodeAbiParameters(\n [\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n ],\n metadata\n );\n return {\n tokenAmount,\n tokenWethPrice,\n wethUsdcPrice,\n alphaWethPrice,\n userTokenBalance,\n } as PoolStrategyMetadata;\n } else {\n return null;\n }\n } catch {\n return null;\n }\n};\n\n/**\n * Decode the full Score storage blob.\n */\nexport const decodeUpvoteStorageBlob = (value: `0x${string}`) => {\n try {\n const [\n scoreKey,\n scoreDelta,\n originalSender,\n appAddress,\n strategyAddress,\n timestamp,\n scoreStoredContext,\n scoreUnstoredContext,\n metadata,\n ] = decodeAbiParameters(\n [\n { type: \"bytes32\" },\n { type: \"int256\" },\n { type: \"address\" },\n { type: \"address\" },\n { type: \"address\" },\n { type: \"uint256\" },\n { type: \"bytes\" },\n { type: \"bytes\" },\n { type: \"bytes\" },\n ],\n value\n );\n\n const decodedMetadata = decodeStrategyMetadata(\n metadata as `0x${string}`,\n strategyAddress as string\n );\n\n return {\n scoreKey: scoreKey as `0x${string}`,\n scoreDelta: Number(scoreDelta),\n originalSender: originalSender as Address,\n appAddress: appAddress as Address,\n strategyAddress: strategyAddress as Address,\n timestamp: Number(timestamp),\n scoreStoredContext: scoreStoredContext as `0x${string}`,\n scoreUnstoredContext: scoreUnstoredContext as `0x${string}`,\n decodedMetadata,\n };\n } catch {\n return null;\n }\n};\n\n/**\n * Select the appropriate strategy based on pool key validity.\n * Returns PURE_ALPHA if no valid pool key; DYNAMIC_SPLIT otherwise.\n */\nexport const selectStrategy = (poolKey?: PoolKey | null): Address => {\n if (!poolKey || !isValidPoolKey(poolKey)) {\n return PURE_ALPHA_STRATEGY.address;\n }\n return DYNAMIC_SPLIT_STRATEGY.address;\n};\n\nfunction isValidPoolKey(poolKey: PoolKey): boolean {\n return (\n poolKey.fee !== undefined ||\n poolKey.tickSpacing !== undefined ||\n poolKey.currency0 !== undefined\n );\n}\n\n/**\n * Decode an upvote message from Net protocol into a consistent format.\n * Handles both legacy and strategy message formats.\n */\nexport function decodeUpvoteMessage(msg: {\n topic: string;\n data: `0x${string}`;\n text: string;\n}) {\n try {\n if (msg.topic === \"t\") {\n if (!msg.data || msg.data === \"0x\" || msg.data.length < 32) {\n return null;\n }\n\n try {\n const [\n numUpvotesDecoded,\n tokenWethPrice,\n wethUsdcPrice,\n alphaWethPrice,\n userTokenBalance,\n ] = decodeAbiParameters(\n [\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n ],\n msg.data\n );\n\n return {\n scoreDelta: Number(numUpvotesDecoded),\n tokenWethPrice: Number(tokenWethPrice),\n wethUsdcPrice: Number(wethUsdcPrice),\n alphaWethPrice: Number(alphaWethPrice),\n userTokenBalance: Number(userTokenBalance),\n tokenAddress: msg.text,\n messageType: \"legacy\" as const,\n };\n } catch {\n return null;\n }\n } else if (\n (msg.topic.startsWith(\"0x\") && msg.topic.length === 42) ||\n msg.topic.startsWith(\"p-\")\n ) {\n const [\n numUpvotesDecoded,\n tokenWethPrice,\n wethUsdcPrice,\n alphaWethPrice,\n userTokenBalance,\n ] = decodeAbiParameters(\n [\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n ],\n msg.data\n );\n\n return {\n scoreDelta: Number(numUpvotesDecoded),\n tokenWethPrice: Number(tokenWethPrice),\n wethUsdcPrice: Number(wethUsdcPrice),\n alphaWethPrice: Number(alphaWethPrice),\n userTokenBalance: Number(userTokenBalance),\n tokenAddress: msg.topic,\n messageType: \"legacy\" as const,\n };\n } else if (msg.topic.startsWith(\"app-\") && msg.topic.endsWith(\"-first\")) {\n const topicParts = msg.topic.split(\"-\");\n\n if (topicParts.length === 3) {\n // \"app-{addr}-first\"\n return {\n appAddress: topicParts[1],\n messageType: \"app-first\" as const,\n };\n } else if (topicParts.length === 5 && topicParts[2] === \"strategy\") {\n // \"app-{addr}-strategy-{strat}-first\"\n return {\n appAddress: topicParts[1],\n strategyAddress: topicParts[3],\n messageType: \"app-strategy-first\" as const,\n };\n } else if (topicParts.length === 5 && topicParts[2] === \"user\") {\n // \"app-{addr}-user-{user}-first\"\n return {\n appAddress: topicParts[1],\n userAddress: topicParts[3],\n tokenAddress: msg.text,\n messageType: \"app-user-first\" as const,\n };\n } else if (\n topicParts.length === 7 &&\n topicParts[2] === \"strategy\" &&\n topicParts[4] === \"user\"\n ) {\n // \"app-{addr}-strategy-{strat}-user-{user}-first\"\n return {\n appAddress: topicParts[1],\n strategyAddress: topicParts[3],\n userAddress: topicParts[5],\n tokenAddress: msg.text,\n messageType: \"app-strategy-user-first\" as const,\n };\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n","import {\n type Address,\n encodeAbiParameters,\n keccak256,\n encodePacked,\n getAddress,\n} from \"viem\";\nimport { getStorageKeyBytes } from \"@net-protocol/storage\";\nimport { encodeUpvoteKey } from \"./strategyUtils\";\nimport type { ScoreItem, FeedMessage } from \"../types\";\n\n/**\n * Generate score key for token upvotes.\n * Pads the token address into a bytes32 value.\n */\nexport const getTokenScoreKey = (tokenAddress: string): `0x${string}` => {\n return encodeUpvoteKey(tokenAddress);\n};\n\n/**\n * Generate score key for storage upvotes.\n * keccak256(encodePacked(storageKeyBytes32, operatorAddress))\n */\nexport const getStorageScoreKey = (\n operatorAddress: string,\n storageKey: string\n): `0x${string}` => {\n const bytes32Key = getStorageKeyBytes(storageKey) as `0x${string}`;\n return keccak256(\n encodePacked(\n [\"bytes32\", \"address\"],\n [bytes32Key, operatorAddress as Address]\n )\n );\n};\n\n/**\n * Generate content-based key for feed posts.\n * Uses all message content to create a unique identifier that's\n * independent of query filter (works regardless of how messages are fetched).\n *\n * Two messages with identical content will share the same key (and upvotes),\n * which is semantically correct - they are the same content.\n */\nexport const getFeedContentKey = (message: FeedMessage): `0x${string}` => {\n return keccak256(\n encodePacked(\n [\"address\", \"string\", \"address\", \"uint256\", \"string\", \"bytes\"],\n [\n message.app,\n message.topic,\n message.sender,\n message.timestamp,\n message.text,\n message.data,\n ]\n )\n );\n};\n\n/**\n * Get score key for any ScoreItem type.\n */\nexport const getScoreKey = (item: ScoreItem): `0x${string}` => {\n switch (item.type) {\n case \"token\":\n return getTokenScoreKey(item.tokenAddress);\n case \"storage\":\n return getStorageScoreKey(item.operatorAddress, item.storageKey);\n case \"feed\": {\n const contentKey = getFeedContentKey(item.message);\n return getStorageScoreKey(\n item.message.sender,\n contentKey\n );\n }\n }\n};\n\n/**\n * Check if a score key represents a token upvote (zero-padded address)\n * vs a hash-based key (storage/feed).\n */\nexport const isTokenScoreKey = (scoreKey: string): boolean => {\n return scoreKey.startsWith(\"0x000000000000000000000000\");\n};\n\n/**\n * Extract and validate token address from a token score key.\n * Returns the checksummed address or null if invalid.\n */\nexport const extractTokenAddressFromScoreKey = (\n scoreKey: string\n): string | null => {\n if (!isTokenScoreKey(scoreKey)) {\n return null;\n }\n\n const tokenAddress = `0x${scoreKey.slice(26)}`;\n\n if (tokenAddress.startsWith(\"0x\") && tokenAddress.length === 42) {\n try {\n return getAddress(tokenAddress);\n } catch {\n return null;\n }\n }\n\n return null;\n};\n\n/**\n * Generate upvote stored context for storage upvotes.\n * ABI-encodes (bytes32 storageKeyBytes, address operatorAddress).\n */\nexport const getStorageUpvoteContext = (\n operatorAddress: string,\n storageKey: string\n): `0x${string}` => {\n const bytes32Key = getStorageKeyBytes(storageKey) as `0x${string}`;\n return encodeAbiParameters(\n [{ type: \"bytes32\" }, { type: \"address\" }],\n [bytes32Key, operatorAddress as Address]\n );\n};\n","import { useMemo } from \"react\";\nimport { useReadContract } from \"wagmi\";\nimport { UPVOTE_APP, ALL_STRATEGY_ADDRESSES } from \"../constants\";\nimport { getScoreKey } from \"../utils/scoreKeyUtils\";\nimport type { UseUpvotesBatchOptions } from \"../types\";\n\n/**\n * React hook for fetching upvote counts for multiple ScoreItems in a single contract call.\n * Uses UpvoteApp.getUpvotesWithLegacy with batched score keys.\n *\n * @param options - Batch upvote query options\n * @param options.chainId - Chain ID to query\n * @param options.items - Array of ScoreItems (token, storage, or feed) to get counts for\n * @param options.strategies - Strategy addresses to include (default: all strategies)\n * @param options.enabled - Whether the query is enabled (default: true)\n * @returns Object with upvoteCounts array, isLoading, error, and refetch\n *\n * @example\n * ```tsx\n * const { upvoteCounts, isLoading } = useUpvotesBatch({\n * chainId: 8453,\n * items: [\n * { type: \"token\", tokenAddress: \"0x...\" },\n * { type: \"storage\", operatorAddress: \"0x...\", storageKey: \"my-key\" },\n * ],\n * });\n * ```\n */\nexport function useUpvotesBatch({\n chainId,\n items,\n strategies = ALL_STRATEGY_ADDRESSES,\n enabled = true,\n}: UseUpvotesBatchOptions) {\n const scoreKeys = useMemo(\n () => items.map((item) => getScoreKey(item)),\n [items]\n );\n\n const { data, isLoading, error, refetch } = useReadContract({\n address: UPVOTE_APP.address,\n abi: UPVOTE_APP.abi,\n functionName: \"getUpvotesWithLegacy\",\n args: [scoreKeys, strategies],\n chainId,\n query: { enabled: enabled && scoreKeys.length > 0 },\n });\n\n return {\n upvoteCounts: Array.isArray(data) ? (data as bigint[]).map(Number) : [],\n isLoading,\n error,\n refetch,\n };\n}\n","import { useMemo } from \"react\";\nimport { useUpvotes } from \"./useUpvotes\";\nimport { getTokenScoreKey } from \"../utils/scoreKeyUtils\";\nimport type { UseTokenUpvotesOptions } from \"../types\";\n\n/**\n * Convenience React hook for fetching upvotes for a single token address.\n * Wraps useUpvotes with automatic token score key generation.\n *\n * @param options - Token upvote query options\n * @param options.chainId - Chain ID to query\n * @param options.tokenAddress - The token contract address\n * @param options.enabled - Whether the query is enabled (default: true)\n * @returns Object with upvotes count, isLoading, error, and refetch\n *\n * @example\n * ```tsx\n * const { upvotes, isLoading } = useTokenUpvotes({\n * chainId: 8453,\n * tokenAddress: \"0x...\",\n * });\n * ```\n */\nexport function useTokenUpvotes({\n chainId,\n tokenAddress,\n enabled = true,\n}: UseTokenUpvotesOptions) {\n const scoreKey = useMemo(\n () => getTokenScoreKey(tokenAddress),\n [tokenAddress]\n );\n\n return useUpvotes({ chainId, scoreKey, enabled });\n}\n"]}
package/dist/react.mjs ADDED
@@ -0,0 +1,289 @@
1
+ import { useReadContract } from 'wagmi';
2
+ import { useMemo } from 'react';
3
+ import { keccak256, encodePacked } from 'viem';
4
+ import { getStorageKeyBytes } from '@net-protocol/storage';
5
+
6
+ // src/hooks/useUpvotes.ts
7
+
8
+ // src/abis/upvote-app.json
9
+ var upvote_app_default = [
10
+ { type: "constructor", inputs: [], stateMutability: "nonpayable" },
11
+ {
12
+ type: "function",
13
+ name: "CORE_CONTRACT",
14
+ inputs: [],
15
+ outputs: [
16
+ { name: "", type: "address", internalType: "contract Score" }
17
+ ],
18
+ stateMutability: "view"
19
+ },
20
+ {
21
+ type: "function",
22
+ name: "LEGACY_CONTRACT",
23
+ inputs: [],
24
+ outputs: [
25
+ {
26
+ name: "",
27
+ type: "address",
28
+ internalType: "contract ILegacyUpvoteContract"
29
+ }
30
+ ],
31
+ stateMutability: "view"
32
+ },
33
+ {
34
+ type: "function",
35
+ name: "getUpvotesWithLegacy",
36
+ inputs: [
37
+ {
38
+ name: "upvoteKeys",
39
+ type: "bytes32[]",
40
+ internalType: "bytes32[]"
41
+ },
42
+ {
43
+ name: "strategies",
44
+ type: "address[]",
45
+ internalType: "address[]"
46
+ }
47
+ ],
48
+ outputs: [
49
+ { name: "counts", type: "uint256[]", internalType: "uint256[]" }
50
+ ],
51
+ stateMutability: "view"
52
+ },
53
+ {
54
+ type: "function",
55
+ name: "name",
56
+ inputs: [],
57
+ outputs: [{ name: "", type: "string", internalType: "string" }],
58
+ stateMutability: "pure"
59
+ },
60
+ {
61
+ type: "function",
62
+ name: "owner",
63
+ inputs: [],
64
+ outputs: [{ name: "", type: "address", internalType: "address" }],
65
+ stateMutability: "view"
66
+ },
67
+ {
68
+ type: "function",
69
+ name: "renounceOwnership",
70
+ inputs: [],
71
+ outputs: [],
72
+ stateMutability: "nonpayable"
73
+ },
74
+ {
75
+ type: "function",
76
+ name: "transferOwnership",
77
+ inputs: [
78
+ { name: "newOwner", type: "address", internalType: "address" }
79
+ ],
80
+ outputs: [],
81
+ stateMutability: "nonpayable"
82
+ },
83
+ {
84
+ type: "function",
85
+ name: "upvote",
86
+ inputs: [
87
+ {
88
+ name: "strategy",
89
+ type: "address",
90
+ internalType: "contract IScoreStrategy"
91
+ },
92
+ { name: "scoreKey", type: "bytes32", internalType: "bytes32" },
93
+ { name: "scoreDelta", type: "uint256", internalType: "uint256" },
94
+ {
95
+ name: "scoreStoredContext",
96
+ type: "bytes",
97
+ internalType: "bytes"
98
+ },
99
+ {
100
+ name: "scoreUnstoredContext",
101
+ type: "bytes",
102
+ internalType: "bytes"
103
+ }
104
+ ],
105
+ outputs: [],
106
+ stateMutability: "payable"
107
+ },
108
+ {
109
+ type: "function",
110
+ name: "withdrawETH",
111
+ inputs: [{ name: "to", type: "address", internalType: "address" }],
112
+ outputs: [],
113
+ stateMutability: "nonpayable"
114
+ },
115
+ {
116
+ type: "function",
117
+ name: "withdrawErc20",
118
+ inputs: [
119
+ { name: "to", type: "address", internalType: "address" },
120
+ { name: "token", type: "address", internalType: "address" },
121
+ { name: "amount", type: "uint256", internalType: "uint256" }
122
+ ],
123
+ outputs: [],
124
+ stateMutability: "nonpayable"
125
+ },
126
+ {
127
+ type: "event",
128
+ name: "OwnershipTransferred",
129
+ inputs: [
130
+ {
131
+ name: "previousOwner",
132
+ type: "address",
133
+ indexed: true,
134
+ internalType: "address"
135
+ },
136
+ {
137
+ name: "newOwner",
138
+ type: "address",
139
+ indexed: true,
140
+ internalType: "address"
141
+ }
142
+ ],
143
+ anonymous: false
144
+ },
145
+ {
146
+ type: "error",
147
+ name: "OwnableInvalidOwner",
148
+ inputs: [
149
+ { name: "owner", type: "address", internalType: "address" }
150
+ ]
151
+ },
152
+ {
153
+ type: "error",
154
+ name: "OwnableUnauthorizedAccount",
155
+ inputs: [
156
+ { name: "account", type: "address", internalType: "address" }
157
+ ]
158
+ },
159
+ { type: "error", name: "WithdrawFailed", inputs: [] }
160
+ ];
161
+
162
+ // src/constants.ts
163
+ var UPVOTE_APP = {
164
+ address: "0x00000001f0b8173316a016a5067ad74e8cea47bf",
165
+ abi: upvote_app_default
166
+ };
167
+ var PURE_ALPHA_STRATEGY = {
168
+ address: "0x00000001b1bcdeddeafd5296aaf4f3f3e21ae876"};
169
+ var UNIV234_POOLS_STRATEGY = {
170
+ address: "0x000000063f84e07a3e7a7ee578b42704ee6d22c9"};
171
+ var DYNAMIC_SPLIT_STRATEGY = {
172
+ address: "0x0000000869160f0b2a213adefb46a7ea7e62ac7a"};
173
+ var ALL_STRATEGY_ADDRESSES = [
174
+ UNIV234_POOLS_STRATEGY.address,
175
+ PURE_ALPHA_STRATEGY.address,
176
+ DYNAMIC_SPLIT_STRATEGY.address
177
+ ];
178
+
179
+ // src/hooks/useUpvotes.ts
180
+ function useUpvotes({
181
+ chainId,
182
+ scoreKey,
183
+ strategies = ALL_STRATEGY_ADDRESSES,
184
+ enabled = true
185
+ }) {
186
+ const { data, isLoading, error, refetch } = useReadContract({
187
+ address: UPVOTE_APP.address,
188
+ abi: UPVOTE_APP.abi,
189
+ functionName: "getUpvotesWithLegacy",
190
+ args: [[scoreKey], strategies],
191
+ chainId,
192
+ query: { enabled }
193
+ });
194
+ return {
195
+ upvotes: Array.isArray(data) && data.length > 0 ? Number(data[0]) : 0,
196
+ isLoading,
197
+ error,
198
+ refetch
199
+ };
200
+ }
201
+ var encodeUpvoteKey = (tokenAddress) => {
202
+ return `0x${BigInt(`0x${tokenAddress.slice(2)}`).toString(16).padStart(64, "0")}`;
203
+ };
204
+
205
+ // src/utils/scoreKeyUtils.ts
206
+ var getTokenScoreKey = (tokenAddress) => {
207
+ return encodeUpvoteKey(tokenAddress);
208
+ };
209
+ var getStorageScoreKey = (operatorAddress, storageKey) => {
210
+ const bytes32Key = getStorageKeyBytes(storageKey);
211
+ return keccak256(
212
+ encodePacked(
213
+ ["bytes32", "address"],
214
+ [bytes32Key, operatorAddress]
215
+ )
216
+ );
217
+ };
218
+ var getFeedContentKey = (message) => {
219
+ return keccak256(
220
+ encodePacked(
221
+ ["address", "string", "address", "uint256", "string", "bytes"],
222
+ [
223
+ message.app,
224
+ message.topic,
225
+ message.sender,
226
+ message.timestamp,
227
+ message.text,
228
+ message.data
229
+ ]
230
+ )
231
+ );
232
+ };
233
+ var getScoreKey = (item) => {
234
+ switch (item.type) {
235
+ case "token":
236
+ return getTokenScoreKey(item.tokenAddress);
237
+ case "storage":
238
+ return getStorageScoreKey(item.operatorAddress, item.storageKey);
239
+ case "feed": {
240
+ const contentKey = getFeedContentKey(item.message);
241
+ return getStorageScoreKey(
242
+ item.message.sender,
243
+ contentKey
244
+ );
245
+ }
246
+ }
247
+ };
248
+
249
+ // src/hooks/useUpvotesBatch.ts
250
+ function useUpvotesBatch({
251
+ chainId,
252
+ items,
253
+ strategies = ALL_STRATEGY_ADDRESSES,
254
+ enabled = true
255
+ }) {
256
+ const scoreKeys = useMemo(
257
+ () => items.map((item) => getScoreKey(item)),
258
+ [items]
259
+ );
260
+ const { data, isLoading, error, refetch } = useReadContract({
261
+ address: UPVOTE_APP.address,
262
+ abi: UPVOTE_APP.abi,
263
+ functionName: "getUpvotesWithLegacy",
264
+ args: [scoreKeys, strategies],
265
+ chainId,
266
+ query: { enabled: enabled && scoreKeys.length > 0 }
267
+ });
268
+ return {
269
+ upvoteCounts: Array.isArray(data) ? data.map(Number) : [],
270
+ isLoading,
271
+ error,
272
+ refetch
273
+ };
274
+ }
275
+ function useTokenUpvotes({
276
+ chainId,
277
+ tokenAddress,
278
+ enabled = true
279
+ }) {
280
+ const scoreKey = useMemo(
281
+ () => getTokenScoreKey(tokenAddress),
282
+ [tokenAddress]
283
+ );
284
+ return useUpvotes({ chainId, scoreKey, enabled });
285
+ }
286
+
287
+ export { getScoreKey, getStorageScoreKey, getTokenScoreKey, useTokenUpvotes, useUpvotes, useUpvotesBatch };
288
+ //# sourceMappingURL=react.mjs.map
289
+ //# sourceMappingURL=react.mjs.map