@nadohq/mobile-client 0.64.0 → 0.66.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -7
- package/dist/MobileClient-M4oC4lrX.cjs +1101 -0
- package/dist/MobileClient-M4oC4lrX.cjs.map +1 -0
- package/dist/MobileClient.cjs +1 -1
- package/dist/MobileClient.d.cts +306 -10
- package/dist/MobileClient.d.cts.map +1 -1
- package/dist/MobileClient.d.ts +306 -10
- package/dist/MobileClient.d.ts.map +1 -1
- package/dist/MobileClient.js +544 -5
- package/dist/MobileClient.js.map +1 -1
- package/dist/{MobileServerFailureError-Dd3c6P_Z.d.ts → MobileServerFailureError-C9iqNsxI.d.ts} +2 -3
- package/dist/MobileServerFailureError-C9iqNsxI.d.ts.map +1 -0
- package/dist/{MobileServerFailureError-Bpa_WA9f.d.cts → MobileServerFailureError-MtS2reel.d.cts} +2 -3
- package/dist/MobileServerFailureError-MtS2reel.d.cts.map +1 -0
- package/dist/MobileUnsupportedFeedItemError-BsZvW8i2.d.cts +15 -0
- package/dist/MobileUnsupportedFeedItemError-BsZvW8i2.d.cts.map +1 -0
- package/dist/MobileUnsupportedFeedItemError-BsZvW8i2.d.ts +15 -0
- package/dist/MobileUnsupportedFeedItemError-BsZvW8i2.d.ts.map +1 -0
- package/dist/MobileUnsupportedNotificationRouteError-DpiNBvvY.d.cts +15 -0
- package/dist/MobileUnsupportedNotificationRouteError-DpiNBvvY.d.cts.map +1 -0
- package/dist/MobileUnsupportedNotificationRouteError-DpiNBvvY.d.ts +15 -0
- package/dist/MobileUnsupportedNotificationRouteError-DpiNBvvY.d.ts.map +1 -0
- package/dist/{buildSignedMobileRequest-Cb1T74xV.d.ts → buildSignedMobileRequest-BR-KJhIF.d.ts} +2 -2
- package/dist/{buildSignedMobileRequest-Cb1T74xV.d.ts.map → buildSignedMobileRequest-BR-KJhIF.d.ts.map} +1 -1
- package/dist/{buildSignedMobileRequest-NHbMAPzd.d.cts → buildSignedMobileRequest-DyKCK34Y.d.cts} +2 -2
- package/dist/{buildSignedMobileRequest-NHbMAPzd.d.cts.map → buildSignedMobileRequest-DyKCK34Y.d.cts.map} +1 -1
- package/dist/{canonicalize-BBYGh17w.d.ts → canonicalize-Bv6UIAbR.d.ts} +2 -2
- package/dist/canonicalize-Bv6UIAbR.d.ts.map +1 -0
- package/dist/{canonicalize-BF_SiNvO.d.cts → canonicalize-CWh3XZzj.d.cts} +2 -2
- package/dist/canonicalize-CWh3XZzj.d.cts.map +1 -0
- package/dist/clientTypes-BUn5_OzK.d.ts +1665 -0
- package/dist/clientTypes-BUn5_OzK.d.ts.map +1 -0
- package/dist/clientTypes-DOpUcu80.d.cts +1665 -0
- package/dist/clientTypes-DOpUcu80.d.cts.map +1 -0
- package/dist/dataMappers.cjs +691 -14
- package/dist/dataMappers.cjs.map +1 -1
- package/dist/dataMappers.d.cts +254 -8
- package/dist/dataMappers.d.cts.map +1 -1
- package/dist/dataMappers.d.ts +254 -8
- package/dist/dataMappers.d.ts.map +1 -1
- package/dist/dataMappers.js +651 -15
- package/dist/dataMappers.js.map +1 -1
- package/dist/{eip712MethodByType-BSx11xG-.d.cts → eip712MethodByType-CJ6BoayT.d.cts} +2 -2
- package/dist/eip712MethodByType-CJ6BoayT.d.cts.map +1 -0
- package/dist/{eip712MethodByType-DkiAjCLs.d.ts → eip712MethodByType-Dx4mvgni.d.ts} +2 -2
- package/dist/eip712MethodByType-Dx4mvgni.d.ts.map +1 -0
- package/dist/{feed-DTJlsg8W.d.ts → feed-DErOLaoY.d.cts} +4 -2
- package/dist/feed-DErOLaoY.d.cts.map +1 -0
- package/dist/{feed-DTJlsg8W.d.cts → feed-DErOLaoY.d.ts} +4 -2
- package/dist/feed-DErOLaoY.d.ts.map +1 -0
- package/dist/index.cjs +9 -2
- package/dist/index.d.cts +15 -16
- package/dist/index.d.ts +15 -16
- package/dist/index.js +5 -3
- package/dist/{mobileErrorCodes-3LtreeZM.d.ts → mobileErrorCodes-vD6rbFuF.d.cts} +25 -6
- package/dist/mobileErrorCodes-vD6rbFuF.d.cts.map +1 -0
- package/dist/{mobileErrorCodes-3LtreeZM.d.cts → mobileErrorCodes-vD6rbFuF.d.ts} +25 -6
- package/dist/mobileErrorCodes-vD6rbFuF.d.ts.map +1 -0
- package/dist/{payloadHash-BOWGjqdb.d.cts → payloadHash-CdkF2Ocr.d.cts} +2 -2
- package/dist/payloadHash-CdkF2Ocr.d.cts.map +1 -0
- package/dist/{payloadHash-Bzf4CtjV.d.ts → payloadHash-HD29K77M.d.ts} +2 -2
- package/dist/payloadHash-HD29K77M.d.ts.map +1 -0
- package/dist/serverExecuteTypes-5JyyIXRK.d.ts +178 -0
- package/dist/serverExecuteTypes-5JyyIXRK.d.ts.map +1 -0
- package/dist/serverExecuteTypes-CHrQ9Rtq.d.cts +178 -0
- package/dist/serverExecuteTypes-CHrQ9Rtq.d.cts.map +1 -0
- package/dist/serverModelTypes-CGUZCi0y.d.cts +938 -0
- package/dist/serverModelTypes-CGUZCi0y.d.cts.map +1 -0
- package/dist/serverModelTypes-CGUZCi0y.d.ts +938 -0
- package/dist/serverModelTypes-CGUZCi0y.d.ts.map +1 -0
- package/dist/{serverResponseGuards-BU1Xv_tG.d.ts → serverResponseGuards-Bvw8ltYJ.d.ts} +2 -2
- package/dist/{serverResponseGuards-BU1Xv_tG.d.ts.map → serverResponseGuards-Bvw8ltYJ.d.ts.map} +1 -1
- package/dist/{serverResponseGuards-Dkdok0Sm.d.cts → serverResponseGuards-i1njcYKN.d.cts} +2 -2
- package/dist/{serverResponseGuards-Dkdok0Sm.d.cts.map → serverResponseGuards-i1njcYKN.d.cts.map} +1 -1
- package/dist/signing/buildSignedMobileRequest.d.cts +1 -1
- package/dist/signing/buildSignedMobileRequest.d.ts +1 -1
- package/dist/signing/canonicalize.cjs +86 -0
- package/dist/signing/canonicalize.cjs.map +1 -1
- package/dist/signing/canonicalize.d.cts +1 -1
- package/dist/signing/canonicalize.d.ts +1 -1
- package/dist/signing/canonicalize.js +86 -0
- package/dist/signing/canonicalize.js.map +1 -1
- package/dist/signing/eip712MethodByType.cjs +12 -0
- package/dist/signing/eip712MethodByType.cjs.map +1 -1
- package/dist/signing/eip712MethodByType.d.cts +1 -1
- package/dist/signing/eip712MethodByType.d.ts +1 -1
- package/dist/signing/eip712MethodByType.js +12 -0
- package/dist/signing/eip712MethodByType.js.map +1 -1
- package/dist/signing/index.d.cts +5 -5
- package/dist/signing/index.d.ts +5 -5
- package/dist/signing/payloadHash.cjs +1 -1
- package/dist/signing/payloadHash.d.cts +1 -1
- package/dist/signing/payloadHash.d.ts +1 -1
- package/dist/signing/payloadHash.js +1 -1
- package/dist/signing/types.d.cts +1 -1
- package/dist/signing/types.d.ts +1 -1
- package/dist/types/MobileServerFailureError.d.cts +1 -1
- package/dist/types/MobileServerFailureError.d.ts +1 -1
- package/dist/types/MobileUnsupportedFeedItemError.cjs +19 -0
- package/dist/types/MobileUnsupportedFeedItemError.cjs.map +1 -0
- package/dist/types/MobileUnsupportedFeedItemError.d.cts +2 -0
- package/dist/types/MobileUnsupportedFeedItemError.d.ts +2 -0
- package/dist/types/MobileUnsupportedFeedItemError.js +18 -0
- package/dist/types/MobileUnsupportedFeedItemError.js.map +1 -0
- package/dist/types/MobileUnsupportedNotificationRouteError.cjs +19 -0
- package/dist/types/MobileUnsupportedNotificationRouteError.cjs.map +1 -0
- package/dist/types/MobileUnsupportedNotificationRouteError.d.cts +2 -0
- package/dist/types/MobileUnsupportedNotificationRouteError.d.ts +2 -0
- package/dist/types/MobileUnsupportedNotificationRouteError.js +18 -0
- package/dist/types/MobileUnsupportedNotificationRouteError.js.map +1 -0
- package/dist/types/clientTypes.d.cts +2 -2
- package/dist/types/clientTypes.d.ts +2 -2
- package/dist/types/index.cjs +6 -0
- package/dist/types/index.d.cts +9 -9
- package/dist/types/index.d.ts +9 -9
- package/dist/types/index.js +4 -2
- package/dist/types/mobileErrorCodes.cjs +39 -1
- package/dist/types/mobileErrorCodes.cjs.map +1 -1
- package/dist/types/mobileErrorCodes.d.cts +1 -1
- package/dist/types/mobileErrorCodes.d.ts +1 -1
- package/dist/types/mobileErrorCodes.js +39 -1
- package/dist/types/mobileErrorCodes.js.map +1 -1
- package/dist/types/serverBaseTypes.d.cts +1 -1
- package/dist/types/serverBaseTypes.d.ts +1 -1
- package/dist/types/serverExecuteTypes.d.cts +2 -2
- package/dist/types/serverExecuteTypes.d.ts +2 -2
- package/dist/types/serverModelTypes.cjs +15 -0
- package/dist/types/serverModelTypes.cjs.map +1 -1
- package/dist/types/serverModelTypes.d.cts +2 -2
- package/dist/types/serverModelTypes.d.ts +2 -2
- package/dist/types/serverModelTypes.js +14 -1
- package/dist/types/serverModelTypes.js.map +1 -1
- package/dist/types/serverQueryTypes.d.cts +2 -2
- package/dist/types/serverQueryTypes.d.ts +2 -2
- package/dist/types/serverRequestTypes.d.cts +2 -2
- package/dist/types/serverRequestTypes.d.ts +2 -2
- package/dist/types-C9YE4EIt.d.cts +794 -0
- package/dist/types-C9YE4EIt.d.cts.map +1 -0
- package/dist/types-Cwy1y_9x.d.ts +794 -0
- package/dist/types-Cwy1y_9x.d.ts.map +1 -0
- package/dist/utils/buildMobileFeedImageMultipart.cjs +31 -0
- package/dist/utils/buildMobileFeedImageMultipart.cjs.map +1 -0
- package/dist/utils/buildMobileFeedImageMultipart.d.cts +15 -0
- package/dist/utils/buildMobileFeedImageMultipart.d.cts.map +1 -0
- package/dist/utils/buildMobileFeedImageMultipart.d.ts +15 -0
- package/dist/utils/buildMobileFeedImageMultipart.d.ts.map +1 -0
- package/dist/utils/buildMobileFeedImageMultipart.js +30 -0
- package/dist/utils/buildMobileFeedImageMultipart.js.map +1 -0
- package/dist/utils/feed.cjs +3 -0
- package/dist/utils/feed.cjs.map +1 -1
- package/dist/utils/feed.d.cts +2 -2
- package/dist/utils/feed.d.ts +2 -2
- package/dist/utils/feed.js +3 -1
- package/dist/utils/feed.js.map +1 -1
- package/dist/utils/index.cjs +2 -1
- package/dist/utils/index.d.cts +3 -3
- package/dist/utils/index.d.ts +3 -3
- package/dist/utils/index.js +2 -2
- package/dist/utils/serverResponseGuards.d.cts +1 -1
- package/dist/utils/serverResponseGuards.d.ts +1 -1
- package/package.json +3 -3
- package/src/MobileClient.ts +789 -7
- package/src/dataMappers.test.ts +848 -0
- package/src/dataMappers.ts +924 -17
- package/src/feedImages.test.ts +309 -0
- package/src/notifications.test.ts +950 -0
- package/src/signing/canonicalize.ts +119 -0
- package/src/signing/eip712MethodByType.ts +15 -0
- package/src/signing/signing.test.ts +362 -0
- package/src/signing/types.ts +108 -13
- package/src/socialFeed.test.ts +38 -2
- package/src/types/MobileUnsupportedFeedItemError.ts +18 -0
- package/src/types/MobileUnsupportedNotificationRouteError.ts +16 -0
- package/src/types/clientTypes.ts +1012 -34
- package/src/types/index.ts +2 -0
- package/src/types/mobileErrorCodes.ts +38 -0
- package/src/types/serverExecuteTypes.ts +112 -3
- package/src/types/serverModelTypes.ts +581 -28
- package/src/types/serverQueryTypes.ts +212 -5
- package/src/types/serverRequestTypes.ts +213 -13
- package/src/utils/buildMobileFeedImageMultipart.test.ts +45 -0
- package/src/utils/buildMobileFeedImageMultipart.ts +36 -0
- package/src/utils/feed.ts +3 -0
- package/dist/MobileClient-aDxiM_Kf.cjs +0 -562
- package/dist/MobileClient-aDxiM_Kf.cjs.map +0 -1
- package/dist/MobileServerFailureError-Bpa_WA9f.d.cts.map +0 -1
- package/dist/MobileServerFailureError-Dd3c6P_Z.d.ts.map +0 -1
- package/dist/canonicalize-BBYGh17w.d.ts.map +0 -1
- package/dist/canonicalize-BF_SiNvO.d.cts.map +0 -1
- package/dist/clientTypes-BWFKo9oE.d.cts +0 -844
- package/dist/clientTypes-BWFKo9oE.d.cts.map +0 -1
- package/dist/clientTypes-DCTiUV0H.d.ts +0 -844
- package/dist/clientTypes-DCTiUV0H.d.ts.map +0 -1
- package/dist/eip712MethodByType-BSx11xG-.d.cts.map +0 -1
- package/dist/eip712MethodByType-DkiAjCLs.d.ts.map +0 -1
- package/dist/feed-DTJlsg8W.d.cts.map +0 -1
- package/dist/feed-DTJlsg8W.d.ts.map +0 -1
- package/dist/mobileErrorCodes-3LtreeZM.d.cts.map +0 -1
- package/dist/mobileErrorCodes-3LtreeZM.d.ts.map +0 -1
- package/dist/payloadHash-BOWGjqdb.d.cts.map +0 -1
- package/dist/payloadHash-Bzf4CtjV.d.ts.map +0 -1
- package/dist/serverBaseTypes-DWf3iGWy.d.ts +0 -25
- package/dist/serverBaseTypes-DWf3iGWy.d.ts.map +0 -1
- package/dist/serverBaseTypes-KREDe2M9.d.cts +0 -25
- package/dist/serverBaseTypes-KREDe2M9.d.cts.map +0 -1
- package/dist/serverExecuteTypes-DVRa6ifu.d.cts +0 -89
- package/dist/serverExecuteTypes-DVRa6ifu.d.cts.map +0 -1
- package/dist/serverExecuteTypes-DlYZCp1f.d.ts +0 -89
- package/dist/serverExecuteTypes-DlYZCp1f.d.ts.map +0 -1
- package/dist/serverModelTypes-DAqEyYtB.d.cts +0 -508
- package/dist/serverModelTypes-DAqEyYtB.d.cts.map +0 -1
- package/dist/serverModelTypes-DAqEyYtB.d.ts +0 -508
- package/dist/serverModelTypes-DAqEyYtB.d.ts.map +0 -1
- package/dist/serverQueryTypes-BFdwq0Z2.d.ts +0 -171
- package/dist/serverQueryTypes-BFdwq0Z2.d.ts.map +0 -1
- package/dist/serverQueryTypes-DNdMpmDr.d.cts +0 -171
- package/dist/serverQueryTypes-DNdMpmDr.d.cts.map +0 -1
- package/dist/serverRequestTypes-BNA7FCY6.d.ts +0 -200
- package/dist/serverRequestTypes-BNA7FCY6.d.ts.map +0 -1
- package/dist/serverRequestTypes-CxDRFKfv.d.cts +0 -200
- package/dist/serverRequestTypes-CxDRFKfv.d.cts.map +0 -1
- package/dist/types-BCr2G5gS.d.cts +0 -84
- package/dist/types-BCr2G5gS.d.cts.map +0 -1
- package/dist/types-C18k-9Vy.d.ts +0 -84
- package/dist/types-C18k-9Vy.d.ts.map +0 -1
|
@@ -1,24 +1,64 @@
|
|
|
1
1
|
import { Hex } from 'viem';
|
|
2
2
|
import { MobileServerSuccessResponse } from './serverBaseTypes';
|
|
3
3
|
import {
|
|
4
|
-
MobileNotificationPlatform,
|
|
5
4
|
MobileServerAvatarPreset,
|
|
6
5
|
MobileServerFeedTrade,
|
|
7
6
|
MobileServerFollowListAccount,
|
|
7
|
+
MobileServerNotificationCapabilities,
|
|
8
|
+
MobileServerNotificationDeviceMetadata,
|
|
9
|
+
MobileServerNotificationInboxItem,
|
|
8
10
|
MobileServerNotificationPreferences,
|
|
11
|
+
MobileServerNotificationSettings,
|
|
9
12
|
MobileServerProfile,
|
|
13
|
+
MobileServerSocialFeedActionCandidate,
|
|
14
|
+
MobileServerSocialFeedActionMarker,
|
|
15
|
+
MobileServerSocialFeedAuthor,
|
|
16
|
+
MobileServerSocialFeedCandle,
|
|
10
17
|
MobileServerSocialFeedCohort,
|
|
18
|
+
MobileServerSocialFeedDrawing,
|
|
19
|
+
MobileServerSocialFeedEstimatedLiquidationLine,
|
|
20
|
+
MobileServerSocialFeedHistorySummary,
|
|
11
21
|
MobileServerSocialFeedItem,
|
|
12
22
|
MobileServerSocialFeedItemPatch,
|
|
23
|
+
MobileServerSocialFeedMarket,
|
|
24
|
+
MobileServerSocialFeedPositionHistoryCard,
|
|
13
25
|
MobileServerSocialFeedPositionPatch,
|
|
26
|
+
MobileServerSocialFeedPublishablePosition,
|
|
14
27
|
MobileServerSocialFeedReadSession,
|
|
28
|
+
MobileServerSocialFeedReply,
|
|
29
|
+
MobileServerSocialFeedTimelineEntry,
|
|
30
|
+
MobileServerSocialFeedTradingContext,
|
|
31
|
+
MobileSocialFeedActionResolution,
|
|
32
|
+
MobileSocialFeedChartDataQuality,
|
|
33
|
+
MobileSocialFeedHistoryQuality,
|
|
34
|
+
MobileSocialFeedPositionResolution,
|
|
35
|
+
MobileSocialFeedPositionResolutionReason,
|
|
15
36
|
MobileSocialFeedUnavailableTarget,
|
|
16
37
|
} from './serverModelTypes';
|
|
17
38
|
import {
|
|
18
39
|
MobileServerPublicQueryRequestByType,
|
|
19
40
|
MobileServerPublicQueryRequestType,
|
|
41
|
+
MobileServerSignedQueryRequestType,
|
|
20
42
|
} from './serverRequestTypes';
|
|
21
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Success payloads for each signed `query`, keyed by request `type`.
|
|
46
|
+
*/
|
|
47
|
+
export interface MobileServerSignedQueryResponseByType {
|
|
48
|
+
/** Wallet subscriptions and the signing Identity's bells. */
|
|
49
|
+
notification_subscriptions: MobileServerNotificationSubscriptionsResponse;
|
|
50
|
+
/** Private notification page. */
|
|
51
|
+
notification_inbox_v2: MobileServerNotificationInboxV2Response;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Full success response for a signed `query`, with its payload inlined alongside `status`.
|
|
56
|
+
*/
|
|
57
|
+
export type MobileServerSignedQuerySuccessResponse<
|
|
58
|
+
T extends MobileServerSignedQueryRequestType =
|
|
59
|
+
MobileServerSignedQueryRequestType,
|
|
60
|
+
> = MobileServerSuccessResponse & MobileServerSignedQueryResponseByType[T];
|
|
61
|
+
|
|
22
62
|
/**
|
|
23
63
|
* Unsigned `public_query` request body: a `type` discriminant flattened with its params.
|
|
24
64
|
*/
|
|
@@ -147,15 +187,58 @@ export interface MobileServerNotificationPreferencesResponse {
|
|
|
147
187
|
preferences: MobileServerNotificationPreferences;
|
|
148
188
|
}
|
|
149
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Payload of the `notification_registration_v2` public query, including legacy registrations.
|
|
192
|
+
*/
|
|
193
|
+
export interface MobileServerNotificationRegistrationV2Response {
|
|
194
|
+
/** Opaque decimal string; do not convert to a JavaScript number. */
|
|
195
|
+
registration_generation: string;
|
|
196
|
+
/** Persisted capabilities of the most recent registration; legacy type/route arrays are empty. */
|
|
197
|
+
capabilities: MobileServerNotificationCapabilities;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Full settings document returned by both `notification_settings_v2` and `update_notification_settings_v2`.
|
|
202
|
+
*/
|
|
203
|
+
export interface MobileServerNotificationSettingsV2Response {
|
|
204
|
+
/** Settings schema version. */
|
|
205
|
+
schema_version: 2;
|
|
206
|
+
/** Settings revision, independent of the subscription revision. */
|
|
207
|
+
revision: number;
|
|
208
|
+
/** Full saved settings. */
|
|
209
|
+
settings: MobileServerNotificationSettings;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Payload of the `notification_subscriptions` signed query.
|
|
214
|
+
*/
|
|
215
|
+
export interface MobileServerNotificationSubscriptionsResponse {
|
|
216
|
+
/** Wallet-level subscription revision; read again after every mutation. */
|
|
217
|
+
revision: number;
|
|
218
|
+
/** Whether the one-time local favorites import has completed. */
|
|
219
|
+
favorites_imported: boolean;
|
|
220
|
+
/** Subscribed market IDs in ascending order. */
|
|
221
|
+
market_ids: number[];
|
|
222
|
+
/** Followed subaccounts with bells enabled for the signing Identity. */
|
|
223
|
+
trader_bells: Hex[];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Payload of the `notification_inbox_v2` signed query, ordered newest first.
|
|
228
|
+
*/
|
|
229
|
+
export interface MobileServerNotificationInboxV2Response {
|
|
230
|
+
/** Accepted intents owned by the signing wallet. */
|
|
231
|
+
notifications: MobileServerNotificationInboxItem[];
|
|
232
|
+
/** Pass unchanged to the next request, or null when pagination is complete. */
|
|
233
|
+
next_cursor: string | null;
|
|
234
|
+
}
|
|
235
|
+
|
|
150
236
|
/**
|
|
151
237
|
* Payload of the `registered_wallet` public query success response. Inlined into the envelope rather than
|
|
152
238
|
* nested under a key, matching the backend's `RegisteredWalletResponse`.
|
|
153
239
|
*/
|
|
154
|
-
export interface MobileServerRegisteredWalletResponse {
|
|
240
|
+
export interface MobileServerRegisteredWalletResponse extends MobileServerNotificationDeviceMetadata {
|
|
155
241
|
wallet: Hex;
|
|
156
|
-
platform: MobileNotificationPlatform;
|
|
157
|
-
locale: string | null;
|
|
158
|
-
app_version: string | null;
|
|
159
242
|
token_fingerprint_prefix: string;
|
|
160
243
|
last_seen_at: number;
|
|
161
244
|
}
|
|
@@ -167,6 +250,26 @@ export interface MobileServerRegisteredWalletResponse {
|
|
|
167
250
|
* by {@link MobileServerPublicQuerySuccessResponse}.
|
|
168
251
|
*/
|
|
169
252
|
export interface MobileServerPublicQueryResponseByType {
|
|
253
|
+
/** Latest saved device generation and v1/v2 capabilities. */
|
|
254
|
+
notification_registration_v2: MobileServerNotificationRegistrationV2Response;
|
|
255
|
+
/** Full settings document with its revision. */
|
|
256
|
+
notification_settings_v2: MobileServerNotificationSettingsV2Response;
|
|
257
|
+
/** Open position candidates. */
|
|
258
|
+
self_feed_positions: MobileServerSocialFeedPositionsResponse;
|
|
259
|
+
/** Position command resolution. */
|
|
260
|
+
resolve_feed_position: MobileServerSocialFeedPositionResolutionResponse;
|
|
261
|
+
/** Trusted order action resolution. */
|
|
262
|
+
resolve_feed_action: MobileServerSocialFeedActionResolutionResponse;
|
|
263
|
+
/** Parent drawing and version. */
|
|
264
|
+
feed_chart_drawing: MobileServerSocialFeedDrawingResponse;
|
|
265
|
+
/** Comment thread page. */
|
|
266
|
+
feed_comments: MobileServerSocialFeedCommentsResponse;
|
|
267
|
+
/** Full lifecycle history. */
|
|
268
|
+
position_history: MobileServerSocialFeedPositionHistoryResponse;
|
|
269
|
+
/** Candle page and markers. */
|
|
270
|
+
position_chart: MobileServerSocialFeedPositionChartResponse;
|
|
271
|
+
/** Read-only watcher observation. */
|
|
272
|
+
position_watchers: MobileServerSocialFeedWatchersResponse;
|
|
170
273
|
/** Preset IDs and public image URLs in display order. */
|
|
171
274
|
avatar_presets: MobileServerAvatarPresetsResponse;
|
|
172
275
|
/** For You recommendations. */
|
|
@@ -204,3 +307,107 @@ export type MobileServerPublicQuerySuccessResponse<
|
|
|
204
307
|
T extends MobileServerPublicQueryRequestType =
|
|
205
308
|
MobileServerPublicQueryRequestType,
|
|
206
309
|
> = MobileServerSuccessResponse & MobileServerPublicQueryResponseByType[T];
|
|
310
|
+
|
|
311
|
+
/** Selected account's current candidates. */
|
|
312
|
+
export interface MobileServerSocialFeedPositionsResponse {
|
|
313
|
+
/** Position eligibility hints. */
|
|
314
|
+
positions: MobileServerSocialFeedPublishablePosition[];
|
|
315
|
+
/** Next bound cursor, or null. */
|
|
316
|
+
next_cursor: string | null;
|
|
317
|
+
/** Observation time. */
|
|
318
|
+
as_of_ms: number;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/** Slash-command resolution, including normal empty outcomes. */
|
|
322
|
+
export interface MobileServerSocialFeedPositionResolutionResponse {
|
|
323
|
+
/** Resolution status. */
|
|
324
|
+
resolution: MobileSocialFeedPositionResolution;
|
|
325
|
+
/** Resolved market, or null. */
|
|
326
|
+
product: MobileServerSocialFeedMarket | null;
|
|
327
|
+
/** Current candidates. */
|
|
328
|
+
candidates: MobileServerSocialFeedPublishablePosition[];
|
|
329
|
+
/** Explanation for empty candidates. */
|
|
330
|
+
reason: MobileSocialFeedPositionResolutionReason | null;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** Authoritative order segments, not an inferred latest trade. */
|
|
334
|
+
export interface MobileServerSocialFeedActionResolutionResponse {
|
|
335
|
+
/** Requested order. */
|
|
336
|
+
order_digest: Hex;
|
|
337
|
+
/** Pending until all confirmed segments are projected. */
|
|
338
|
+
resolution: MobileSocialFeedActionResolution;
|
|
339
|
+
/** Trusted actions, empty when pending. */
|
|
340
|
+
actions: MobileServerSocialFeedActionCandidate[];
|
|
341
|
+
/** Observation time. */
|
|
342
|
+
as_of_ms: number;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/** Drawing read result; a readable parent without a drawing succeeds with null. */
|
|
346
|
+
export interface MobileServerSocialFeedDrawingResponse {
|
|
347
|
+
/** Parent UUID. */
|
|
348
|
+
item_id: string;
|
|
349
|
+
/** Display version. */
|
|
350
|
+
item_version: string;
|
|
351
|
+
/** Parsed drawing, or null. */
|
|
352
|
+
drawing: MobileServerSocialFeedDrawing | null;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/** Comment thread, including bidirectional pagination around an optional anchor. */
|
|
356
|
+
export interface MobileServerSocialFeedCommentsResponse {
|
|
357
|
+
/** Readable comments. */
|
|
358
|
+
comments: MobileServerSocialFeedReply[];
|
|
359
|
+
/** Total readable count. */
|
|
360
|
+
total_count: number;
|
|
361
|
+
/** Forward cursor. */
|
|
362
|
+
next_cursor: string | null;
|
|
363
|
+
/** Backward cursor. */
|
|
364
|
+
previous_cursor: string | null;
|
|
365
|
+
/** Requested anchor, or null. */
|
|
366
|
+
anchor_reply_id: string | null;
|
|
367
|
+
/** Original or new session. */
|
|
368
|
+
read_session: MobileServerSocialFeedReadSession;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/** Full position history with additional metrics and trusted trading hints. */
|
|
372
|
+
export interface MobileServerSocialFeedPositionHistoryResponse {
|
|
373
|
+
/** Current or frozen position and history metrics. */
|
|
374
|
+
position: MobileServerSocialFeedPositionHistoryCard;
|
|
375
|
+
/** Counts across the authorized history. */
|
|
376
|
+
summary: MobileServerSocialFeedHistorySummary;
|
|
377
|
+
/** Ordered action and take entries. */
|
|
378
|
+
timeline: MobileServerSocialFeedTimelineEntry[];
|
|
379
|
+
/** Next history cursor. */
|
|
380
|
+
next_cursor: string | null;
|
|
381
|
+
/** History completeness. */
|
|
382
|
+
history_quality: MobileSocialFeedHistoryQuality;
|
|
383
|
+
/** Position-mode session. */
|
|
384
|
+
read_session: MobileServerSocialFeedReadSession;
|
|
385
|
+
/** Viewing-account state, not authentication. */
|
|
386
|
+
trading_context: MobileServerSocialFeedTradingContext;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/** Candles and actions, with separate estimated risk-price line. */
|
|
390
|
+
export interface MobileServerSocialFeedPositionChartResponse {
|
|
391
|
+
/** Descending candle page. */
|
|
392
|
+
candles: MobileServerSocialFeedCandle[];
|
|
393
|
+
/** Action markers with explicit price bases. */
|
|
394
|
+
action_markers: MobileServerSocialFeedActionMarker[];
|
|
395
|
+
/** Estimated line, if applicable and available. */
|
|
396
|
+
estimated_liquidation_line: MobileServerSocialFeedEstimatedLiquidationLine | null;
|
|
397
|
+
/** Exclusive next-page bound. */
|
|
398
|
+
next_before_ms: number | null;
|
|
399
|
+
/** Observation time. */
|
|
400
|
+
as_of_ms: number;
|
|
401
|
+
/** Overall source quality. */
|
|
402
|
+
data_quality: MobileSocialFeedChartDataQuality;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/** Read-only watcher observation; account previews are self-reported. */
|
|
406
|
+
export interface MobileServerSocialFeedWatchersResponse {
|
|
407
|
+
/** Distinct active browsing credentials. */
|
|
408
|
+
watcher_count: number;
|
|
409
|
+
/** Deduplicated public account previews. */
|
|
410
|
+
watcher_preview: MobileServerSocialFeedAuthor[];
|
|
411
|
+
/** Observation time. */
|
|
412
|
+
as_of_ms: number;
|
|
413
|
+
}
|
|
@@ -1,10 +1,73 @@
|
|
|
1
1
|
import { Hex } from 'viem';
|
|
2
2
|
import { MobileSignedInner } from '../signing/types';
|
|
3
3
|
import {
|
|
4
|
+
MobileNotificationRouteName,
|
|
5
|
+
MobileNotificationTypeId,
|
|
6
|
+
MobileServerNotificationDeviceMetadata,
|
|
4
7
|
MobileServerNotificationPreferences,
|
|
8
|
+
MobileServerNotificationSettings,
|
|
9
|
+
MobileServerSocialFeedChartRange,
|
|
10
|
+
MobileSocialFeedChartInterval,
|
|
5
11
|
MobileSocialFeedMarketCategory,
|
|
12
|
+
MobileSocialFeedPresenceState,
|
|
6
13
|
MobileSocialFeedType,
|
|
7
14
|
} from './serverModelTypes';
|
|
15
|
+
import type { MobileServerSignedQueryResponseByType } from './serverQueryTypes';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Common wire-format credential for token-authenticated notification requests.
|
|
19
|
+
* Unregistration also accepts an inactive or unknown well-formed token.
|
|
20
|
+
*/
|
|
21
|
+
export interface MobileServerWithExpoTokenParams {
|
|
22
|
+
/** Expo push token; never expose it to another user. */
|
|
23
|
+
expo_token: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Registration fields shared by v1 and v2 signed inner payloads.
|
|
28
|
+
* Nullable metadata keys remain present when signing so the MessagePack hash matches the backend.
|
|
29
|
+
*/
|
|
30
|
+
export interface MobileServerRegisterExpoTokenParams
|
|
31
|
+
extends
|
|
32
|
+
MobileServerWithExpoTokenParams,
|
|
33
|
+
MobileServerNotificationDeviceMetadata {}
|
|
34
|
+
|
|
35
|
+
/** Registration request with a v2-only capability declaration. */
|
|
36
|
+
export interface MobileServerRegisterExpoTokenV2Params extends MobileServerRegisterExpoTokenParams {
|
|
37
|
+
/** Actual notification features supported by the device. */
|
|
38
|
+
capabilities: {
|
|
39
|
+
/** Registration accepts only the v2 protocol. */
|
|
40
|
+
payload_versions: [2];
|
|
41
|
+
/** Supported notification types. */
|
|
42
|
+
type_ids: MobileNotificationTypeId[];
|
|
43
|
+
/** Supported navigation destinations. */
|
|
44
|
+
routes: MobileNotificationRouteName[];
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* One subscription operation; exactly one operation is non-null and unused operations must be null.
|
|
50
|
+
*/
|
|
51
|
+
export interface MobileServerNotificationSubscriptionsUpdate {
|
|
52
|
+
/** Latest subscription revision, not the settings revision. */
|
|
53
|
+
expected_revision: number;
|
|
54
|
+
/** Set one bell; enabling requires an existing follow relationship. */
|
|
55
|
+
trader_bell: {
|
|
56
|
+
/** Target non-isolated subaccount belonging to another wallet. */
|
|
57
|
+
subaccount: Hex;
|
|
58
|
+
/** Desired bell state. */
|
|
59
|
+
enabled: boolean;
|
|
60
|
+
} | null;
|
|
61
|
+
/** Subscribe or unsubscribe one known market. */
|
|
62
|
+
market: {
|
|
63
|
+
/** Positive market product ID. */
|
|
64
|
+
product_id: number;
|
|
65
|
+
/** Desired subscription state. */
|
|
66
|
+
subscribed: boolean;
|
|
67
|
+
} | null;
|
|
68
|
+
/** One-time merge of up to 500 local market IDs; mutually exclusive with the other operations. */
|
|
69
|
+
import_markets: number[] | null;
|
|
70
|
+
}
|
|
8
71
|
|
|
9
72
|
/**
|
|
10
73
|
* Opt-in extras for a `profiles` query. Each one costs extra rate-limit weight per profile and adds fields
|
|
@@ -65,7 +128,7 @@ export interface MobileServerSocialFeedListParams {
|
|
|
65
128
|
minimum_notional?: number;
|
|
66
129
|
/** Page size, 1–50; defaults to 20. */
|
|
67
130
|
limit?: number;
|
|
68
|
-
/**
|
|
131
|
+
/** Original reading session; required with cursor. Legitimate requests renew its idle expiration. */
|
|
69
132
|
session_id?: string;
|
|
70
133
|
/** Opaque pagination cursor, distinct from update_cursor and watermark. */
|
|
71
134
|
cursor?: string;
|
|
@@ -92,6 +155,88 @@ export interface MobileServerSocialFeedReadParams {
|
|
|
92
155
|
* Params for each unsigned `public_query`, keyed by request `type`.
|
|
93
156
|
*/
|
|
94
157
|
export interface MobileServerPublicQueryRequestByType {
|
|
158
|
+
/** Selected account's open position candidates. */
|
|
159
|
+
self_feed_positions: {
|
|
160
|
+
/** Full identity. */
|
|
161
|
+
view_as: Hex;
|
|
162
|
+
/** Market filter. */
|
|
163
|
+
product_id?: number;
|
|
164
|
+
/** Bound pagination cursor. */
|
|
165
|
+
cursor?: string;
|
|
166
|
+
/** Page size, 1-50. */
|
|
167
|
+
limit?: number;
|
|
168
|
+
};
|
|
169
|
+
/** Resolve a position command without signing. */
|
|
170
|
+
resolve_feed_position: {
|
|
171
|
+
/** Full identity. */
|
|
172
|
+
view_as: Hex;
|
|
173
|
+
/** Unmodified command text. */
|
|
174
|
+
input: string;
|
|
175
|
+
/** Optional market disambiguation. */
|
|
176
|
+
product_id?: number;
|
|
177
|
+
};
|
|
178
|
+
/** Resolve an order's complete trusted lifecycle segments. */
|
|
179
|
+
resolve_feed_action: {
|
|
180
|
+
/** Order-owning identity. */
|
|
181
|
+
view_as: Hex;
|
|
182
|
+
/** Trading order digest. */
|
|
183
|
+
order_digest: Hex;
|
|
184
|
+
};
|
|
185
|
+
/** Read a drawing within the parent item's visibility. */
|
|
186
|
+
feed_chart_drawing: MobileServerSocialFeedReadParams & {
|
|
187
|
+
/** Parent UUID. */
|
|
188
|
+
item_id: string;
|
|
189
|
+
/** Original session, paired with viewer_token. */
|
|
190
|
+
session_id?: string;
|
|
191
|
+
};
|
|
192
|
+
/** Read or navigate a comment thread. */
|
|
193
|
+
feed_comments: MobileServerSocialFeedReadParams & {
|
|
194
|
+
/** Root UUID. */
|
|
195
|
+
root_item_id: string;
|
|
196
|
+
/** Thread cursor. */
|
|
197
|
+
cursor?: string;
|
|
198
|
+
/** Page size, 1-50. */
|
|
199
|
+
limit?: number;
|
|
200
|
+
/** First-page anchor, mutually exclusive with cursor. */
|
|
201
|
+
anchor_reply_id?: string;
|
|
202
|
+
/** Original reading session. */
|
|
203
|
+
session_id?: string;
|
|
204
|
+
};
|
|
205
|
+
/** Full lifecycle history rather than published feed items alone. */
|
|
206
|
+
position_history: MobileServerSocialFeedReadParams & {
|
|
207
|
+
/** Lifecycle UUID. */
|
|
208
|
+
position_id: string;
|
|
209
|
+
/** Filter to published takes. */
|
|
210
|
+
takes_only?: boolean;
|
|
211
|
+
/** History cursor. */
|
|
212
|
+
cursor?: string;
|
|
213
|
+
/** Page size, 1-50. */
|
|
214
|
+
limit?: number;
|
|
215
|
+
/** Original position-mode session. */
|
|
216
|
+
session_id?: string;
|
|
217
|
+
};
|
|
218
|
+
/** Market candles and independently priced action markers. */
|
|
219
|
+
position_chart: MobileServerSocialFeedReadParams & {
|
|
220
|
+
/** Lifecycle UUID. */
|
|
221
|
+
position_id: string;
|
|
222
|
+
/** Original session, paired with viewer_token. */
|
|
223
|
+
session_id?: string;
|
|
224
|
+
/** Candle interval. */
|
|
225
|
+
interval: MobileSocialFeedChartInterval;
|
|
226
|
+
/** Half-open time interval. */
|
|
227
|
+
range: MobileServerSocialFeedChartRange;
|
|
228
|
+
/** Exclusive next-page bound. */
|
|
229
|
+
before_ms?: number;
|
|
230
|
+
/** Page size, 1-500. */
|
|
231
|
+
limit?: number;
|
|
232
|
+
};
|
|
233
|
+
/** Watcher query; does not register presence. */
|
|
234
|
+
position_watchers: {
|
|
235
|
+
/** Lifecycle UUID. */
|
|
236
|
+
position_id: string;
|
|
237
|
+
/** Relationship perspective only. */
|
|
238
|
+
view_as?: Hex;
|
|
239
|
+
};
|
|
95
240
|
/** Ordered server-owned avatar catalogue. */
|
|
96
241
|
avatar_presets: Record<never, never>;
|
|
97
242
|
/** Public recommendations with optional relationship perspective. */
|
|
@@ -128,6 +273,8 @@ export interface MobileServerPublicQueryRequestByType {
|
|
|
128
273
|
feed_item: MobileServerSocialFeedReadParams & {
|
|
129
274
|
/** Target item UUID. */
|
|
130
275
|
item_id: string;
|
|
276
|
+
/** Detail-visit event; omit for prefetch. Does not increment the count alone. */
|
|
277
|
+
view_event_id?: string;
|
|
131
278
|
/** Preview size, 0-3. */
|
|
132
279
|
comment_preview_limit?: number;
|
|
133
280
|
/** Omit to create a new reading session. */
|
|
@@ -178,8 +325,12 @@ export interface MobileServerPublicQueryRequestByType {
|
|
|
178
325
|
*/
|
|
179
326
|
cursor?: string;
|
|
180
327
|
};
|
|
181
|
-
notification_preferences:
|
|
182
|
-
|
|
328
|
+
notification_preferences: MobileServerWithExpoTokenParams;
|
|
329
|
+
/** Persisted device generation and capabilities. */
|
|
330
|
+
notification_registration_v2: MobileServerWithExpoTokenParams;
|
|
331
|
+
/** Versioned notification settings. */
|
|
332
|
+
notification_settings_v2: MobileServerWithExpoTokenParams;
|
|
333
|
+
registered_wallet: MobileServerWithExpoTokenParams;
|
|
183
334
|
}
|
|
184
335
|
|
|
185
336
|
/**
|
|
@@ -189,12 +340,48 @@ export type MobileServerPublicQueryRequestType =
|
|
|
189
340
|
keyof MobileServerPublicQueryRequestByType;
|
|
190
341
|
|
|
191
342
|
/**
|
|
192
|
-
* Params for each unsigned `public_execute`, keyed by request `type`.
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
343
|
+
* Params for each unsigned `public_execute`, keyed by request `type`. No signature, sender, or nonce is sent.
|
|
344
|
+
* `record_feed_views` and `position_presence` are authorized by the original reading session (`session_id`)
|
|
345
|
+
* and browser credential (`viewer_token`), not an Expo push token.
|
|
346
|
+
* For `unregister_expo_token` and `update_preferences`, possession of an active Expo push token authorizes
|
|
347
|
+
* the notification mutation: the backend resolves the token's owning wallet and mutates its state. These
|
|
348
|
+
* notification writes use the backend's last-write-wins commit order, so callers must serialize them.
|
|
196
349
|
*/
|
|
197
350
|
export interface MobileServerPublicExecuteRequestByType {
|
|
351
|
+
/** Full settings replacement with optimistic concurrency control. */
|
|
352
|
+
update_notification_settings_v2: MobileServerWithExpoTokenParams & {
|
|
353
|
+
/** Latest settings revision. */
|
|
354
|
+
expected_revision: number;
|
|
355
|
+
/** Complete settings document. */
|
|
356
|
+
settings: MobileServerNotificationSettings;
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
/** Explicit detail-visit report using the original browsing credential. */
|
|
360
|
+
record_feed_views: {
|
|
361
|
+
/** Original reading session. */
|
|
362
|
+
session_id: string;
|
|
363
|
+
/** Original credential. */
|
|
364
|
+
viewer_token: string;
|
|
365
|
+
/** Detail-visit event previously registered on feed_item. */
|
|
366
|
+
view_event_id: string;
|
|
367
|
+
/** Exactly one fully delivered detail-target item. */
|
|
368
|
+
item_ids: string[];
|
|
369
|
+
};
|
|
370
|
+
/** Per-page visitor lease; no wallet signature. */
|
|
371
|
+
position_presence: {
|
|
372
|
+
/** Lifecycle UUID. */
|
|
373
|
+
position_id: string;
|
|
374
|
+
/** Original reading session. */
|
|
375
|
+
session_id: string;
|
|
376
|
+
/** Page-scoped UUID. */
|
|
377
|
+
view_session_id: string;
|
|
378
|
+
/** Lease lifecycle state. */
|
|
379
|
+
state: MobileSocialFeedPresenceState;
|
|
380
|
+
/** Original browsing credential. */
|
|
381
|
+
viewer_token: string;
|
|
382
|
+
/** Omission preserves the display account; null clears it. */
|
|
383
|
+
watcher_subaccount?: Hex | null;
|
|
384
|
+
};
|
|
198
385
|
unregister_expo_token: { expo_token: string };
|
|
199
386
|
update_preferences: {
|
|
200
387
|
expo_token: string;
|
|
@@ -209,20 +396,33 @@ export type MobileServerPublicExecuteRequestType =
|
|
|
209
396
|
keyof MobileServerPublicExecuteRequestByType;
|
|
210
397
|
|
|
211
398
|
/**
|
|
212
|
-
* Discriminant `type` values for signed `execute` requests
|
|
213
|
-
*
|
|
214
|
-
* params map — a signed request body *is* its inner payload flattened with the envelope, so
|
|
399
|
+
* Discriminant `type` values for signed `execute` requests, excluding signed queries. Unlike the public
|
|
400
|
+
* queries these carry no separate params map — a signed request body is its inner payload flattened with the envelope, so
|
|
215
401
|
* {@link MobileSignedInner} is the single source of truth for both the fields and their significant order.
|
|
216
402
|
*/
|
|
217
|
-
export type MobileServerExecuteRequestType =
|
|
403
|
+
export type MobileServerExecuteRequestType = Exclude<
|
|
404
|
+
MobileSignedInner['type'],
|
|
405
|
+
MobileServerSignedQueryRequestType
|
|
406
|
+
>;
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Discriminant `type` values for signed `query` requests, distinct from unsigned `public_query` requests.
|
|
410
|
+
*/
|
|
411
|
+
export type MobileServerSignedQueryRequestType =
|
|
412
|
+
keyof MobileServerSignedQueryResponseByType;
|
|
218
413
|
|
|
219
414
|
/**
|
|
220
415
|
* Wire `request_type` the backend echoes on failure envelopes, prefixed by the route that produced it:
|
|
221
416
|
* `public_query_*` for unsigned queries, `public_execute_*` for unsigned writes, and `execute_*` for signed
|
|
222
|
-
* writes (e.g. `execute_set_username`)
|
|
223
|
-
*
|
|
417
|
+
* writes (e.g. `execute_set_username`), or `query_*` for signed reads. Unlike the EIP-712 method,
|
|
418
|
+
* these values never carry the `mobile:` prefix. Protected image reads use `feed_image` or
|
|
419
|
+
* `feed_comment_image` without a route prefix; malformed multipart uploads use `execute_image_upload`.
|
|
224
420
|
*/
|
|
225
421
|
export type MobileServerRequestType =
|
|
422
|
+
| 'feed_image'
|
|
423
|
+
| 'feed_comment_image'
|
|
424
|
+
| 'execute_image_upload'
|
|
425
|
+
| `query_${MobileServerSignedQueryRequestType}`
|
|
226
426
|
| `public_query_${MobileServerPublicQueryRequestType}`
|
|
227
427
|
| `public_execute_${MobileServerPublicExecuteRequestType}`
|
|
228
428
|
| `execute_${MobileServerExecuteRequestType}`;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, jest } from '@jest/globals';
|
|
2
|
+
import { buildMobileFeedImageMultipart } from './buildMobileFeedImageMultipart';
|
|
3
|
+
|
|
4
|
+
describe('buildMobileFeedImageMultipart', () => {
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
jest.restoreAllMocks();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('keeps multipart overhead fixed across timestamp and random boundary lengths', () => {
|
|
10
|
+
const payload = '{"type":"create_feed_post_image_uploads"}';
|
|
11
|
+
const fileBytes = new Uint8Array([0, 1, 255]);
|
|
12
|
+
const expected = buildMobileFeedImageMultipart(payload, fileBytes);
|
|
13
|
+
for (const timestamp of [0, 1_700_000_000_000, 8_640_000_000_000_000]) {
|
|
14
|
+
for (const random of [0, 0.000001, 0.5, 0.999999]) {
|
|
15
|
+
jest.spyOn(Date, 'now').mockReturnValue(timestamp);
|
|
16
|
+
jest.spyOn(Math, 'random').mockReturnValue(random);
|
|
17
|
+
const actual = buildMobileFeedImageMultipart(payload, fileBytes);
|
|
18
|
+
expect(actual.body.byteLength).toBe(expected.body.byteLength);
|
|
19
|
+
expect(actual.contentType.length).toBe(expected.contentType.length);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('emits payload and file parts with a boundary Content-Type', () => {
|
|
25
|
+
const fileBytes = new Uint8Array([0, 1, 127, 128, 255, 13, 10]);
|
|
26
|
+
const { body, contentType } = buildMobileFeedImageMultipart(
|
|
27
|
+
'{"type":"create_feed_post_image_uploads"}',
|
|
28
|
+
fileBytes,
|
|
29
|
+
);
|
|
30
|
+
const text = String.fromCharCode(...body);
|
|
31
|
+
expect(contentType.startsWith('multipart/form-data; boundary=')).toBe(true);
|
|
32
|
+
expect(text).toContain('name="payload"');
|
|
33
|
+
expect(text).toContain('name="file"; filename="image"');
|
|
34
|
+
expect(text).toContain('{"type":"create_feed_post_image_uploads"}');
|
|
35
|
+
const boundary = contentType.split('boundary=')[1];
|
|
36
|
+
const fileStart = text.indexOf('\r\n\r\n', text.indexOf('name="file"')) + 4;
|
|
37
|
+
expect(body.slice(fileStart, fileStart + fileBytes.length)).toEqual(
|
|
38
|
+
fileBytes,
|
|
39
|
+
);
|
|
40
|
+
expect(text.slice(fileStart + fileBytes.length)).toBe(
|
|
41
|
+
`\r\n--${boundary}--\r\n`,
|
|
42
|
+
);
|
|
43
|
+
expect(text.startsWith(`--${boundary}\r\n`)).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { concatBytes, stringToBytes } from 'viem';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Builds a multipart/form-data body for feed image uploads without relying on DOM FormData/Blob.
|
|
5
|
+
* Parts are exactly `payload` (JSON text) and `file` (raw bytes), matching the mobile execute contract.
|
|
6
|
+
* @param payloadJson - Stringified signed execute body.
|
|
7
|
+
* @param fileBytes - Original image bytes.
|
|
8
|
+
* @returns Raw multipart body and its Content-Type header value including boundary.
|
|
9
|
+
*/
|
|
10
|
+
export function buildMobileFeedImageMultipart(
|
|
11
|
+
payloadJson: string,
|
|
12
|
+
fileBytes: Uint8Array,
|
|
13
|
+
): { body: Uint8Array; contentType: string } {
|
|
14
|
+
// Fixed-length boundaries keep multipart overhead identical for the pre-signing size check and upload.
|
|
15
|
+
const boundary = `----nadoFeedImage${Date.now().toString(16).padStart(14, '0')}${Math.floor(
|
|
16
|
+
Math.random() * 1e6,
|
|
17
|
+
)
|
|
18
|
+
.toString(16)
|
|
19
|
+
.padStart(5, '0')}`;
|
|
20
|
+
const preamble =
|
|
21
|
+
`--${boundary}\r\n` +
|
|
22
|
+
'Content-Disposition: form-data; name="payload"\r\n' +
|
|
23
|
+
'Content-Type: application/json\r\n\r\n' +
|
|
24
|
+
`${payloadJson}\r\n` +
|
|
25
|
+
`--${boundary}\r\n` +
|
|
26
|
+
'Content-Disposition: form-data; name="file"; filename="image"\r\n' +
|
|
27
|
+
'Content-Type: application/octet-stream\r\n\r\n';
|
|
28
|
+
return {
|
|
29
|
+
body: concatBytes([
|
|
30
|
+
stringToBytes(preamble),
|
|
31
|
+
fileBytes,
|
|
32
|
+
stringToBytes(`\r\n--${boundary}--\r\n`),
|
|
33
|
+
]),
|
|
34
|
+
contentType: `multipart/form-data; boundary=${boundary}`,
|
|
35
|
+
};
|
|
36
|
+
}
|
package/src/utils/feed.ts
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export const MOBILE_FEED_MAX_PAGE_SIZE = 50;
|
|
6
6
|
|
|
7
|
+
/** Maximum feed image upload request size, including the signed payload and multipart framing (2 MiB). */
|
|
8
|
+
export const MOBILE_FEED_IMAGE_MAX_REQUEST_BYTES = 2 * 1024 * 1024;
|
|
9
|
+
|
|
7
10
|
/**
|
|
8
11
|
* Lowest minimum notional the backend accepts, in whole dollars. Filtered requests below this fail with
|
|
9
12
|
* `INVALID_FEED_FILTER`; omitting the filter entirely returns the unfiltered feed.
|