@nadohq/mobile-client 0.53.0 → 0.55.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.
Files changed (147) hide show
  1. package/README.md +12 -4
  2. package/dist/{MobileClient-CEVEYnV1.cjs → MobileClient-BbTaqTzi.cjs} +141 -3
  3. package/dist/MobileClient-BbTaqTzi.cjs.map +1 -0
  4. package/dist/MobileClient.cjs +1 -1
  5. package/dist/MobileClient.d.cts +75 -8
  6. package/dist/MobileClient.d.cts.map +1 -1
  7. package/dist/MobileClient.d.ts +75 -8
  8. package/dist/MobileClient.d.ts.map +1 -1
  9. package/dist/MobileClient.js +141 -3
  10. package/dist/MobileClient.js.map +1 -1
  11. package/dist/{MobileServerFailureError-GsGrBgO0.d.ts → MobileServerFailureError-B2og8e5O.d.ts} +3 -3
  12. package/dist/{MobileServerFailureError-GsGrBgO0.d.ts.map → MobileServerFailureError-B2og8e5O.d.ts.map} +1 -1
  13. package/dist/{MobileServerFailureError-D4ina2b2.d.cts → MobileServerFailureError-BrLtaHnU.d.cts} +3 -3
  14. package/dist/{MobileServerFailureError-D4ina2b2.d.cts.map → MobileServerFailureError-BrLtaHnU.d.cts.map} +1 -1
  15. package/dist/{buildSignedMobileRequest-D9XzRTyq.d.cts → buildSignedMobileRequest-CZ-EdxYI.d.cts} +2 -2
  16. package/dist/{buildSignedMobileRequest-D9XzRTyq.d.cts.map → buildSignedMobileRequest-CZ-EdxYI.d.cts.map} +1 -1
  17. package/dist/{buildSignedMobileRequest-7Iwi5k6h.d.ts → buildSignedMobileRequest-CoAVSDPx.d.ts} +2 -2
  18. package/dist/{buildSignedMobileRequest-7Iwi5k6h.d.ts.map → buildSignedMobileRequest-CoAVSDPx.d.ts.map} +1 -1
  19. package/dist/{canonicalize-OYR35XMP.d.cts → canonicalize-0_B6UOxO.d.cts} +2 -2
  20. package/dist/canonicalize-0_B6UOxO.d.cts.map +1 -0
  21. package/dist/{canonicalize-T4ShepBu.d.ts → canonicalize-BC-JICjp.d.ts} +2 -2
  22. package/dist/canonicalize-BC-JICjp.d.ts.map +1 -0
  23. package/dist/clientTypes-P4LAjreY.d.ts +731 -0
  24. package/dist/clientTypes-P4LAjreY.d.ts.map +1 -0
  25. package/dist/clientTypes-YF5d8bvg.d.cts +731 -0
  26. package/dist/clientTypes-YF5d8bvg.d.cts.map +1 -0
  27. package/dist/dataMappers.cjs +358 -0
  28. package/dist/dataMappers.cjs.map +1 -1
  29. package/dist/dataMappers.d.cts +132 -6
  30. package/dist/dataMappers.d.cts.map +1 -1
  31. package/dist/dataMappers.d.ts +132 -6
  32. package/dist/dataMappers.d.ts.map +1 -1
  33. package/dist/dataMappers.js +339 -2
  34. package/dist/dataMappers.js.map +1 -1
  35. package/dist/{eip712MethodByType-D6edRSIs.d.ts → eip712MethodByType-DWtLyPY7.d.ts} +2 -2
  36. package/dist/eip712MethodByType-DWtLyPY7.d.ts.map +1 -0
  37. package/dist/{eip712MethodByType-BAqld4fP.d.cts → eip712MethodByType-sHQ-VTHd.d.cts} +2 -2
  38. package/dist/eip712MethodByType-sHQ-VTHd.d.cts.map +1 -0
  39. package/dist/index.cjs +1 -1
  40. package/dist/index.d.cts +15 -15
  41. package/dist/index.d.ts +15 -15
  42. package/dist/{mobileErrorCodes-CGYR3_Io.d.ts → mobileErrorCodes-DccrM4NI.d.cts} +8 -2
  43. package/dist/{mobileErrorCodes-CGYR3_Io.d.cts.map → mobileErrorCodes-DccrM4NI.d.cts.map} +1 -1
  44. package/dist/{mobileErrorCodes-CGYR3_Io.d.cts → mobileErrorCodes-DccrM4NI.d.ts} +8 -2
  45. package/dist/{mobileErrorCodes-CGYR3_Io.d.ts.map → mobileErrorCodes-DccrM4NI.d.ts.map} +1 -1
  46. package/dist/{payloadHash-B7Nmf64N.d.cts → payloadHash-CSgTglN4.d.cts} +2 -2
  47. package/dist/payloadHash-CSgTglN4.d.cts.map +1 -0
  48. package/dist/{payloadHash-RxkbwgTH.d.ts → payloadHash-qsU1DEF0.d.ts} +2 -2
  49. package/dist/payloadHash-qsU1DEF0.d.ts.map +1 -0
  50. package/dist/{serverBaseTypes-BOuAdmuQ.d.cts → serverBaseTypes-CuMsGXgc.d.cts} +2 -2
  51. package/dist/{serverBaseTypes-BOuAdmuQ.d.cts.map → serverBaseTypes-CuMsGXgc.d.cts.map} +1 -1
  52. package/dist/{serverBaseTypes-DDzfBA1a.d.ts → serverBaseTypes-DKCLDn3x.d.ts} +2 -2
  53. package/dist/{serverBaseTypes-DDzfBA1a.d.ts.map → serverBaseTypes-DKCLDn3x.d.ts.map} +1 -1
  54. package/dist/{serverExecuteTypes-DrxK2r7m.d.ts → serverExecuteTypes-DKG1mqy1.d.ts} +3 -3
  55. package/dist/{serverExecuteTypes-DrxK2r7m.d.ts.map → serverExecuteTypes-DKG1mqy1.d.ts.map} +1 -1
  56. package/dist/{serverExecuteTypes-DamHfu25.d.cts → serverExecuteTypes-TPX0GCgv.d.cts} +3 -3
  57. package/dist/{serverExecuteTypes-DamHfu25.d.cts.map → serverExecuteTypes-TPX0GCgv.d.cts.map} +1 -1
  58. package/dist/serverModelTypes-MlqdaMRd.d.cts +490 -0
  59. package/dist/serverModelTypes-MlqdaMRd.d.cts.map +1 -0
  60. package/dist/serverModelTypes-MlqdaMRd.d.ts +490 -0
  61. package/dist/serverModelTypes-MlqdaMRd.d.ts.map +1 -0
  62. package/dist/serverQueryTypes-BLUe10AI.d.ts +152 -0
  63. package/dist/serverQueryTypes-BLUe10AI.d.ts.map +1 -0
  64. package/dist/serverQueryTypes-BZOoJBpb.d.cts +152 -0
  65. package/dist/serverQueryTypes-BZOoJBpb.d.cts.map +1 -0
  66. package/dist/{serverRequestTypes-BylecTUn.d.cts → serverRequestTypes-BULjZnnz.d.ts} +69 -4
  67. package/dist/serverRequestTypes-BULjZnnz.d.ts.map +1 -0
  68. package/dist/{serverRequestTypes-DcdmGfTu.d.ts → serverRequestTypes-XbnLUsXT.d.cts} +69 -4
  69. package/dist/serverRequestTypes-XbnLUsXT.d.cts.map +1 -0
  70. package/dist/{serverResponseGuards-CjR1tv7G.d.cts → serverResponseGuards-DIj9MIrJ.d.cts} +2 -2
  71. package/dist/{serverResponseGuards-CjR1tv7G.d.cts.map → serverResponseGuards-DIj9MIrJ.d.cts.map} +1 -1
  72. package/dist/{serverResponseGuards-BspbRjOM.d.ts → serverResponseGuards-DY_8lAo7.d.ts} +2 -2
  73. package/dist/{serverResponseGuards-BspbRjOM.d.ts.map → serverResponseGuards-DY_8lAo7.d.ts.map} +1 -1
  74. package/dist/signing/buildSignedMobileRequest.d.cts +1 -1
  75. package/dist/signing/buildSignedMobileRequest.d.ts +1 -1
  76. package/dist/signing/canonicalize.d.cts +1 -1
  77. package/dist/signing/canonicalize.d.ts +1 -1
  78. package/dist/signing/eip712MethodByType.d.cts +1 -1
  79. package/dist/signing/eip712MethodByType.d.ts +1 -1
  80. package/dist/signing/index.d.cts +5 -5
  81. package/dist/signing/index.d.ts +5 -5
  82. package/dist/signing/payloadHash.d.cts +1 -1
  83. package/dist/signing/payloadHash.d.ts +1 -1
  84. package/dist/signing/types.d.cts +1 -1
  85. package/dist/signing/types.d.ts +1 -1
  86. package/dist/types/MobileServerFailureError.d.cts +1 -1
  87. package/dist/types/MobileServerFailureError.d.ts +1 -1
  88. package/dist/types/clientTypes.d.cts +2 -2
  89. package/dist/types/clientTypes.d.ts +2 -2
  90. package/dist/types/index.d.cts +9 -9
  91. package/dist/types/index.d.ts +9 -9
  92. package/dist/types/mobileErrorCodes.cjs +13 -1
  93. package/dist/types/mobileErrorCodes.cjs.map +1 -1
  94. package/dist/types/mobileErrorCodes.d.cts +1 -1
  95. package/dist/types/mobileErrorCodes.d.ts +1 -1
  96. package/dist/types/mobileErrorCodes.js +13 -1
  97. package/dist/types/mobileErrorCodes.js.map +1 -1
  98. package/dist/types/serverBaseTypes.d.cts +1 -1
  99. package/dist/types/serverBaseTypes.d.ts +1 -1
  100. package/dist/types/serverExecuteTypes.d.cts +1 -1
  101. package/dist/types/serverExecuteTypes.d.ts +1 -1
  102. package/dist/types/serverModelTypes.cjs.map +1 -1
  103. package/dist/types/serverModelTypes.d.cts +2 -2
  104. package/dist/types/serverModelTypes.d.ts +2 -2
  105. package/dist/types/serverModelTypes.js.map +1 -1
  106. package/dist/types/serverQueryTypes.d.cts +2 -2
  107. package/dist/types/serverQueryTypes.d.ts +2 -2
  108. package/dist/types/serverRequestTypes.d.cts +2 -2
  109. package/dist/types/serverRequestTypes.d.ts +2 -2
  110. package/dist/{types-BG321aOe.d.ts → types-B_4veFLc.d.ts} +3 -3
  111. package/dist/{types-BG321aOe.d.ts.map → types-B_4veFLc.d.ts.map} +1 -1
  112. package/dist/{types-D30luCKT.d.cts → types-CwpXP7xM.d.cts} +3 -3
  113. package/dist/{types-D30luCKT.d.cts.map → types-CwpXP7xM.d.cts.map} +1 -1
  114. package/dist/utils/index.d.cts +1 -1
  115. package/dist/utils/index.d.ts +1 -1
  116. package/dist/utils/serverResponseGuards.d.cts +1 -1
  117. package/dist/utils/serverResponseGuards.d.ts +1 -1
  118. package/package.json +3 -3
  119. package/src/MobileClient.ts +192 -2
  120. package/src/dataMappers.ts +503 -1
  121. package/src/socialFeed.test.ts +723 -0
  122. package/src/types/clientTypes.ts +467 -0
  123. package/src/types/mobileErrorCodes.ts +12 -0
  124. package/src/types/serverModelTypes.ts +388 -0
  125. package/src/types/serverQueryTypes.ts +74 -0
  126. package/src/types/serverRequestTypes.ts +94 -1
  127. package/dist/MobileClient-CEVEYnV1.cjs.map +0 -1
  128. package/dist/canonicalize-OYR35XMP.d.cts.map +0 -1
  129. package/dist/canonicalize-T4ShepBu.d.ts.map +0 -1
  130. package/dist/clientTypes-FQTkDfq3.d.cts +0 -349
  131. package/dist/clientTypes-FQTkDfq3.d.cts.map +0 -1
  132. package/dist/clientTypes-FaHdWkNu.d.ts +0 -349
  133. package/dist/clientTypes-FaHdWkNu.d.ts.map +0 -1
  134. package/dist/eip712MethodByType-BAqld4fP.d.cts.map +0 -1
  135. package/dist/eip712MethodByType-D6edRSIs.d.ts.map +0 -1
  136. package/dist/payloadHash-B7Nmf64N.d.cts.map +0 -1
  137. package/dist/payloadHash-RxkbwgTH.d.ts.map +0 -1
  138. package/dist/serverModelTypes-YmHqfxc8.d.cts +0 -173
  139. package/dist/serverModelTypes-YmHqfxc8.d.cts.map +0 -1
  140. package/dist/serverModelTypes-YmHqfxc8.d.ts +0 -173
  141. package/dist/serverModelTypes-YmHqfxc8.d.ts.map +0 -1
  142. package/dist/serverQueryTypes-C-_h9awN.d.ts +0 -89
  143. package/dist/serverQueryTypes-C-_h9awN.d.ts.map +0 -1
  144. package/dist/serverQueryTypes-CuVsrzGV.d.cts +0 -89
  145. package/dist/serverQueryTypes-CuVsrzGV.d.cts.map +0 -1
  146. package/dist/serverRequestTypes-BylecTUn.d.cts.map +0 -1
  147. package/dist/serverRequestTypes-DcdmGfTu.d.ts.map +0 -1
