@metamask-previews/social-controllers 0.0.0-preview-bfb4d9f5a → 0.1.0-preview-1d148d2
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 +4 -1
- package/dist/SocialController.cjs +3 -1
- package/dist/SocialController.cjs.map +1 -1
- package/dist/SocialController.mjs +3 -1
- package/dist/SocialController.mjs.map +1 -1
- package/dist/SocialService.cjs +6 -2
- package/dist/SocialService.cjs.map +1 -1
- package/dist/SocialService.d.cts.map +1 -1
- package/dist/SocialService.d.mts.map +1 -1
- package/dist/SocialService.mjs +6 -2
- package/dist/SocialService.mjs.map +1 -1
- package/dist/social-types.cjs.map +1 -1
- package/dist/social-types.d.cts +8 -2
- package/dist/social-types.d.cts.map +1 -1
- package/dist/social-types.d.mts +8 -2
- package/dist/social-types.d.mts.map +1 -1
- package/dist/social-types.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.0]
|
|
11
|
+
|
|
10
12
|
### Added
|
|
11
13
|
|
|
12
14
|
- Initial release ([#8321](https://github.com/MetaMask/core/pull/8321), [#8335](https://github.com/MetaMask/core/pull/8335), [#8337](https://github.com/MetaMask/core/pull/8337))
|
|
@@ -18,4 +20,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
18
20
|
- `unfollowTrader` — unfollows traders and removes addresses from state
|
|
19
21
|
- `updateFollowing` — fetches following list and replaces addresses in state
|
|
20
22
|
|
|
21
|
-
[Unreleased]: https://github.com/MetaMask/core/
|
|
23
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/social-controllers@0.1.0...HEAD
|
|
24
|
+
[0.1.0]: https://github.com/MetaMask/core/releases/tag/@metamask/social-controllers@0.1.0
|
|
@@ -83,7 +83,9 @@ class SocialController extends base_controller_1.BaseController {
|
|
|
83
83
|
*/
|
|
84
84
|
async followTrader(options) {
|
|
85
85
|
const followResponse = await this.messenger.call('SocialService:follow', options);
|
|
86
|
-
const newAddresses =
|
|
86
|
+
const newAddresses = [
|
|
87
|
+
...new Set(followResponse.followed.map((profile) => profile.address)),
|
|
88
|
+
];
|
|
87
89
|
this.update((state) => {
|
|
88
90
|
const existing = new Set(state.followingAddresses);
|
|
89
91
|
const uniqueNewAddresses = newAddresses.filter((address) => !existing.has(address));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocialController.cjs","sourceRoot":"","sources":["../src/SocialController.ts"],"names":[],"mappings":";;;AAKA,+DAA2D;AAG3D,6DAAoD;AAoBpD,oBAAoB;AAEpB,MAAM,yBAAyB,GAAG;IAChC,mBAAmB;IACnB,cAAc;IACd,gBAAgB;IAChB,iBAAiB;CACT,CAAC;AA+CX,wBAAwB;AAExB;;;;GAIG;AACH,SAAgB,+BAA+B;IAC7C,OAAO;QACL,kBAAkB,EAAE,EAAE;QACtB,kBAAkB,EAAE,EAAE;KACvB,CAAC;AACJ,CAAC;AALD,0EAKC;AAED,yBAAyB;AAEzB,MAAM,wBAAwB,GAAyC;IACrE,kBAAkB,EAAE;QAClB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,KAAK;QAC7B,kBAAkB,EAAE,KAAK;QACzB,QAAQ,EAAE,IAAI;KACf;IACD,kBAAkB,EAAE;QAClB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,KAAK;QAC7B,kBAAkB,EAAE,KAAK;QACzB,QAAQ,EAAE,IAAI;KACf;CACF,CAAC;AAEF,qBAAqB;AAErB;;;;;;;GAOG;AACH,MAAa,gBAAiB,SAAQ,gCAIrC;IACC,YAAY,EAAE,SAAS,EAAE,KAAK,EAA2B;QACvD,KAAK,CAAC;YACJ,IAAI,EAAE,iCAAc;YACpB,QAAQ,EAAE,wBAAwB;YAClC,KAAK,EAAE;gBACL,GAAG,+BAA+B,EAAE;gBACpC,GAAG,KAAK;aACT;YACD,SAAS;SACV,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,iBAAiB,CACrB,OAAiC;QAEjC,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACnD,gCAAgC,EAChC,OAAO,CACR,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,OAAO,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,YAAY,CAAC,OAAsB;QACvC,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC9C,sBAAsB,EACtB,OAAO,CACR,CAAC;QAEF,MAAM,YAAY,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"SocialController.cjs","sourceRoot":"","sources":["../src/SocialController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport { controllerName } from './social-constants';\nimport type {\n FetchFollowingOptions,\n FetchLeaderboardOptions,\n FollowOptions,\n FollowResponse,\n FollowingResponse,\n LeaderboardResponse,\n SocialControllerState,\n UnfollowOptions,\n UnfollowResponse,\n} from './social-types';\nimport type { SocialControllerMethodActions } from './SocialController-method-action-types';\nimport type {\n SocialServiceFetchFollowingAction,\n SocialServiceFetchLeaderboardAction,\n SocialServiceFollowAction,\n SocialServiceUnfollowAction,\n} from './SocialService-method-action-types';\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'updateLeaderboard',\n 'followTrader',\n 'unfollowTrader',\n 'updateFollowing',\n] as const;\n\n// === ACTION TYPES ===\n\nexport type SocialControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n SocialControllerState\n>;\n\nexport type SocialControllerActions =\n | SocialControllerGetStateAction\n | SocialControllerMethodActions;\n\n// === EVENT TYPES ===\n\nexport type SocialControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n SocialControllerState\n>;\n\nexport type SocialControllerEvents = SocialControllerStateChangeEvent;\n\n// === ALLOWED ACTIONS/EVENTS ===\n\ntype AllowedActions =\n | SocialServiceFetchLeaderboardAction\n | SocialServiceFollowAction\n | SocialServiceUnfollowAction\n | SocialServiceFetchFollowingAction;\n\ntype AllowedEvents = never;\n\n// === MESSENGER TYPE ===\n\nexport type SocialControllerMessenger = Messenger<\n typeof controllerName,\n SocialControllerActions | AllowedActions,\n SocialControllerEvents | AllowedEvents\n>;\n\n// === OPTIONS ===\n\nexport type SocialControllerOptions = {\n messenger: SocialControllerMessenger;\n state?: Partial<SocialControllerState>;\n};\n\n// === DEFAULT STATE ===\n\n/**\n * Returns the default state for the SocialController.\n *\n * @returns A fresh default state object.\n */\nexport function getDefaultSocialControllerState(): SocialControllerState {\n return {\n leaderboardEntries: [],\n followingAddresses: [],\n };\n}\n\n// === STATE METADATA ===\n\nconst socialControllerMetadata: StateMetadata<SocialControllerState> = {\n leaderboardEntries: {\n persist: true,\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n usedInUi: true,\n },\n followingAddresses: {\n persist: true,\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n usedInUi: true,\n },\n};\n\n// === CONTROLLER ===\n\n/**\n * Controller that manages social trading state for the extension UI.\n *\n * Acts as a simple store with no TTL or eviction — the UI decides when\n * to re-fetch, and the social-api's own cache layer handles upstream\n * rate-limiting. State is persisted across sessions so the UI can render\n * immediately on startup while a fresh fetch is in flight.\n */\nexport class SocialController extends BaseController<\n typeof controllerName,\n SocialControllerState,\n SocialControllerMessenger\n> {\n constructor({ messenger, state }: SocialControllerOptions) {\n super({\n name: controllerName,\n metadata: socialControllerMetadata,\n state: {\n ...getDefaultSocialControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Fetches the leaderboard and persists the entries to state.\n *\n * @param options - Optional leaderboard query parameters.\n * @returns The leaderboard response from the social-api.\n */\n async updateLeaderboard(\n options?: FetchLeaderboardOptions,\n ): Promise<LeaderboardResponse> {\n const leaderboardResponse = await this.messenger.call(\n 'SocialService:fetchLeaderboard',\n options,\n );\n\n this.update((state) => {\n state.leaderboardEntries = leaderboardResponse.traders;\n });\n\n return leaderboardResponse;\n }\n\n /**\n * Follows one or more traders and updates the following list in state.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the current user.\n * @param options.targets - Addresses or profile IDs to follow.\n * @returns The follow response with confirmed follows.\n */\n async followTrader(options: FollowOptions): Promise<FollowResponse> {\n const followResponse = await this.messenger.call(\n 'SocialService:follow',\n options,\n );\n\n const newAddresses = [\n ...new Set(followResponse.followed.map((profile) => profile.address)),\n ];\n\n this.update((state) => {\n const existing = new Set(state.followingAddresses);\n const uniqueNewAddresses = newAddresses.filter(\n (address) => !existing.has(address),\n );\n state.followingAddresses.push(...uniqueNewAddresses);\n });\n\n return followResponse;\n }\n\n /**\n * Unfollows one or more traders and updates the following list in state.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the current user.\n * @param options.targets - Addresses or profile IDs to unfollow.\n * @returns The unfollow response with confirmed unfollows.\n */\n async unfollowTrader(options: UnfollowOptions): Promise<UnfollowResponse> {\n const unfollowResponse = await this.messenger.call(\n 'SocialService:unfollow',\n options,\n );\n\n const removedAddresses = new Set(\n unfollowResponse.unfollowed.map((profile) => profile.address),\n );\n\n this.update((state) => {\n state.followingAddresses = state.followingAddresses.filter(\n (address) => !removedAddresses.has(address),\n );\n });\n\n return unfollowResponse;\n }\n\n /**\n * Fetches the list of traders the current user follows and replaces\n * the following addresses in state.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the current user.\n * @returns The following response.\n */\n async updateFollowing(\n options: FetchFollowingOptions,\n ): Promise<FollowingResponse> {\n const followingResponse = await this.messenger.call(\n 'SocialService:fetchFollowing',\n options,\n );\n\n this.update((state) => {\n state.followingAddresses = followingResponse.following.map(\n (profile) => profile.address,\n );\n });\n\n return followingResponse;\n }\n}\n"]}
|
|
@@ -79,7 +79,9 @@ export class SocialController extends BaseController {
|
|
|
79
79
|
*/
|
|
80
80
|
async followTrader(options) {
|
|
81
81
|
const followResponse = await this.messenger.call('SocialService:follow', options);
|
|
82
|
-
const newAddresses =
|
|
82
|
+
const newAddresses = [
|
|
83
|
+
...new Set(followResponse.followed.map((profile) => profile.address)),
|
|
84
|
+
];
|
|
83
85
|
this.update((state) => {
|
|
84
86
|
const existing = new Set(state.followingAddresses);
|
|
85
87
|
const uniqueNewAddresses = newAddresses.filter((address) => !existing.has(address));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocialController.mjs","sourceRoot":"","sources":["../src/SocialController.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAG3D,OAAO,EAAE,cAAc,EAAE,+BAA2B;AAoBpD,oBAAoB;AAEpB,MAAM,yBAAyB,GAAG;IAChC,mBAAmB;IACnB,cAAc;IACd,gBAAgB;IAChB,iBAAiB;CACT,CAAC;AA+CX,wBAAwB;AAExB;;;;GAIG;AACH,MAAM,UAAU,+BAA+B;IAC7C,OAAO;QACL,kBAAkB,EAAE,EAAE;QACtB,kBAAkB,EAAE,EAAE;KACvB,CAAC;AACJ,CAAC;AAED,yBAAyB;AAEzB,MAAM,wBAAwB,GAAyC;IACrE,kBAAkB,EAAE;QAClB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,KAAK;QAC7B,kBAAkB,EAAE,KAAK;QACzB,QAAQ,EAAE,IAAI;KACf;IACD,kBAAkB,EAAE;QAClB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,KAAK;QAC7B,kBAAkB,EAAE,KAAK;QACzB,QAAQ,EAAE,IAAI;KACf;CACF,CAAC;AAEF,qBAAqB;AAErB;;;;;;;GAOG;AACH,MAAM,OAAO,gBAAiB,SAAQ,cAIrC;IACC,YAAY,EAAE,SAAS,EAAE,KAAK,EAA2B;QACvD,KAAK,CAAC;YACJ,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,wBAAwB;YAClC,KAAK,EAAE;gBACL,GAAG,+BAA+B,EAAE;gBACpC,GAAG,KAAK;aACT;YACD,SAAS;SACV,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,iBAAiB,CACrB,OAAiC;QAEjC,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACnD,gCAAgC,EAChC,OAAO,CACR,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,kBAAkB,GAAG,mBAAmB,CAAC,OAAO,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,YAAY,CAAC,OAAsB;QACvC,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC9C,sBAAsB,EACtB,OAAO,CACR,CAAC;QAEF,MAAM,YAAY,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"SocialController.mjs","sourceRoot":"","sources":["../src/SocialController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\n\nimport { controllerName } from './social-constants';\nimport type {\n FetchFollowingOptions,\n FetchLeaderboardOptions,\n FollowOptions,\n FollowResponse,\n FollowingResponse,\n LeaderboardResponse,\n SocialControllerState,\n UnfollowOptions,\n UnfollowResponse,\n} from './social-types';\nimport type { SocialControllerMethodActions } from './SocialController-method-action-types';\nimport type {\n SocialServiceFetchFollowingAction,\n SocialServiceFetchLeaderboardAction,\n SocialServiceFollowAction,\n SocialServiceUnfollowAction,\n} from './SocialService-method-action-types';\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'updateLeaderboard',\n 'followTrader',\n 'unfollowTrader',\n 'updateFollowing',\n] as const;\n\n// === ACTION TYPES ===\n\nexport type SocialControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n SocialControllerState\n>;\n\nexport type SocialControllerActions =\n | SocialControllerGetStateAction\n | SocialControllerMethodActions;\n\n// === EVENT TYPES ===\n\nexport type SocialControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n SocialControllerState\n>;\n\nexport type SocialControllerEvents = SocialControllerStateChangeEvent;\n\n// === ALLOWED ACTIONS/EVENTS ===\n\ntype AllowedActions =\n | SocialServiceFetchLeaderboardAction\n | SocialServiceFollowAction\n | SocialServiceUnfollowAction\n | SocialServiceFetchFollowingAction;\n\ntype AllowedEvents = never;\n\n// === MESSENGER TYPE ===\n\nexport type SocialControllerMessenger = Messenger<\n typeof controllerName,\n SocialControllerActions | AllowedActions,\n SocialControllerEvents | AllowedEvents\n>;\n\n// === OPTIONS ===\n\nexport type SocialControllerOptions = {\n messenger: SocialControllerMessenger;\n state?: Partial<SocialControllerState>;\n};\n\n// === DEFAULT STATE ===\n\n/**\n * Returns the default state for the SocialController.\n *\n * @returns A fresh default state object.\n */\nexport function getDefaultSocialControllerState(): SocialControllerState {\n return {\n leaderboardEntries: [],\n followingAddresses: [],\n };\n}\n\n// === STATE METADATA ===\n\nconst socialControllerMetadata: StateMetadata<SocialControllerState> = {\n leaderboardEntries: {\n persist: true,\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n usedInUi: true,\n },\n followingAddresses: {\n persist: true,\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n usedInUi: true,\n },\n};\n\n// === CONTROLLER ===\n\n/**\n * Controller that manages social trading state for the extension UI.\n *\n * Acts as a simple store with no TTL or eviction — the UI decides when\n * to re-fetch, and the social-api's own cache layer handles upstream\n * rate-limiting. State is persisted across sessions so the UI can render\n * immediately on startup while a fresh fetch is in flight.\n */\nexport class SocialController extends BaseController<\n typeof controllerName,\n SocialControllerState,\n SocialControllerMessenger\n> {\n constructor({ messenger, state }: SocialControllerOptions) {\n super({\n name: controllerName,\n metadata: socialControllerMetadata,\n state: {\n ...getDefaultSocialControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Fetches the leaderboard and persists the entries to state.\n *\n * @param options - Optional leaderboard query parameters.\n * @returns The leaderboard response from the social-api.\n */\n async updateLeaderboard(\n options?: FetchLeaderboardOptions,\n ): Promise<LeaderboardResponse> {\n const leaderboardResponse = await this.messenger.call(\n 'SocialService:fetchLeaderboard',\n options,\n );\n\n this.update((state) => {\n state.leaderboardEntries = leaderboardResponse.traders;\n });\n\n return leaderboardResponse;\n }\n\n /**\n * Follows one or more traders and updates the following list in state.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the current user.\n * @param options.targets - Addresses or profile IDs to follow.\n * @returns The follow response with confirmed follows.\n */\n async followTrader(options: FollowOptions): Promise<FollowResponse> {\n const followResponse = await this.messenger.call(\n 'SocialService:follow',\n options,\n );\n\n const newAddresses = [\n ...new Set(followResponse.followed.map((profile) => profile.address)),\n ];\n\n this.update((state) => {\n const existing = new Set(state.followingAddresses);\n const uniqueNewAddresses = newAddresses.filter(\n (address) => !existing.has(address),\n );\n state.followingAddresses.push(...uniqueNewAddresses);\n });\n\n return followResponse;\n }\n\n /**\n * Unfollows one or more traders and updates the following list in state.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the current user.\n * @param options.targets - Addresses or profile IDs to unfollow.\n * @returns The unfollow response with confirmed unfollows.\n */\n async unfollowTrader(options: UnfollowOptions): Promise<UnfollowResponse> {\n const unfollowResponse = await this.messenger.call(\n 'SocialService:unfollow',\n options,\n );\n\n const removedAddresses = new Set(\n unfollowResponse.unfollowed.map((profile) => profile.address),\n );\n\n this.update((state) => {\n state.followingAddresses = state.followingAddresses.filter(\n (address) => !removedAddresses.has(address),\n );\n });\n\n return unfollowResponse;\n }\n\n /**\n * Fetches the list of traders the current user follows and replaces\n * the following addresses in state.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the current user.\n * @returns The following response.\n */\n async updateFollowing(\n options: FetchFollowingOptions,\n ): Promise<FollowingResponse> {\n const followingResponse = await this.messenger.call(\n 'SocialService:fetchFollowing',\n options,\n );\n\n this.update((state) => {\n state.followingAddresses = followingResponse.following.map(\n (profile) => profile.address,\n );\n });\n\n return followingResponse;\n }\n}\n"]}
|
package/dist/SocialService.cjs
CHANGED
|
@@ -67,8 +67,12 @@ const LeaderboardEntryStruct = (0, superstruct_1.type)({
|
|
|
67
67
|
imageUrl: (0, superstruct_1.optional)((0, superstruct_1.nullable)((0, superstruct_1.string)())),
|
|
68
68
|
pnl30d: (0, superstruct_1.number)(),
|
|
69
69
|
winRate30d: (0, superstruct_1.optional)((0, superstruct_1.nullable)((0, superstruct_1.number)())),
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
roiPercent30d: (0, superstruct_1.optional)((0, superstruct_1.nullable)((0, superstruct_1.number)())),
|
|
71
|
+
tradeCount30d: (0, superstruct_1.optional)((0, superstruct_1.nullable)((0, superstruct_1.number)())),
|
|
72
|
+
pnl7d: (0, superstruct_1.optional)((0, superstruct_1.nullable)((0, superstruct_1.number)())),
|
|
73
|
+
winRate7d: (0, superstruct_1.optional)((0, superstruct_1.nullable)((0, superstruct_1.number)())),
|
|
74
|
+
roiPercent7d: (0, superstruct_1.optional)((0, superstruct_1.nullable)((0, superstruct_1.number)())),
|
|
75
|
+
tradeCount7d: (0, superstruct_1.optional)((0, superstruct_1.nullable)((0, superstruct_1.number)())),
|
|
72
76
|
pnlPerChain: (0, superstruct_1.record)((0, superstruct_1.string)(), (0, superstruct_1.number)()),
|
|
73
77
|
followerCount: (0, superstruct_1.number)(),
|
|
74
78
|
socialHandles: SocialHandlesStruct,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocialService.cjs","sourceRoot":"","sources":["../src/SocialService.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n DataServiceInvalidateQueriesAction,\n} from '@metamask/base-data-service';\nimport { BaseDataService } from '@metamask/base-data-service';\nimport type { CreateServicePolicyOptions } from '@metamask/controller-utils';\nimport { HttpError } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport {\n array,\n boolean,\n is,\n nullable,\n number,\n optional,\n record,\n string,\n type as structType,\n} from '@metamask/superstruct';\n\nimport { serviceName, SocialServiceErrorMessage } from './social-constants';\nimport type {\n FetchFollowersOptions,\n FetchFollowingOptions,\n FetchLeaderboardOptions,\n FetchPositionsOptions,\n FetchTraderProfileOptions,\n FollowersResponse,\n FollowingResponse,\n FollowOptions,\n FollowResponse,\n LeaderboardResponse,\n PositionsResponse,\n TraderProfileResponse,\n UnfollowOptions,\n UnfollowResponse,\n} from './social-types';\nimport type { SocialServiceMethodActions } from './SocialService-method-action-types';\n\n// ---------------------------------------------------------------------------\n// Superstruct validation schemas\n// ---------------------------------------------------------------------------\n\nconst SocialHandlesStruct = structType({\n twitter: optional(nullable(string())),\n farcaster: optional(nullable(string())),\n ens: optional(nullable(string())),\n lens: optional(nullable(string())),\n});\n\nconst ProfileSummaryStruct = structType({\n profileId: string(),\n address: string(),\n name: string(),\n imageUrl: optional(nullable(string())),\n});\n\nconst TradeStruct = structType({\n direction: string(),\n tokenAmount: number(),\n usdCost: number(),\n timestamp: number(),\n transactionHash: string(),\n});\n\nconst PositionStruct = structType({\n tokenSymbol: string(),\n tokenName: string(),\n tokenAddress: string(),\n chain: string(),\n positionAmount: number(),\n boughtUsd: number(),\n soldUsd: number(),\n realizedPnl: number(),\n costBasis: number(),\n trades: array(TradeStruct),\n lastTradeAt: number(),\n currentValueUSD: optional(nullable(number())),\n pnlValueUsd: optional(nullable(number())),\n pnlPercent: optional(nullable(number())),\n});\n\nconst PaginationStruct = structType({\n hasMore: boolean(),\n nextPage: optional(number()),\n});\n\nconst LeaderboardEntryStruct = structType({\n rank: number(),\n addresses: array(string()),\n profileId: string(),\n name: string(),\n imageUrl: optional(nullable(string())),\n pnl30d: number(),\n winRate30d: optional(nullable(number())),\n roi30d: optional(nullable(number())),\n tradeCount: optional(nullable(number())),\n pnlPerChain: record(string(), number()),\n followerCount: number(),\n socialHandles: SocialHandlesStruct,\n});\n\nconst LeaderboardResponseStruct = structType({\n traders: array(LeaderboardEntryStruct),\n});\n\nconst TraderProfileStruct = structType({\n profileId: string(),\n address: string(),\n allAddresses: array(string()),\n name: string(),\n imageUrl: optional(nullable(string())),\n});\n\nconst TraderStatsStruct = structType({\n pnl30d: optional(nullable(number())),\n winRate30d: optional(nullable(number())),\n roiPercent30d: optional(nullable(number())),\n tradeCount30d: optional(nullable(number())),\n pnl7d: optional(nullable(number())),\n winRate7d: optional(nullable(number())),\n roiPercent7d: optional(nullable(number())),\n tradeCount7d: optional(nullable(number())),\n});\n\nconst PerChainBreakdownStruct = structType({\n perChainPnl: record(string(), number()),\n perChainRoi: record(string(), nullable(number())),\n perChainVolume: record(string(), number()),\n});\n\nconst TraderProfileResponseStruct = structType({\n profile: TraderProfileStruct,\n stats: TraderStatsStruct,\n perChainBreakdown: PerChainBreakdownStruct,\n socialHandles: SocialHandlesStruct,\n followerCount: number(),\n followingCount: number(),\n});\n\nconst PositionsResponseStruct = structType({\n positions: array(PositionStruct),\n pagination: PaginationStruct,\n computedAt: optional(nullable(string())),\n});\n\nconst FollowersResponseStruct = structType({\n followers: array(ProfileSummaryStruct),\n count: number(),\n});\n\nconst FollowingResponseStruct = structType({\n following: array(ProfileSummaryStruct),\n count: number(),\n});\n\nconst FollowResponseStruct = structType({\n followed: array(ProfileSummaryStruct),\n});\n\nconst UnfollowResponseStruct = structType({\n unfollowed: array(ProfileSummaryStruct),\n});\n\n// ---------------------------------------------------------------------------\n// Messenger types\n// ---------------------------------------------------------------------------\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'fetchLeaderboard',\n 'fetchTraderProfile',\n 'fetchOpenPositions',\n 'fetchClosedPositions',\n 'fetchFollowers',\n 'fetchFollowing',\n 'follow',\n 'unfollow',\n] as const;\n\nexport type SocialServiceActions =\n | SocialServiceMethodActions\n | DataServiceInvalidateQueriesAction<typeof serviceName>;\n\nexport type SocialServiceEvents =\n | DataServiceCacheUpdatedEvent<typeof serviceName>\n | DataServiceGranularCacheUpdatedEvent<typeof serviceName>;\n\nexport type SocialServiceMessenger = Messenger<\n typeof serviceName,\n SocialServiceActions,\n SocialServiceEvents\n>;\n\n// ---------------------------------------------------------------------------\n// Service\n// ---------------------------------------------------------------------------\n\n/**\n * Data service wrapping social-api endpoints.\n */\nexport class SocialService extends BaseDataService<\n typeof serviceName,\n SocialServiceMessenger\n> {\n readonly #baseUrl: string;\n\n get #v1Url(): string {\n return `${this.#baseUrl}/api/v1`;\n }\n\n get #v2Url(): string {\n return `${this.#baseUrl}/api/v2`;\n }\n\n constructor({\n messenger,\n baseUrl,\n policyOptions,\n }: {\n messenger: SocialServiceMessenger;\n baseUrl: string;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n super({ name: serviceName, messenger, policyOptions });\n this.#baseUrl = baseUrl;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Throws an HttpError if the response is not ok.\n *\n * @param response - The fetch response to check.\n * @param message - The error message prefix from SocialServiceErrorMessage.\n */\n static #throwIfNotOk(response: Response, message: string): void {\n if (!response.ok) {\n throw new HttpError(response.status, `${message}: ${response.status}`);\n }\n }\n\n /**\n * Fetches the leaderboard of top traders.\n *\n * Calls `GET ${baseUrl}/leaderboard`.\n *\n * @param options - Optional query parameters for sorting, chain filtering, and limit.\n * @returns The leaderboard response with ranked traders.\n */\n async fetchLeaderboard(\n options?: FetchLeaderboardOptions,\n ): Promise<LeaderboardResponse> {\n const leaderboardResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchLeaderboard`, options ?? null],\n queryFn: async () => {\n const { sort, chains, limit } = options ?? {};\n const url = new URL(`${this.#v1Url}/leaderboard`);\n if (sort) {\n url.searchParams.append('sort', sort);\n }\n if (chains) {\n for (const chain of chains) {\n url.searchParams.append('chains', chain);\n }\n }\n if (limit !== undefined) {\n url.searchParams.append('limit', String(limit));\n }\n\n const response = await fetch(url.toString());\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_LEADERBOARD_FAILED,\n );\n const leaderboardData = await response.json();\n if (!is(leaderboardData, LeaderboardResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_LEADERBOARD_INVALID_RESPONSE,\n );\n }\n return leaderboardData as LeaderboardResponse;\n },\n });\n\n return leaderboardResponse;\n }\n\n /**\n * Fetches a trader's profile by address or profile ID.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/profile`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @returns The trader profile response.\n */\n async fetchTraderProfile(\n options: FetchTraderProfileOptions,\n ): Promise<TraderProfileResponse> {\n const { addressOrId } = options;\n\n const traderProfileResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchTraderProfile`, addressOrId],\n queryFn: async () => {\n const url = `${this.#v1Url}/traders/${encodeURIComponent(addressOrId)}/profile`;\n const response = await fetch(url);\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_TRADER_PROFILE_FAILED,\n );\n const traderProfileData = await response.json();\n if (!is(traderProfileData, TraderProfileResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_TRADER_PROFILE_INVALID_RESPONSE,\n );\n }\n return traderProfileData as TraderProfileResponse;\n },\n });\n\n return traderProfileResponse;\n }\n\n /**\n * Fetches a trader's open positions.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/positions/open`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @param options.chain - Filter by chain.\n * @param options.sort - Sort by 'value' or 'latest'.\n * @param options.limit - Number of results per page.\n * @param options.page - Page number (1-based).\n * @returns The positions response.\n */\n async fetchOpenPositions(\n options: FetchPositionsOptions,\n ): Promise<PositionsResponse> {\n return this.#fetchPositions('open', options);\n }\n\n /**\n * Fetches a trader's closed positions.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/positions/closed`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @param options.chain - Filter by chain.\n * @param options.sort - Sort by 'value' or 'latest'.\n * @param options.limit - Number of results per page.\n * @param options.page - Page number (1-based).\n * @returns The positions response.\n */\n async fetchClosedPositions(\n options: FetchPositionsOptions,\n ): Promise<PositionsResponse> {\n return this.#fetchPositions('closed', options);\n }\n\n /**\n * Fetches a trader's MetaMask followers.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/followers`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @returns The followers response.\n */\n async fetchFollowers(\n options: FetchFollowersOptions,\n ): Promise<FollowersResponse> {\n const { addressOrId } = options;\n\n const followersResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchFollowers`, addressOrId],\n queryFn: async () => {\n const url = `${this.#v1Url}/traders/${encodeURIComponent(addressOrId)}/followers`;\n const response = await fetch(url);\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_FOLLOWERS_FAILED,\n );\n const followersData = await response.json();\n if (!is(followersData, FollowersResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_FOLLOWERS_INVALID_RESPONSE,\n );\n }\n return followersData as FollowersResponse;\n },\n });\n\n return followersResponse;\n }\n\n /**\n * Fetches the list of traders a user is following.\n *\n * Calls `GET ${baseUrl}/users/${addressOrUid}/following`.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID.\n * @returns The following response.\n */\n async fetchFollowing(\n options: FetchFollowingOptions,\n ): Promise<FollowingResponse> {\n const { addressOrUid } = options;\n\n const followingResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchFollowing`, addressOrUid],\n staleTime: 0,\n queryFn: async () => {\n const url = `${this.#v1Url}/users/${encodeURIComponent(addressOrUid)}/following`;\n const response = await fetch(url);\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_FOLLOWING_FAILED,\n );\n const followingData = await response.json();\n if (!is(followingData, FollowingResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_FOLLOWING_INVALID_RESPONSE,\n );\n }\n return followingData as FollowingResponse;\n },\n });\n\n return followingResponse;\n }\n\n /**\n * Follows one or more traders.\n *\n * Calls `PUT ${baseUrl}/users/${addressOrUid}/follows`.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the user.\n * @param options.targets - Array of wallet addresses or profile IDs to follow.\n * @returns The follow response with confirmed follows.\n */\n async follow(options: FollowOptions): Promise<FollowResponse> {\n const { addressOrUid, targets } = options;\n\n const followResponse = await this.fetchQuery({\n queryKey: [`${this.name}:follow`, addressOrUid, targets],\n staleTime: 0,\n queryFn: async () => {\n const url = `${this.#v1Url}/users/${encodeURIComponent(addressOrUid)}/follows`;\n const response = await fetch(url, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ targets }),\n });\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FOLLOW_FAILED,\n );\n const followData = await response.json();\n if (!is(followData, FollowResponseStruct)) {\n throw new Error(SocialServiceErrorMessage.FOLLOW_INVALID_RESPONSE);\n }\n return followData as FollowResponse;\n },\n });\n\n return followResponse;\n }\n\n /**\n * Unfollows one or more traders.\n *\n * Calls `DELETE ${baseUrl}/users/${addressOrUid}/follows?targets=...`.\n * Targets are sent as query params because Fastify does not parse\n * request bodies on DELETE requests per RFC 9110.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the user.\n * @param options.targets - Array of wallet addresses or profile IDs to unfollow.\n * @returns The unfollow response with confirmed unfollows.\n */\n async unfollow(options: UnfollowOptions): Promise<UnfollowResponse> {\n const { addressOrUid, targets } = options;\n\n const unfollowResponse = await this.fetchQuery({\n queryKey: [`${this.name}:unfollow`, addressOrUid, targets],\n staleTime: 0,\n queryFn: async () => {\n const url = new URL(\n `${this.#v1Url}/users/${encodeURIComponent(addressOrUid)}/follows`,\n );\n for (const target of targets) {\n url.searchParams.append('targets', target);\n }\n const response = await fetch(url.toString(), { method: 'DELETE' });\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.UNFOLLOW_FAILED,\n );\n const unfollowData = await response.json();\n if (!is(unfollowData, UnfollowResponseStruct)) {\n throw new Error(SocialServiceErrorMessage.UNFOLLOW_INVALID_RESPONSE);\n }\n return unfollowData as UnfollowResponse;\n },\n });\n\n return unfollowResponse;\n }\n\n /**\n * Shared helper for fetching open/closed positions.\n *\n * @param status - \"open\" or \"closed\".\n * @param options - Options bag including addressOrId and query parameters.\n * @returns The positions response.\n */\n async #fetchPositions(\n status: 'open' | 'closed',\n options: FetchPositionsOptions,\n ): Promise<PositionsResponse> {\n const { addressOrId, chain, sort, limit, page } = options;\n\n const failedMessage =\n status === 'open'\n ? SocialServiceErrorMessage.FETCH_OPEN_POSITIONS_FAILED\n : SocialServiceErrorMessage.FETCH_CLOSED_POSITIONS_FAILED;\n const invalidMessage =\n status === 'open'\n ? SocialServiceErrorMessage.FETCH_OPEN_POSITIONS_INVALID_RESPONSE\n : SocialServiceErrorMessage.FETCH_CLOSED_POSITIONS_INVALID_RESPONSE;\n\n const positionsResponse = await this.fetchQuery({\n queryKey: [\n `${this.name}:fetch${status === 'open' ? 'Open' : 'Closed'}Positions`,\n addressOrId,\n chain ?? null,\n // sort is not used for open positions (v2 endpoint dropped it),\n // so exclude it from the key to avoid redundant cache entries\n status === 'closed' ? (sort ?? null) : null,\n limit ?? null,\n page ?? null,\n ],\n queryFn: async () => {\n const url = new URL(\n `${this.#v2Url}/traders/${encodeURIComponent(addressOrId)}/positions/${status}`,\n );\n if (chain) {\n url.searchParams.append('chain', chain);\n }\n // sort is not supported on the v2 open-positions endpoint\n if (sort && status === 'closed') {\n url.searchParams.append('sort', sort);\n }\n if (limit !== undefined) {\n url.searchParams.append('limit', String(limit));\n }\n if (page !== undefined) {\n url.searchParams.append('page', String(page));\n }\n\n const response = await fetch(url.toString());\n SocialService.#throwIfNotOk(response, failedMessage);\n const positionsData = await response.json();\n if (!is(positionsData, PositionsResponseStruct)) {\n throw new Error(invalidMessage);\n }\n return positionsData as PositionsResponse;\n },\n });\n\n return positionsResponse;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SocialService.cjs","sourceRoot":"","sources":["../src/SocialService.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n DataServiceInvalidateQueriesAction,\n} from '@metamask/base-data-service';\nimport { BaseDataService } from '@metamask/base-data-service';\nimport type { CreateServicePolicyOptions } from '@metamask/controller-utils';\nimport { HttpError } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport {\n array,\n boolean,\n is,\n nullable,\n number,\n optional,\n record,\n string,\n type as structType,\n} from '@metamask/superstruct';\n\nimport { serviceName, SocialServiceErrorMessage } from './social-constants';\nimport type {\n FetchFollowersOptions,\n FetchFollowingOptions,\n FetchLeaderboardOptions,\n FetchPositionsOptions,\n FetchTraderProfileOptions,\n FollowersResponse,\n FollowingResponse,\n FollowOptions,\n FollowResponse,\n LeaderboardResponse,\n PositionsResponse,\n TraderProfileResponse,\n UnfollowOptions,\n UnfollowResponse,\n} from './social-types';\nimport type { SocialServiceMethodActions } from './SocialService-method-action-types';\n\n// ---------------------------------------------------------------------------\n// Superstruct validation schemas\n// ---------------------------------------------------------------------------\n\nconst SocialHandlesStruct = structType({\n twitter: optional(nullable(string())),\n farcaster: optional(nullable(string())),\n ens: optional(nullable(string())),\n lens: optional(nullable(string())),\n});\n\nconst ProfileSummaryStruct = structType({\n profileId: string(),\n address: string(),\n name: string(),\n imageUrl: optional(nullable(string())),\n});\n\nconst TradeStruct = structType({\n direction: string(),\n tokenAmount: number(),\n usdCost: number(),\n timestamp: number(),\n transactionHash: string(),\n});\n\nconst PositionStruct = structType({\n tokenSymbol: string(),\n tokenName: string(),\n tokenAddress: string(),\n chain: string(),\n positionAmount: number(),\n boughtUsd: number(),\n soldUsd: number(),\n realizedPnl: number(),\n costBasis: number(),\n trades: array(TradeStruct),\n lastTradeAt: number(),\n currentValueUSD: optional(nullable(number())),\n pnlValueUsd: optional(nullable(number())),\n pnlPercent: optional(nullable(number())),\n});\n\nconst PaginationStruct = structType({\n hasMore: boolean(),\n nextPage: optional(number()),\n});\n\nconst LeaderboardEntryStruct = structType({\n rank: number(),\n addresses: array(string()),\n profileId: string(),\n name: string(),\n imageUrl: optional(nullable(string())),\n pnl30d: number(),\n winRate30d: optional(nullable(number())),\n roiPercent30d: optional(nullable(number())),\n tradeCount30d: optional(nullable(number())),\n pnl7d: optional(nullable(number())),\n winRate7d: optional(nullable(number())),\n roiPercent7d: optional(nullable(number())),\n tradeCount7d: optional(nullable(number())),\n pnlPerChain: record(string(), number()),\n followerCount: number(),\n socialHandles: SocialHandlesStruct,\n});\n\nconst LeaderboardResponseStruct = structType({\n traders: array(LeaderboardEntryStruct),\n});\n\nconst TraderProfileStruct = structType({\n profileId: string(),\n address: string(),\n allAddresses: array(string()),\n name: string(),\n imageUrl: optional(nullable(string())),\n});\n\nconst TraderStatsStruct = structType({\n pnl30d: optional(nullable(number())),\n winRate30d: optional(nullable(number())),\n roiPercent30d: optional(nullable(number())),\n tradeCount30d: optional(nullable(number())),\n pnl7d: optional(nullable(number())),\n winRate7d: optional(nullable(number())),\n roiPercent7d: optional(nullable(number())),\n tradeCount7d: optional(nullable(number())),\n});\n\nconst PerChainBreakdownStruct = structType({\n perChainPnl: record(string(), number()),\n perChainRoi: record(string(), nullable(number())),\n perChainVolume: record(string(), number()),\n});\n\nconst TraderProfileResponseStruct = structType({\n profile: TraderProfileStruct,\n stats: TraderStatsStruct,\n perChainBreakdown: PerChainBreakdownStruct,\n socialHandles: SocialHandlesStruct,\n followerCount: number(),\n followingCount: number(),\n});\n\nconst PositionsResponseStruct = structType({\n positions: array(PositionStruct),\n pagination: PaginationStruct,\n computedAt: optional(nullable(string())),\n});\n\nconst FollowersResponseStruct = structType({\n followers: array(ProfileSummaryStruct),\n count: number(),\n});\n\nconst FollowingResponseStruct = structType({\n following: array(ProfileSummaryStruct),\n count: number(),\n});\n\nconst FollowResponseStruct = structType({\n followed: array(ProfileSummaryStruct),\n});\n\nconst UnfollowResponseStruct = structType({\n unfollowed: array(ProfileSummaryStruct),\n});\n\n// ---------------------------------------------------------------------------\n// Messenger types\n// ---------------------------------------------------------------------------\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'fetchLeaderboard',\n 'fetchTraderProfile',\n 'fetchOpenPositions',\n 'fetchClosedPositions',\n 'fetchFollowers',\n 'fetchFollowing',\n 'follow',\n 'unfollow',\n] as const;\n\nexport type SocialServiceActions =\n | SocialServiceMethodActions\n | DataServiceInvalidateQueriesAction<typeof serviceName>;\n\nexport type SocialServiceEvents =\n | DataServiceCacheUpdatedEvent<typeof serviceName>\n | DataServiceGranularCacheUpdatedEvent<typeof serviceName>;\n\nexport type SocialServiceMessenger = Messenger<\n typeof serviceName,\n SocialServiceActions,\n SocialServiceEvents\n>;\n\n// ---------------------------------------------------------------------------\n// Service\n// ---------------------------------------------------------------------------\n\n/**\n * Data service wrapping social-api endpoints.\n */\nexport class SocialService extends BaseDataService<\n typeof serviceName,\n SocialServiceMessenger\n> {\n readonly #baseUrl: string;\n\n get #v1Url(): string {\n return `${this.#baseUrl}/api/v1`;\n }\n\n get #v2Url(): string {\n return `${this.#baseUrl}/api/v2`;\n }\n\n constructor({\n messenger,\n baseUrl,\n policyOptions,\n }: {\n messenger: SocialServiceMessenger;\n baseUrl: string;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n super({ name: serviceName, messenger, policyOptions });\n this.#baseUrl = baseUrl;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Throws an HttpError if the response is not ok.\n *\n * @param response - The fetch response to check.\n * @param message - The error message prefix from SocialServiceErrorMessage.\n */\n static #throwIfNotOk(response: Response, message: string): void {\n if (!response.ok) {\n throw new HttpError(response.status, `${message}: ${response.status}`);\n }\n }\n\n /**\n * Fetches the leaderboard of top traders.\n *\n * Calls `GET ${baseUrl}/leaderboard`.\n *\n * @param options - Optional query parameters for sorting, chain filtering, and limit.\n * @returns The leaderboard response with ranked traders.\n */\n async fetchLeaderboard(\n options?: FetchLeaderboardOptions,\n ): Promise<LeaderboardResponse> {\n const leaderboardResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchLeaderboard`, options ?? null],\n queryFn: async () => {\n const { sort, chains, limit } = options ?? {};\n const url = new URL(`${this.#v1Url}/leaderboard`);\n if (sort) {\n url.searchParams.append('sort', sort);\n }\n if (chains) {\n for (const chain of chains) {\n url.searchParams.append('chains', chain);\n }\n }\n if (limit !== undefined) {\n url.searchParams.append('limit', String(limit));\n }\n\n const response = await fetch(url.toString());\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_LEADERBOARD_FAILED,\n );\n const leaderboardData = await response.json();\n if (!is(leaderboardData, LeaderboardResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_LEADERBOARD_INVALID_RESPONSE,\n );\n }\n return leaderboardData as LeaderboardResponse;\n },\n });\n\n return leaderboardResponse;\n }\n\n /**\n * Fetches a trader's profile by address or profile ID.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/profile`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @returns The trader profile response.\n */\n async fetchTraderProfile(\n options: FetchTraderProfileOptions,\n ): Promise<TraderProfileResponse> {\n const { addressOrId } = options;\n\n const traderProfileResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchTraderProfile`, addressOrId],\n queryFn: async () => {\n const url = `${this.#v1Url}/traders/${encodeURIComponent(addressOrId)}/profile`;\n const response = await fetch(url);\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_TRADER_PROFILE_FAILED,\n );\n const traderProfileData = await response.json();\n if (!is(traderProfileData, TraderProfileResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_TRADER_PROFILE_INVALID_RESPONSE,\n );\n }\n return traderProfileData as TraderProfileResponse;\n },\n });\n\n return traderProfileResponse;\n }\n\n /**\n * Fetches a trader's open positions.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/positions/open`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @param options.chain - Filter by chain.\n * @param options.sort - Sort by 'value' or 'latest'.\n * @param options.limit - Number of results per page.\n * @param options.page - Page number (1-based).\n * @returns The positions response.\n */\n async fetchOpenPositions(\n options: FetchPositionsOptions,\n ): Promise<PositionsResponse> {\n return this.#fetchPositions('open', options);\n }\n\n /**\n * Fetches a trader's closed positions.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/positions/closed`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @param options.chain - Filter by chain.\n * @param options.sort - Sort by 'value' or 'latest'.\n * @param options.limit - Number of results per page.\n * @param options.page - Page number (1-based).\n * @returns The positions response.\n */\n async fetchClosedPositions(\n options: FetchPositionsOptions,\n ): Promise<PositionsResponse> {\n return this.#fetchPositions('closed', options);\n }\n\n /**\n * Fetches a trader's MetaMask followers.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/followers`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @returns The followers response.\n */\n async fetchFollowers(\n options: FetchFollowersOptions,\n ): Promise<FollowersResponse> {\n const { addressOrId } = options;\n\n const followersResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchFollowers`, addressOrId],\n queryFn: async () => {\n const url = `${this.#v1Url}/traders/${encodeURIComponent(addressOrId)}/followers`;\n const response = await fetch(url);\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_FOLLOWERS_FAILED,\n );\n const followersData = await response.json();\n if (!is(followersData, FollowersResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_FOLLOWERS_INVALID_RESPONSE,\n );\n }\n return followersData as FollowersResponse;\n },\n });\n\n return followersResponse;\n }\n\n /**\n * Fetches the list of traders a user is following.\n *\n * Calls `GET ${baseUrl}/users/${addressOrUid}/following`.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID.\n * @returns The following response.\n */\n async fetchFollowing(\n options: FetchFollowingOptions,\n ): Promise<FollowingResponse> {\n const { addressOrUid } = options;\n\n const followingResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchFollowing`, addressOrUid],\n staleTime: 0,\n queryFn: async () => {\n const url = `${this.#v1Url}/users/${encodeURIComponent(addressOrUid)}/following`;\n const response = await fetch(url);\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_FOLLOWING_FAILED,\n );\n const followingData = await response.json();\n if (!is(followingData, FollowingResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_FOLLOWING_INVALID_RESPONSE,\n );\n }\n return followingData as FollowingResponse;\n },\n });\n\n return followingResponse;\n }\n\n /**\n * Follows one or more traders.\n *\n * Calls `PUT ${baseUrl}/users/${addressOrUid}/follows`.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the user.\n * @param options.targets - Array of wallet addresses or profile IDs to follow.\n * @returns The follow response with confirmed follows.\n */\n async follow(options: FollowOptions): Promise<FollowResponse> {\n const { addressOrUid, targets } = options;\n\n const followResponse = await this.fetchQuery({\n queryKey: [`${this.name}:follow`, addressOrUid, targets],\n staleTime: 0,\n queryFn: async () => {\n const url = `${this.#v1Url}/users/${encodeURIComponent(addressOrUid)}/follows`;\n const response = await fetch(url, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ targets }),\n });\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FOLLOW_FAILED,\n );\n const followData = await response.json();\n if (!is(followData, FollowResponseStruct)) {\n throw new Error(SocialServiceErrorMessage.FOLLOW_INVALID_RESPONSE);\n }\n return followData as FollowResponse;\n },\n });\n\n return followResponse;\n }\n\n /**\n * Unfollows one or more traders.\n *\n * Calls `DELETE ${baseUrl}/users/${addressOrUid}/follows?targets=...`.\n * Targets are sent as query params because Fastify does not parse\n * request bodies on DELETE requests per RFC 9110.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the user.\n * @param options.targets - Array of wallet addresses or profile IDs to unfollow.\n * @returns The unfollow response with confirmed unfollows.\n */\n async unfollow(options: UnfollowOptions): Promise<UnfollowResponse> {\n const { addressOrUid, targets } = options;\n\n const unfollowResponse = await this.fetchQuery({\n queryKey: [`${this.name}:unfollow`, addressOrUid, targets],\n staleTime: 0,\n queryFn: async () => {\n const url = new URL(\n `${this.#v1Url}/users/${encodeURIComponent(addressOrUid)}/follows`,\n );\n for (const target of targets) {\n url.searchParams.append('targets', target);\n }\n const response = await fetch(url.toString(), { method: 'DELETE' });\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.UNFOLLOW_FAILED,\n );\n const unfollowData = await response.json();\n if (!is(unfollowData, UnfollowResponseStruct)) {\n throw new Error(SocialServiceErrorMessage.UNFOLLOW_INVALID_RESPONSE);\n }\n return unfollowData as UnfollowResponse;\n },\n });\n\n return unfollowResponse;\n }\n\n /**\n * Shared helper for fetching open/closed positions.\n *\n * @param status - \"open\" or \"closed\".\n * @param options - Options bag including addressOrId and query parameters.\n * @returns The positions response.\n */\n async #fetchPositions(\n status: 'open' | 'closed',\n options: FetchPositionsOptions,\n ): Promise<PositionsResponse> {\n const { addressOrId, chain, sort, limit, page } = options;\n\n const failedMessage =\n status === 'open'\n ? SocialServiceErrorMessage.FETCH_OPEN_POSITIONS_FAILED\n : SocialServiceErrorMessage.FETCH_CLOSED_POSITIONS_FAILED;\n const invalidMessage =\n status === 'open'\n ? SocialServiceErrorMessage.FETCH_OPEN_POSITIONS_INVALID_RESPONSE\n : SocialServiceErrorMessage.FETCH_CLOSED_POSITIONS_INVALID_RESPONSE;\n\n const positionsResponse = await this.fetchQuery({\n queryKey: [\n `${this.name}:fetch${status === 'open' ? 'Open' : 'Closed'}Positions`,\n addressOrId,\n chain ?? null,\n // sort is not used for open positions (v2 endpoint dropped it),\n // so exclude it from the key to avoid redundant cache entries\n status === 'closed' ? (sort ?? null) : null,\n limit ?? null,\n page ?? null,\n ],\n queryFn: async () => {\n const url = new URL(\n `${this.#v2Url}/traders/${encodeURIComponent(addressOrId)}/positions/${status}`,\n );\n if (chain) {\n url.searchParams.append('chain', chain);\n }\n // sort is not supported on the v2 open-positions endpoint\n if (sort && status === 'closed') {\n url.searchParams.append('sort', sort);\n }\n if (limit !== undefined) {\n url.searchParams.append('limit', String(limit));\n }\n if (page !== undefined) {\n url.searchParams.append('page', String(page));\n }\n\n const response = await fetch(url.toString());\n SocialService.#throwIfNotOk(response, failedMessage);\n const positionsData = await response.json();\n if (!is(positionsData, PositionsResponseStruct)) {\n throw new Error(invalidMessage);\n }\n return positionsData as PositionsResponse;\n },\n });\n\n return positionsResponse;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocialService.d.cts","sourceRoot":"","sources":["../src/SocialService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,oCAAoC,EACpC,kCAAkC,EACnC,oCAAoC;AACrC,OAAO,EAAE,eAAe,EAAE,oCAAoC;AAC9D,OAAO,KAAK,EAAE,0BAA0B,EAAE,mCAAmC;AAE7E,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAarD,OAAO,EAAE,WAAW,EAA6B,+BAA2B;AAC5E,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EACjB,2BAAuB;AACxB,OAAO,KAAK,EAAE,0BAA0B,EAAE,gDAA4C;
|
|
1
|
+
{"version":3,"file":"SocialService.d.cts","sourceRoot":"","sources":["../src/SocialService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,oCAAoC,EACpC,kCAAkC,EACnC,oCAAoC;AACrC,OAAO,EAAE,eAAe,EAAE,oCAAoC;AAC9D,OAAO,KAAK,EAAE,0BAA0B,EAAE,mCAAmC;AAE7E,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAarD,OAAO,EAAE,WAAW,EAA6B,+BAA2B;AAC5E,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EACjB,2BAAuB;AACxB,OAAO,KAAK,EAAE,0BAA0B,EAAE,gDAA4C;AAkJtF,MAAM,MAAM,oBAAoB,GAC5B,0BAA0B,GAC1B,kCAAkC,CAAC,OAAO,WAAW,CAAC,CAAC;AAE3D,MAAM,MAAM,mBAAmB,GAC3B,4BAA4B,CAAC,OAAO,WAAW,CAAC,GAChD,oCAAoC,CAAC,OAAO,WAAW,CAAC,CAAC;AAE7D,MAAM,MAAM,sBAAsB,GAAG,SAAS,CAC5C,OAAO,WAAW,EAClB,oBAAoB,EACpB,mBAAmB,CACpB,CAAC;AAMF;;GAEG;AACH,qBAAa,aAAc,SAAQ,eAAe,CAChD,OAAO,WAAW,EAClB,sBAAsB,CACvB;;gBAWa,EACV,SAAS,EACT,OAAO,EACP,aAAa,GACd,EAAE;QACD,SAAS,EAAE,sBAAsB,CAAC;QAClC,OAAO,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,0BAA0B,CAAC;KAC5C;IAsBD;;;;;;;OAOG;IACG,gBAAgB,CACpB,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,mBAAmB,CAAC;IAoC/B;;;;;;;;OAQG;IACG,kBAAkB,CACtB,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,qBAAqB,CAAC;IAyBjC;;;;;;;;;;;;OAYG;IACG,kBAAkB,CACtB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IAI7B;;;;;;;;;;;;OAYG;IACG,oBAAoB,CACxB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IAI7B;;;;;;;;OAQG;IACG,cAAc,CAClB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IAyB7B;;;;;;;;OAQG;IACG,cAAc,CAClB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IA0B7B;;;;;;;;;OASG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IA4B7D;;;;;;;;;;;OAWG;IACG,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;CA4FpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocialService.d.mts","sourceRoot":"","sources":["../src/SocialService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,oCAAoC,EACpC,kCAAkC,EACnC,oCAAoC;AACrC,OAAO,EAAE,eAAe,EAAE,oCAAoC;AAC9D,OAAO,KAAK,EAAE,0BAA0B,EAAE,mCAAmC;AAE7E,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAarD,OAAO,EAAE,WAAW,EAA6B,+BAA2B;AAC5E,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EACjB,2BAAuB;AACxB,OAAO,KAAK,EAAE,0BAA0B,EAAE,gDAA4C;
|
|
1
|
+
{"version":3,"file":"SocialService.d.mts","sourceRoot":"","sources":["../src/SocialService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,oCAAoC,EACpC,kCAAkC,EACnC,oCAAoC;AACrC,OAAO,EAAE,eAAe,EAAE,oCAAoC;AAC9D,OAAO,KAAK,EAAE,0BAA0B,EAAE,mCAAmC;AAE7E,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AAarD,OAAO,EAAE,WAAW,EAA6B,+BAA2B;AAC5E,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EACjB,2BAAuB;AACxB,OAAO,KAAK,EAAE,0BAA0B,EAAE,gDAA4C;AAkJtF,MAAM,MAAM,oBAAoB,GAC5B,0BAA0B,GAC1B,kCAAkC,CAAC,OAAO,WAAW,CAAC,CAAC;AAE3D,MAAM,MAAM,mBAAmB,GAC3B,4BAA4B,CAAC,OAAO,WAAW,CAAC,GAChD,oCAAoC,CAAC,OAAO,WAAW,CAAC,CAAC;AAE7D,MAAM,MAAM,sBAAsB,GAAG,SAAS,CAC5C,OAAO,WAAW,EAClB,oBAAoB,EACpB,mBAAmB,CACpB,CAAC;AAMF;;GAEG;AACH,qBAAa,aAAc,SAAQ,eAAe,CAChD,OAAO,WAAW,EAClB,sBAAsB,CACvB;;gBAWa,EACV,SAAS,EACT,OAAO,EACP,aAAa,GACd,EAAE;QACD,SAAS,EAAE,sBAAsB,CAAC;QAClC,OAAO,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,0BAA0B,CAAC;KAC5C;IAsBD;;;;;;;OAOG;IACG,gBAAgB,CACpB,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,mBAAmB,CAAC;IAoC/B;;;;;;;;OAQG;IACG,kBAAkB,CACtB,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,qBAAqB,CAAC;IAyBjC;;;;;;;;;;;;OAYG;IACG,kBAAkB,CACtB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IAI7B;;;;;;;;;;;;OAYG;IACG,oBAAoB,CACxB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IAI7B;;;;;;;;OAQG;IACG,cAAc,CAClB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IAyB7B;;;;;;;;OAQG;IACG,cAAc,CAClB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IA0B7B;;;;;;;;;OASG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IA4B7D;;;;;;;;;;;OAWG;IACG,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;CA4FpE"}
|
package/dist/SocialService.mjs
CHANGED
|
@@ -64,8 +64,12 @@ const LeaderboardEntryStruct = structType({
|
|
|
64
64
|
imageUrl: optional(nullable(string())),
|
|
65
65
|
pnl30d: number(),
|
|
66
66
|
winRate30d: optional(nullable(number())),
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
roiPercent30d: optional(nullable(number())),
|
|
68
|
+
tradeCount30d: optional(nullable(number())),
|
|
69
|
+
pnl7d: optional(nullable(number())),
|
|
70
|
+
winRate7d: optional(nullable(number())),
|
|
71
|
+
roiPercent7d: optional(nullable(number())),
|
|
72
|
+
tradeCount7d: optional(nullable(number())),
|
|
69
73
|
pnlPerChain: record(string(), number()),
|
|
70
74
|
followerCount: number(),
|
|
71
75
|
socialHandles: SocialHandlesStruct,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocialService.mjs","sourceRoot":"","sources":["../src/SocialService.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n DataServiceInvalidateQueriesAction,\n} from '@metamask/base-data-service';\nimport { BaseDataService } from '@metamask/base-data-service';\nimport type { CreateServicePolicyOptions } from '@metamask/controller-utils';\nimport { HttpError } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport {\n array,\n boolean,\n is,\n nullable,\n number,\n optional,\n record,\n string,\n type as structType,\n} from '@metamask/superstruct';\n\nimport { serviceName, SocialServiceErrorMessage } from './social-constants';\nimport type {\n FetchFollowersOptions,\n FetchFollowingOptions,\n FetchLeaderboardOptions,\n FetchPositionsOptions,\n FetchTraderProfileOptions,\n FollowersResponse,\n FollowingResponse,\n FollowOptions,\n FollowResponse,\n LeaderboardResponse,\n PositionsResponse,\n TraderProfileResponse,\n UnfollowOptions,\n UnfollowResponse,\n} from './social-types';\nimport type { SocialServiceMethodActions } from './SocialService-method-action-types';\n\n// ---------------------------------------------------------------------------\n// Superstruct validation schemas\n// ---------------------------------------------------------------------------\n\nconst SocialHandlesStruct = structType({\n twitter: optional(nullable(string())),\n farcaster: optional(nullable(string())),\n ens: optional(nullable(string())),\n lens: optional(nullable(string())),\n});\n\nconst ProfileSummaryStruct = structType({\n profileId: string(),\n address: string(),\n name: string(),\n imageUrl: optional(nullable(string())),\n});\n\nconst TradeStruct = structType({\n direction: string(),\n tokenAmount: number(),\n usdCost: number(),\n timestamp: number(),\n transactionHash: string(),\n});\n\nconst PositionStruct = structType({\n tokenSymbol: string(),\n tokenName: string(),\n tokenAddress: string(),\n chain: string(),\n positionAmount: number(),\n boughtUsd: number(),\n soldUsd: number(),\n realizedPnl: number(),\n costBasis: number(),\n trades: array(TradeStruct),\n lastTradeAt: number(),\n currentValueUSD: optional(nullable(number())),\n pnlValueUsd: optional(nullable(number())),\n pnlPercent: optional(nullable(number())),\n});\n\nconst PaginationStruct = structType({\n hasMore: boolean(),\n nextPage: optional(number()),\n});\n\nconst LeaderboardEntryStruct = structType({\n rank: number(),\n addresses: array(string()),\n profileId: string(),\n name: string(),\n imageUrl: optional(nullable(string())),\n pnl30d: number(),\n winRate30d: optional(nullable(number())),\n roi30d: optional(nullable(number())),\n tradeCount: optional(nullable(number())),\n pnlPerChain: record(string(), number()),\n followerCount: number(),\n socialHandles: SocialHandlesStruct,\n});\n\nconst LeaderboardResponseStruct = structType({\n traders: array(LeaderboardEntryStruct),\n});\n\nconst TraderProfileStruct = structType({\n profileId: string(),\n address: string(),\n allAddresses: array(string()),\n name: string(),\n imageUrl: optional(nullable(string())),\n});\n\nconst TraderStatsStruct = structType({\n pnl30d: optional(nullable(number())),\n winRate30d: optional(nullable(number())),\n roiPercent30d: optional(nullable(number())),\n tradeCount30d: optional(nullable(number())),\n pnl7d: optional(nullable(number())),\n winRate7d: optional(nullable(number())),\n roiPercent7d: optional(nullable(number())),\n tradeCount7d: optional(nullable(number())),\n});\n\nconst PerChainBreakdownStruct = structType({\n perChainPnl: record(string(), number()),\n perChainRoi: record(string(), nullable(number())),\n perChainVolume: record(string(), number()),\n});\n\nconst TraderProfileResponseStruct = structType({\n profile: TraderProfileStruct,\n stats: TraderStatsStruct,\n perChainBreakdown: PerChainBreakdownStruct,\n socialHandles: SocialHandlesStruct,\n followerCount: number(),\n followingCount: number(),\n});\n\nconst PositionsResponseStruct = structType({\n positions: array(PositionStruct),\n pagination: PaginationStruct,\n computedAt: optional(nullable(string())),\n});\n\nconst FollowersResponseStruct = structType({\n followers: array(ProfileSummaryStruct),\n count: number(),\n});\n\nconst FollowingResponseStruct = structType({\n following: array(ProfileSummaryStruct),\n count: number(),\n});\n\nconst FollowResponseStruct = structType({\n followed: array(ProfileSummaryStruct),\n});\n\nconst UnfollowResponseStruct = structType({\n unfollowed: array(ProfileSummaryStruct),\n});\n\n// ---------------------------------------------------------------------------\n// Messenger types\n// ---------------------------------------------------------------------------\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'fetchLeaderboard',\n 'fetchTraderProfile',\n 'fetchOpenPositions',\n 'fetchClosedPositions',\n 'fetchFollowers',\n 'fetchFollowing',\n 'follow',\n 'unfollow',\n] as const;\n\nexport type SocialServiceActions =\n | SocialServiceMethodActions\n | DataServiceInvalidateQueriesAction<typeof serviceName>;\n\nexport type SocialServiceEvents =\n | DataServiceCacheUpdatedEvent<typeof serviceName>\n | DataServiceGranularCacheUpdatedEvent<typeof serviceName>;\n\nexport type SocialServiceMessenger = Messenger<\n typeof serviceName,\n SocialServiceActions,\n SocialServiceEvents\n>;\n\n// ---------------------------------------------------------------------------\n// Service\n// ---------------------------------------------------------------------------\n\n/**\n * Data service wrapping social-api endpoints.\n */\nexport class SocialService extends BaseDataService<\n typeof serviceName,\n SocialServiceMessenger\n> {\n readonly #baseUrl: string;\n\n get #v1Url(): string {\n return `${this.#baseUrl}/api/v1`;\n }\n\n get #v2Url(): string {\n return `${this.#baseUrl}/api/v2`;\n }\n\n constructor({\n messenger,\n baseUrl,\n policyOptions,\n }: {\n messenger: SocialServiceMessenger;\n baseUrl: string;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n super({ name: serviceName, messenger, policyOptions });\n this.#baseUrl = baseUrl;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Throws an HttpError if the response is not ok.\n *\n * @param response - The fetch response to check.\n * @param message - The error message prefix from SocialServiceErrorMessage.\n */\n static #throwIfNotOk(response: Response, message: string): void {\n if (!response.ok) {\n throw new HttpError(response.status, `${message}: ${response.status}`);\n }\n }\n\n /**\n * Fetches the leaderboard of top traders.\n *\n * Calls `GET ${baseUrl}/leaderboard`.\n *\n * @param options - Optional query parameters for sorting, chain filtering, and limit.\n * @returns The leaderboard response with ranked traders.\n */\n async fetchLeaderboard(\n options?: FetchLeaderboardOptions,\n ): Promise<LeaderboardResponse> {\n const leaderboardResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchLeaderboard`, options ?? null],\n queryFn: async () => {\n const { sort, chains, limit } = options ?? {};\n const url = new URL(`${this.#v1Url}/leaderboard`);\n if (sort) {\n url.searchParams.append('sort', sort);\n }\n if (chains) {\n for (const chain of chains) {\n url.searchParams.append('chains', chain);\n }\n }\n if (limit !== undefined) {\n url.searchParams.append('limit', String(limit));\n }\n\n const response = await fetch(url.toString());\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_LEADERBOARD_FAILED,\n );\n const leaderboardData = await response.json();\n if (!is(leaderboardData, LeaderboardResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_LEADERBOARD_INVALID_RESPONSE,\n );\n }\n return leaderboardData as LeaderboardResponse;\n },\n });\n\n return leaderboardResponse;\n }\n\n /**\n * Fetches a trader's profile by address or profile ID.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/profile`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @returns The trader profile response.\n */\n async fetchTraderProfile(\n options: FetchTraderProfileOptions,\n ): Promise<TraderProfileResponse> {\n const { addressOrId } = options;\n\n const traderProfileResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchTraderProfile`, addressOrId],\n queryFn: async () => {\n const url = `${this.#v1Url}/traders/${encodeURIComponent(addressOrId)}/profile`;\n const response = await fetch(url);\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_TRADER_PROFILE_FAILED,\n );\n const traderProfileData = await response.json();\n if (!is(traderProfileData, TraderProfileResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_TRADER_PROFILE_INVALID_RESPONSE,\n );\n }\n return traderProfileData as TraderProfileResponse;\n },\n });\n\n return traderProfileResponse;\n }\n\n /**\n * Fetches a trader's open positions.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/positions/open`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @param options.chain - Filter by chain.\n * @param options.sort - Sort by 'value' or 'latest'.\n * @param options.limit - Number of results per page.\n * @param options.page - Page number (1-based).\n * @returns The positions response.\n */\n async fetchOpenPositions(\n options: FetchPositionsOptions,\n ): Promise<PositionsResponse> {\n return this.#fetchPositions('open', options);\n }\n\n /**\n * Fetches a trader's closed positions.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/positions/closed`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @param options.chain - Filter by chain.\n * @param options.sort - Sort by 'value' or 'latest'.\n * @param options.limit - Number of results per page.\n * @param options.page - Page number (1-based).\n * @returns The positions response.\n */\n async fetchClosedPositions(\n options: FetchPositionsOptions,\n ): Promise<PositionsResponse> {\n return this.#fetchPositions('closed', options);\n }\n\n /**\n * Fetches a trader's MetaMask followers.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/followers`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @returns The followers response.\n */\n async fetchFollowers(\n options: FetchFollowersOptions,\n ): Promise<FollowersResponse> {\n const { addressOrId } = options;\n\n const followersResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchFollowers`, addressOrId],\n queryFn: async () => {\n const url = `${this.#v1Url}/traders/${encodeURIComponent(addressOrId)}/followers`;\n const response = await fetch(url);\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_FOLLOWERS_FAILED,\n );\n const followersData = await response.json();\n if (!is(followersData, FollowersResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_FOLLOWERS_INVALID_RESPONSE,\n );\n }\n return followersData as FollowersResponse;\n },\n });\n\n return followersResponse;\n }\n\n /**\n * Fetches the list of traders a user is following.\n *\n * Calls `GET ${baseUrl}/users/${addressOrUid}/following`.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID.\n * @returns The following response.\n */\n async fetchFollowing(\n options: FetchFollowingOptions,\n ): Promise<FollowingResponse> {\n const { addressOrUid } = options;\n\n const followingResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchFollowing`, addressOrUid],\n staleTime: 0,\n queryFn: async () => {\n const url = `${this.#v1Url}/users/${encodeURIComponent(addressOrUid)}/following`;\n const response = await fetch(url);\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_FOLLOWING_FAILED,\n );\n const followingData = await response.json();\n if (!is(followingData, FollowingResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_FOLLOWING_INVALID_RESPONSE,\n );\n }\n return followingData as FollowingResponse;\n },\n });\n\n return followingResponse;\n }\n\n /**\n * Follows one or more traders.\n *\n * Calls `PUT ${baseUrl}/users/${addressOrUid}/follows`.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the user.\n * @param options.targets - Array of wallet addresses or profile IDs to follow.\n * @returns The follow response with confirmed follows.\n */\n async follow(options: FollowOptions): Promise<FollowResponse> {\n const { addressOrUid, targets } = options;\n\n const followResponse = await this.fetchQuery({\n queryKey: [`${this.name}:follow`, addressOrUid, targets],\n staleTime: 0,\n queryFn: async () => {\n const url = `${this.#v1Url}/users/${encodeURIComponent(addressOrUid)}/follows`;\n const response = await fetch(url, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ targets }),\n });\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FOLLOW_FAILED,\n );\n const followData = await response.json();\n if (!is(followData, FollowResponseStruct)) {\n throw new Error(SocialServiceErrorMessage.FOLLOW_INVALID_RESPONSE);\n }\n return followData as FollowResponse;\n },\n });\n\n return followResponse;\n }\n\n /**\n * Unfollows one or more traders.\n *\n * Calls `DELETE ${baseUrl}/users/${addressOrUid}/follows?targets=...`.\n * Targets are sent as query params because Fastify does not parse\n * request bodies on DELETE requests per RFC 9110.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the user.\n * @param options.targets - Array of wallet addresses or profile IDs to unfollow.\n * @returns The unfollow response with confirmed unfollows.\n */\n async unfollow(options: UnfollowOptions): Promise<UnfollowResponse> {\n const { addressOrUid, targets } = options;\n\n const unfollowResponse = await this.fetchQuery({\n queryKey: [`${this.name}:unfollow`, addressOrUid, targets],\n staleTime: 0,\n queryFn: async () => {\n const url = new URL(\n `${this.#v1Url}/users/${encodeURIComponent(addressOrUid)}/follows`,\n );\n for (const target of targets) {\n url.searchParams.append('targets', target);\n }\n const response = await fetch(url.toString(), { method: 'DELETE' });\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.UNFOLLOW_FAILED,\n );\n const unfollowData = await response.json();\n if (!is(unfollowData, UnfollowResponseStruct)) {\n throw new Error(SocialServiceErrorMessage.UNFOLLOW_INVALID_RESPONSE);\n }\n return unfollowData as UnfollowResponse;\n },\n });\n\n return unfollowResponse;\n }\n\n /**\n * Shared helper for fetching open/closed positions.\n *\n * @param status - \"open\" or \"closed\".\n * @param options - Options bag including addressOrId and query parameters.\n * @returns The positions response.\n */\n async #fetchPositions(\n status: 'open' | 'closed',\n options: FetchPositionsOptions,\n ): Promise<PositionsResponse> {\n const { addressOrId, chain, sort, limit, page } = options;\n\n const failedMessage =\n status === 'open'\n ? SocialServiceErrorMessage.FETCH_OPEN_POSITIONS_FAILED\n : SocialServiceErrorMessage.FETCH_CLOSED_POSITIONS_FAILED;\n const invalidMessage =\n status === 'open'\n ? SocialServiceErrorMessage.FETCH_OPEN_POSITIONS_INVALID_RESPONSE\n : SocialServiceErrorMessage.FETCH_CLOSED_POSITIONS_INVALID_RESPONSE;\n\n const positionsResponse = await this.fetchQuery({\n queryKey: [\n `${this.name}:fetch${status === 'open' ? 'Open' : 'Closed'}Positions`,\n addressOrId,\n chain ?? null,\n // sort is not used for open positions (v2 endpoint dropped it),\n // so exclude it from the key to avoid redundant cache entries\n status === 'closed' ? (sort ?? null) : null,\n limit ?? null,\n page ?? null,\n ],\n queryFn: async () => {\n const url = new URL(\n `${this.#v2Url}/traders/${encodeURIComponent(addressOrId)}/positions/${status}`,\n );\n if (chain) {\n url.searchParams.append('chain', chain);\n }\n // sort is not supported on the v2 open-positions endpoint\n if (sort && status === 'closed') {\n url.searchParams.append('sort', sort);\n }\n if (limit !== undefined) {\n url.searchParams.append('limit', String(limit));\n }\n if (page !== undefined) {\n url.searchParams.append('page', String(page));\n }\n\n const response = await fetch(url.toString());\n SocialService.#throwIfNotOk(response, failedMessage);\n const positionsData = await response.json();\n if (!is(positionsData, PositionsResponseStruct)) {\n throw new Error(invalidMessage);\n }\n return positionsData as PositionsResponse;\n },\n });\n\n return positionsResponse;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SocialService.mjs","sourceRoot":"","sources":["../src/SocialService.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n DataServiceInvalidateQueriesAction,\n} from '@metamask/base-data-service';\nimport { BaseDataService } from '@metamask/base-data-service';\nimport type { CreateServicePolicyOptions } from '@metamask/controller-utils';\nimport { HttpError } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport {\n array,\n boolean,\n is,\n nullable,\n number,\n optional,\n record,\n string,\n type as structType,\n} from '@metamask/superstruct';\n\nimport { serviceName, SocialServiceErrorMessage } from './social-constants';\nimport type {\n FetchFollowersOptions,\n FetchFollowingOptions,\n FetchLeaderboardOptions,\n FetchPositionsOptions,\n FetchTraderProfileOptions,\n FollowersResponse,\n FollowingResponse,\n FollowOptions,\n FollowResponse,\n LeaderboardResponse,\n PositionsResponse,\n TraderProfileResponse,\n UnfollowOptions,\n UnfollowResponse,\n} from './social-types';\nimport type { SocialServiceMethodActions } from './SocialService-method-action-types';\n\n// ---------------------------------------------------------------------------\n// Superstruct validation schemas\n// ---------------------------------------------------------------------------\n\nconst SocialHandlesStruct = structType({\n twitter: optional(nullable(string())),\n farcaster: optional(nullable(string())),\n ens: optional(nullable(string())),\n lens: optional(nullable(string())),\n});\n\nconst ProfileSummaryStruct = structType({\n profileId: string(),\n address: string(),\n name: string(),\n imageUrl: optional(nullable(string())),\n});\n\nconst TradeStruct = structType({\n direction: string(),\n tokenAmount: number(),\n usdCost: number(),\n timestamp: number(),\n transactionHash: string(),\n});\n\nconst PositionStruct = structType({\n tokenSymbol: string(),\n tokenName: string(),\n tokenAddress: string(),\n chain: string(),\n positionAmount: number(),\n boughtUsd: number(),\n soldUsd: number(),\n realizedPnl: number(),\n costBasis: number(),\n trades: array(TradeStruct),\n lastTradeAt: number(),\n currentValueUSD: optional(nullable(number())),\n pnlValueUsd: optional(nullable(number())),\n pnlPercent: optional(nullable(number())),\n});\n\nconst PaginationStruct = structType({\n hasMore: boolean(),\n nextPage: optional(number()),\n});\n\nconst LeaderboardEntryStruct = structType({\n rank: number(),\n addresses: array(string()),\n profileId: string(),\n name: string(),\n imageUrl: optional(nullable(string())),\n pnl30d: number(),\n winRate30d: optional(nullable(number())),\n roiPercent30d: optional(nullable(number())),\n tradeCount30d: optional(nullable(number())),\n pnl7d: optional(nullable(number())),\n winRate7d: optional(nullable(number())),\n roiPercent7d: optional(nullable(number())),\n tradeCount7d: optional(nullable(number())),\n pnlPerChain: record(string(), number()),\n followerCount: number(),\n socialHandles: SocialHandlesStruct,\n});\n\nconst LeaderboardResponseStruct = structType({\n traders: array(LeaderboardEntryStruct),\n});\n\nconst TraderProfileStruct = structType({\n profileId: string(),\n address: string(),\n allAddresses: array(string()),\n name: string(),\n imageUrl: optional(nullable(string())),\n});\n\nconst TraderStatsStruct = structType({\n pnl30d: optional(nullable(number())),\n winRate30d: optional(nullable(number())),\n roiPercent30d: optional(nullable(number())),\n tradeCount30d: optional(nullable(number())),\n pnl7d: optional(nullable(number())),\n winRate7d: optional(nullable(number())),\n roiPercent7d: optional(nullable(number())),\n tradeCount7d: optional(nullable(number())),\n});\n\nconst PerChainBreakdownStruct = structType({\n perChainPnl: record(string(), number()),\n perChainRoi: record(string(), nullable(number())),\n perChainVolume: record(string(), number()),\n});\n\nconst TraderProfileResponseStruct = structType({\n profile: TraderProfileStruct,\n stats: TraderStatsStruct,\n perChainBreakdown: PerChainBreakdownStruct,\n socialHandles: SocialHandlesStruct,\n followerCount: number(),\n followingCount: number(),\n});\n\nconst PositionsResponseStruct = structType({\n positions: array(PositionStruct),\n pagination: PaginationStruct,\n computedAt: optional(nullable(string())),\n});\n\nconst FollowersResponseStruct = structType({\n followers: array(ProfileSummaryStruct),\n count: number(),\n});\n\nconst FollowingResponseStruct = structType({\n following: array(ProfileSummaryStruct),\n count: number(),\n});\n\nconst FollowResponseStruct = structType({\n followed: array(ProfileSummaryStruct),\n});\n\nconst UnfollowResponseStruct = structType({\n unfollowed: array(ProfileSummaryStruct),\n});\n\n// ---------------------------------------------------------------------------\n// Messenger types\n// ---------------------------------------------------------------------------\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'fetchLeaderboard',\n 'fetchTraderProfile',\n 'fetchOpenPositions',\n 'fetchClosedPositions',\n 'fetchFollowers',\n 'fetchFollowing',\n 'follow',\n 'unfollow',\n] as const;\n\nexport type SocialServiceActions =\n | SocialServiceMethodActions\n | DataServiceInvalidateQueriesAction<typeof serviceName>;\n\nexport type SocialServiceEvents =\n | DataServiceCacheUpdatedEvent<typeof serviceName>\n | DataServiceGranularCacheUpdatedEvent<typeof serviceName>;\n\nexport type SocialServiceMessenger = Messenger<\n typeof serviceName,\n SocialServiceActions,\n SocialServiceEvents\n>;\n\n// ---------------------------------------------------------------------------\n// Service\n// ---------------------------------------------------------------------------\n\n/**\n * Data service wrapping social-api endpoints.\n */\nexport class SocialService extends BaseDataService<\n typeof serviceName,\n SocialServiceMessenger\n> {\n readonly #baseUrl: string;\n\n get #v1Url(): string {\n return `${this.#baseUrl}/api/v1`;\n }\n\n get #v2Url(): string {\n return `${this.#baseUrl}/api/v2`;\n }\n\n constructor({\n messenger,\n baseUrl,\n policyOptions,\n }: {\n messenger: SocialServiceMessenger;\n baseUrl: string;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n super({ name: serviceName, messenger, policyOptions });\n this.#baseUrl = baseUrl;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Throws an HttpError if the response is not ok.\n *\n * @param response - The fetch response to check.\n * @param message - The error message prefix from SocialServiceErrorMessage.\n */\n static #throwIfNotOk(response: Response, message: string): void {\n if (!response.ok) {\n throw new HttpError(response.status, `${message}: ${response.status}`);\n }\n }\n\n /**\n * Fetches the leaderboard of top traders.\n *\n * Calls `GET ${baseUrl}/leaderboard`.\n *\n * @param options - Optional query parameters for sorting, chain filtering, and limit.\n * @returns The leaderboard response with ranked traders.\n */\n async fetchLeaderboard(\n options?: FetchLeaderboardOptions,\n ): Promise<LeaderboardResponse> {\n const leaderboardResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchLeaderboard`, options ?? null],\n queryFn: async () => {\n const { sort, chains, limit } = options ?? {};\n const url = new URL(`${this.#v1Url}/leaderboard`);\n if (sort) {\n url.searchParams.append('sort', sort);\n }\n if (chains) {\n for (const chain of chains) {\n url.searchParams.append('chains', chain);\n }\n }\n if (limit !== undefined) {\n url.searchParams.append('limit', String(limit));\n }\n\n const response = await fetch(url.toString());\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_LEADERBOARD_FAILED,\n );\n const leaderboardData = await response.json();\n if (!is(leaderboardData, LeaderboardResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_LEADERBOARD_INVALID_RESPONSE,\n );\n }\n return leaderboardData as LeaderboardResponse;\n },\n });\n\n return leaderboardResponse;\n }\n\n /**\n * Fetches a trader's profile by address or profile ID.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/profile`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @returns The trader profile response.\n */\n async fetchTraderProfile(\n options: FetchTraderProfileOptions,\n ): Promise<TraderProfileResponse> {\n const { addressOrId } = options;\n\n const traderProfileResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchTraderProfile`, addressOrId],\n queryFn: async () => {\n const url = `${this.#v1Url}/traders/${encodeURIComponent(addressOrId)}/profile`;\n const response = await fetch(url);\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_TRADER_PROFILE_FAILED,\n );\n const traderProfileData = await response.json();\n if (!is(traderProfileData, TraderProfileResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_TRADER_PROFILE_INVALID_RESPONSE,\n );\n }\n return traderProfileData as TraderProfileResponse;\n },\n });\n\n return traderProfileResponse;\n }\n\n /**\n * Fetches a trader's open positions.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/positions/open`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @param options.chain - Filter by chain.\n * @param options.sort - Sort by 'value' or 'latest'.\n * @param options.limit - Number of results per page.\n * @param options.page - Page number (1-based).\n * @returns The positions response.\n */\n async fetchOpenPositions(\n options: FetchPositionsOptions,\n ): Promise<PositionsResponse> {\n return this.#fetchPositions('open', options);\n }\n\n /**\n * Fetches a trader's closed positions.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/positions/closed`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @param options.chain - Filter by chain.\n * @param options.sort - Sort by 'value' or 'latest'.\n * @param options.limit - Number of results per page.\n * @param options.page - Page number (1-based).\n * @returns The positions response.\n */\n async fetchClosedPositions(\n options: FetchPositionsOptions,\n ): Promise<PositionsResponse> {\n return this.#fetchPositions('closed', options);\n }\n\n /**\n * Fetches a trader's MetaMask followers.\n *\n * Calls `GET ${baseUrl}/traders/${addressOrId}/followers`.\n *\n * @param options - Options bag.\n * @param options.addressOrId - Wallet address or Clicker profile ID.\n * @returns The followers response.\n */\n async fetchFollowers(\n options: FetchFollowersOptions,\n ): Promise<FollowersResponse> {\n const { addressOrId } = options;\n\n const followersResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchFollowers`, addressOrId],\n queryFn: async () => {\n const url = `${this.#v1Url}/traders/${encodeURIComponent(addressOrId)}/followers`;\n const response = await fetch(url);\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_FOLLOWERS_FAILED,\n );\n const followersData = await response.json();\n if (!is(followersData, FollowersResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_FOLLOWERS_INVALID_RESPONSE,\n );\n }\n return followersData as FollowersResponse;\n },\n });\n\n return followersResponse;\n }\n\n /**\n * Fetches the list of traders a user is following.\n *\n * Calls `GET ${baseUrl}/users/${addressOrUid}/following`.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID.\n * @returns The following response.\n */\n async fetchFollowing(\n options: FetchFollowingOptions,\n ): Promise<FollowingResponse> {\n const { addressOrUid } = options;\n\n const followingResponse = await this.fetchQuery({\n queryKey: [`${this.name}:fetchFollowing`, addressOrUid],\n staleTime: 0,\n queryFn: async () => {\n const url = `${this.#v1Url}/users/${encodeURIComponent(addressOrUid)}/following`;\n const response = await fetch(url);\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FETCH_FOLLOWING_FAILED,\n );\n const followingData = await response.json();\n if (!is(followingData, FollowingResponseStruct)) {\n throw new Error(\n SocialServiceErrorMessage.FETCH_FOLLOWING_INVALID_RESPONSE,\n );\n }\n return followingData as FollowingResponse;\n },\n });\n\n return followingResponse;\n }\n\n /**\n * Follows one or more traders.\n *\n * Calls `PUT ${baseUrl}/users/${addressOrUid}/follows`.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the user.\n * @param options.targets - Array of wallet addresses or profile IDs to follow.\n * @returns The follow response with confirmed follows.\n */\n async follow(options: FollowOptions): Promise<FollowResponse> {\n const { addressOrUid, targets } = options;\n\n const followResponse = await this.fetchQuery({\n queryKey: [`${this.name}:follow`, addressOrUid, targets],\n staleTime: 0,\n queryFn: async () => {\n const url = `${this.#v1Url}/users/${encodeURIComponent(addressOrUid)}/follows`;\n const response = await fetch(url, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ targets }),\n });\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.FOLLOW_FAILED,\n );\n const followData = await response.json();\n if (!is(followData, FollowResponseStruct)) {\n throw new Error(SocialServiceErrorMessage.FOLLOW_INVALID_RESPONSE);\n }\n return followData as FollowResponse;\n },\n });\n\n return followResponse;\n }\n\n /**\n * Unfollows one or more traders.\n *\n * Calls `DELETE ${baseUrl}/users/${addressOrUid}/follows?targets=...`.\n * Targets are sent as query params because Fastify does not parse\n * request bodies on DELETE requests per RFC 9110.\n *\n * @param options - Options bag.\n * @param options.addressOrUid - Wallet address or Clicker profile ID of the user.\n * @param options.targets - Array of wallet addresses or profile IDs to unfollow.\n * @returns The unfollow response with confirmed unfollows.\n */\n async unfollow(options: UnfollowOptions): Promise<UnfollowResponse> {\n const { addressOrUid, targets } = options;\n\n const unfollowResponse = await this.fetchQuery({\n queryKey: [`${this.name}:unfollow`, addressOrUid, targets],\n staleTime: 0,\n queryFn: async () => {\n const url = new URL(\n `${this.#v1Url}/users/${encodeURIComponent(addressOrUid)}/follows`,\n );\n for (const target of targets) {\n url.searchParams.append('targets', target);\n }\n const response = await fetch(url.toString(), { method: 'DELETE' });\n SocialService.#throwIfNotOk(\n response,\n SocialServiceErrorMessage.UNFOLLOW_FAILED,\n );\n const unfollowData = await response.json();\n if (!is(unfollowData, UnfollowResponseStruct)) {\n throw new Error(SocialServiceErrorMessage.UNFOLLOW_INVALID_RESPONSE);\n }\n return unfollowData as UnfollowResponse;\n },\n });\n\n return unfollowResponse;\n }\n\n /**\n * Shared helper for fetching open/closed positions.\n *\n * @param status - \"open\" or \"closed\".\n * @param options - Options bag including addressOrId and query parameters.\n * @returns The positions response.\n */\n async #fetchPositions(\n status: 'open' | 'closed',\n options: FetchPositionsOptions,\n ): Promise<PositionsResponse> {\n const { addressOrId, chain, sort, limit, page } = options;\n\n const failedMessage =\n status === 'open'\n ? SocialServiceErrorMessage.FETCH_OPEN_POSITIONS_FAILED\n : SocialServiceErrorMessage.FETCH_CLOSED_POSITIONS_FAILED;\n const invalidMessage =\n status === 'open'\n ? SocialServiceErrorMessage.FETCH_OPEN_POSITIONS_INVALID_RESPONSE\n : SocialServiceErrorMessage.FETCH_CLOSED_POSITIONS_INVALID_RESPONSE;\n\n const positionsResponse = await this.fetchQuery({\n queryKey: [\n `${this.name}:fetch${status === 'open' ? 'Open' : 'Closed'}Positions`,\n addressOrId,\n chain ?? null,\n // sort is not used for open positions (v2 endpoint dropped it),\n // so exclude it from the key to avoid redundant cache entries\n status === 'closed' ? (sort ?? null) : null,\n limit ?? null,\n page ?? null,\n ],\n queryFn: async () => {\n const url = new URL(\n `${this.#v2Url}/traders/${encodeURIComponent(addressOrId)}/positions/${status}`,\n );\n if (chain) {\n url.searchParams.append('chain', chain);\n }\n // sort is not supported on the v2 open-positions endpoint\n if (sort && status === 'closed') {\n url.searchParams.append('sort', sort);\n }\n if (limit !== undefined) {\n url.searchParams.append('limit', String(limit));\n }\n if (page !== undefined) {\n url.searchParams.append('page', String(page));\n }\n\n const response = await fetch(url.toString());\n SocialService.#throwIfNotOk(response, failedMessage);\n const positionsData = await response.json();\n if (!is(positionsData, PositionsResponseStruct)) {\n throw new Error(invalidMessage);\n }\n return positionsData as PositionsResponse;\n },\n });\n\n return positionsResponse;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"social-types.cjs","sourceRoot":"","sources":["../src/social-types.ts"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E","sourcesContent":["// ---------------------------------------------------------------------------\n// Shared sub-types\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal profile summary used across follow/follower responses.\n */\nexport type ProfileSummary = {\n /** Clicker profile ID (UUID). */\n profileId: string;\n /** Primary wallet address. */\n address: string;\n /** Display name or truncated address. */\n name: string;\n /** Profile avatar URL. */\n imageUrl?: string | null;\n};\n\n/**\n * Social media handles attached to a trader profile.\n */\nexport type SocialHandles = {\n twitter?: string | null;\n farcaster?: string | null;\n ens?: string | null;\n lens?: string | null;\n};\n\n/**\n * A single trade within a position.\n */\nexport type Trade = {\n /** \"buy\" or \"sell\". */\n direction: string;\n /** Quantity traded. */\n tokenAmount: number;\n /** USD value of the trade. */\n usdCost: number;\n /** Unix timestamp. */\n timestamp: number;\n /** On-chain transaction hash. */\n transactionHash: string;\n};\n\n// ---------------------------------------------------------------------------\n// Leaderboard\n// ---------------------------------------------------------------------------\n\n/**\n * A single entry in the leaderboard response.\n */\nexport type LeaderboardEntry = {\n rank: number;\n addresses: string[];\n profileId: string;\n name: string;\n imageUrl?: string | null;\n pnl30d: number;\n winRate30d?: number | null;\n roi30d?: number | null;\n tradeCount?: number | null;\n pnlPerChain: Record<string, number>;\n followerCount: number;\n socialHandles: SocialHandles;\n};\n\n/**\n * Response from `GET /v1/leaderboard`.\n */\nexport type LeaderboardResponse = {\n traders: LeaderboardEntry[];\n};\n\n// ---------------------------------------------------------------------------\n// Trader profile\n// ---------------------------------------------------------------------------\n\nexport type TraderProfile = {\n profileId: string;\n address: string;\n allAddresses: string[];\n name: string;\n imageUrl?: string | null;\n};\n\nexport type TraderStats = {\n pnl30d?: number | null;\n winRate30d?: number | null;\n /** Renamed from roi30d. */\n roiPercent30d?: number | null;\n /** Renamed from tradeCount. */\n tradeCount30d?: number | null;\n pnl7d?: number | null;\n winRate7d?: number | null;\n roiPercent7d?: number | null;\n tradeCount7d?: number | null;\n};\n\nexport type PerChainBreakdown = {\n perChainPnl: Record<string, number>;\n /** ROI can be null for chains with no trading activity (zero cost-basis). */\n perChainRoi: Record<string, number | null>;\n perChainVolume: Record<string, number>;\n};\n\n/**\n * Response from `GET /v1/traders/:addressOrId/profile`.\n */\nexport type TraderProfileResponse = {\n profile: TraderProfile;\n stats: TraderStats;\n perChainBreakdown: PerChainBreakdown;\n socialHandles: SocialHandles;\n followerCount: number;\n followingCount: number;\n};\n\n// ---------------------------------------------------------------------------\n// Positions\n// ---------------------------------------------------------------------------\n\nexport type Position = {\n tokenSymbol: string;\n tokenName: string;\n tokenAddress: string;\n chain: string;\n positionAmount: number;\n boughtUsd: number;\n soldUsd: number;\n realizedPnl: number;\n costBasis: number;\n trades: Trade[];\n lastTradeAt: number;\n /** Current USD value of the remaining position (open positions only). */\n currentValueUSD?: number | null;\n /** Unrealized + realized PnL in USD. */\n pnlValueUsd?: number | null;\n /** PnL as a percentage of cost basis. */\n pnlPercent?: number | null;\n};\n\nexport type Pagination = {\n hasMore: boolean;\n nextPage?: number;\n};\n\n/**\n * Response from `GET /v1/traders/:addressOrId/positions/open`\n * and `GET /v1/traders/:addressOrId/positions/closed`.\n */\nexport type PositionsResponse = {\n positions: Position[];\n pagination: Pagination;\n /** ISO 8601 timestamp indicating when the response was computed server-side. */\n computedAt?: string | null;\n};\n\n// ---------------------------------------------------------------------------\n// Followers\n// ---------------------------------------------------------------------------\n\n/**\n * Response from `GET /v1/traders/:addressOrId/followers`.\n */\nexport type FollowersResponse = {\n followers: ProfileSummary[];\n count: number;\n};\n\n// ---------------------------------------------------------------------------\n// Following\n// ---------------------------------------------------------------------------\n\n/**\n * Response from `GET /v1/users/:addressOrUid/following`.\n */\nexport type FollowingResponse = {\n following: ProfileSummary[];\n count: number;\n};\n\n// ---------------------------------------------------------------------------\n// Follow / Unfollow\n// ---------------------------------------------------------------------------\n\n/**\n * Response from `PUT /v1/users/:addressOrUid/follows`.\n */\nexport type FollowResponse = {\n followed: ProfileSummary[];\n};\n\n/**\n * Response from `DELETE /v1/users/:addressOrUid/follows`.\n */\nexport type UnfollowResponse = {\n unfollowed: ProfileSummary[];\n};\n\n// ---------------------------------------------------------------------------\n// Fetch options\n// ---------------------------------------------------------------------------\n\nexport type FetchLeaderboardOptions = {\n sort?: 'pnl' | 'winRate' | 'roi';\n chains?: string[];\n limit?: number;\n};\n\nexport type FetchTraderProfileOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrId: string;\n};\n\nexport type FetchPositionsOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrId: string;\n chain?: string;\n sort?: 'value' | 'latest';\n limit?: number;\n page?: number;\n};\n\nexport type FetchFollowersOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrId: string;\n};\n\nexport type FetchFollowingOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrUid: string;\n};\n\nexport type FollowOptions = {\n /** Wallet address or Clicker profile ID of the user. */\n addressOrUid: string;\n /** Array of wallet addresses or profile IDs to follow. */\n targets: string[];\n};\n\nexport type UnfollowOptions = {\n /** Wallet address or Clicker profile ID of the user. */\n addressOrUid: string;\n /** Array of wallet addresses or profile IDs to unfollow. */\n targets: string[];\n};\n\n// ---------------------------------------------------------------------------\n// Controller state\n// ---------------------------------------------------------------------------\n\n/**\n * State managed by the SocialController.\n *\n * The controller acts as a simple store — no TTL or eviction logic.\n * The UI decides when to re-fetch; the social-api's own cache layer\n * handles upstream rate-limiting.\n */\nexport type SocialControllerState = {\n /** Cached ranked trader list from the last `updateLeaderboard` call. */\n leaderboardEntries: LeaderboardEntry[];\n /** Addresses the current user follows — drives Follow/Following button state. */\n followingAddresses: string[];\n};\n"]}
|
|
1
|
+
{"version":3,"file":"social-types.cjs","sourceRoot":"","sources":["../src/social-types.ts"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E","sourcesContent":["// ---------------------------------------------------------------------------\n// Shared sub-types\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal profile summary used across follow/follower responses.\n */\nexport type ProfileSummary = {\n /** Clicker profile ID (UUID). */\n profileId: string;\n /** Primary wallet address. */\n address: string;\n /** Display name or truncated address. */\n name: string;\n /** Profile avatar URL. */\n imageUrl?: string | null;\n};\n\n/**\n * Social media handles attached to a trader profile.\n */\nexport type SocialHandles = {\n twitter?: string | null;\n farcaster?: string | null;\n ens?: string | null;\n lens?: string | null;\n};\n\n/**\n * A single trade within a position.\n */\nexport type Trade = {\n /** \"buy\" or \"sell\". */\n direction: string;\n /** Quantity traded. */\n tokenAmount: number;\n /** USD value of the trade. */\n usdCost: number;\n /** Unix timestamp. */\n timestamp: number;\n /** On-chain transaction hash. */\n transactionHash: string;\n};\n\n// ---------------------------------------------------------------------------\n// Leaderboard\n// ---------------------------------------------------------------------------\n\n/**\n * A single entry in the leaderboard response.\n */\nexport type LeaderboardEntry = {\n rank: number;\n addresses: string[];\n profileId: string;\n name: string;\n imageUrl?: string | null;\n pnl30d: number;\n winRate30d?: number | null;\n /** Renamed from roi30d. */\n roiPercent30d?: number | null;\n /** Renamed from tradeCount. */\n tradeCount30d?: number | null;\n pnl7d?: number | null;\n winRate7d?: number | null;\n roiPercent7d?: number | null;\n tradeCount7d?: number | null;\n pnlPerChain: Record<string, number>;\n followerCount: number;\n socialHandles: SocialHandles;\n};\n\n/**\n * Response from `GET /v1/leaderboard`.\n */\nexport type LeaderboardResponse = {\n traders: LeaderboardEntry[];\n};\n\n// ---------------------------------------------------------------------------\n// Trader profile\n// ---------------------------------------------------------------------------\n\nexport type TraderProfile = {\n profileId: string;\n address: string;\n allAddresses: string[];\n name: string;\n imageUrl?: string | null;\n};\n\nexport type TraderStats = {\n pnl30d?: number | null;\n winRate30d?: number | null;\n /** Renamed from roi30d. */\n roiPercent30d?: number | null;\n /** Renamed from tradeCount. */\n tradeCount30d?: number | null;\n pnl7d?: number | null;\n winRate7d?: number | null;\n roiPercent7d?: number | null;\n tradeCount7d?: number | null;\n};\n\nexport type PerChainBreakdown = {\n perChainPnl: Record<string, number>;\n /** ROI can be null for chains with no trading activity (zero cost-basis). */\n perChainRoi: Record<string, number | null>;\n perChainVolume: Record<string, number>;\n};\n\n/**\n * Response from `GET /v1/traders/:addressOrId/profile`.\n */\nexport type TraderProfileResponse = {\n profile: TraderProfile;\n stats: TraderStats;\n perChainBreakdown: PerChainBreakdown;\n socialHandles: SocialHandles;\n followerCount: number;\n followingCount: number;\n};\n\n// ---------------------------------------------------------------------------\n// Positions\n// ---------------------------------------------------------------------------\n\nexport type Position = {\n tokenSymbol: string;\n tokenName: string;\n tokenAddress: string;\n chain: string;\n positionAmount: number;\n boughtUsd: number;\n soldUsd: number;\n realizedPnl: number;\n costBasis: number;\n trades: Trade[];\n lastTradeAt: number;\n /** Current USD value of the remaining position (open positions only). */\n currentValueUSD?: number | null;\n /** Unrealized + realized PnL in USD. */\n pnlValueUsd?: number | null;\n /** PnL as a percentage of cost basis. */\n pnlPercent?: number | null;\n};\n\nexport type Pagination = {\n hasMore: boolean;\n nextPage?: number;\n};\n\n/**\n * Response from `GET /v1/traders/:addressOrId/positions/open`\n * and `GET /v1/traders/:addressOrId/positions/closed`.\n */\nexport type PositionsResponse = {\n positions: Position[];\n pagination: Pagination;\n /** ISO 8601 timestamp indicating when the response was computed server-side. */\n computedAt?: string | null;\n};\n\n// ---------------------------------------------------------------------------\n// Followers\n// ---------------------------------------------------------------------------\n\n/**\n * Response from `GET /v1/traders/:addressOrId/followers`.\n */\nexport type FollowersResponse = {\n followers: ProfileSummary[];\n count: number;\n};\n\n// ---------------------------------------------------------------------------\n// Following\n// ---------------------------------------------------------------------------\n\n/**\n * Response from `GET /v1/users/:addressOrUid/following`.\n */\nexport type FollowingResponse = {\n following: ProfileSummary[];\n count: number;\n};\n\n// ---------------------------------------------------------------------------\n// Follow / Unfollow\n// ---------------------------------------------------------------------------\n\n/**\n * Response from `PUT /v1/users/:addressOrUid/follows`.\n */\nexport type FollowResponse = {\n followed: ProfileSummary[];\n};\n\n/**\n * Response from `DELETE /v1/users/:addressOrUid/follows`.\n */\nexport type UnfollowResponse = {\n unfollowed: ProfileSummary[];\n};\n\n// ---------------------------------------------------------------------------\n// Fetch options\n// ---------------------------------------------------------------------------\n\nexport type FetchLeaderboardOptions = {\n sort?: 'pnl' | 'winRate' | 'roi';\n chains?: string[];\n limit?: number;\n};\n\nexport type FetchTraderProfileOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrId: string;\n};\n\nexport type FetchPositionsOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrId: string;\n chain?: string;\n sort?: 'value' | 'latest';\n limit?: number;\n page?: number;\n};\n\nexport type FetchFollowersOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrId: string;\n};\n\nexport type FetchFollowingOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrUid: string;\n};\n\nexport type FollowOptions = {\n /** Wallet address or Clicker profile ID of the user. */\n addressOrUid: string;\n /** Array of wallet addresses or profile IDs to follow. */\n targets: string[];\n};\n\nexport type UnfollowOptions = {\n /** Wallet address or Clicker profile ID of the user. */\n addressOrUid: string;\n /** Array of wallet addresses or profile IDs to unfollow. */\n targets: string[];\n};\n\n// ---------------------------------------------------------------------------\n// Controller state\n// ---------------------------------------------------------------------------\n\n/**\n * State managed by the SocialController.\n *\n * The controller acts as a simple store — no TTL or eviction logic.\n * The UI decides when to re-fetch; the social-api's own cache layer\n * handles upstream rate-limiting.\n */\nexport type SocialControllerState = {\n /** Cached ranked trader list from the last `updateLeaderboard` call. */\n leaderboardEntries: LeaderboardEntry[];\n /** Addresses the current user follows — drives Follow/Following button state. */\n followingAddresses: string[];\n};\n"]}
|
package/dist/social-types.d.cts
CHANGED
|
@@ -46,8 +46,14 @@ export type LeaderboardEntry = {
|
|
|
46
46
|
imageUrl?: string | null;
|
|
47
47
|
pnl30d: number;
|
|
48
48
|
winRate30d?: number | null;
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
/** Renamed from roi30d. */
|
|
50
|
+
roiPercent30d?: number | null;
|
|
51
|
+
/** Renamed from tradeCount. */
|
|
52
|
+
tradeCount30d?: number | null;
|
|
53
|
+
pnl7d?: number | null;
|
|
54
|
+
winRate7d?: number | null;
|
|
55
|
+
roiPercent7d?: number | null;
|
|
56
|
+
tradeCount7d?: number | null;
|
|
51
57
|
pnlPerChain: Record<string, number>;
|
|
52
58
|
followerCount: number;
|
|
53
59
|
socialHandles: SocialHandles;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"social-types.d.cts","sourceRoot":"","sources":["../src/social-types.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAMF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"social-types.d.cts","sourceRoot":"","sources":["../src/social-types.ts"],"names":[],"mappings":"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"}
|
package/dist/social-types.d.mts
CHANGED
|
@@ -46,8 +46,14 @@ export type LeaderboardEntry = {
|
|
|
46
46
|
imageUrl?: string | null;
|
|
47
47
|
pnl30d: number;
|
|
48
48
|
winRate30d?: number | null;
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
/** Renamed from roi30d. */
|
|
50
|
+
roiPercent30d?: number | null;
|
|
51
|
+
/** Renamed from tradeCount. */
|
|
52
|
+
tradeCount30d?: number | null;
|
|
53
|
+
pnl7d?: number | null;
|
|
54
|
+
winRate7d?: number | null;
|
|
55
|
+
roiPercent7d?: number | null;
|
|
56
|
+
tradeCount7d?: number | null;
|
|
51
57
|
pnlPerChain: Record<string, number>;
|
|
52
58
|
followerCount: number;
|
|
53
59
|
socialHandles: SocialHandles;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"social-types.d.mts","sourceRoot":"","sources":["../src/social-types.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAMF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"social-types.d.mts","sourceRoot":"","sources":["../src/social-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"social-types.mjs","sourceRoot":"","sources":["../src/social-types.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E","sourcesContent":["// ---------------------------------------------------------------------------\n// Shared sub-types\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal profile summary used across follow/follower responses.\n */\nexport type ProfileSummary = {\n /** Clicker profile ID (UUID). */\n profileId: string;\n /** Primary wallet address. */\n address: string;\n /** Display name or truncated address. */\n name: string;\n /** Profile avatar URL. */\n imageUrl?: string | null;\n};\n\n/**\n * Social media handles attached to a trader profile.\n */\nexport type SocialHandles = {\n twitter?: string | null;\n farcaster?: string | null;\n ens?: string | null;\n lens?: string | null;\n};\n\n/**\n * A single trade within a position.\n */\nexport type Trade = {\n /** \"buy\" or \"sell\". */\n direction: string;\n /** Quantity traded. */\n tokenAmount: number;\n /** USD value of the trade. */\n usdCost: number;\n /** Unix timestamp. */\n timestamp: number;\n /** On-chain transaction hash. */\n transactionHash: string;\n};\n\n// ---------------------------------------------------------------------------\n// Leaderboard\n// ---------------------------------------------------------------------------\n\n/**\n * A single entry in the leaderboard response.\n */\nexport type LeaderboardEntry = {\n rank: number;\n addresses: string[];\n profileId: string;\n name: string;\n imageUrl?: string | null;\n pnl30d: number;\n winRate30d?: number | null;\n roi30d?: number | null;\n tradeCount?: number | null;\n pnlPerChain: Record<string, number>;\n followerCount: number;\n socialHandles: SocialHandles;\n};\n\n/**\n * Response from `GET /v1/leaderboard`.\n */\nexport type LeaderboardResponse = {\n traders: LeaderboardEntry[];\n};\n\n// ---------------------------------------------------------------------------\n// Trader profile\n// ---------------------------------------------------------------------------\n\nexport type TraderProfile = {\n profileId: string;\n address: string;\n allAddresses: string[];\n name: string;\n imageUrl?: string | null;\n};\n\nexport type TraderStats = {\n pnl30d?: number | null;\n winRate30d?: number | null;\n /** Renamed from roi30d. */\n roiPercent30d?: number | null;\n /** Renamed from tradeCount. */\n tradeCount30d?: number | null;\n pnl7d?: number | null;\n winRate7d?: number | null;\n roiPercent7d?: number | null;\n tradeCount7d?: number | null;\n};\n\nexport type PerChainBreakdown = {\n perChainPnl: Record<string, number>;\n /** ROI can be null for chains with no trading activity (zero cost-basis). */\n perChainRoi: Record<string, number | null>;\n perChainVolume: Record<string, number>;\n};\n\n/**\n * Response from `GET /v1/traders/:addressOrId/profile`.\n */\nexport type TraderProfileResponse = {\n profile: TraderProfile;\n stats: TraderStats;\n perChainBreakdown: PerChainBreakdown;\n socialHandles: SocialHandles;\n followerCount: number;\n followingCount: number;\n};\n\n// ---------------------------------------------------------------------------\n// Positions\n// ---------------------------------------------------------------------------\n\nexport type Position = {\n tokenSymbol: string;\n tokenName: string;\n tokenAddress: string;\n chain: string;\n positionAmount: number;\n boughtUsd: number;\n soldUsd: number;\n realizedPnl: number;\n costBasis: number;\n trades: Trade[];\n lastTradeAt: number;\n /** Current USD value of the remaining position (open positions only). */\n currentValueUSD?: number | null;\n /** Unrealized + realized PnL in USD. */\n pnlValueUsd?: number | null;\n /** PnL as a percentage of cost basis. */\n pnlPercent?: number | null;\n};\n\nexport type Pagination = {\n hasMore: boolean;\n nextPage?: number;\n};\n\n/**\n * Response from `GET /v1/traders/:addressOrId/positions/open`\n * and `GET /v1/traders/:addressOrId/positions/closed`.\n */\nexport type PositionsResponse = {\n positions: Position[];\n pagination: Pagination;\n /** ISO 8601 timestamp indicating when the response was computed server-side. */\n computedAt?: string | null;\n};\n\n// ---------------------------------------------------------------------------\n// Followers\n// ---------------------------------------------------------------------------\n\n/**\n * Response from `GET /v1/traders/:addressOrId/followers`.\n */\nexport type FollowersResponse = {\n followers: ProfileSummary[];\n count: number;\n};\n\n// ---------------------------------------------------------------------------\n// Following\n// ---------------------------------------------------------------------------\n\n/**\n * Response from `GET /v1/users/:addressOrUid/following`.\n */\nexport type FollowingResponse = {\n following: ProfileSummary[];\n count: number;\n};\n\n// ---------------------------------------------------------------------------\n// Follow / Unfollow\n// ---------------------------------------------------------------------------\n\n/**\n * Response from `PUT /v1/users/:addressOrUid/follows`.\n */\nexport type FollowResponse = {\n followed: ProfileSummary[];\n};\n\n/**\n * Response from `DELETE /v1/users/:addressOrUid/follows`.\n */\nexport type UnfollowResponse = {\n unfollowed: ProfileSummary[];\n};\n\n// ---------------------------------------------------------------------------\n// Fetch options\n// ---------------------------------------------------------------------------\n\nexport type FetchLeaderboardOptions = {\n sort?: 'pnl' | 'winRate' | 'roi';\n chains?: string[];\n limit?: number;\n};\n\nexport type FetchTraderProfileOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrId: string;\n};\n\nexport type FetchPositionsOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrId: string;\n chain?: string;\n sort?: 'value' | 'latest';\n limit?: number;\n page?: number;\n};\n\nexport type FetchFollowersOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrId: string;\n};\n\nexport type FetchFollowingOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrUid: string;\n};\n\nexport type FollowOptions = {\n /** Wallet address or Clicker profile ID of the user. */\n addressOrUid: string;\n /** Array of wallet addresses or profile IDs to follow. */\n targets: string[];\n};\n\nexport type UnfollowOptions = {\n /** Wallet address or Clicker profile ID of the user. */\n addressOrUid: string;\n /** Array of wallet addresses or profile IDs to unfollow. */\n targets: string[];\n};\n\n// ---------------------------------------------------------------------------\n// Controller state\n// ---------------------------------------------------------------------------\n\n/**\n * State managed by the SocialController.\n *\n * The controller acts as a simple store — no TTL or eviction logic.\n * The UI decides when to re-fetch; the social-api's own cache layer\n * handles upstream rate-limiting.\n */\nexport type SocialControllerState = {\n /** Cached ranked trader list from the last `updateLeaderboard` call. */\n leaderboardEntries: LeaderboardEntry[];\n /** Addresses the current user follows — drives Follow/Following button state. */\n followingAddresses: string[];\n};\n"]}
|
|
1
|
+
{"version":3,"file":"social-types.mjs","sourceRoot":"","sources":["../src/social-types.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E","sourcesContent":["// ---------------------------------------------------------------------------\n// Shared sub-types\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal profile summary used across follow/follower responses.\n */\nexport type ProfileSummary = {\n /** Clicker profile ID (UUID). */\n profileId: string;\n /** Primary wallet address. */\n address: string;\n /** Display name or truncated address. */\n name: string;\n /** Profile avatar URL. */\n imageUrl?: string | null;\n};\n\n/**\n * Social media handles attached to a trader profile.\n */\nexport type SocialHandles = {\n twitter?: string | null;\n farcaster?: string | null;\n ens?: string | null;\n lens?: string | null;\n};\n\n/**\n * A single trade within a position.\n */\nexport type Trade = {\n /** \"buy\" or \"sell\". */\n direction: string;\n /** Quantity traded. */\n tokenAmount: number;\n /** USD value of the trade. */\n usdCost: number;\n /** Unix timestamp. */\n timestamp: number;\n /** On-chain transaction hash. */\n transactionHash: string;\n};\n\n// ---------------------------------------------------------------------------\n// Leaderboard\n// ---------------------------------------------------------------------------\n\n/**\n * A single entry in the leaderboard response.\n */\nexport type LeaderboardEntry = {\n rank: number;\n addresses: string[];\n profileId: string;\n name: string;\n imageUrl?: string | null;\n pnl30d: number;\n winRate30d?: number | null;\n /** Renamed from roi30d. */\n roiPercent30d?: number | null;\n /** Renamed from tradeCount. */\n tradeCount30d?: number | null;\n pnl7d?: number | null;\n winRate7d?: number | null;\n roiPercent7d?: number | null;\n tradeCount7d?: number | null;\n pnlPerChain: Record<string, number>;\n followerCount: number;\n socialHandles: SocialHandles;\n};\n\n/**\n * Response from `GET /v1/leaderboard`.\n */\nexport type LeaderboardResponse = {\n traders: LeaderboardEntry[];\n};\n\n// ---------------------------------------------------------------------------\n// Trader profile\n// ---------------------------------------------------------------------------\n\nexport type TraderProfile = {\n profileId: string;\n address: string;\n allAddresses: string[];\n name: string;\n imageUrl?: string | null;\n};\n\nexport type TraderStats = {\n pnl30d?: number | null;\n winRate30d?: number | null;\n /** Renamed from roi30d. */\n roiPercent30d?: number | null;\n /** Renamed from tradeCount. */\n tradeCount30d?: number | null;\n pnl7d?: number | null;\n winRate7d?: number | null;\n roiPercent7d?: number | null;\n tradeCount7d?: number | null;\n};\n\nexport type PerChainBreakdown = {\n perChainPnl: Record<string, number>;\n /** ROI can be null for chains with no trading activity (zero cost-basis). */\n perChainRoi: Record<string, number | null>;\n perChainVolume: Record<string, number>;\n};\n\n/**\n * Response from `GET /v1/traders/:addressOrId/profile`.\n */\nexport type TraderProfileResponse = {\n profile: TraderProfile;\n stats: TraderStats;\n perChainBreakdown: PerChainBreakdown;\n socialHandles: SocialHandles;\n followerCount: number;\n followingCount: number;\n};\n\n// ---------------------------------------------------------------------------\n// Positions\n// ---------------------------------------------------------------------------\n\nexport type Position = {\n tokenSymbol: string;\n tokenName: string;\n tokenAddress: string;\n chain: string;\n positionAmount: number;\n boughtUsd: number;\n soldUsd: number;\n realizedPnl: number;\n costBasis: number;\n trades: Trade[];\n lastTradeAt: number;\n /** Current USD value of the remaining position (open positions only). */\n currentValueUSD?: number | null;\n /** Unrealized + realized PnL in USD. */\n pnlValueUsd?: number | null;\n /** PnL as a percentage of cost basis. */\n pnlPercent?: number | null;\n};\n\nexport type Pagination = {\n hasMore: boolean;\n nextPage?: number;\n};\n\n/**\n * Response from `GET /v1/traders/:addressOrId/positions/open`\n * and `GET /v1/traders/:addressOrId/positions/closed`.\n */\nexport type PositionsResponse = {\n positions: Position[];\n pagination: Pagination;\n /** ISO 8601 timestamp indicating when the response was computed server-side. */\n computedAt?: string | null;\n};\n\n// ---------------------------------------------------------------------------\n// Followers\n// ---------------------------------------------------------------------------\n\n/**\n * Response from `GET /v1/traders/:addressOrId/followers`.\n */\nexport type FollowersResponse = {\n followers: ProfileSummary[];\n count: number;\n};\n\n// ---------------------------------------------------------------------------\n// Following\n// ---------------------------------------------------------------------------\n\n/**\n * Response from `GET /v1/users/:addressOrUid/following`.\n */\nexport type FollowingResponse = {\n following: ProfileSummary[];\n count: number;\n};\n\n// ---------------------------------------------------------------------------\n// Follow / Unfollow\n// ---------------------------------------------------------------------------\n\n/**\n * Response from `PUT /v1/users/:addressOrUid/follows`.\n */\nexport type FollowResponse = {\n followed: ProfileSummary[];\n};\n\n/**\n * Response from `DELETE /v1/users/:addressOrUid/follows`.\n */\nexport type UnfollowResponse = {\n unfollowed: ProfileSummary[];\n};\n\n// ---------------------------------------------------------------------------\n// Fetch options\n// ---------------------------------------------------------------------------\n\nexport type FetchLeaderboardOptions = {\n sort?: 'pnl' | 'winRate' | 'roi';\n chains?: string[];\n limit?: number;\n};\n\nexport type FetchTraderProfileOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrId: string;\n};\n\nexport type FetchPositionsOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrId: string;\n chain?: string;\n sort?: 'value' | 'latest';\n limit?: number;\n page?: number;\n};\n\nexport type FetchFollowersOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrId: string;\n};\n\nexport type FetchFollowingOptions = {\n /** Wallet address or Clicker profile ID. */\n addressOrUid: string;\n};\n\nexport type FollowOptions = {\n /** Wallet address or Clicker profile ID of the user. */\n addressOrUid: string;\n /** Array of wallet addresses or profile IDs to follow. */\n targets: string[];\n};\n\nexport type UnfollowOptions = {\n /** Wallet address or Clicker profile ID of the user. */\n addressOrUid: string;\n /** Array of wallet addresses or profile IDs to unfollow. */\n targets: string[];\n};\n\n// ---------------------------------------------------------------------------\n// Controller state\n// ---------------------------------------------------------------------------\n\n/**\n * State managed by the SocialController.\n *\n * The controller acts as a simple store — no TTL or eviction logic.\n * The UI decides when to re-fetch; the social-api's own cache layer\n * handles upstream rate-limiting.\n */\nexport type SocialControllerState = {\n /** Cached ranked trader list from the last `updateLeaderboard` call. */\n leaderboardEntries: LeaderboardEntry[];\n /** Addresses the current user follows — drives Follow/Following button state. */\n followingAddresses: string[];\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/social-controllers",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.0-preview-1d148d2",
|
|
4
4
|
"description": "A collection of social related controllers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@metamask/base-controller": "^9.0.1",
|
|
52
52
|
"@metamask/base-data-service": "^0.1.1",
|
|
53
53
|
"@metamask/controller-utils": "^11.20.0",
|
|
54
|
-
"@metamask/messenger": "^1.
|
|
54
|
+
"@metamask/messenger": "^1.1.0",
|
|
55
55
|
"@metamask/superstruct": "^3.1.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|