@nadohq/mobile-client 0.65.0 → 0.67.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 +202 -10
- package/dist/{MobileClient-CfVZXTcz.cjs → MobileClient-vuI5wlB_.cjs} +303 -21
- package/dist/MobileClient-vuI5wlB_.cjs.map +1 -0
- package/dist/MobileClient.cjs +1 -1
- package/dist/MobileClient.d.cts +175 -20
- package/dist/MobileClient.d.cts.map +1 -1
- package/dist/MobileClient.d.ts +175 -20
- package/dist/MobileClient.d.ts.map +1 -1
- package/dist/MobileClient.js +303 -21
- package/dist/MobileClient.js.map +1 -1
- package/dist/{MobileServerFailureError-BZVwlsMg.d.ts → MobileServerFailureError-BeCCNShj.d.cts} +2 -3
- package/dist/MobileServerFailureError-BeCCNShj.d.cts.map +1 -0
- package/dist/{MobileServerFailureError-CbtK8kD4.d.cts → MobileServerFailureError-hHv28weI.d.ts} +2 -3
- package/dist/MobileServerFailureError-hHv28weI.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-C1v0flCR.d.cts → buildSignedMobileRequest-DcEMKU_4.d.cts} +2 -2
- package/dist/{buildSignedMobileRequest-C1v0flCR.d.cts.map → buildSignedMobileRequest-DcEMKU_4.d.cts.map} +1 -1
- package/dist/{buildSignedMobileRequest-UeeWdYGU.d.ts → buildSignedMobileRequest-DlTMvoXR.d.ts} +2 -2
- package/dist/{buildSignedMobileRequest-UeeWdYGU.d.ts.map → buildSignedMobileRequest-DlTMvoXR.d.ts.map} +1 -1
- package/dist/{canonicalize-5eeZrkzQ.d.ts → canonicalize-BOZlflI3.d.ts} +2 -2
- package/dist/canonicalize-BOZlflI3.d.ts.map +1 -0
- package/dist/{canonicalize-CBaZprTo.d.cts → canonicalize-BvCozzvJ.d.cts} +2 -2
- package/dist/canonicalize-BvCozzvJ.d.cts.map +1 -0
- package/dist/{clientTypes-_mEgzmNs.d.cts → clientTypes-KpHlCDGZ.d.cts} +341 -38
- package/dist/clientTypes-KpHlCDGZ.d.cts.map +1 -0
- package/dist/{clientTypes-C9dJufxk.d.ts → clientTypes-XRI41VdC.d.ts} +341 -38
- package/dist/clientTypes-XRI41VdC.d.ts.map +1 -0
- package/dist/dataMappers.cjs +257 -20
- package/dist/dataMappers.cjs.map +1 -1
- package/dist/dataMappers.d.cts +98 -15
- package/dist/dataMappers.d.cts.map +1 -1
- package/dist/dataMappers.d.ts +98 -15
- package/dist/dataMappers.d.ts.map +1 -1
- package/dist/dataMappers.js +242 -20
- package/dist/dataMappers.js.map +1 -1
- package/dist/{eip712MethodByType-D8jLoxDu.d.cts → eip712MethodByType-DyAmzH7b.d.cts} +2 -2
- package/dist/eip712MethodByType-DyAmzH7b.d.cts.map +1 -0
- package/dist/{eip712MethodByType-DcUh8h-l.d.ts → eip712MethodByType-qSSAF6i2.d.ts} +2 -2
- package/dist/eip712MethodByType-qSSAF6i2.d.ts.map +1 -0
- package/dist/feed-BrgkFqP3.d.cts +23 -0
- package/dist/feed-BrgkFqP3.d.cts.map +1 -0
- package/dist/feed-DcbhLoo1.d.ts +23 -0
- package/dist/feed-DcbhLoo1.d.ts.map +1 -0
- package/dist/index-BVVgDSdq.d.cts +1 -0
- package/dist/index-BVVgDSdq.d.ts +1 -0
- package/dist/index.cjs +8 -2
- package/dist/index.d.cts +14 -16
- package/dist/index.d.ts +14 -16
- package/dist/index.js +4 -3
- package/dist/{mobileErrorCodes-CmjYEIYm.d.ts → mobileErrorCodes-CdwX6QTO.d.cts} +8 -3
- package/dist/mobileErrorCodes-CdwX6QTO.d.cts.map +1 -0
- package/dist/{mobileErrorCodes-CmjYEIYm.d.cts → mobileErrorCodes-CdwX6QTO.d.ts} +8 -3
- package/dist/mobileErrorCodes-CdwX6QTO.d.ts.map +1 -0
- package/dist/{payloadHash-DhHmgRqL.d.cts → payloadHash-BgGSZock.d.cts} +2 -2
- package/dist/payloadHash-BgGSZock.d.cts.map +1 -0
- package/dist/{payloadHash-E1_8fpLW.d.ts → payloadHash-Bi6upCLQ.d.ts} +2 -2
- package/dist/payloadHash-Bi6upCLQ.d.ts.map +1 -0
- package/dist/{serverExecuteTypes-BwWGspOg.d.ts → serverExecuteTypes-DuCWe_H_.d.cts} +23 -14
- package/dist/serverExecuteTypes-DuCWe_H_.d.cts.map +1 -0
- package/dist/{serverExecuteTypes-B-OJok19.d.cts → serverExecuteTypes-usJ6HMJv.d.ts} +23 -14
- package/dist/serverExecuteTypes-usJ6HMJv.d.ts.map +1 -0
- package/dist/{serverModelTypes-CiA-dy1R.d.ts → serverModelTypes-CTHMNIQS.d.cts} +170 -13
- package/dist/serverModelTypes-CTHMNIQS.d.cts.map +1 -0
- package/dist/{serverModelTypes-CiA-dy1R.d.cts → serverModelTypes-CTHMNIQS.d.ts} +170 -13
- package/dist/serverModelTypes-CTHMNIQS.d.ts.map +1 -0
- package/dist/{serverResponseGuards-CShiXpHT.d.ts → serverResponseGuards-CzmldAad.d.cts} +2 -2
- package/dist/{serverResponseGuards-BW69PS7O.d.cts.map → serverResponseGuards-CzmldAad.d.cts.map} +1 -1
- package/dist/{serverResponseGuards-BW69PS7O.d.cts → serverResponseGuards-Dvkbjp2_.d.ts} +2 -2
- package/dist/{serverResponseGuards-CShiXpHT.d.ts.map → serverResponseGuards-Dvkbjp2_.d.ts.map} +1 -1
- package/dist/signing/buildSignedMobileRequest.d.cts +1 -1
- package/dist/signing/buildSignedMobileRequest.d.ts +1 -1
- package/dist/signing/canonicalize.cjs +53 -2
- 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 +53 -2
- package/dist/signing/canonicalize.js.map +1 -1
- package/dist/signing/eip712MethodByType.cjs +7 -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 +7 -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/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 +4 -0
- package/dist/types/index.d.cts +8 -9
- package/dist/types/index.d.ts +8 -9
- package/dist/types/index.js +3 -2
- package/dist/types/mobileErrorCodes.cjs +11 -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 +11 -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-CByl_NyJ.d.ts +825 -0
- package/dist/types-CByl_NyJ.d.ts.map +1 -0
- package/dist/types-CR5iaKR4.d.cts +825 -0
- package/dist/types-CR5iaKR4.d.cts.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 +12 -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 +11 -1
- package/dist/utils/feed.js.map +1 -1
- package/dist/utils/index.cjs +3 -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 +444 -19
- package/src/dataMappers.test.ts +511 -6
- package/src/dataMappers.ts +325 -24
- package/src/feedImages.test.ts +309 -0
- package/src/notifications.test.ts +950 -0
- package/src/signing/canonicalize.ts +72 -0
- package/src/signing/eip712MethodByType.ts +10 -0
- package/src/signing/signing.test.ts +67 -1
- package/src/signing/types.ts +55 -9
- package/src/socialFeed.test.ts +63 -2
- package/src/types/MobileUnsupportedNotificationRouteError.ts +16 -0
- package/src/types/clientTypes.ts +427 -36
- package/src/types/index.ts +1 -0
- package/src/types/mobileErrorCodes.ts +10 -0
- package/src/types/serverExecuteTypes.ts +22 -10
- package/src/types/serverModelTypes.ts +216 -11
- package/src/types/serverQueryTypes.ts +106 -9
- package/src/types/serverRequestTypes.ts +114 -17
- package/src/utils/buildMobileFeedImageMultipart.test.ts +45 -0
- package/src/utils/buildMobileFeedImageMultipart.ts +36 -0
- package/src/utils/feed.ts +16 -0
- package/dist/MobileClient-CfVZXTcz.cjs.map +0 -1
- package/dist/MobileServerFailureError-BZVwlsMg.d.ts.map +0 -1
- package/dist/MobileServerFailureError-CbtK8kD4.d.cts.map +0 -1
- package/dist/canonicalize-5eeZrkzQ.d.ts.map +0 -1
- package/dist/canonicalize-CBaZprTo.d.cts.map +0 -1
- package/dist/clientTypes-C9dJufxk.d.ts.map +0 -1
- package/dist/clientTypes-_mEgzmNs.d.cts.map +0 -1
- package/dist/eip712MethodByType-D8jLoxDu.d.cts.map +0 -1
- package/dist/eip712MethodByType-DcUh8h-l.d.ts.map +0 -1
- package/dist/feed-DTJlsg8W.d.cts +0 -14
- package/dist/feed-DTJlsg8W.d.cts.map +0 -1
- package/dist/feed-DTJlsg8W.d.ts +0 -14
- package/dist/feed-DTJlsg8W.d.ts.map +0 -1
- package/dist/mobileErrorCodes-CmjYEIYm.d.cts.map +0 -1
- package/dist/mobileErrorCodes-CmjYEIYm.d.ts.map +0 -1
- package/dist/payloadHash-DhHmgRqL.d.cts.map +0 -1
- package/dist/payloadHash-E1_8fpLW.d.ts.map +0 -1
- package/dist/serverBaseTypes-B5J1_TyC.d.cts +0 -25
- package/dist/serverBaseTypes-B5J1_TyC.d.cts.map +0 -1
- package/dist/serverBaseTypes-DnLzsdm-.d.ts +0 -25
- package/dist/serverBaseTypes-DnLzsdm-.d.ts.map +0 -1
- package/dist/serverExecuteTypes-B-OJok19.d.cts.map +0 -1
- package/dist/serverExecuteTypes-BwWGspOg.d.ts.map +0 -1
- package/dist/serverModelTypes-CiA-dy1R.d.cts.map +0 -1
- package/dist/serverModelTypes-CiA-dy1R.d.ts.map +0 -1
- package/dist/serverQueryTypes-CJcjLB7n.d.ts +0 -283
- package/dist/serverQueryTypes-CJcjLB7n.d.ts.map +0 -1
- package/dist/serverQueryTypes-V1f9yE7L.d.cts +0 -283
- package/dist/serverQueryTypes-V1f9yE7L.d.cts.map +0 -1
- package/dist/serverRequestTypes-CRlkNSu5.d.cts +0 -270
- package/dist/serverRequestTypes-CRlkNSu5.d.cts.map +0 -1
- package/dist/serverRequestTypes-DZoOhV2o.d.ts +0 -270
- package/dist/serverRequestTypes-DZoOhV2o.d.ts.map +0 -1
- package/dist/types-BiRmH5Iv.d.cts +0 -108
- package/dist/types-BiRmH5Iv.d.cts.map +0 -1
- package/dist/types-DoJuq0Ij.d.ts +0 -108
- package/dist/types-DoJuq0Ij.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -50,7 +50,11 @@ await mobile.setUsername({
|
|
|
50
50
|
`getNotificationPreferences`, `getRegisteredWallet`, `getForYouFeed`, `getTopTradersFeed`,
|
|
51
51
|
`getFriendsFeed`, `getProfileFeed`, `getMarketFeed`, `getPositionFeed`, `getFeedItem`, `getFeedUpdates`,
|
|
52
52
|
`getSelfFeedPositions`, `resolveFeedPosition`, `resolveFeedAction`, `getFeedChartDrawing`, `getFeedComments`,
|
|
53
|
-
`getPositionHistory`, `getPositionChart`, `getPositionWatchers`.
|
|
53
|
+
`getPositionHistory`, `getPositionHistoryAll`, `getPositionThoughts`, `getPositionChart`, `getPositionWatchers`.
|
|
54
|
+
|
|
55
|
+
`getNotificationRegistrationV2` and `getNotificationSettingsV2` use an active Expo token as their credential,
|
|
56
|
+
not a wallet signature. Before displaying wallet settings, compare the wallet returned by `getRegisteredWallet`
|
|
57
|
+
with the connected wallet (case-insensitively).
|
|
54
58
|
|
|
55
59
|
`getProfiles` is the only profile route: it batches up to 25 subaccounts, returns them in the requested order,
|
|
56
60
|
and carries follower totals (`include.followCounts`) and a follow summary (`include.followSummary.viewAs`) as
|
|
@@ -70,10 +74,11 @@ page is ordered by the listed relationship alone and `isFollowing` is absent rat
|
|
|
70
74
|
|
|
71
75
|
`getFeed` returns the global trade feed. Session-based feeds include `getForYouFeed`, `getTopTradersFeed`,
|
|
72
76
|
and `getFriendsFeed` (requires `viewAs`), plus `getProfileFeed`, `getMarketFeed`, and `getPositionFeed`.
|
|
73
|
-
`getFeedItem` reads one item
|
|
74
|
-
All are unsigned. Profile, position, and item reads include the `viewAs`
|
|
75
|
-
`account_view`; the viewing account is not proof of wallet ownership.
|
|
76
|
-
quantities, notionals, and PnL retain x18 units. See method and
|
|
77
|
+
`getFeedItem` reads one item without counting a view. Report views independently with `recordFeedViews`. `getFeedUpdates` polls session patches
|
|
78
|
+
using the returned `viewerToken`. All are unsigned. Profile, position, and item reads include the `viewAs`
|
|
79
|
+
account's own hidden content under `account_view`; the viewing account is not proof of wallet ownership.
|
|
80
|
+
Prices are decimal `BigNumber` values; quantities, notionals, and PnL retain x18 units. See method and
|
|
81
|
+
parameter JSDoc for session and polling rules.
|
|
77
82
|
|
|
78
83
|
`getSelfFeedPositions`, `resolveFeedPosition`, and `resolveFeedAction` require `viewAs` and return eligibility
|
|
79
84
|
hints for that account, not authenticated permissions. `getFeedComments` supports anchored, bidirectional
|
|
@@ -85,20 +90,207 @@ and a position-mode session for navigation and updates. `getPositionChart` retur
|
|
|
85
90
|
keeping execution and liquidation Oracle prices separate. `getPositionWatchers` reads visitor counts without
|
|
86
91
|
registering presence. Watching account previews are self-reported, not proof of account ownership.
|
|
87
92
|
|
|
93
|
+
### Position history and thoughts
|
|
94
|
+
|
|
95
|
+
`getPositionHistory` and `getPositionHistoryAll` return `owner`, the current position owner's full profile,
|
|
96
|
+
even for an empty timeline. Do not infer ownership from a take or the viewing account.
|
|
97
|
+
Position patches do not refresh owner information; query history or profiles again.
|
|
98
|
+
|
|
99
|
+
`getPositionHistoryAll` returns only the most recent 500 actions, ordered by last event time and action UUID
|
|
100
|
+
descending. It excludes authored content: `relatedTake` is null and `summary.takeCount` is zero, even when
|
|
101
|
+
thoughts exist. `summary.actionCount` counts this response's scope. `nextCursor: null` means this endpoint
|
|
102
|
+
does not paginate, not that all history was returned. Use `getPositionHistory` with a fresh first request
|
|
103
|
+
for complete history. Each call creates a new session; only `viewerToken` may be reused.
|
|
104
|
+
Limit, cursor, and sessionId are not accepted.
|
|
105
|
+
|
|
106
|
+
`getPositionThoughts` returns only published posts/trade cards with both nonblank text and a saved drawing.
|
|
107
|
+
Uploaded/external images do not qualify. It returns full parsed drawing data and keeps descending first
|
|
108
|
+
drawing creation time / item UUID order. Do not sort by displayAtMs or updatedAtMs. Changing an existing
|
|
109
|
+
drawing does not move it; saved data need not contain visible strokes.
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
const first = await mobile.getPositionThoughts({ positionId, limit: 20 });
|
|
113
|
+
if (first.nextCursor !== null) {
|
|
114
|
+
const next = await mobile.getPositionThoughts({
|
|
115
|
+
positionId,
|
|
116
|
+
limit: 20,
|
|
117
|
+
sessionId: first.readSession.sessionId,
|
|
118
|
+
viewerToken: first.readSession.viewerToken,
|
|
119
|
+
cursor: first.nextCursor,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
There is no 500-item total cap for thoughts. Continue until nextCursor is null, even when a page is empty.
|
|
125
|
+
Keep positionId, limit, and credentials unchanged; omitted viewAs inherits the original perspective.
|
|
126
|
+
Thoughts sessions cannot be exchanged with history/feed sessions. New eligible content requires refreshing.
|
|
127
|
+
Fully delivered items support existing detail, drawing, image, and update APIs with the returned session.
|
|
128
|
+
A 6328 error means the initial directory exceeded capacity; do not automatically retry the same query.
|
|
129
|
+
A 6312 error requires a fresh session. Neither condition represents a successfully truncated result.
|
|
130
|
+
|
|
88
131
|
### Public Executes
|
|
89
132
|
|
|
90
|
-
`unregisterExpoToken`, `updateNotificationPreferences`. These are authenticated by possession of an active Expo
|
|
133
|
+
`unregisterExpoToken`, `updateNotificationPreferences`, `updateNotificationSettingsV2`. These are authenticated by possession of an active Expo
|
|
91
134
|
push token rather than a wallet signature, so they still work at logout when a signature may be unobtainable.
|
|
92
135
|
|
|
93
|
-
`recordFeedViews`
|
|
94
|
-
|
|
136
|
+
`recordFeedViews` accepts `itemIds`, an array of 1–50 canonical lowercase UUIDs. Posts, trade cards,
|
|
137
|
+
comments, and replies can be mixed; only the supplied IDs increment, without incrementing their parents.
|
|
138
|
+
It sends only `type` and `item_ids` to `/public_execute`, without a wallet signature or reading session,
|
|
139
|
+
and returns `{ status: 'success' }`. Same-request duplicates count once, but another request increments
|
|
140
|
+
again. Missing, deleted, unpublished, excluded, and unsupported targets are skipped; even an entirely
|
|
141
|
+
skipped batch returns success. Invalid fields, UUIDs, or array sizes reject the entire batch.
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
await mobile.recordFeedViews({ itemIds: [postId, commentId, replyId] });
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
This operation is **not idempotent**: retrying after an uncertain network failure may count twice.
|
|
148
|
+
The SDK does not automatically retry. Read current counts from `interaction.viewCount` in details,
|
|
149
|
+
comment groups and their `replies`, previews, or session updates; the report returns no per-item counts.
|
|
150
|
+
|
|
151
|
+
`setPositionPresence` still requires reading-session credentials and a page-scoped `viewSessionId`.
|
|
152
|
+
Pagination, updates, and protected image reads also keep their existing session rules. Fetch uploaded
|
|
153
|
+
image bytes with `getFeedImageBytes` using the original credentials and paths from image metadata.
|
|
154
|
+
Legitimate session reads renew the idle expiration; use the latest `expiresAtMs`. View reports neither
|
|
155
|
+
require nor renew a reading session.
|
|
156
|
+
|
|
157
|
+
### Comment groups
|
|
158
|
+
|
|
159
|
+
`getFeedComments` returns top-level `comments`, each with a complete flat `replies` array containing all
|
|
160
|
+
readable descendants in the thread snapshot. The `limit` (default 20, range 1–50) counts top-level groups;
|
|
161
|
+
descendants do not consume the limit and do not have separate cursors or nested `replies` arrays.
|
|
162
|
+
Top-level comments are newest first; descendants are oldest first with depth then UUID breaking timestamp
|
|
163
|
+
ties. Original parent relationships remain in `replyToItemId` and `replyToAuthor`.
|
|
164
|
+
|
|
165
|
+
`totalCount` counts all readable replies in the thread snapshot; `topLevelCount` counts only top-level
|
|
166
|
+
comments. Neither is limited to the returned page. An `anchorReplyId` at any depth returns its top-level
|
|
167
|
+
group and is echoed in the response. Forward/backward cursors never split a group. An unreadable ancestor
|
|
168
|
+
also makes its descendants unreadable. New replies at any depth require refreshing; updates only modify
|
|
169
|
+
already delivered content.
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
const page = await mobile.getFeedComments({ rootItemId, limit: 20 });
|
|
173
|
+
for (const group of page.comments) {
|
|
174
|
+
// Render the top-level comment, followed by group.replies in the returned order.
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Comment previews remain individual replies. A preview's `nextCursor` opens the first complete group page
|
|
179
|
+
in the same snapshot; replace the preview with that page instead of prepending preview items.
|
|
180
|
+
|
|
181
|
+
### Feed image reads
|
|
182
|
+
|
|
183
|
+
For React Native `Image` or expo-image, use `getFeedImageRequest` to pass the authenticated
|
|
184
|
+
URL and headers directly without converting bytes to base64:
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import { isMobileSocialFeedUploadedImage } from '@nadohq/mobile-client';
|
|
188
|
+
|
|
189
|
+
const source = isMobileSocialFeedUploadedImage(image)
|
|
190
|
+
? (() => {
|
|
191
|
+
const { url, headers } = mobile.getFeedImageRequest({
|
|
192
|
+
path: image.url,
|
|
193
|
+
sessionId: readSession.sessionId,
|
|
194
|
+
viewerToken: readSession.viewerToken,
|
|
195
|
+
});
|
|
196
|
+
return { uri: url, headers };
|
|
197
|
+
})()
|
|
198
|
+
: { uri: image.url }; // External URL: never attach Mobile session headers.
|
|
199
|
+
```
|
|
95
200
|
|
|
96
201
|
### Signed Executes
|
|
97
202
|
|
|
98
203
|
`setUsername`, `setBio`, `createAvatarUpload`, `setAvatar`, `setPrivateMode`, `registerExpoToken`, `setFollow`,
|
|
99
|
-
`createFeedPost`, `createFeedComment`, `
|
|
204
|
+
`createFeedPost`, `createFeedComment`, `createFeedPostImageUpload`, `createFeedCommentImageUpload`,
|
|
205
|
+
`createFeedChartDrawing`, `updateFeedChartDrawing`, `setFeedLike`, `registerExpoTokenV2`,
|
|
206
|
+
`updateNotificationSubscriptions`, `recordProductEvents`.
|
|
207
|
+
|
|
208
|
+
Upload images one at a time with the multipart helpers (≤ 2 MiB whole request), then pass ordered ready
|
|
209
|
+
`imageIds` to `createFeedPost` / `createFeedComment`. The SDK throws `RangeError` before requesting a signature or sending a request
|
|
210
|
+
that exceeds `MOBILE_FEED_IMAGE_MAX_REQUEST_BYTES`, including the signed payload and multipart framing.
|
|
211
|
+
Unconfigured image storage returns `SOCIAL_FEED_DATA_UNAVAILABLE` (6320, HTTP 503).
|
|
212
|
+
Posts still require nonblank text or a drawing; comments
|
|
213
|
+
still require nonblank text. See method and parameter JSDoc for publication, retries, mention offsets, drawing
|
|
214
|
+
data, and mutation ordering.
|
|
215
|
+
|
|
216
|
+
Posts and comments also accept `imageUrls`, up to ten HTTP/HTTPS URLs independent of the nine uploaded
|
|
217
|
+
images. URLs must include a hostname and contain no whitespace/control characters. Omit the field or pass
|
|
218
|
+
`[]`; null and the old wire field `image_url` are rejected. The SDK signs `image_urls` after `image_ids`.
|
|
219
|
+
Keep original URL strings, array order, and field presence unchanged on retries: omission and `[]` hash
|
|
220
|
+
differently. Coordinate this request change with the service version; old `image_url` retries are incompatible.
|
|
221
|
+
|
|
222
|
+
Responses keep one `images` array: upload metadata first, then URL-only objects in submitted order.
|
|
223
|
+
`MobileSocialFeedImage` represents uploaded images or external URLs; narrow with
|
|
224
|
+
`isMobileSocialFeedUploadedImage` before accessing upload metadata.
|
|
225
|
+
Direct upload methods return `MobileSocialFeedUploadedImage` with all metadata. Load external URLs directly
|
|
226
|
+
without Mobile session headers.
|
|
227
|
+
|
|
228
|
+
### Signed Queries
|
|
229
|
+
|
|
230
|
+
`getNotificationSubscriptions` and `getNotificationInboxV2` use wallet authentication on `/query`.
|
|
231
|
+
They do not require an Expo token or system push permission. The configured linked signer is supported.
|
|
232
|
+
|
|
233
|
+
### Notifications V2
|
|
234
|
+
|
|
235
|
+
The notification v2 operations are available on `MobileClient`, including `client.context.mobileClient` from
|
|
236
|
+
`@nadohq/client`. Settings, capabilities, subscriptions, inbox data, and product events use camelCase SDK models.
|
|
237
|
+
The SDK maps requests to snake_case wire fields and removes the success envelope from read results.
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
const auth = {
|
|
241
|
+
subaccountOwner: walletClient.account.address,
|
|
242
|
+
subaccountName: 'default',
|
|
243
|
+
chainId: ink.id,
|
|
244
|
+
verifyingAddr: '0x...' as const,
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
await mobile.registerExpoTokenV2({
|
|
248
|
+
...auth,
|
|
249
|
+
expoToken,
|
|
250
|
+
platform: 'ios',
|
|
251
|
+
capabilities: {
|
|
252
|
+
payloadVersions: [2],
|
|
253
|
+
typeIds: ['order_fill', 'new_follower'],
|
|
254
|
+
routes: ['portfolio', 'profile'],
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
const registration = await mobile.getNotificationRegistrationV2({ expoToken });
|
|
258
|
+
const current = await mobile.getNotificationSettingsV2({ expoToken });
|
|
259
|
+
const saved = await mobile.updateNotificationSettingsV2({
|
|
260
|
+
expoToken,
|
|
261
|
+
expectedRevision: current.revision,
|
|
262
|
+
settings: { ...current.settings, positionThresholds: [25] },
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
const subscriptions = await mobile.getNotificationSubscriptions(auth);
|
|
266
|
+
await mobile.updateNotificationSubscriptions({
|
|
267
|
+
...auth,
|
|
268
|
+
update: {
|
|
269
|
+
expectedRevision: subscriptions.revision,
|
|
270
|
+
market: { productId: 2, subscribed: true },
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
const updatedSubscriptions = await mobile.getNotificationSubscriptions(auth);
|
|
274
|
+
const inbox = await mobile.getNotificationInboxV2({ ...auth, limit: 20 });
|
|
275
|
+
```
|
|
100
276
|
|
|
101
|
-
|
|
277
|
+
- Declare only types/routes the application handles. Re-registration advances the generation and cancels
|
|
278
|
+
old pending deliveries; calling legacy `registerExpoToken` resets capabilities to v1.
|
|
279
|
+
- Settings replacement requires every field. Settings and subscription revisions are independent.
|
|
280
|
+
On `MOBILE_ERROR_CODES.NOTIFICATION_REVISION_CONFLICT` (6203), re-read and merge only the current user change.
|
|
281
|
+
- A subscription update selects exactly one operation; omit the other operations and the SDK sends them as `null`. Successful subscription
|
|
282
|
+
updates return only status, so re-query even after repeated ON/OFF. Favorites import merges once, never replaces.
|
|
283
|
+
- Enabling a bell requires following the target. Unfollowing clears its bell without advancing the subscription
|
|
284
|
+
revision; refresh subscriptions after follow mutations. Bells are Identity-scoped; markets are wallet-scoped.
|
|
285
|
+
Pass `traderBell.subaccount` as a `Subaccount` (`subaccountOwner` and `subaccountName`); the SDK encodes it for signing.
|
|
286
|
+
- Inbox pages are accepted intents, not delivery/read receipts. There is no title/body, unread count, mark-read,
|
|
287
|
+
or delete operation. Do not use the unimplemented legacy `notification_history` route.
|
|
288
|
+
An unknown destination rejects the page with `MobileUnsupportedNotificationRouteError`.
|
|
289
|
+
- `recordProductEvents({ ...auth, events })` accepts 1-50 events atomically. Provide the fields required by `eventName`,
|
|
290
|
+
actual millisecond timestamps, and stable `clientEventId` UUIDs across retries. The SDK fills unused wire fields with `null`. Supported
|
|
291
|
+
names are `notif_opened`, `market_viewed`, `chart_opened`, and `search`; obtain analytics consent first.
|
|
292
|
+
- Legacy preferences remain supported and synchronize overlapping v2 fields. Keep legacy push parsing because
|
|
293
|
+
order notifications may use a v1 fallback even for v2 registrations.
|
|
102
294
|
|
|
103
295
|
### Linked Signers
|
|
104
296
|
|