@@ -196,3 +196,391 @@ export interface MobileServerNotificationPreferences {
196
196
  schema_version: 1;
197
197
  categories: MobileServerNotificationCategoryPreference[];
198
198
  }
199
+
200
+ /** Content filters accepted by the six social feed lists. Empty or omitted means all. */
201
+ export type MobileSocialFeedType =
202
+ | 'open'
203
+ | 'close'
204
+ | 'size_change'
205
+ | 'thoughts'
206
+ | 'analysis'
207
+ | 'comments';
208
+
209
+ /** Market category used by the social feed. */
210
+ export type MobileSocialFeedMarketCategory = 'crypto' | 'finance';
211
+
212
+ /** Qualification tier for an account-level PnL badge. */
213
+ export type MobileSocialFeedTraderBadgeCode = 'shark' | 'whale';
214
+
215
+ /** Availability of the current or last successful qualification snapshot. */
216
+ export type MobileSocialFeedCohortStatus = 'ready' | 'stale';
217
+
218
+ /** Availability of an author's qualification data. */
219
+ export type MobileSocialFeedTraderDataStatus =
220
+ | MobileSocialFeedCohortStatus
221
+ | 'unavailable';
222
+
223
+ /** Category from the authoritative market source. */
224
+ export type MobileSocialFeedSourceCategory =
225
+ | 'crypto'
226
+ | 'stocks'
227
+ | 'forex'
228
+ | 'commodities';
229
+
230
+ /** Accounting basis used for position PnL. */
231
+ export type MobileSocialFeedPnlBasis =
232
+ | 'unrealized_excl_fees_funding'
233
+ | 'realized_incl_fees_funding';
234
+
235
+ /** Whether position PnL is live or frozen at close. */
236
+ export type MobileSocialFeedPnlMode = 'live' | 'frozen';
237
+
238
+ /** Completeness of position PnL accounting. */
239
+ export type MobileSocialFeedPnlQuality = 'ready' | 'pending' | 'unavailable';
240
+
241
+ /** Source of the displayed position size and entry price. */
242
+ export type MobileSocialFeedPositionDisplayBasis =
243
+ | 'current_position'
244
+ | 'closing_snapshot';
245
+
246
+ /** Current state of a position lifecycle. */
247
+ export type MobileSocialFeedPositionState = 'open' | 'closed';
248
+
249
+ /** Completeness of the available position history. */
250
+ export type MobileSocialFeedHistoryQuality = 'complete' | 'partial';
251
+
252
+ /** Trading action represented by an ordinary size-change row. */
253
+ export type MobileSocialFeedTradeSizeChangeAction = 'increased' | 'reduced';
254
+
255
+ /** Trading action represented by an automatic trade card. */
256
+ export type MobileSocialFeedTradeCardAction =
257
+ | 'opened'
258
+ | 'closed'
259
+ | MobileSocialFeedTradeSizeChangeAction;
260
+
261
+ /** Whether a reading session was created for a list or a direct item. */
262
+ export type MobileSocialFeedReadSessionMode = 'feed' | 'item';
263
+
264
+ /** Kind of feed update target. */
265
+ export type MobileSocialFeedTargetType = 'item' | 'position';
266
+
267
+ /** Official account-level 30-day PnL badge, independent of position PnL. */
268
+ export interface MobileServerSocialFeedTraderBadge {
269
+ /** Qualification tier. */
270
+ code: MobileSocialFeedTraderBadgeCode;
271
+ /** Signed integer in x18 units. */
272
+ pnl_x18: string;
273
+ /** Stable compatibility identifier for the official Portfolio month result. */
274
+ metric_key: 'account_pnl_30d_equity';
275
+ /** PnL window label. */
276
+ window: '30d';
277
+ /** Official source timestamp in Unix milliseconds. */
278
+ source_as_of_ms: number;
279
+ /** Fetch completion timestamp in Unix milliseconds. */
280
+ fetched_at_ms: number;
281
+ /** Qualification snapshot UUID. */
282
+ snapshot_id: string;
283
+ }
284
+
285
+ /** Public author identity and the selected viewing account's follow state. */
286
+ export interface MobileServerSocialFeedAuthor extends MobileServerIdentitySummary {
287
+ /** Selected view_as account's follow state; null without a viewing account. */
288
+ is_following: boolean | null;
289
+ /** Null when no qualifying badge is available. */
290
+ trader_badge: MobileServerSocialFeedTraderBadge | null;
291
+ /** Stale means the last successful cohort is used after a refresh failure. */
292
+ trader_data_status: MobileSocialFeedTraderDataStatus;
293
+ }
294
+
295
+ /** Market metadata from the service's authoritative market source. */
296
+ export interface MobileServerSocialFeedMarket {
297
+ /** Market product ID. */
298
+ product_id: number;
299
+ /** Market symbol. */
300
+ symbol: string;
301
+ /** Logo URL when available. */
302
+ logo_url: string | null;
303
+ /** Social feed category when known. */
304
+ category: MobileSocialFeedMarketCategory | null;
305
+ /** Original market categories. */
306
+ source_categories: MobileSocialFeedSourceCategory[];
307
+ }
308
+
309
+ /** Leverage display value; unknown isolated leverage differs from inapplicable cross leverage. */
310
+ export interface MobileSocialFeedLeverage {
311
+ /** Rounded whole-number string, or null. Never an estimated replacement. */
312
+ value: string | null;
313
+ /** Cross margin uses not_applicable. */
314
+ basis: 'effective' | 'unknown' | 'not_applicable';
315
+ }
316
+
317
+ /** Position PnL with explicit accounting basis and data quality. */
318
+ export interface MobileServerSocialFeedPnl {
319
+ /** Signed x18 integer; null means unknown, not zero. */
320
+ amount_x18: string | null;
321
+ /** Open positions exclude fees/funding; closed results include them. */
322
+ basis: MobileSocialFeedPnlBasis;
323
+ /** Closed positions use frozen results. */
324
+ mode: MobileSocialFeedPnlMode;
325
+ /** Source timestamp in Unix milliseconds. */
326
+ as_of_ms: number;
327
+ /** Whether accounting is complete, pending, or unavailable. */
328
+ quality: MobileSocialFeedPnlQuality;
329
+ }
330
+
331
+ /** Complete mutable position fields delivered together at one version. */
332
+ export interface MobileServerSocialFeedPositionPatch {
333
+ /** Position lifecycle UUID. */
334
+ position_id: string;
335
+ /** Positive integer string; compare as integers without Number conversion. */
336
+ position_version: string;
337
+ /** Position state timestamp in Unix milliseconds. */
338
+ state_as_of_ms: number;
339
+ /** Remaining average entry cost, frozen on close; x18 or null. */
340
+ entry_price_x18: string | null;
341
+ /** Basis of the displayed size and entry price. */
342
+ display_basis: MobileSocialFeedPositionDisplayBasis;
343
+ /** Closing snapshot reference time, or null. */
344
+ snapshot_at_ms: number | null;
345
+ /** Absolute quantity in x18 units. */
346
+ quantity_x18: string;
347
+ /** Notional value in x18 units. */
348
+ notional_x18: string;
349
+ /** Current lifecycle state. */
350
+ state: MobileSocialFeedPositionState;
351
+ /** Completeness of the available historical facts. */
352
+ history_quality: MobileSocialFeedHistoryQuality;
353
+ /** Margin mode. */
354
+ margin_mode: MobileFeedMarginMode;
355
+ /** Current or closing leverage. */
356
+ leverage: MobileSocialFeedLeverage;
357
+ /** Leverage reference time; null when unknown or inapplicable. */
358
+ leverage_at_ms: number | null;
359
+ /** Current remaining PnL or the closed lifecycle's net result. */
360
+ pnl: MobileServerSocialFeedPnl;
361
+ }
362
+
363
+ /** Position displayed inside an automatic trade card. */
364
+ export interface MobileServerSocialFeedPositionCard extends MobileServerSocialFeedPositionPatch {
365
+ /** Market product ID. */
366
+ product_id: number;
367
+ /** Market display metadata. */
368
+ market: MobileServerSocialFeedMarket;
369
+ /** Position direction. */
370
+ direction: MobileFeedTradePositionDirection;
371
+ }
372
+
373
+ /** Interaction counters; interaction writes are not currently available. */
374
+ export interface MobileServerSocialFeedInteraction {
375
+ /** Number of likes. */
376
+ like_count: number;
377
+ /** Number of comments. */
378
+ comment_count: number;
379
+ /** Number of recorded views. */
380
+ view_count: number;
381
+ /** Null while likes are unavailable, including with a viewing account. */
382
+ liked_by_me: boolean | null;
383
+ }
384
+
385
+ /** Capability flags for a social feed item. */
386
+ export interface MobileServerSocialFeedCapabilities {
387
+ /** Whether liking is available. */
388
+ can_like: boolean;
389
+ /** Whether commenting is available. */
390
+ can_comment: boolean;
391
+ /** Whether exposure recording is available. */
392
+ can_record_view: boolean;
393
+ }
394
+
395
+ /** Comment preview metadata for a social trade card. */
396
+ export interface MobileServerSocialFeedCommentPreview {
397
+ /** Currently empty. */
398
+ items: never[];
399
+ /** Comment count. */
400
+ total_count: number;
401
+ /** Comment cursor, if available. */
402
+ next_cursor: string | null;
403
+ }
404
+
405
+ /** Exposure requirements associated with a reading session. */
406
+ export interface MobileServerSocialFeedViewTracking {
407
+ /** Required visible fraction. */
408
+ min_visible_ratio: number;
409
+ /** Required visible duration in milliseconds. */
410
+ min_duration_ms: number;
411
+ }
412
+
413
+ /** Coverage of the candidate authors in a qualification snapshot. */
414
+ export interface MobileServerSocialFeedCohortCoverage {
415
+ /** Coverage domain. */
416
+ scope: 'eligible_content_candidates';
417
+ /** Candidate author count. */
418
+ total_authors: number;
419
+ /** Authors queried for this snapshot. */
420
+ queried_authors: number;
421
+ /** A successful response requires complete coverage. */
422
+ complete: true;
423
+ }
424
+
425
+ /** Shared qualification snapshot used for Top Traders eligibility and badges. */
426
+ export interface MobileServerSocialFeedCohort {
427
+ /** Cohort UUID. */
428
+ snapshot_id: string;
429
+ /** Ready or the previous successful snapshot after a refresh failure. */
430
+ status: MobileSocialFeedCohortStatus;
431
+ /** Coverage of all eligible candidate authors. */
432
+ coverage: MobileServerSocialFeedCohortCoverage;
433
+ }
434
+
435
+ /** Metadata shared by the automatic trade cards and rows available from the social feed. */
436
+ export interface MobileServerSocialFeedItemBase {
437
+ /** Item UUID. */
438
+ id: string;
439
+ /** Whether authored analysis exists. */
440
+ has_analysis: boolean;
441
+ /** Drawings are not currently available. */
442
+ drawing: null;
443
+ /** Author identity, badge, and follow perspective. */
444
+ author: MobileServerSocialFeedAuthor;
445
+ /** Creation time in Unix milliseconds. */
446
+ created_at_ms: number;
447
+ /** Sorting time in Unix milliseconds. */
448
+ display_at_ms: number;
449
+ /** Positive integer version string. */
450
+ version: string;
451
+ /** Market metadata. */
452
+ market: MobileServerSocialFeedMarket;
453
+ /** Server capability flags; currently all false. */
454
+ capabilities: MobileServerSocialFeedCapabilities;
455
+ }
456
+
457
+ /** Automatic trade card returned by the social feed. */
458
+ export interface MobileServerSocialFeedTradeCard extends MobileServerSocialFeedItemBase {
459
+ /** Card discriminant. */
460
+ kind: 'trade_card';
461
+ /** Trading action. */
462
+ action: MobileSocialFeedTradeCardAction;
463
+ /** Card text, empty for automatic cards. */
464
+ text: string;
465
+ /** Automatic cards have no mentions. */
466
+ mentions: never[];
467
+ /** Current or frozen position display. */
468
+ position: MobileServerSocialFeedPositionCard;
469
+ /** Interaction counters. */
470
+ interaction: MobileServerSocialFeedInteraction;
471
+ /** Comment content is not currently available. */
472
+ comment_preview: MobileServerSocialFeedCommentPreview;
473
+ }
474
+
475
+ /** Fields shared by size-change and liquidation trade rows. */
476
+ export interface MobileServerSocialFeedTradeRowBase extends MobileServerSocialFeedItemBase {
477
+ /** Row discriminant. */
478
+ kind: 'trade_row';
479
+ /** Associated lifecycle UUID. */
480
+ position_id: string;
481
+ /** Position direction. */
482
+ direction: MobileFeedTradePositionDirection;
483
+ /** Historical margin mode. */
484
+ margin_mode: MobileFeedMarginMode;
485
+ /** Historical action leverage, not the position's current leverage. */
486
+ leverage: MobileSocialFeedLeverage;
487
+ /** Historical leverage reference time. */
488
+ leverage_at_ms: number | null;
489
+ /** Number of aggregated trades. */
490
+ trade_count: number;
491
+ /** Absolute traded quantity in x18 units. */
492
+ quantity_x18: string;
493
+ /** Actual execution price in x18 units, never an Oracle substitution. */
494
+ average_price_x18: string | null;
495
+ }
496
+
497
+ /** A size-change row or liquidation row with independently nullable financial facts. */
498
+ export type MobileServerSocialFeedTradeRow =
499
+ MobileServerSocialFeedTradeRowBase &
500
+ (
501
+ | {
502
+ /** Ordinary size-change action. */
503
+ action: MobileSocialFeedTradeSizeChangeAction;
504
+ /** Executed notional in x18 units. */
505
+ notional_x18: string;
506
+ }
507
+ | {
508
+ /** Liquidation discriminant. */
509
+ action: 'liquidated';
510
+ /** Quantity times event Oracle; null if that Oracle is unknown. */
511
+ notional_x18: string | null;
512
+ /** Entry cost immediately before the event, in x18 units. */
513
+ entry_price_x18: string | null;
514
+ /** Event Oracle used for display and size filtering. */
515
+ liquidation_oracle_price_x18: string | null;
516
+ /** Actual execution price, independent of Oracle. */
517
+ liquidation_execution_price_x18: string | null;
518
+ /** Signed action PnL excluding ordinary fees/funding, or null. */
519
+ realized_pnl_delta_x18: string | null;
520
+ }
521
+ );
522
+
523
+ /** Automatic feed content; excludes posts, replies, drawings, and interaction writes. */
524
+ export type MobileServerSocialFeedItem =
525
+ | MobileServerSocialFeedTradeCard
526
+ | MobileServerSocialFeedTradeRow;
527
+
528
+ /** Fixed-duration social feed reading session. Credentials and cursors must be returned unchanged. */
529
+ export interface MobileServerSocialFeedReadSession {
530
+ /** Session identifier. */
531
+ session_id: string;
532
+ /** Feed or direct item session. */
533
+ mode: MobileSocialFeedReadSessionMode;
534
+ /** Fixed expiration time in Unix milliseconds; pagination does not extend it. */
535
+ expires_at_ms: number;
536
+ /** Exposure metadata only; recording is not available from the social feed. */
537
+ view_tracking: MobileServerSocialFeedViewTracking;
538
+ /** Initial update baseline, distinct from the page cursor. */
539
+ update_cursor: string | null;
540
+ /** Credential for this reading session. Do not log or cache publicly. */
541
+ viewer_token: string;
542
+ }
543
+
544
+ /** Item delta: omitted means unchanged; explicit null clears a prior value. */
545
+ export interface MobileServerSocialFeedItemPatch {
546
+ /** Current author identity, follow state, and qualification badge. */
547
+ author: MobileServerSocialFeedAuthor;
548
+ /** Target item UUID. */
549
+ item_id: string;
550
+ /** Positive integer version string. */
551
+ version: string;
552
+ /** Updated interaction counters. */
553
+ interaction?: MobileServerSocialFeedInteraction;
554
+ /** Updated display timestamp; does not reorder the current list. */
555
+ display_at_ms: number;
556
+ /** Updated aggregate count. */
557
+ trade_count?: number;
558
+ /** Updated quantity in x18 units. */
559
+ quantity_x18?: string;
560
+ /** Updated notional; liquidation Oracle may be unknown. */
561
+ notional_x18?: string | null;
562
+ /** Updated actual execution price. */
563
+ average_price_x18?: string | null;
564
+ /** Historical liquidation entry cost. */
565
+ entry_price_x18?: string | null;
566
+ /** Updated liquidation Oracle. */
567
+ liquidation_oracle_price_x18?: string | null;
568
+ /** Updated actual liquidation execution price. */
569
+ liquidation_execution_price_x18?: string | null;
570
+ /** Updated signed action PnL. */
571
+ realized_pnl_delta_x18?: string | null;
572
+ /** Updated historical row leverage. */
573
+ leverage?: MobileSocialFeedLeverage;
574
+ /** Updated historical leverage reference time. */
575
+ leverage_at_ms?: number | null;
576
+ }
577
+
578
+ /** A previously authorized target that can no longer be read; shared by wire and client responses. */
579
+ export interface MobileSocialFeedUnavailableTarget {
580
+ /** Target kind. */
581
+ type: MobileSocialFeedTargetType;
582
+ /** Target UUID. */
583
+ id: string;
584
+ /** Uniform reason prevents leaking inaccessible content. */
585
+ reason: 'unavailable';
586
+ }
@@ -6,6 +6,12 @@ import {
6
6
  MobileServerFollowListAccount,
7
7
  MobileServerNotificationPreferences,
8
8
  MobileServerProfile,
9
+ MobileServerSocialFeedCohort,
10
+ MobileServerSocialFeedItem,
11
+ MobileServerSocialFeedItemPatch,
12
+ MobileServerSocialFeedPositionPatch,
13
+ MobileServerSocialFeedReadSession,
14
+ MobileSocialFeedUnavailableTarget,
9
15
  } from './serverModelTypes';
