diff --git a/packages/social-controllers/CHANGELOG.md b/packages/social-controllers/CHANGELOG.md index 8c8da7efed5..c8c4fba50db 100644 --- a/packages/social-controllers/CHANGELOG.md +++ b/packages/social-controllers/CHANGELOG.md @@ -9,10 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Add optional `tokenImageUrl` field to `Position` type and `PositionStruct` validation schema ([#8448](https://github.com/MetaMask/core/pull/8448)) +- Add optional `avgHoldMinutes` field to `TraderStats` type and `TraderStatsStruct` validation schema ([#8448](https://github.com/MetaMask/core/pull/8448)) - Add `intent` and optional `category` fields to `Trade` type ([#8410](https://github.com/MetaMask/core/pull/8410)) - Export `TradeStruct` superstruct schema; derive `Trade` type via `Infer` ([#8410](https://github.com/MetaMask/core/pull/8410)) - Narrow `direction` to `'buy' | 'sell'` and `intent` to `'enter' | 'exit'` on `Trade` type ([#8410](https://github.com/MetaMask/core/pull/8410)) +### Fixed + +- Fix `fetchClosedPositions` using v2 URL instead of v1, which caused 404 errors since the closed positions endpoint only exists on v1 ([#8448](https://github.com/MetaMask/core/pull/8448)) + ### Changed - Bump `@metamask/messenger` from `^1.1.0` to `^1.1.1` ([#8373](https://github.com/MetaMask/core/pull/8373)) diff --git a/packages/social-controllers/src/SocialService.test.ts b/packages/social-controllers/src/SocialService.test.ts index eb8ad32f1ce..b4745abda2b 100644 --- a/packages/social-controllers/src/SocialService.test.ts +++ b/packages/social-controllers/src/SocialService.test.ts @@ -44,6 +44,7 @@ const mockPosition = { costBasis: 3000, trades: [mockTrade], lastTradeAt: 1700000000, + tokenImageUrl: 'https://assets.daylight.xyz/images/token-eth.png', }; function createMessenger(): SocialServiceMessenger { @@ -239,6 +240,7 @@ describe('SocialService', () => { winRate7d: 0.7, roiPercent7d: 1.2, tradeCount7d: 15, + avgHoldMinutes: 120, }, perChainBreakdown: { perChainPnl: { base: 30000 }, @@ -477,7 +479,7 @@ describe('SocialService', () => { expect(result).toStrictEqual(mockPositionsResponse); expect(mockFetch).toHaveBeenCalledWith( - `${V2_URL}/traders/0x1234/positions/closed`, + `${V1_URL}/traders/0x1234/positions/closed`, ); }); diff --git a/packages/social-controllers/src/SocialService.ts b/packages/social-controllers/src/SocialService.ts index 7c753b22203..8e8efa4b972 100644 --- a/packages/social-controllers/src/SocialService.ts +++ b/packages/social-controllers/src/SocialService.ts @@ -69,6 +69,7 @@ const PositionStruct = structType({ costBasis: number(), trades: array(TradeStruct), lastTradeAt: number(), + tokenImageUrl: optional(nullable(string())), currentValueUSD: optional(nullable(number())), pnlValueUsd: optional(nullable(number())), pnlPercent: optional(nullable(number())), @@ -119,6 +120,7 @@ const TraderStatsStruct = structType({ winRate7d: optional(nullable(number())), roiPercent7d: optional(nullable(number())), tradeCount7d: optional(nullable(number())), + avgHoldMinutes: optional(nullable(number())), }); const PerChainBreakdownStruct = structType({ @@ -546,8 +548,10 @@ export class SocialService extends BaseDataService< page ?? null, ], queryFn: async () => { + const baseUrl = + status === 'open' ? this.#v2Url : this.#v1Url; const url = new URL( - `${this.#v2Url}/traders/${encodeURIComponent(addressOrId)}/positions/${status}`, + `${baseUrl}/traders/${encodeURIComponent(addressOrId)}/positions/${status}`, ); if (chain) { url.searchParams.append('chain', chain); diff --git a/packages/social-controllers/src/social-types.ts b/packages/social-controllers/src/social-types.ts index e80b9abd57e..1cbac3aa25d 100644 --- a/packages/social-controllers/src/social-types.ts +++ b/packages/social-controllers/src/social-types.ts @@ -105,6 +105,8 @@ export type TraderStats = { winRate7d?: number | null; roiPercent7d?: number | null; tradeCount7d?: number | null; + /** Median holding time in minutes. */ + avgHoldMinutes?: number | null; }; export type PerChainBreakdown = { @@ -142,6 +144,8 @@ export type Position = { costBasis: number; trades: Trade[]; lastTradeAt: number; + /** Daylight-hosted token image URL. */ + tokenImageUrl?: string | null; /** Current USD value of the remaining position (open positions only). */ currentValueUSD?: number | null; /** Unrealized + realized PnL in USD. */