@nadohq/mobile-client 0.65.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.
Files changed (207) hide show
  1. package/README.md +107 -8
  2. package/dist/{MobileClient-CfVZXTcz.cjs → MobileClient-M4oC4lrX.cjs} +258 -16
  3. package/dist/MobileClient-M4oC4lrX.cjs.map +1 -0
  4. package/dist/MobileClient.cjs +1 -1
  5. package/dist/MobileClient.d.cts +146 -16
  6. package/dist/MobileClient.d.cts.map +1 -1
  7. package/dist/MobileClient.d.ts +146 -16
  8. package/dist/MobileClient.d.ts.map +1 -1
  9. package/dist/MobileClient.js +258 -16
  10. package/dist/MobileClient.js.map +1 -1
  11. package/dist/{MobileServerFailureError-BZVwlsMg.d.ts → MobileServerFailureError-C9iqNsxI.d.ts} +2 -3
  12. package/dist/MobileServerFailureError-C9iqNsxI.d.ts.map +1 -0
  13. package/dist/{MobileServerFailureError-CbtK8kD4.d.cts → MobileServerFailureError-MtS2reel.d.cts} +2 -3
  14. package/dist/MobileServerFailureError-MtS2reel.d.cts.map +1 -0
  15. package/dist/MobileUnsupportedNotificationRouteError-DpiNBvvY.d.cts +15 -0
  16. package/dist/MobileUnsupportedNotificationRouteError-DpiNBvvY.d.cts.map +1 -0
  17. package/dist/MobileUnsupportedNotificationRouteError-DpiNBvvY.d.ts +15 -0
  18. package/dist/MobileUnsupportedNotificationRouteError-DpiNBvvY.d.ts.map +1 -0
  19. package/dist/{buildSignedMobileRequest-UeeWdYGU.d.ts → buildSignedMobileRequest-BR-KJhIF.d.ts} +2 -2
  20. package/dist/{buildSignedMobileRequest-UeeWdYGU.d.ts.map → buildSignedMobileRequest-BR-KJhIF.d.ts.map} +1 -1
  21. package/dist/{buildSignedMobileRequest-C1v0flCR.d.cts → buildSignedMobileRequest-DyKCK34Y.d.cts} +2 -2
  22. package/dist/{buildSignedMobileRequest-C1v0flCR.d.cts.map → buildSignedMobileRequest-DyKCK34Y.d.cts.map} +1 -1
  23. package/dist/{canonicalize-5eeZrkzQ.d.ts → canonicalize-Bv6UIAbR.d.ts} +2 -2
  24. package/dist/canonicalize-Bv6UIAbR.d.ts.map +1 -0
  25. package/dist/{canonicalize-CBaZprTo.d.cts → canonicalize-CWh3XZzj.d.cts} +2 -2
  26. package/dist/canonicalize-CWh3XZzj.d.cts.map +1 -0
  27. package/dist/{clientTypes-C9dJufxk.d.ts → clientTypes-BUn5_OzK.d.ts} +297 -20
  28. package/dist/clientTypes-BUn5_OzK.d.ts.map +1 -0
  29. package/dist/{clientTypes-_mEgzmNs.d.cts → clientTypes-DOpUcu80.d.cts} +297 -20
  30. package/dist/clientTypes-DOpUcu80.d.cts.map +1 -0
  31. package/dist/dataMappers.cjs +203 -5
  32. package/dist/dataMappers.cjs.map +1 -1
  33. package/dist/dataMappers.d.cts +70 -7
  34. package/dist/dataMappers.d.cts.map +1 -1
  35. package/dist/dataMappers.d.ts +70 -7
  36. package/dist/dataMappers.d.ts.map +1 -1
  37. package/dist/dataMappers.js +192 -6
  38. package/dist/dataMappers.js.map +1 -1
  39. package/dist/{eip712MethodByType-D8jLoxDu.d.cts → eip712MethodByType-CJ6BoayT.d.cts} +2 -2
  40. package/dist/eip712MethodByType-CJ6BoayT.d.cts.map +1 -0
  41. package/dist/{eip712MethodByType-DcUh8h-l.d.ts → eip712MethodByType-Dx4mvgni.d.ts} +2 -2
  42. package/dist/eip712MethodByType-Dx4mvgni.d.ts.map +1 -0
  43. package/dist/{feed-DTJlsg8W.d.ts → feed-DErOLaoY.d.cts} +4 -2
  44. package/dist/feed-DErOLaoY.d.cts.map +1 -0
  45. package/dist/{feed-DTJlsg8W.d.cts → feed-DErOLaoY.d.ts} +4 -2
  46. package/dist/feed-DErOLaoY.d.ts.map +1 -0
  47. package/dist/index.cjs +7 -2
  48. package/dist/index.d.cts +14 -16
  49. package/dist/index.d.ts +14 -16
  50. package/dist/index.js +4 -3
  51. package/dist/{mobileErrorCodes-CmjYEIYm.d.ts → mobileErrorCodes-vD6rbFuF.d.cts} +8 -3
  52. package/dist/mobileErrorCodes-vD6rbFuF.d.cts.map +1 -0
  53. package/dist/{mobileErrorCodes-CmjYEIYm.d.cts → mobileErrorCodes-vD6rbFuF.d.ts} +8 -3
  54. package/dist/mobileErrorCodes-vD6rbFuF.d.ts.map +1 -0
  55. package/dist/{payloadHash-DhHmgRqL.d.cts → payloadHash-CdkF2Ocr.d.cts} +2 -2
  56. package/dist/payloadHash-CdkF2Ocr.d.cts.map +1 -0
  57. package/dist/{payloadHash-E1_8fpLW.d.ts → payloadHash-HD29K77M.d.ts} +2 -2
  58. package/dist/payloadHash-HD29K77M.d.ts.map +1 -0
  59. package/dist/{serverExecuteTypes-B-OJok19.d.cts → serverExecuteTypes-5JyyIXRK.d.ts} +21 -5
  60. package/dist/serverExecuteTypes-5JyyIXRK.d.ts.map +1 -0
  61. package/dist/{serverExecuteTypes-BwWGspOg.d.ts → serverExecuteTypes-CHrQ9Rtq.d.cts} +21 -5
  62. package/dist/serverExecuteTypes-CHrQ9Rtq.d.cts.map +1 -0
  63. package/dist/{serverModelTypes-CiA-dy1R.d.ts → serverModelTypes-CGUZCi0y.d.cts} +163 -8
  64. package/dist/serverModelTypes-CGUZCi0y.d.cts.map +1 -0
  65. package/dist/{serverModelTypes-CiA-dy1R.d.cts → serverModelTypes-CGUZCi0y.d.ts} +163 -8
  66. package/dist/serverModelTypes-CGUZCi0y.d.ts.map +1 -0
  67. package/dist/{serverResponseGuards-CShiXpHT.d.ts → serverResponseGuards-Bvw8ltYJ.d.ts} +2 -2
  68. package/dist/{serverResponseGuards-CShiXpHT.d.ts.map → serverResponseGuards-Bvw8ltYJ.d.ts.map} +1 -1
  69. package/dist/{serverResponseGuards-BW69PS7O.d.cts → serverResponseGuards-i1njcYKN.d.cts} +2 -2
  70. package/dist/{serverResponseGuards-BW69PS7O.d.cts.map → serverResponseGuards-i1njcYKN.d.cts.map} +1 -1
  71. package/dist/signing/buildSignedMobileRequest.d.cts +1 -1
  72. package/dist/signing/buildSignedMobileRequest.d.ts +1 -1
  73. package/dist/signing/canonicalize.cjs +51 -2
  74. package/dist/signing/canonicalize.cjs.map +1 -1
  75. package/dist/signing/canonicalize.d.cts +1 -1
  76. package/dist/signing/canonicalize.d.ts +1 -1
  77. package/dist/signing/canonicalize.js +51 -2
  78. package/dist/signing/canonicalize.js.map +1 -1
  79. package/dist/signing/eip712MethodByType.cjs +7 -0
  80. package/dist/signing/eip712MethodByType.cjs.map +1 -1
  81. package/dist/signing/eip712MethodByType.d.cts +1 -1
  82. package/dist/signing/eip712MethodByType.d.ts +1 -1
  83. package/dist/signing/eip712MethodByType.js +7 -0
  84. package/dist/signing/eip712MethodByType.js.map +1 -1
  85. package/dist/signing/index.d.cts +5 -5
  86. package/dist/signing/index.d.ts +5 -5
  87. package/dist/signing/payloadHash.cjs +1 -1
  88. package/dist/signing/payloadHash.d.cts +1 -1
  89. package/dist/signing/payloadHash.d.ts +1 -1
  90. package/dist/signing/payloadHash.js +1 -1
  91. package/dist/signing/types.d.cts +1 -1
  92. package/dist/signing/types.d.ts +1 -1
  93. package/dist/types/MobileServerFailureError.d.cts +1 -1
  94. package/dist/types/MobileServerFailureError.d.ts +1 -1
  95. package/dist/types/MobileUnsupportedNotificationRouteError.cjs +19 -0
  96. package/dist/types/MobileUnsupportedNotificationRouteError.cjs.map +1 -0
  97. package/dist/types/MobileUnsupportedNotificationRouteError.d.cts +2 -0
  98. package/dist/types/MobileUnsupportedNotificationRouteError.d.ts +2 -0
  99. package/dist/types/MobileUnsupportedNotificationRouteError.js +18 -0
  100. package/dist/types/MobileUnsupportedNotificationRouteError.js.map +1 -0
  101. package/dist/types/clientTypes.d.cts +2 -2
  102. package/dist/types/clientTypes.d.ts +2 -2
  103. package/dist/types/index.cjs +4 -0
  104. package/dist/types/index.d.cts +8 -9
  105. package/dist/types/index.d.ts +8 -9
  106. package/dist/types/index.js +3 -2
  107. package/dist/types/mobileErrorCodes.cjs +11 -1
  108. package/dist/types/mobileErrorCodes.cjs.map +1 -1
  109. package/dist/types/mobileErrorCodes.d.cts +1 -1
  110. package/dist/types/mobileErrorCodes.d.ts +1 -1
  111. package/dist/types/mobileErrorCodes.js +11 -1
  112. package/dist/types/mobileErrorCodes.js.map +1 -1
  113. package/dist/types/serverBaseTypes.d.cts +1 -1
  114. package/dist/types/serverBaseTypes.d.ts +1 -1
  115. package/dist/types/serverExecuteTypes.d.cts +2 -2
  116. package/dist/types/serverExecuteTypes.d.ts +2 -2
  117. package/dist/types/serverModelTypes.cjs +15 -0
  118. package/dist/types/serverModelTypes.cjs.map +1 -1
  119. package/dist/types/serverModelTypes.d.cts +2 -2
  120. package/dist/types/serverModelTypes.d.ts +2 -2
  121. package/dist/types/serverModelTypes.js +14 -1
  122. package/dist/types/serverModelTypes.js.map +1 -1
  123. package/dist/types/serverQueryTypes.d.cts +2 -2
  124. package/dist/types/serverQueryTypes.d.ts +2 -2
  125. package/dist/types/serverRequestTypes.d.cts +2 -2
  126. package/dist/types/serverRequestTypes.d.ts +2 -2
  127. package/dist/types-C9YE4EIt.d.cts +794 -0
  128. package/dist/types-C9YE4EIt.d.cts.map +1 -0
  129. package/dist/types-Cwy1y_9x.d.ts +794 -0
  130. package/dist/types-Cwy1y_9x.d.ts.map +1 -0
  131. package/dist/utils/buildMobileFeedImageMultipart.cjs +31 -0
  132. package/dist/utils/buildMobileFeedImageMultipart.cjs.map +1 -0
  133. package/dist/utils/buildMobileFeedImageMultipart.d.cts +15 -0
  134. package/dist/utils/buildMobileFeedImageMultipart.d.cts.map +1 -0
  135. package/dist/utils/buildMobileFeedImageMultipart.d.ts +15 -0
  136. package/dist/utils/buildMobileFeedImageMultipart.d.ts.map +1 -0
  137. package/dist/utils/buildMobileFeedImageMultipart.js +30 -0
  138. package/dist/utils/buildMobileFeedImageMultipart.js.map +1 -0
  139. package/dist/utils/feed.cjs +3 -0
  140. package/dist/utils/feed.cjs.map +1 -1
  141. package/dist/utils/feed.d.cts +2 -2
  142. package/dist/utils/feed.d.ts +2 -2
  143. package/dist/utils/feed.js +3 -1
  144. package/dist/utils/feed.js.map +1 -1
  145. package/dist/utils/index.cjs +2 -1
  146. package/dist/utils/index.d.cts +3 -3
  147. package/dist/utils/index.d.ts +3 -3
  148. package/dist/utils/index.js +2 -2
  149. package/dist/utils/serverResponseGuards.d.cts +1 -1
  150. package/dist/utils/serverResponseGuards.d.ts +1 -1
  151. package/package.json +3 -3
  152. package/src/MobileClient.ts +388 -11
  153. package/src/dataMappers.test.ts +108 -2
  154. package/src/dataMappers.ts +253 -5
  155. package/src/feedImages.test.ts +309 -0
  156. package/src/notifications.test.ts +950 -0
  157. package/src/signing/canonicalize.ts +66 -0
  158. package/src/signing/eip712MethodByType.ts +10 -0
  159. package/src/signing/signing.test.ts +16 -1
  160. package/src/signing/types.ts +51 -9
  161. package/src/socialFeed.test.ts +38 -2
  162. package/src/types/MobileUnsupportedNotificationRouteError.ts +16 -0
  163. package/src/types/clientTypes.ts +372 -16
  164. package/src/types/index.ts +1 -0
  165. package/src/types/mobileErrorCodes.ts +10 -0
  166. package/src/types/serverExecuteTypes.ts +20 -0
  167. package/src/types/serverModelTypes.ts +205 -6
  168. package/src/types/serverQueryTypes.ts +74 -5
  169. package/src/types/serverRequestTypes.ts +101 -12
  170. package/src/utils/buildMobileFeedImageMultipart.test.ts +45 -0
  171. package/src/utils/buildMobileFeedImageMultipart.ts +36 -0
  172. package/src/utils/feed.ts +3 -0
  173. package/dist/MobileClient-CfVZXTcz.cjs.map +0 -1
  174. package/dist/MobileServerFailureError-BZVwlsMg.d.ts.map +0 -1
  175. package/dist/MobileServerFailureError-CbtK8kD4.d.cts.map +0 -1
  176. package/dist/canonicalize-5eeZrkzQ.d.ts.map +0 -1
  177. package/dist/canonicalize-CBaZprTo.d.cts.map +0 -1
  178. package/dist/clientTypes-C9dJufxk.d.ts.map +0 -1
  179. package/dist/clientTypes-_mEgzmNs.d.cts.map +0 -1
  180. package/dist/eip712MethodByType-D8jLoxDu.d.cts.map +0 -1
  181. package/dist/eip712MethodByType-DcUh8h-l.d.ts.map +0 -1
  182. package/dist/feed-DTJlsg8W.d.cts.map +0 -1
  183. package/dist/feed-DTJlsg8W.d.ts.map +0 -1
  184. package/dist/mobileErrorCodes-CmjYEIYm.d.cts.map +0 -1
  185. package/dist/mobileErrorCodes-CmjYEIYm.d.ts.map +0 -1
  186. package/dist/payloadHash-DhHmgRqL.d.cts.map +0 -1
  187. package/dist/payloadHash-E1_8fpLW.d.ts.map +0 -1
  188. package/dist/serverBaseTypes-B5J1_TyC.d.cts +0 -25
  189. package/dist/serverBaseTypes-B5J1_TyC.d.cts.map +0 -1
  190. package/dist/serverBaseTypes-DnLzsdm-.d.ts +0 -25
  191. package/dist/serverBaseTypes-DnLzsdm-.d.ts.map +0 -1
  192. package/dist/serverExecuteTypes-B-OJok19.d.cts.map +0 -1
  193. package/dist/serverExecuteTypes-BwWGspOg.d.ts.map +0 -1
  194. package/dist/serverModelTypes-CiA-dy1R.d.cts.map +0 -1
  195. package/dist/serverModelTypes-CiA-dy1R.d.ts.map +0 -1
  196. package/dist/serverQueryTypes-CJcjLB7n.d.ts +0 -283
  197. package/dist/serverQueryTypes-CJcjLB7n.d.ts.map +0 -1
  198. package/dist/serverQueryTypes-V1f9yE7L.d.cts +0 -283
  199. package/dist/serverQueryTypes-V1f9yE7L.d.cts.map +0 -1
  200. package/dist/serverRequestTypes-CRlkNSu5.d.cts +0 -270
  201. package/dist/serverRequestTypes-CRlkNSu5.d.cts.map +0 -1
  202. package/dist/serverRequestTypes-DZoOhV2o.d.ts +0 -270
  203. package/dist/serverRequestTypes-DZoOhV2o.d.ts.map +0 -1
  204. package/dist/types-BiRmH5Iv.d.cts +0 -108
  205. package/dist/types-BiRmH5Iv.d.cts.map +0 -1
  206. package/dist/types-DoJuq0Ij.d.ts +0 -108
  207. package/dist/types-DoJuq0Ij.d.ts.map +0 -1