10
16
  import {
11
17
  MobileServerPublicQueryRequestByType,
@@ -63,6 +69,58 @@ export interface MobileServerFeedResponse {
63
69
  next_cursor: string | null;
64
70
  }
65
71
 
72
+ /** Fixed-window list response; an empty page can still have a next cursor. */
73
+ export interface MobileServerSocialFeedResponse {
74
+ /** Reading session and its browser credential. */
75
+ read_session: MobileServerSocialFeedReadSession;
76
+ /** Visible items in server order; deduplicate by ID without local reordering. */
77
+ items: MobileServerSocialFeedItem[];
78
+ /** Opaque cursor; null only when pagination is complete. */
79
+ next_cursor: string | null;
80
+ /** New-content baseline, not a pagination or update cursor. */
81
+ watermark: string;
82
+ }
83
+
84
+ /** Main-feed page with its ordering version. */
85
+ export interface MobileServerSocialFeedRankedResponse extends MobileServerSocialFeedResponse {
86
+ /** Current ordering contract: chronological-v1. */
87
+ ranking_version: string;
88
+ }
89
+
90
+ /** Top Traders page, with one shared qualification snapshot for eligibility and badges. */
91
+ export interface MobileServerSocialFeedTopTradersResponse extends MobileServerSocialFeedRankedResponse {
92
+ /** Author eligibility snapshot. */
93
+ cohort: MobileServerSocialFeedCohort;
94
+ }
95
+
96
+ /** Item details with either a new item session or the reused authorized session. */
97
+ export interface MobileServerSocialFeedItemResponse {
98
+ /** Full visible item. */
99
+ item: MobileServerSocialFeedItem;
100
+ /** Session authorized for subsequent updates. */
101
+ read_session: MobileServerSocialFeedReadSession;
102
+ }
103
+
104
+ /** Batched viewport updates; apply only the current viewport's latest request sequence. */
105
+ export interface MobileServerSocialFeedUpdatesResponse {
106
+ /** Item deltas, independent of current-position patches. */
107
+ item_patches: MobileServerSocialFeedItemPatch[];
108
+ /** Complete mutable position facts at one version. */
109
+ position_patches: MobileServerSocialFeedPositionPatch[];
110
+ /** Previously authorized targets that can no longer be read. */
111
+ unavailable_targets: MobileSocialFeedUnavailableTarget[];
112
+ /** New-content hint; always zero for directly created item sessions. */
113
+ new_items_count: number;
114
+ /** Baseline to use for the next update call with the same viewport. */
115
+ update_cursor: string;
116
+ /** Full snapshot of applicable mutable fields; currently always true. Apply author updates even when the item version is unchanged. */
117
+ reset: boolean;
118
+ /** Echoed viewport revision. */
119
+ viewport_revision: number;
120
+ /** Echoed request sequence. */
121
+ request_seq: number;
122
+ }
123
+
66
124
  /**
67
125
  * Payload of the `notification_preferences` public query success response.
68
126
  */
@@ -90,6 +148,22 @@ export interface MobileServerRegisteredWalletResponse {
90
148
  * by {@link MobileServerPublicQuerySuccessResponse}.
91
149
  */
92
150
  export interface MobileServerPublicQueryResponseByType {
151
+ /** For You recommendations. */
152
+ for_you_feed: MobileServerSocialFeedRankedResponse;
153
+ /** Qualified authors and cohort metadata. */
154
+ top_traders_feed: MobileServerSocialFeedTopTradersResponse;
155
+ /** Public content from followed authors. */
156
+ friends_feed: MobileServerSocialFeedRankedResponse;
157
+ /** Published author content. */
158
+ profile_feed: MobileServerSocialFeedResponse;
159
+ /** Published market content. */
160
+ market_feed: MobileServerSocialFeedResponse;
161
+ /** Published position activity. */
162
+ position_feed: MobileServerSocialFeedResponse;
163
+ /** Item details and reading session. */
164
+ feed_item: MobileServerSocialFeedItemResponse;
165
+ /** Authorized viewport changes. */
166
+ feed_updates: MobileServerSocialFeedUpdatesResponse;
93
167
  username_availability: MobileServerUsernameAvailabilityResponse;
94
168
  profiles: MobileServerProfilesResponse;
95
169
  followers: MobileServerFollowListResponse;
@@ -1,6 +1,10 @@
1
1
  import { Hex } from 'viem';
2
2
  import { MobileSignedInner } from '../signing/types';
3
- import { MobileServerNotificationPreferences } from './serverModelTypes';
3
+ import {
4
+ MobileServerNotificationPreferences,
5
+ MobileSocialFeedMarketCategory,
6
+ MobileSocialFeedType,
7
+ } from './serverModelTypes';
4
8
 
5
9
  /**
6
10
  * Opt-in extras for a `profiles` query. Each one costs extra rate-limit weight per profile and adds fields
@@ -36,10 +40,99 @@ export interface MobileServerFollowListRequest {
36
40
  limit?: number;
37
41
  }
38
42
 
43
+ /** Common filters and pagination for social feed lists. */
44
+ export interface MobileServerSocialFeedListParams {
45
+ /** OR-ed content filters; combined with other filters using AND. */
46
+ feed_types?: MobileSocialFeedType[];
47
+ /** Strict lower bound in whole dollars, 1 through Number.MAX_SAFE_INTEGER. */
48
+ minimum_notional?: number;
49
+ /** Page size, 1–50; defaults to 20. */
50
+ limit?: number;
51
+ /** Fixed 15-minute reading session; required with cursor. */
52
+ session_id?: string;
53
+ /** Opaque pagination cursor, distinct from update_cursor and watermark. */
54
+ cursor?: string;
55
+ }
56
+
57
+ /** List fields for main feeds and author feeds. */
58
+ export interface MobileServerSocialFeedCategorizedParams extends MobileServerSocialFeedListParams {
59
+ /** Omit to read all market categories. */
60
+ market_category?: MobileSocialFeedMarketCategory;
61
+ }
62
+
63
+ /** Unsigned browsing context; the viewing account is not proof of wallet ownership. */
64
+ export interface MobileServerSocialFeedReadParams {
65
+ /**
66
+ * Complete non-isolated viewing account. Profile, position, and item reads include this account's
67
+ * own hidden content under account_view, in addition to resolving relationship state.
68
+ */
69
+ view_as?: Hex;
70
+ /** Original browsing credential when reusing a session. */
71
+ viewer_token?: string;
72
+ }
73
+
39
74
  /**
40
75
  * Params for each unsigned `public_query`, keyed by request `type`.
41
76
  */
42
77
  export interface MobileServerPublicQueryRequestByType {
78
+ /** Public recommendations with optional relationship perspective. */
79
+ for_you_feed: MobileServerSocialFeedCategorizedParams &
80
+ MobileServerSocialFeedReadParams;
81
+ /** Public content from qualified authors. */
82
+ top_traders_feed: MobileServerSocialFeedCategorizedParams &
83
+ MobileServerSocialFeedReadParams;
84
+ /** Public content from authors followed by view_as. */
85
+ friends_feed: MobileServerSocialFeedCategorizedParams &
86
+ MobileServerSocialFeedReadParams & {
87
+ /** Complete non-isolated identity subaccount; required on every request. */
88
+ view_as: Hex;
89
+ };
90
+ /** Author content visible to view_as; the target is separate from the viewing account. */
91
+ profile_feed: MobileServerSocialFeedCategorizedParams &
92
+ MobileServerSocialFeedReadParams & {
93
+ /** Target author identity, independent of view_as. */
94
+ subaccount: Hex;
95
+ };
96
+ /** Public market content. */
97
+ market_feed: MobileServerSocialFeedListParams &
98
+ MobileServerSocialFeedReadParams & {
99
+ /** Target product. */
100
+ product_id: number;
101
+ };
102
+ /** Published activity in one lifecycle, including hidden content owned by view_as. */
103
+ position_feed: MobileServerSocialFeedListParams &
104
+ MobileServerSocialFeedReadParams & {
105
+ /** Target position UUID. */
106
+ position_id: string;
107
+ };
108
+ /** Item details visible to view_as, optionally reusing a reading session. */
109
+ feed_item: MobileServerSocialFeedReadParams & {
110
+ /** Target item UUID. */
111
+ item_id: string;
112
+ /** Preview size, 0-3. */
113
+ comment_preview_limit?: number;
114
+ /** Omit to create a new reading session. */
115
+ session_id?: string;
116
+ };
117
+ /** Updates inherit the original public session's viewing account. */
118
+ feed_updates: {
119
+ /** Original reading session. */
120
+ session_id: string;
121
+ /** Previously delivered item UUIDs. */
122
+ visible_item_ids: string[];
123
+ /** Authorized position UUIDs. */
124
+ visible_position_ids: string[];
125
+ /** Baseline from the last accepted update. */
126
+ update_cursor?: string | null;
127
+ /** Current viewport version. */
128
+ viewport_revision: number;
129
+ /** Request sequence increasing across the entire session, including viewport changes. */
130
+ request_seq: number;
131
+ /** Original public browsing credential. */
132
+ viewer_token: string;
133
+ /** The viewing account cannot be changed by an update. */
134
+ view_as?: never;
135
+ };
43
136
  username_availability: { display_name: string };
44
137
  profiles: {
45
138
  /**
@@ -1 +0,0 @@
1
- {"version":3,"file":"MobileClient-CEVEYnV1.cjs","names":["subaccountToHex","mapMobileProfilesIncludeToServer","mapMobilePublicProfile","mapMobileFollowListParamsToServer","mapMobileFollowListPage","mapMobileFeedPage","mapMobileNotificationPreferences","mapMobileRegisteredWallet","mapMobileNotificationPreferencesToServer","mapMobileFollowMutationResult","WalletNotProvidedError","buildSignedMobileRequest","isMobileServerFailureResponse","MobileServerFailureError","isMobileServerSuccessResponse"],"sources":["../src/MobileClient.ts"],"sourcesContent":["import {\n getNadoClientTypeHeaders,\n subaccountToHex,\n WalletClientWithAccount,\n WalletNotProvidedError,\n} from '@nadohq/shared';\nimport axios, { AxiosInstance, AxiosResponse } from 'axios';\nimport {\n mapMobileFeedPage,\n mapMobileFollowListPage,\n mapMobileFollowListParamsToServer,\n mapMobileFollowMutationResult,\n mapMobileNotificationPreferences,\n mapMobileNotificationPreferencesToServer,\n mapMobileProfilesIncludeToServer,\n mapMobilePublicProfile,\n mapMobileRegisteredWallet,\n} from './dataMappers';\nimport {\n buildSignedMobileRequest,\n MobileSignedInner,\n MobileSignedInnerByType,\n MobileSignedInnerParams,\n MobileSignedRequest,\n} from './signing';\nimport {\n GetMobileFeedParams,\n GetMobileFollowersParams,\n GetMobileFollowingParams,\n GetMobileNotificationPreferencesParams,\n GetMobileProfilesParams,\n GetMobileRegisteredWalletParams,\n GetMobileUsernameAvailabilityParams,\n MobileFeedPage,\n MobileFollowListPage,\n MobileFollowMutationResult,\n MobileNotificationPreferences,\n MobilePublicProfile,\n MobileRegisteredWallet,\n MobileRegisterExpoTokenParams,\n MobileSetFollowParams,\n MobileSetPrivateModeParams,\n MobileSetUsernameParams,\n MobileSignedRequestParams,\n MobileUnregisterExpoTokenParams,\n MobileUpdateNotificationPreferencesParams,\n MobileUsernameAvailability,\n} from './types/clientTypes';\nimport { MobileServerFailureError } from './types/MobileServerFailureError';\nimport { MobileServerSuccessResponse } from './types/serverBaseTypes';\nimport {\n MobileServerExecuteResult,\n MobileServerExecuteSuccessResponse,\n MobileServerPublicExecuteRequest,\n} from './types/serverExecuteTypes';\nimport {\n MobileServerPublicQueryRequest,\n MobileServerPublicQuerySuccessResponse,\n} from './types/serverQueryTypes';\nimport {\n MobileServerExecuteRequestType,\n MobileServerPublicQueryRequestByType,\n MobileServerPublicQueryRequestType,\n} from './types/serverRequestTypes';\nimport {\n isMobileServerFailureResponse,\n isMobileServerSuccessResponse,\n} from './utils/serverResponseGuards';\n\n/**\n * Options for constructing a {@link MobileClient}.\n */\nexport interface MobileClientOpts {\n /**\n * Base URL of the mobile service API, e.g. {@link MOBILE_CLIENT_ENDPOINTS}.\n */\n url: string;\n /**\n * Wallet client used to sign requests.\n */\n walletClient?: WalletClientWithAccount;\n /**\n * If provided, this signer is used instead of `walletClient` for all signed requests.\n */\n linkedSignerWalletClient?: WalletClientWithAccount;\n /**\n * If provided, identifies the calling client, sent as a header with every request.\n */\n clientType?: string;\n}\n\n/**\n * Client for the Nado mobile service API: usernames, public profile lookups, the global trade feed, the\n * follower/following graph, privacy settings, and push notification device/preference management.\n */\nexport class MobileClient {\n readonly opts: MobileClientOpts;\n readonly axiosInstance: AxiosInstance;\n\n constructor(opts: MobileClientOpts) {\n this.opts = opts;\n this.axiosInstance = axios.create({\n withCredentials: true,\n // We have custom logic to validate response status and create an appropriate error\n validateStatus: () => true,\n headers: getNadoClientTypeHeaders(opts.clientType),\n });\n }\n\n /**\n * Sets the linked signer for requests\n *\n * @param linkedSignerWalletClient The linkedSigner to use for all signatures. Set to null to revert to the chain signer\n */\n public setLinkedSigner(\n linkedSignerWalletClient: WalletClientWithAccount | null,\n ) {\n this.opts.linkedSignerWalletClient = linkedSignerWalletClient ?? undefined;\n }\n\n /*\n Public queries\n */\n\n /**\n * Checks whether a username derived from the given display name is available to claim.\n */\n async getUsernameAvailability(\n params: GetMobileUsernameAvailabilityParams,\n ): Promise<MobileUsernameAvailability> {\n const body: MobileServerPublicQueryRequest<'username_availability'> = {\n type: 'username_availability',\n display_name: params.displayName,\n };\n const data = await this.publicQuery(body);\n return { username: data.username, available: data.available };\n }\n\n /**\n * Looks up public profiles, optionally with follower totals and a follow summary. Returns one profile per\n * requested subaccount, in the requested order, so callers can correlate positionally. Every non-isolated\n * subaccount resolves, with `username` and `displayName` `null` until a username is claimed. Private Mode\n * does not hide the profile itself, only the account's activity.\n *\n * This is the only profile route, so use it for a single subaccount too. It is unsigned, which means\n * `include.followSummary.viewAs` is an unauthenticated claim.\n *\n * @throws {MobileServerFailureError} With error code `INVALID_PROFILES_REQUEST` if `subaccounts` is empty,\n * holds duplicates, or exceeds `MOBILE_PROFILES_MAX_BATCH_SIZE` (25), or `PROFILE_NOT_FOUND` if any\n * requested subaccount — or the follow summary's `viewAs` — is in the engine-created isolated namespace.\n * One isolated member fails the whole batch rather than being omitted.\n */\n async getProfiles(\n params: GetMobileProfilesParams,\n ): Promise<MobilePublicProfile[]> {\n const body: MobileServerPublicQueryRequest<'profiles'> = {\n type: 'profiles',\n subaccounts: params.subaccounts.map(subaccountToHex),\n include: params.include\n ? mapMobileProfilesIncludeToServer(params.include)\n : undefined,\n };\n const data = await this.publicQuery(body);\n return data.profiles.map(mapMobilePublicProfile);\n }\n\n /**\n * Fetches a page of the accounts that follow the given Profile.\n *\n * Ordering depends on `viewAs`. With it, accounts the Viewer already follows come first, unfamiliar\n * accounts second, and every row carries an `isFollowing`. Without it, the page is ordered by the listed\n * relationship alone and no row carries an `isFollowing`. In both cases the newest listed relationship\n * comes first within a group, with a bytes32 tie-break. The grouping is evaluated per request against the\n * live graph, so following an account from inside the list moves it between groups on the next page —\n * deduplicate by subaccount and do not re-sort locally.\n *\n * @throws {MobileServerFailureError} With error code `PROFILE_NOT_FOUND` if the viewed Profile or `viewAs`\n * is isolated, `INVALID_FOLLOW_CURSOR` if the cursor is malformed or was issued for a different `viewAs`,\n * Profile, or list direction (discard it and restart from the first page), or `INVALID_FOLLOW_LIMIT` if\n * `limit` is outside 1–50.\n */\n async getFollowers(\n params: GetMobileFollowersParams,\n ): Promise<MobileFollowListPage> {\n const body: MobileServerPublicQueryRequest<'followers'> = {\n type: 'followers',\n ...mapMobileFollowListParamsToServer(params),\n };\n const data = await this.publicQuery(body);\n return mapMobileFollowListPage(data);\n }\n\n /**\n * Fetches a page of the accounts the given Profile follows. Ordering, cursor rules, and errors match\n * {@link MobileClient.getFollowers}. When `viewAs` reads its own Following list every row is familiar, so\n * every `isFollowing` is `true`.\n */\n async getFollowing(\n params: GetMobileFollowingParams,\n ): Promise<MobileFollowListPage> {\n const body: MobileServerPublicQueryRequest<'following'> = {\n type: 'following',\n ...mapMobileFollowListParamsToServer(params),\n };\n const data = await this.publicQuery(body);\n return mapMobileFollowListPage(data);\n }\n\n /**\n * Fetches a page of the global trade feed: public perpetual trades, newest first, optionally filtered by a\n * whole-dollar minimum notional (omitted means unfiltered). Trades by subaccounts that have not claimed a\n * username are included with `null` name fields; only private accounts are filtered out. The feed is\n * best-effort rather than authoritative history, and pagination is live (not snapshot), so deduplicate pages\n * by {@link MobileFeedTrade.orderDigest}.\n *\n * @throws {MobileServerFailureError} With error code `INVALID_FEED_FILTER` if `minimumNotional` or\n * `limit` is outside its allowed domain (fix the request; do not retry unchanged), or\n * `INVALID_FEED_CURSOR` if the cursor is malformed or was issued for a different `minimumNotional`\n * (discard the cursor and restart from the first page).\n */\n async getFeed(params: GetMobileFeedParams = {}): Promise<MobileFeedPage> {\n const body: MobileServerPublicQueryRequest<'feed'> = {\n type: 'feed',\n minimum_notional: params.minimumNotional,\n limit: params.limit,\n cursor: params.cursor,\n };\n const data = await this.publicQuery(body);\n return mapMobileFeedPage(data);\n }\n\n /**\n * Fetches the push notification preferences of the wallet that owns the given Expo push token. Unsigned —\n * the token identifies the wallet on its own. Falls back to the backend's defaults if the wallet has never\n * updated its preferences.\n *\n * @throws {MobileServerFailureError} With error code `INVALID_EXPO_TOKEN` if the token is malformed, or is\n * not currently registered to a wallet.\n */\n async getNotificationPreferences(\n params: GetMobileNotificationPreferencesParams,\n ): Promise<MobileNotificationPreferences> {\n const body: MobileServerPublicQueryRequest<'notification_preferences'> = {\n type: 'notification_preferences',\n expo_token: params.expoToken,\n };\n const data = await this.publicQuery(body);\n return mapMobileNotificationPreferences(data.preferences);\n }\n\n /**\n * Resolves the wallet that an Expo push token is currently registered to, along with the redacted metadata\n * of the device that registered it. Unsigned — the token identifies the wallet on its own. Use it to check\n * whether a locally held token is still active and which wallet currently owns it, since registering the\n * same token under another wallet transfers ownership.\n *\n * @throws {MobileServerFailureError} With error code `INVALID_EXPO_TOKEN` if the token is malformed, or is\n * not currently registered to a wallet — including a token that was unregistered. The backend does not\n * distinguish those cases.\n */\n async getRegisteredWallet(\n params: GetMobileRegisteredWalletParams,\n ): Promise<MobileRegisteredWallet> {\n const body: MobileServerPublicQueryRequest<'registered_wallet'> = {\n type: 'registered_wallet',\n expo_token: params.expoToken,\n };\n const data = await this.publicQuery(body);\n return mapMobileRegisteredWallet(data);\n }\n\n /*\n Public executes\n */\n\n /**\n * Unregisters an Expo push token, stopping delivery to that device. Unsigned, so it still works at logout\n * when a wallet signature may no longer be obtainable. Idempotent: unregistering an inactive or unknown\n * well-formed token succeeds.\n *\n * A registration that commits after this call re-activates the token, so stop or await any in-flight\n * {@link MobileClient.registerExpoToken} before unregistering.\n *\n * @throws {MobileServerFailureError} With error code `INVALID_EXPO_TOKEN` if the token is malformed.\n */\n async unregisterExpoToken(\n params: MobileUnregisterExpoTokenParams,\n ): Promise<MobileServerSuccessResponse> {\n const body: MobileServerPublicExecuteRequest<'unregister_expo_token'> = {\n type: 'unregister_expo_token',\n expo_token: params.expoToken,\n };\n return this.publicExecute(body);\n }\n\n /**\n * Replaces the push notification preferences of the wallet that owns the given Expo push token. Possession\n * of an active token is the credential rather than a signature, so anyone holding the token can overwrite\n * that wallet's preferences. The backend requires `schemaVersion` of 1, exactly one entry per known\n * category, and empty `scopes` on every entry.\n *\n * Writes are last-write-wins on commit order rather than ordered by a client nonce, so callers must\n * serialize their own preference writes.\n *\n * @throws {MobileServerFailureError} With error code `INVALID_PREFERENCES` if those rules are violated, or\n * `INVALID_EXPO_TOKEN` if the token is malformed or is not currently registered to a wallet.\n */\n async updateNotificationPreferences(\n params: MobileUpdateNotificationPreferencesParams,\n ): Promise<MobileServerSuccessResponse> {\n const body: MobileServerPublicExecuteRequest<'update_preferences'> = {\n type: 'update_preferences',\n expo_token: params.expoToken,\n preferences: mapMobileNotificationPreferencesToServer(params.preferences),\n };\n return this.publicExecute(body);\n }\n\n /*\n Signed executes\n */\n\n /**\n * Sets a subaccount's username, derived from the given display name. Upserts: the same call claims a first\n * username and renames an existing one, so callers never need to read the current identity first.\n *\n * @throws {MobileServerFailureError} With error code `INVALID_DISPLAY_NAME` if the display name violates\n * `MOBILE_DISPLAY_NAME_PATTERN`, `USERNAME_UNAVAILABLE` if the derived username is reserved or already\n * taken by another subaccount, `INVALID_IDENTITY_TARGET` if the sender is in the engine-created isolated\n * namespace, or `STALE_IDENTITY_UPDATE` if another identity write for this subaccount committed with a\n * later nonce (re-read the identity before retrying).\n */\n async setUsername(\n params: MobileSetUsernameParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest('set_username', params, {\n display_name: params.displayName,\n });\n return this.execute(signedRequest);\n }\n\n /**\n * Sets whether a subaccount's profile is private.\n */\n async setPrivateMode(\n params: MobileSetPrivateModeParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'set_private_mode',\n params,\n { private_mode: params.privateMode },\n );\n return this.execute(signedRequest);\n }\n\n /**\n * Registers an Expo push token for the wallet, transferring active ownership of the token if another\n * wallet had registered it. Idempotent per `(wallet, token)`.\n *\n * @throws {MobileServerFailureError} With error code `INVALID_EXPO_TOKEN` if the token is not a valid Expo\n * push token, or `INVALID_DEVICE_METADATA` if `locale` (max 35 chars) or `appVersion` (max 64 chars) is\n * too long.\n */\n async registerExpoToken(\n params: MobileRegisterExpoTokenParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'register_expo_token',\n params,\n {\n expo_token: params.expoToken,\n platform: params.platform,\n locale: params.locale ?? null,\n app_version: params.appVersion ?? null,\n },\n );\n return this.execute(signedRequest);\n }\n\n /**\n * Sets whether the signing subaccount follows a Profile. Both directions are idempotent: following again\n * keeps the original relationship creation time, so it does not move the account in recency order, and\n * unfollowing a relationship that does not exist succeeds with `isFollowing: false`. Unfollowing deletes\n * the relationship rather than deactivating it, so a later follow gets a new creation time and moves the\n * account to the front of recency order.\n *\n * Only `isFollowing: true` is checked against the canonical Query DB subaccount index, so unfollowing still\n * works while that index lags.\n *\n * @throws {MobileServerFailureError} With error code `INVALID_FOLLOW_TARGET` if the target is the sender or\n * either party is isolated, `FOLLOWER_NOT_ELIGIBLE` if the sender is not yet in the canonical Query DB\n * subaccount index, or `FOLLOWING_NOT_FOUND` if the target is not. Both index errors are transient for an\n * account that is being recorded, so they are retryable after catch-up — unlike `INVALID_FOLLOW_TARGET`.\n */\n async setFollow(\n params: MobileSetFollowParams,\n ): Promise<MobileFollowMutationResult> {\n const signedRequest = await this.getSignedRequest('set_follow', params, {\n subaccount: subaccountToHex(params.target),\n is_following: params.isFollowing,\n });\n const data = await this.execute(signedRequest);\n return mapMobileFollowMutationResult(data);\n }\n\n /*\n Base Fns\n */\n\n // Returns the request narrowed to `type` so `execute` can infer its response from the request it is given,\n // instead of being told the type a second time at the call site.\n protected async getSignedRequest<T extends MobileSignedInner['type']>(\n type: T,\n params: MobileSignedRequestParams,\n innerParams: MobileSignedInnerParams<T>,\n ): Promise<MobileSignedRequest<MobileSignedInnerByType<T>>> {\n // Use the linked signer if provided, otherwise use the default signer provided to the client\n const walletClient =\n this.opts.linkedSignerWalletClient ?? this.opts.walletClient;\n\n if (walletClient == null) {\n throw new WalletNotProvidedError();\n }\n\n const inner = {\n type,\n ...innerParams,\n } as unknown as MobileSignedInnerByType<T>;\n return buildSignedMobileRequest({ ...params, walletClient, inner });\n }\n\n // Spelled out as an intersection rather than `MobileServerPublicQueryRequest<T>`: the latter is an indexed\n // access on a mapped type, which is not an inference site, so `T` would always widen to the full union.\n protected async publicQuery<T extends MobileServerPublicQueryRequestType>(\n body: { type: T } & MobileServerPublicQueryRequestByType[T],\n ): Promise<MobileServerPublicQuerySuccessResponse<T>> {\n const response = await this.axiosInstance.post<unknown>(\n `${this.opts.url}/public_query`,\n body,\n );\n\n this.checkResponseStatus(response);\n this.checkServerStatus(response);\n\n // checkServerStatus throws on failure responses so the cast to the success response is acceptable here\n return response.data as MobileServerPublicQuerySuccessResponse<T>;\n }\n\n protected async publicExecute(\n body: MobileServerPublicExecuteRequest,\n ): Promise<MobileServerSuccessResponse> {\n const response = await this.axiosInstance.post<MobileServerExecuteResult>(\n `${this.opts.url}/public_execute`,\n body,\n );\n\n this.checkResponseStatus(response);\n this.checkServerStatus(response);\n\n // checkServerStatus catches the failure result and throws the error, so the cast to the success response is acceptable here\n return response.data as MobileServerSuccessResponse;\n }\n\n // `T` is inferred from the body's `type` rather than declared by the caller, for the same reason\n // `publicQuery` spells its body out as an intersection: an indexed access is not an inference site.\n protected async execute<T extends MobileServerExecuteRequestType>(\n body: MobileSignedRequest & { type: T },\n ): Promise<MobileServerExecuteSuccessResponse<T>> {\n const response = await this.axiosInstance.post<MobileServerExecuteResult>(\n `${this.opts.url}/execute`,\n body,\n );\n\n this.checkResponseStatus(response);\n this.checkServerStatus(response);\n\n // checkServerStatus catches the failure result and throws the error, so the cast to the success response is acceptable here\n return response.data as MobileServerExecuteSuccessResponse<T>;\n }\n\n /**\n * Validates the HTTP status before interpreting the body. Unlike the engine, the mobile backend returns\n * failure envelopes with non-2xx statuses (e.g. 404 for `PROFILE_NOT_FOUND`), so a non-2xx response with a\n * failure envelope still throws the typed error; anything else is a transport-level error.\n */\n private checkResponseStatus(response: AxiosResponse<unknown>) {\n if (response.status >= 200 && response.status < 300) {\n return;\n }\n if (isMobileServerFailureResponse(response.data)) {\n throw new MobileServerFailureError(response.data, response.status);\n }\n throw new Error(\n `Unexpected response from mobile service: ${response.status} ${response.statusText}. Data: ${JSON.stringify(response.data)}`,\n );\n }\n\n private checkServerStatus(response: AxiosResponse<unknown>) {\n const { data } = response;\n\n if (isMobileServerFailureResponse(data)) {\n throw new MobileServerFailureError(data, response.status);\n }\n if (!isMobileServerSuccessResponse(data)) {\n throw new Error(\n `Unexpected response from mobile service: missing success envelope. Data: ${JSON.stringify(data)}`,\n );\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"canonicalize-OYR35XMP.d.cts","names":[],"sources":["../src/signing/src/signing/canonicalize.ts"],"mappings":";;;;;AASA;;;;;iBAAgB,uBAAA,CACd,KAAA,EAAO,iBAAA,GACN,iBAAiB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"canonicalize-T4ShepBu.d.ts","names":[],"sources":["../src/signing/src/signing/canonicalize.ts"],"mappings":";;;;;AASA;;;;;iBAAgB,uBAAA,CACd,KAAA,EAAO,iBAAA,GACN,iBAAiB"}