@metamask/social-controllers 3.8.0 → 3.9.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/CHANGELOG.md +17 -1
- package/dist/SocialRealtimeService.d.ts +13 -7
- package/dist/SocialRealtimeService.d.ts.map +1 -1
- package/dist/SocialRealtimeService.js +170 -33
- package/dist/SocialRealtimeService.js.map +1 -1
- package/dist/SocialService-method-action-types.d.ts +5 -1
- package/dist/SocialService-method-action-types.d.ts.map +1 -1
- package/dist/SocialService-method-action-types.js.map +1 -1
- package/dist/SocialService.d.ts +5 -1
- package/dist/SocialService.d.ts.map +1 -1
- package/dist/SocialService.js +7 -271
- package/dist/SocialService.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/social-types.d.ts +17 -3
- package/dist/social-types.d.ts.map +1 -1
- package/dist/social-types.js.map +1 -1
- package/dist/structs.d.ts +1419 -0
- package/dist/structs.d.ts.map +1 -0
- package/dist/structs.js +291 -0
- package/dist/structs.js.map +1 -0
- package/package.json +4 -4
package/dist/SocialService.js
CHANGED
|
@@ -1,278 +1,10 @@
|
|
|
1
1
|
var _a;
|
|
2
2
|
import { BaseDataService } from '@metamask/base-data-service';
|
|
3
3
|
import { HttpError } from '@metamask/controller-utils';
|
|
4
|
-
import {
|
|
4
|
+
import { is } from '@metamask/superstruct';
|
|
5
5
|
import { serviceName, SocialServiceErrorMessage } from './social-constants.js';
|
|
6
|
-
import {
|
|
6
|
+
import { BlockedContentResponseStruct, BlockedProfilesResponseStruct, CommentEngagementStruct, CopyTradeIntentResponseStruct, FollowResponseStruct, FollowersResponseStruct, FollowingResponseStruct, LeaderboardResponseStruct, PositionStruct, PositionsResponseStruct, SwapCommentResponseStruct, TraderProfileResponseStruct, UnfollowResponseStruct, parseFeedResponse, } from './structs.js';
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
|
-
// Superstruct validation schemas
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
const SocialHandlesStruct = structType({
|
|
11
|
-
twitter: optional(nullable(string())),
|
|
12
|
-
farcaster: optional(nullable(string())),
|
|
13
|
-
ens: optional(nullable(string())),
|
|
14
|
-
lens: optional(nullable(string())),
|
|
15
|
-
});
|
|
16
|
-
const ProfileSummaryStruct = structType({
|
|
17
|
-
profileId: string(),
|
|
18
|
-
address: string(),
|
|
19
|
-
name: string(),
|
|
20
|
-
imageUrl: optional(nullable(string())),
|
|
21
|
-
});
|
|
22
|
-
const FeedActorStruct = assign(ProfileSummaryStruct, structType({
|
|
23
|
-
winRate30d: optional(nullable(number())),
|
|
24
|
-
pnl30d: optional(nullable(number())),
|
|
25
|
-
tradeCount30d: optional(nullable(number())),
|
|
26
|
-
followerCount: optional(nullable(number())),
|
|
27
|
-
}));
|
|
28
|
-
const PositionStruct = structType({
|
|
29
|
-
positionId: string(),
|
|
30
|
-
tokenSymbol: string(),
|
|
31
|
-
tokenName: string(),
|
|
32
|
-
tokenAddress: string(),
|
|
33
|
-
chain: string(),
|
|
34
|
-
positionAmount: number(),
|
|
35
|
-
isOpen: optional(boolean()),
|
|
36
|
-
// Incomplete Clicker metrics serialize these as `null` (`undefined + n`
|
|
37
|
-
// becomes `NaN`, then JSON `null`). Rejecting the field used to fail the
|
|
38
|
-
// entire feed page, so they are nullable here.
|
|
39
|
-
boughtUsd: nullable(number()),
|
|
40
|
-
soldUsd: nullable(number()),
|
|
41
|
-
realizedPnl: nullable(number()),
|
|
42
|
-
costBasis: nullable(number()),
|
|
43
|
-
trades: array(TradeStruct),
|
|
44
|
-
lastTradeAt: number(),
|
|
45
|
-
tokenImageUrl: optional(nullable(string())),
|
|
46
|
-
currentValueUSD: optional(nullable(number())),
|
|
47
|
-
pnlValueUsd: optional(nullable(number())),
|
|
48
|
-
pnlPercent: optional(nullable(number())),
|
|
49
|
-
copyCount: optional(number()),
|
|
50
|
-
perpPositionType: optional(nullable(enums(['long', 'short']))),
|
|
51
|
-
perpLeverage: optional(nullable(number())),
|
|
52
|
-
positionAmountWithLeverage: optional(nullable(number())),
|
|
53
|
-
});
|
|
54
|
-
const PaginationStruct = structType({
|
|
55
|
-
hasMore: boolean(),
|
|
56
|
-
nextPage: optional(number()),
|
|
57
|
-
});
|
|
58
|
-
const LeaderboardEntryStruct = structType({
|
|
59
|
-
rank: number(),
|
|
60
|
-
addresses: array(string()),
|
|
61
|
-
profileId: string(),
|
|
62
|
-
name: string(),
|
|
63
|
-
imageUrl: optional(nullable(string())),
|
|
64
|
-
pnl30d: number(),
|
|
65
|
-
winRate30d: optional(nullable(number())),
|
|
66
|
-
roiPercent30d: optional(nullable(number())),
|
|
67
|
-
tradeCount30d: optional(nullable(number())),
|
|
68
|
-
pnl7d: optional(nullable(number())),
|
|
69
|
-
winRate7d: optional(nullable(number())),
|
|
70
|
-
roiPercent7d: optional(nullable(number())),
|
|
71
|
-
tradeCount7d: optional(nullable(number())),
|
|
72
|
-
pnlPerChain: record(string(), number()),
|
|
73
|
-
followerCount: number(),
|
|
74
|
-
socialHandles: SocialHandlesStruct,
|
|
75
|
-
});
|
|
76
|
-
const LeaderboardResponseStruct = structType({
|
|
77
|
-
traders: array(LeaderboardEntryStruct),
|
|
78
|
-
});
|
|
79
|
-
const TraderProfileStruct = structType({
|
|
80
|
-
profileId: string(),
|
|
81
|
-
address: string(),
|
|
82
|
-
allAddresses: array(string()),
|
|
83
|
-
name: string(),
|
|
84
|
-
imageUrl: optional(nullable(string())),
|
|
85
|
-
});
|
|
86
|
-
const TraderStatsStruct = structType({
|
|
87
|
-
pnl30d: optional(nullable(number())),
|
|
88
|
-
winRate30d: optional(nullable(number())),
|
|
89
|
-
roiPercent30d: optional(nullable(number())),
|
|
90
|
-
tradeCount30d: optional(nullable(number())),
|
|
91
|
-
volumeUsd30d: optional(nullable(number())),
|
|
92
|
-
pnl7d: optional(nullable(number())),
|
|
93
|
-
winRate7d: optional(nullable(number())),
|
|
94
|
-
roiPercent7d: optional(nullable(number())),
|
|
95
|
-
tradeCount7d: optional(nullable(number())),
|
|
96
|
-
medianHoldMinutes: optional(nullable(number())),
|
|
97
|
-
});
|
|
98
|
-
const PerChainBreakdownStruct = structType({
|
|
99
|
-
perChainPnl: record(string(), number()),
|
|
100
|
-
perChainRoi: record(string(), nullable(number())),
|
|
101
|
-
perChainVolume: record(string(), number()),
|
|
102
|
-
perChainPnl7d: optional(record(string(), number())),
|
|
103
|
-
perChainRoi7d: optional(record(string(), nullable(number()))),
|
|
104
|
-
perChainVolume7d: optional(record(string(), number())),
|
|
105
|
-
});
|
|
106
|
-
const CopytradedAllTimeStruct = structType({
|
|
107
|
-
count: number(),
|
|
108
|
-
volumeUSD: number(),
|
|
109
|
-
distinctActors: number(),
|
|
110
|
-
});
|
|
111
|
-
const TraderProfileResponseStruct = structType({
|
|
112
|
-
profile: TraderProfileStruct,
|
|
113
|
-
stats: TraderStatsStruct,
|
|
114
|
-
perChainBreakdown: PerChainBreakdownStruct,
|
|
115
|
-
socialHandles: SocialHandlesStruct,
|
|
116
|
-
followerCount: number(),
|
|
117
|
-
followingCount: number(),
|
|
118
|
-
copytradedAllTime: CopytradedAllTimeStruct,
|
|
119
|
-
rankingTag: optional(nullable(enums(TRADER_RANKING_TAGS))),
|
|
120
|
-
});
|
|
121
|
-
const PositionsResponseStruct = structType({
|
|
122
|
-
positions: array(PositionStruct),
|
|
123
|
-
pagination: PaginationStruct,
|
|
124
|
-
computedAt: optional(nullable(string())),
|
|
125
|
-
});
|
|
126
|
-
// A feed item is a position plus the trader who made the trade (`actor`) and
|
|
127
|
-
// the item's creation timestamp. Reuses PositionStruct so the trade/position
|
|
128
|
-
// fields stay in lockstep with the positions endpoints.
|
|
129
|
-
const CommentReactionProfileStruct = structType({
|
|
130
|
-
id: string(),
|
|
131
|
-
name: string(),
|
|
132
|
-
});
|
|
133
|
-
const CommentReactionStruct = structType({
|
|
134
|
-
emotion: string(),
|
|
135
|
-
count: number(),
|
|
136
|
-
profiles: array(CommentReactionProfileStruct),
|
|
137
|
-
});
|
|
138
|
-
const CommentEngagementStruct = structType({
|
|
139
|
-
reactions: array(CommentReactionStruct),
|
|
140
|
-
userReaction: nullable(string()),
|
|
141
|
-
replyCount: optional(number()),
|
|
142
|
-
});
|
|
143
|
-
const AuthorCommentStruct = structType({
|
|
144
|
-
uid: string(),
|
|
145
|
-
text: string(),
|
|
146
|
-
timestamp: number(),
|
|
147
|
-
engagement: CommentEngagementStruct,
|
|
148
|
-
});
|
|
149
|
-
const SwapCommentAuthorStruct = structType({
|
|
150
|
-
id: string(),
|
|
151
|
-
name: string(),
|
|
152
|
-
images: optional(structType({
|
|
153
|
-
raw: nullable(string()),
|
|
154
|
-
xs: nullable(string()),
|
|
155
|
-
sm: nullable(string()),
|
|
156
|
-
})),
|
|
157
|
-
addresses: optional(array(string())),
|
|
158
|
-
externalId: optional(string()),
|
|
159
|
-
});
|
|
160
|
-
const SwapCommentResponseStruct = structType({
|
|
161
|
-
uid: string(),
|
|
162
|
-
transactionHash: string(),
|
|
163
|
-
chain: string(),
|
|
164
|
-
tokenAddress: string(),
|
|
165
|
-
commentText: string(),
|
|
166
|
-
author: SwapCommentAuthorStruct,
|
|
167
|
-
timestamp: number(),
|
|
168
|
-
isAppUserComment: boolean(),
|
|
169
|
-
metrics: CommentEngagementStruct,
|
|
170
|
-
});
|
|
171
|
-
const CopyTradeAccountStruct = structType({
|
|
172
|
-
profileId: string(),
|
|
173
|
-
caip10: string(),
|
|
174
|
-
});
|
|
175
|
-
const CopyTradeIntentResponseStruct = structType({
|
|
176
|
-
id: string(),
|
|
177
|
-
origin: structType({
|
|
178
|
-
kind: literal('comment'),
|
|
179
|
-
id: string(),
|
|
180
|
-
}),
|
|
181
|
-
copierAccount: CopyTradeAccountStruct,
|
|
182
|
-
sourceAccount: nullable(CopyTradeAccountStruct),
|
|
183
|
-
execution: union([
|
|
184
|
-
structType({ product: literal('swaps'), quoteId: string() }),
|
|
185
|
-
structType({ product: literal('perps'), oid: string() }),
|
|
186
|
-
]),
|
|
187
|
-
payoutEligibility: structType({
|
|
188
|
-
status: enums(['payable', 'non_payable']),
|
|
189
|
-
reason: string(),
|
|
190
|
-
}),
|
|
191
|
-
createdAt: string(),
|
|
192
|
-
});
|
|
193
|
-
const FeedItemStruct = assign(PositionStruct, structType({
|
|
194
|
-
actor: FeedActorStruct,
|
|
195
|
-
timestamp: number(),
|
|
196
|
-
authorComment: optional(nullable(AuthorCommentStruct)),
|
|
197
|
-
commentCount: optional(number()),
|
|
198
|
-
replyCount: optional(number()),
|
|
199
|
-
copyCount: optional(number()),
|
|
200
|
-
firstTradeAt: optional(nullable(number())),
|
|
201
|
-
holdTimeMs: optional(nullable(number())),
|
|
202
|
-
entryPriceUsd: optional(nullable(number())),
|
|
203
|
-
}));
|
|
204
|
-
const FeedPaginationStruct = structType({
|
|
205
|
-
olderCursor: nullable(string()),
|
|
206
|
-
newerCursor: nullable(string()),
|
|
207
|
-
});
|
|
208
|
-
const FeedResponseStruct = structType({
|
|
209
|
-
items: array(FeedItemStruct),
|
|
210
|
-
pagination: FeedPaginationStruct,
|
|
211
|
-
});
|
|
212
|
-
/**
|
|
213
|
-
* One malformed feed item must not blank the page. When the envelope is
|
|
214
|
-
* well-shaped, keep items that match {@link FeedItemStruct} and drop the rest.
|
|
215
|
-
* Still throw when `items` or `pagination` themselves are unusable.
|
|
216
|
-
*
|
|
217
|
-
* @param feedData - Parsed JSON body from a feed endpoint.
|
|
218
|
-
* @param invalidMessage - Error message to throw when the envelope is unusable.
|
|
219
|
-
* @returns The validated feed response, possibly with invalid items dropped.
|
|
220
|
-
*/
|
|
221
|
-
const parseFeedResponse = (feedData, invalidMessage) => {
|
|
222
|
-
if (is(feedData, FeedResponseStruct)) {
|
|
223
|
-
return feedData;
|
|
224
|
-
}
|
|
225
|
-
if (typeof feedData !== 'object' ||
|
|
226
|
-
feedData === null ||
|
|
227
|
-
!('items' in feedData) ||
|
|
228
|
-
!('pagination' in feedData)) {
|
|
229
|
-
throw new Error(invalidMessage);
|
|
230
|
-
}
|
|
231
|
-
const { items, pagination } = feedData;
|
|
232
|
-
if (!Array.isArray(items) || !is(pagination, FeedPaginationStruct)) {
|
|
233
|
-
throw new Error(invalidMessage);
|
|
234
|
-
}
|
|
235
|
-
return {
|
|
236
|
-
items: items.filter((item) => is(item, FeedItemStruct)),
|
|
237
|
-
pagination,
|
|
238
|
-
};
|
|
239
|
-
};
|
|
240
|
-
const FollowersResponseStruct = structType({
|
|
241
|
-
followers: array(ProfileSummaryStruct),
|
|
242
|
-
count: number(),
|
|
243
|
-
});
|
|
244
|
-
const FollowingResponseStruct = structType({
|
|
245
|
-
following: array(ProfileSummaryStruct),
|
|
246
|
-
count: number(),
|
|
247
|
-
});
|
|
248
|
-
const FollowResponseStruct = structType({
|
|
249
|
-
followed: array(ProfileSummaryStruct),
|
|
250
|
-
});
|
|
251
|
-
const UnfollowResponseStruct = structType({
|
|
252
|
-
unfollowed: array(ProfileSummaryStruct),
|
|
253
|
-
});
|
|
254
|
-
const BlockedProfileStruct = structType({
|
|
255
|
-
blockedAt: number(),
|
|
256
|
-
reason: nullable(string()),
|
|
257
|
-
profile: ProfileSummaryStruct,
|
|
258
|
-
});
|
|
259
|
-
const BlockedProfilesResponseStruct = structType({
|
|
260
|
-
items: array(BlockedProfileStruct),
|
|
261
|
-
cursor: nullable(string()),
|
|
262
|
-
});
|
|
263
|
-
const BlockedContentStruct = structType({
|
|
264
|
-
blockedAt: number(),
|
|
265
|
-
reason: nullable(string()),
|
|
266
|
-
type: enums(['comment', 'reply']),
|
|
267
|
-
id: string(),
|
|
268
|
-
text: string(),
|
|
269
|
-
createdAt: number(),
|
|
270
|
-
author: nullable(ProfileSummaryStruct),
|
|
271
|
-
});
|
|
272
|
-
const BlockedContentResponseStruct = structType({
|
|
273
|
-
items: array(BlockedContentStruct),
|
|
274
|
-
cursor: nullable(string()),
|
|
275
|
-
});
|
|
276
8
|
// ---------------------------------------------------------------------------
|
|
277
9
|
// Messenger types
|
|
278
10
|
// ---------------------------------------------------------------------------
|
|
@@ -387,6 +119,9 @@ export class SocialService extends BaseDataService {
|
|
|
387
119
|
*
|
|
388
120
|
* Calls `GET ${baseUrl}/traders/${addressOrId}/profile`.
|
|
389
121
|
*
|
|
122
|
+
* `profile.createdAt` is optional. When present it is an ISO-8601 timestamp
|
|
123
|
+
* for when the social-api profile row was inserted.
|
|
124
|
+
*
|
|
390
125
|
* @param options - Options bag.
|
|
391
126
|
* @param options.addressOrId - Wallet address or Clicker profile ID.
|
|
392
127
|
* @returns The trader profile response.
|
|
@@ -547,7 +282,8 @@ export class SocialService extends BaseDataService {
|
|
|
547
282
|
* `pagination.newerCursor` as `newerThan` to fetch newer items.
|
|
548
283
|
*
|
|
549
284
|
* @param options - Options bag.
|
|
550
|
-
* @param options.scope - `following` (default)
|
|
285
|
+
* @param options.scope - `following` (default), `leaderboard`, `all`, or
|
|
286
|
+
* `trending`.
|
|
551
287
|
* @param options.chains - Filter by one or more chains.
|
|
552
288
|
* @param options.limit - Number of results per page.
|
|
553
289
|
* @param options.olderThan - Cursor for older items (scroll down).
|