@@ -12,6 +12,60 @@ export function canonicalizeMobileInner(
12
12
  inner: MobileSignedInner,
13
13
  ): MobileSignedInner {
14
14
  switch (inner.type) {
15
+ case 'register_expo_token_v2':
16
+ return {
17
+ type: inner.type,
18
+ expo_token: inner.expo_token,
19
+ platform: inner.platform,
20
+ locale: inner.locale,
21
+ app_version: inner.app_version,
22
+ capabilities: {
23
+ payload_versions: [...inner.capabilities.payload_versions],
24
+ type_ids: [...inner.capabilities.type_ids],
25
+ routes: [...inner.capabilities.routes],
26
+ },
27
+ };
28
+ case 'notification_subscriptions':
29
+ return { type: inner.type };
30
+ case 'update_notification_subscriptions':
31
+ return {
32
+ type: inner.type,
33
+ expected_revision: inner.expected_revision,
34
+ trader_bell:
35
+ inner.trader_bell == null
36
+ ? null
37
+ : {
38
+ subaccount: inner.trader_bell.subaccount,
39
+ enabled: inner.trader_bell.enabled,
40
+ },
41
+ market:
42
+ inner.market == null
43
+ ? null
44
+ : {
45
+ product_id: inner.market.product_id,
46
+ subscribed: inner.market.subscribed,
47
+ },
48
+ import_markets:
49
+ inner.import_markets == null ? null : [...inner.import_markets],
50
+ };
51
+ case 'notification_inbox_v2':
52
+ return {
53
+ type: inner.type,
54
+ cursor: inner.cursor,
55
+ limit: inner.limit,
56
+ };
57
+ case 'record_product_events':
58
+ return {
59
+ type: inner.type,
60
+ events: inner.events.map((event) => ({
61
+ client_event_id: event.client_event_id,
62
+ event_name: event.event_name,
63
+ notification_id: event.notification_id,
64
+ occurred_at: event.occurred_at,
65
+ product_id: event.product_id,
66
+ query: event.query,
67
+ })),
68
+ };
15
69
  case 'create_feed_post':
16
70
  return {
17
71
  type: inner.type,
@@ -25,6 +79,9 @@ export function canonicalizeMobileInner(
25
79
  ...(inner.drawing_data_json === undefined
26
80
  ? {}
27
81
  : { drawing_data_json: inner.drawing_data_json }),
82
+ ...(inner.image_ids === undefined
83
+ ? {}
84
+ : { image_ids: [...inner.image_ids] }),
28
85
  };
29
86
  case 'create_feed_comment':
30
87
  return {
@@ -39,6 +96,15 @@ export function canonicalizeMobileInner(
39
96
  ...(inner.attached_position_id === undefined
40
97
  ? {}
41
98
  : { attached_position_id: inner.attached_position_id }),
99
+ ...(inner.image_ids === undefined
100
+ ? {}
101
+ : { image_ids: [...inner.image_ids] }),
102
+ };
103
+ case 'create_feed_post_image_uploads':
104
+ case 'create_feed_comment_image_uploads':
105
+ return {
106
+ type: inner.type,
107
+ content_hash: inner.content_hash,
42
108
  };
43
109
  case 'create_feed_chart_drawing':
44
110
  case 'update_feed_chart_drawing':
@@ -7,8 +7,18 @@ export const MOBILE_EIP712_METHOD_BY_TYPE: Record<
7
7
  MobileSignedInner['type'],
8
8
  string
9
9
  > = {
10
+ register_expo_token_v2: 'mobile:execute_register_expo_token_v2',
11
+ notification_subscriptions: 'mobile:query_notification_subscriptions',
12
+ update_notification_subscriptions:
13
+ 'mobile:execute_update_notification_subscriptions',
14
+ notification_inbox_v2: 'mobile:query_notification_inbox_v2',
15
+ record_product_events: 'mobile:execute_record_product_events',
10
16
  create_feed_post: 'mobile:execute_create_feed_post',
11
17
  create_feed_comment: 'mobile:execute_create_feed_comment',
18
+ create_feed_post_image_uploads:
19
+ 'mobile:execute_create_feed_post_image_uploads',
20
+ create_feed_comment_image_uploads:
21
+ 'mobile:execute_create_feed_comment_image_uploads',
12
22
  create_feed_chart_drawing: 'mobile:execute_create_feed_chart_drawing',
13
23
  update_feed_chart_drawing: 'mobile:execute_update_feed_chart_drawing',
14
24
  set_feed_like: 'mobile:execute_set_feed_like',
@@ -435,7 +435,9 @@ describe('[mobile-client]: social content signing', () => {
435
435
  const drawing = ' { "lines" : [], "enabled": false } ';
436
436
 
437
437
  it('canonicalizes every post field and nested mention without changing content', () => {
438
+ const imageIds = ['88888888-8888-4888-8888-888888888888'];
438
439
  const input: MobileSignedInner = {
440
+ image_ids: imageIds,
439
441
  drawing_data_json: drawing,
440
442
  mentions: [mention],
441
443
  text,
@@ -453,6 +455,7 @@ describe('[mobile-client]: social content signing', () => {
453
455
  'text',
454
456
  'mentions',
455
457
  'drawing_data_json',
458
+ 'image_ids',
456
459
  ]);
457
460
  if (result.type !== 'create_feed_post') throw new Error('Expected post');
458
461
  expect(Object.keys(result.mentions[0])).toEqual([
@@ -466,6 +469,8 @@ describe('[mobile-client]: social content signing', () => {
466
469
  expect(result.position_id).toBe(positionId);
467
470
  expect(result.text).toBe(text);
468
471
  expect(result.drawing_data_json).toBe(drawing);
472
+ expect(result.image_ids).toEqual(imageIds);
473
+ expect(result.image_ids).not.toBe(imageIds);
469
474
  expect(result.mentions[0]).toEqual({
470
475
  subaccount: FIXTURE_TARGET_SUBACCOUNT,
471
476
  start: 2,
@@ -582,6 +587,16 @@ describe('[mobile-client]: social content signing', () => {
582
587
  });
583
588
 
584
589
  const payloads: MobileSignedInner[] = [
590
+ {
591
+ type: 'create_feed_post_image_uploads',
592
+ content_hash:
593
+ '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
594
+ },
595
+ {
596
+ type: 'create_feed_comment_image_uploads',
597
+ content_hash:
598
+ '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
599
+ },
585
600
  {
586
601
  type: 'create_feed_post',
587
602
  client_request_id: requestId,
@@ -633,7 +648,7 @@ describe('[mobile-client]: social content signing', () => {
633
648
  signature: signed.signature,
634
649
  });
635
650
  expect(recovered.toLowerCase()).toBe(account.address.toLowerCase());
636
- expect(signed).toMatchObject(canonical);
651
+ expect(signed).toMatchObject({ ...canonical });
637
652
  expect(signed).not.toHaveProperty('payload');
638
653
  },
639
654
  );
@@ -2,10 +2,15 @@ import { WalletClientWithAccount } from '@nadohq/shared';
2
2
  import { Hex } from 'viem';
3
3
  import { MobileSignedRequestParams } from '../types/clientTypes';
4
4
  import {
5
- MobileNotificationPlatform,
6
5
  MobileServerAvatarSelection,
6
+ MobileServerProductEvent,
7
7
  MobileSocialFeedMention,
8
8
  } from '../types/serverModelTypes';
9
+ import {
10
+ MobileServerNotificationSubscriptionsUpdate,
11
+ MobileServerRegisterExpoTokenParams,
12
+ MobileServerRegisterExpoTokenV2Params,
13
+ } from '../types/serverRequestTypes';
9
14
 
10
15
  /**
11
16
  * Unsigned inner payloads that can be authenticated against the mobile service API.
@@ -22,6 +27,32 @@ import {
22
27
  * lowercases; unlike bytes32, string fields such as `display_name` are hashed as-is and keep their casing.
23
28
  */
24
29
  export type MobileSignedInner =
30
+ | ({
31
+ /** Capability-aware device registration. */
32
+ type: 'register_expo_token_v2';
33
+ } & MobileServerRegisterExpoTokenV2Params)
34
+ | {
35
+ /** Signed query for wallet markets and Identity bells. */
36
+ type: 'notification_subscriptions';
37
+ }
38
+ | ({
39
+ /** One revision-guarded subscription operation. */
40
+ type: 'update_notification_subscriptions';
41
+ } & MobileServerNotificationSubscriptionsUpdate)
42
+ | {
43
+ /** Signed query for the wallet's private notification page. */
44
+ type: 'notification_inbox_v2';
45
+ /** Previous page cursor, or nil for the first page. */
46
+ cursor: string | null;
47
+ /** Page size, or nil for the server default. */
48
+ limit: number | null;
49
+ }
50
+ | {
51
+ /** Atomic product analytics batch. */
52
+ type: 'record_product_events';
53
+ /** Events in caller order. */
54
+ events: MobileServerProductEvent[];
55
+ }
25
56
  | {
26
57
  /** Atomic post publication. */
27
58
  type: 'create_feed_post';
@@ -37,6 +68,8 @@ export type MobileSignedInner =
37
68
  mentions: MobileSocialFeedMention[];
38
69
  /** Original JSON text; omitted when absent. */
39
70
  drawing_data_json?: string;
71
+ /** Ordered ready image UUIDs; omitted when absent. */
72
+ image_ids?: string[];
40
73
  }
41
74
  | {
42
75
  /** Atomic comment publication. */
@@ -53,6 +86,20 @@ export type MobileSignedInner =
53
86
  mentions: MobileSocialFeedMention[];
54
87
  /** Optional owned position UUID. */
55
88
  attached_position_id?: string;
89
+ /** Ordered ready image UUIDs; omitted when absent. */
90
+ image_ids?: string[];
91
+ }
92
+ | {
93
+ /** Direct multipart post-image upload; content_hash is Keccak256 of the raw file bytes. */
94
+ type: 'create_feed_post_image_uploads';
95
+ /** `0x`-prefixed lowercase Keccak256 of the original file bytes. */
96
+ content_hash: Hex;
97
+ }
98
+ | {
99
+ /** Direct multipart comment-image upload; content_hash is Keccak256 of the raw file bytes. */
100
+ type: 'create_feed_comment_image_uploads';
101
+ /** `0x`-prefixed lowercase Keccak256 of the original file bytes. */
102
+ content_hash: Hex;
56
103
  }
57
104
  | {
58
105
  /** First attachment. */
@@ -86,15 +133,10 @@ export type MobileSignedInner =
86
133
  }
87
134
  | { type: 'set_username'; display_name: string }
88
135
  | { type: 'set_private_mode'; private_mode: boolean }
89
- | {
136
+ | ({
137
+ /** Legacy device registration without a capability declaration. */
90
138
  type: 'register_expo_token';
91
- expo_token: string;
92
- platform: MobileNotificationPlatform;
93
- // Optional on the wire, but always present (null when unset) so the msgpack payload hash matches the
94
- // backend, which serializes `Option::None` as nil under the same key.
95
- locale: string | null;
96
- app_version: string | null;
97
- }
139
+ } & MobileServerRegisterExpoTokenParams)
98
140
  | {
99
141
  type: 'set_follow';
100
142
  subaccount: Hex;
@@ -82,7 +82,7 @@ const readSession: MobileServerSocialFeedReadSession = {
82
82
  session_id: 'OpaqueSession',
83
83
  mode: 'feed',
84
84
  expires_at_ms: 42,
85
- view_tracking: { min_visible_ratio: 0.5, min_duration_ms: 1000 },
85
+ view_tracking: { mode: 'detail_visit' },
86
86
  update_cursor: null,
87
87
  viewer_token: 'OpaqueViewer',
88
88
  };
@@ -180,6 +180,7 @@ describe('[mobile-client]: social feed transport', () => {
180
180
  });
181
181
  await client.getFeedItem({
182
182
  itemId: itemId.toUpperCase(),
183
+ viewEventId: 'cccccccc-cccc-4ccc-8ccc-cccccccccccc',
183
184
  commentPreviewLimit: 0,
184
185
  viewAs,
185
186
  });
@@ -222,6 +223,9 @@ describe('[mobile-client]: social feed transport', () => {
222
223
  expect(requests[3].body.subaccount).not.toBe(requests[3].body.view_as);
223
224
  expect(requests[5].body.position_id).toBe(positionId.toUpperCase());
224
225
  expect(requests[6].body.item_id).toBe(itemId.toUpperCase());
226
+ expect(requests[6].body.view_event_id).toBe(
227
+ 'cccccccc-cccc-4ccc-8ccc-cccccccccccc',
228
+ );
225
229
  expect(requests[6].body.comment_preview_limit).toBe(0);
226
230
  expect(requests[7].body).toEqual({
227
231
  type: 'feed_updates',
@@ -235,6 +239,37 @@ describe('[mobile-client]: social feed transport', () => {
235
239
  },
236
240
  );
237
241
 
242
+ it('reports detail visits with the registered view event over public_execute', async () => {
243
+ const { client, requests } = mockClient({
244
+ status: 'success',
245
+ accepted_item_ids: [itemId],
246
+ duplicate_item_ids: [],
247
+ });
248
+ client.opts.walletClient = undefined;
249
+ const result = await client.recordFeedViews({
250
+ sessionId: 'OpaqueSession',
251
+ viewerToken: 'OpaqueViewer',
252
+ viewEventId: 'cccccccc-cccc-4ccc-8ccc-cccccccccccc',
253
+ itemId,
254
+ });
255
+ expect(result).toEqual({
256
+ acceptedItemIds: [itemId],
257
+ duplicateItemIds: [],
258
+ });
259
+ expect(requests).toEqual([
260
+ {
261
+ url: 'https://mobile.example/v1/mobile/public_execute',
262
+ body: {
263
+ type: 'record_feed_views',
264
+ session_id: 'OpaqueSession',
265
+ viewer_token: 'OpaqueViewer',
266
+ view_event_id: 'cccccccc-cccc-4ccc-8ccc-cccccccccccc',
267
+ item_ids: [itemId],
268
+ },
269
+ },
270
+ ]);
271
+ });
272
+
238
273
  it('preserves update IDs, session credentials, and cursors unchanged', async () => {
239
274
  const { client, requests } = mockClient();
240
275
  client.opts.walletClient = undefined;
@@ -309,7 +344,7 @@ describe('[mobile-client]: social feed transport', () => {
309
344
  session_id: 'Session',
310
345
  mode: 'feed',
311
346
  expires_at_ms: 42,
312
- view_tracking: { min_visible_ratio: 0.5, min_duration_ms: 1000 },
347
+ view_tracking: { mode: 'detail_visit' },
313
348
  update_cursor: null,
314
349
  viewer_token: 'Viewer',
315
350
  },
@@ -660,6 +695,7 @@ describe('[mobile-client]: social feed response mapping', () => {
660
695
  ...row,
661
696
  kind: 'trade_card',
662
697
  action: 'opened',
698
+ images: [],
663
699
  text: '',
664
700
  mentions: [],
665
701
  author: {
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Error thrown when the mobile service returns a notification route this SDK does not support.
3
+ */
4
+ export class MobileUnsupportedNotificationRouteError extends Error {
5
+ /** Unrecognized route name returned by the service. */
6
+ readonly routeName: string;
7
+
8
+ /**
9
+ * @param routeName - The unrecognized service route name.
10
+ */
11
+ constructor(routeName: string) {
12
+ super(`Unsupported mobile notification route "${routeName}".`);
13
+ this.name = 'MobileUnsupportedNotificationRouteError';
14
+ this.routeName = routeName;
15
+ }
16
+ }