@nadohq/mobile-client 0.29.0 → 0.30.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/dist/{MobileClient-9JSAzblH.cjs → MobileClient-CfDtaEeL.cjs} +21 -1
- package/dist/MobileClient-CfDtaEeL.cjs.map +1 -0
- package/dist/MobileClient.cjs +1 -1
- package/dist/MobileClient.d.cts +21 -9
- package/dist/MobileClient.d.cts.map +1 -1
- package/dist/MobileClient.d.ts +21 -9
- package/dist/MobileClient.d.ts.map +1 -1
- package/dist/MobileClient.js +21 -1
- package/dist/MobileClient.js.map +1 -1
- package/dist/{MobileServerFailureError-ZggEcEda.d.cts → MobileServerFailureError-B11rr9O5.d.cts} +3 -2
- package/dist/MobileServerFailureError-B11rr9O5.d.cts.map +1 -0
- package/dist/{MobileServerFailureError-f9KhKnJj.d.ts → MobileServerFailureError-DoIvXqYV.d.ts} +3 -2
- package/dist/MobileServerFailureError-DoIvXqYV.d.ts.map +1 -0
- package/dist/{buildSignedMobileRequest-CDRsRNHm.d.ts → buildSignedMobileRequest-B4KJ6T1y.d.ts} +2 -2
- package/dist/{buildSignedMobileRequest-CDRsRNHm.d.ts.map → buildSignedMobileRequest-B4KJ6T1y.d.ts.map} +1 -1
- package/dist/{buildSignedMobileRequest-BsbBkU0K.d.cts → buildSignedMobileRequest-EEnDgZF8.d.cts} +2 -2
- package/dist/{buildSignedMobileRequest-BsbBkU0K.d.cts.map → buildSignedMobileRequest-EEnDgZF8.d.cts.map} +1 -1
- package/dist/{canonicalize-Dm7sXwPg.d.cts → canonicalize-CDdYnhL3.d.cts} +2 -2
- package/dist/canonicalize-CDdYnhL3.d.cts.map +1 -0
- package/dist/{canonicalize-PX6dTIdF.d.ts → canonicalize-Cc7hdZLJ.d.ts} +2 -2
- package/dist/canonicalize-Cc7hdZLJ.d.ts.map +1 -0
- package/dist/{clientTypes-DWW2N66c.d.ts → clientTypes-BsOps_pY.d.ts} +67 -3
- package/dist/clientTypes-BsOps_pY.d.ts.map +1 -0
- package/dist/{clientTypes-Et0PUa2d.d.cts → clientTypes-UFInIAQd.d.cts} +67 -3
- package/dist/clientTypes-UFInIAQd.d.cts.map +1 -0
- package/dist/dataMappers.cjs +33 -0
- package/dist/dataMappers.cjs.map +1 -1
- package/dist/dataMappers.d.cts +8 -3
- package/dist/dataMappers.d.cts.map +1 -1
- package/dist/dataMappers.d.ts +8 -3
- package/dist/dataMappers.d.ts.map +1 -1
- package/dist/dataMappers.js +33 -1
- package/dist/dataMappers.js.map +1 -1
- package/dist/{eip712MethodByType-DJgXal9r.d.ts → eip712MethodByType-B67XiwTu.d.ts} +2 -2
- package/dist/eip712MethodByType-B67XiwTu.d.ts.map +1 -0
- package/dist/{eip712MethodByType-DLh9MRsD.d.cts → eip712MethodByType-DCU415zf.d.cts} +2 -2
- package/dist/eip712MethodByType-DCU415zf.d.cts.map +1 -0
- package/dist/feed-BF5k6Ryu.d.ts +14 -0
- package/dist/feed-BF5k6Ryu.d.ts.map +1 -0
- package/dist/feed-CBIwOhTO.d.cts +14 -0
- package/dist/feed-CBIwOhTO.d.cts.map +1 -0
- package/dist/index.cjs +8 -1
- package/dist/index.d.cts +17 -15
- package/dist/index.d.ts +17 -15
- package/dist/index.js +3 -1
- package/dist/{mobileErrorCodes-QG5XbEY6.d.ts → mobileErrorCodes-Cj84nBnT.d.cts} +7 -5
- package/dist/mobileErrorCodes-Cj84nBnT.d.cts.map +1 -0
- package/dist/{mobileErrorCodes-BeyBKmwh.d.cts → mobileErrorCodes-Czmigq9x.d.ts} +7 -5
- package/dist/mobileErrorCodes-Czmigq9x.d.ts.map +1 -0
- package/dist/{patterns-BbxH3_VA.d.ts → patterns-B5gi7OfV.d.ts} +1 -1
- package/dist/patterns-B5gi7OfV.d.ts.map +1 -0
- package/dist/{patterns-B9J2ldpx.d.cts → patterns-Db6fgz8i.d.cts} +1 -1
- package/dist/patterns-Db6fgz8i.d.cts.map +1 -0
- package/dist/{payloadHash-nj8WuLUP.d.cts → payloadHash-BSoGv3Lz.d.cts} +2 -2
- package/dist/payloadHash-BSoGv3Lz.d.cts.map +1 -0
- package/dist/{payloadHash-Bmhzs78N.d.ts → payloadHash-BVP2v3p9.d.ts} +2 -2
- package/dist/payloadHash-BVP2v3p9.d.ts.map +1 -0
- package/dist/serverBaseTypes-A16onlPN.d.cts +25 -0
- package/dist/serverBaseTypes-A16onlPN.d.cts.map +1 -0
- package/dist/serverBaseTypes-m3zEi0X9.d.ts +25 -0
- package/dist/serverBaseTypes-m3zEi0X9.d.ts.map +1 -0
- package/dist/{serverExecuteTypes-DKYK1V7C.d.cts → serverExecuteTypes-C-bioiuQ.d.cts} +2 -2
- package/dist/serverExecuteTypes-C-bioiuQ.d.cts.map +1 -0
- package/dist/{serverExecuteTypes-CXnMjKnt.d.ts → serverExecuteTypes-DfzWOeIx.d.ts} +2 -2
- package/dist/serverExecuteTypes-DfzWOeIx.d.ts.map +1 -0
- package/dist/serverModelTypes-CPZUvVil.d.cts +143 -0
- package/dist/serverModelTypes-CPZUvVil.d.cts.map +1 -0
- package/dist/serverModelTypes-CqnqHY5F.d.ts +143 -0
- package/dist/serverModelTypes-CqnqHY5F.d.ts.map +1 -0
- package/dist/serverQueryTypes-CJLWWZBs.d.ts +91 -0
- package/dist/serverQueryTypes-CJLWWZBs.d.ts.map +1 -0
- package/dist/serverQueryTypes-C_cCx0Ac.d.cts +91 -0
- package/dist/serverQueryTypes-C_cCx0Ac.d.cts.map +1 -0
- package/dist/serverRequestTypes-DQDy3K9O.d.ts +62 -0
- package/dist/serverRequestTypes-DQDy3K9O.d.ts.map +1 -0
- package/dist/serverRequestTypes-DnU_FfMI.d.cts +62 -0
- package/dist/serverRequestTypes-DnU_FfMI.d.cts.map +1 -0
- package/dist/{serverResponseGuards-DjCNL3CR.d.cts → serverResponseGuards-BlvfJjsa.d.cts} +2 -2
- package/dist/{serverResponseGuards-DjCNL3CR.d.cts.map → serverResponseGuards-BlvfJjsa.d.cts.map} +1 -1
- package/dist/{serverResponseGuards-C_vZIgGl.d.ts → serverResponseGuards-gpHH8SHk.d.ts} +2 -2
- package/dist/{serverResponseGuards-C_vZIgGl.d.ts.map → serverResponseGuards-gpHH8SHk.d.ts.map} +1 -1
- package/dist/signing/buildSignedMobileRequest.cjs +1 -1
- package/dist/signing/buildSignedMobileRequest.d.cts +1 -1
- package/dist/signing/buildSignedMobileRequest.d.ts +1 -1
- package/dist/signing/canonicalize.d.cts +1 -1
- package/dist/signing/canonicalize.d.ts +1 -1
- package/dist/signing/eip712MethodByType.d.cts +1 -1
- package/dist/signing/eip712MethodByType.d.ts +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/types.d.cts +1 -1
- package/dist/signing/types.d.ts +1 -1
- package/dist/types/MobileServerFailureError.cjs +1 -1
- package/dist/types/MobileServerFailureError.cjs.map +1 -1
- package/dist/types/MobileServerFailureError.d.cts +1 -1
- package/dist/types/MobileServerFailureError.d.ts +1 -1
- package/dist/types/MobileServerFailureError.js.map +1 -1
- 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 +9 -8
- package/dist/types/index.d.ts +9 -8
- package/dist/types/index.js +2 -1
- package/dist/types/mobileErrorCodes.cjs +9 -5
- 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 +8 -4
- package/dist/types/mobileErrorCodes.js.map +1 -1
- package/dist/types/serverBaseTypes.d.cts +2 -2
- package/dist/types/serverBaseTypes.d.ts +2 -2
- package/dist/types/serverExecuteTypes.d.cts +1 -1
- package/dist/types/serverExecuteTypes.d.ts +1 -1
- package/dist/types/serverModelTypes.cjs +29 -0
- package/dist/types/serverModelTypes.cjs.map +1 -0
- package/dist/types/serverModelTypes.d.cts +2 -2
- package/dist/types/serverModelTypes.d.ts +2 -2
- package/dist/types/serverModelTypes.js +26 -1
- package/dist/types/serverModelTypes.js.map +1 -0
- package/dist/types/serverQueryTypes.d.cts +2 -2
- package/dist/types/serverQueryTypes.d.ts +2 -2
- package/dist/types/serverRequestTypes.cjs +0 -0
- package/dist/types/serverRequestTypes.d.cts +2 -0
- package/dist/types/serverRequestTypes.d.ts +2 -0
- package/dist/types/serverRequestTypes.js +1 -0
- package/dist/{types-uCD4BNZR.d.cts → types-CzOeSYnW.d.cts} +3 -3
- package/dist/{types-uCD4BNZR.d.cts.map → types-CzOeSYnW.d.cts.map} +1 -1
- package/dist/{types-B76Pn7Sy.d.ts → types-UHjZR-js.d.ts} +3 -3
- package/dist/{types-B76Pn7Sy.d.ts.map → types-UHjZR-js.d.ts.map} +1 -1
- package/dist/utils/feed.cjs +17 -0
- package/dist/utils/feed.cjs.map +1 -0
- package/dist/utils/feed.d.cts +2 -0
- package/dist/utils/feed.d.ts +2 -0
- package/dist/utils/feed.js +15 -0
- package/dist/utils/feed.js.map +1 -0
- package/dist/utils/index.cjs +3 -0
- package/dist/utils/index.d.cts +4 -3
- package/dist/utils/index.d.ts +4 -3
- package/dist/utils/index.js +2 -1
- package/dist/utils/patterns.d.cts +1 -1
- package/dist/utils/patterns.d.ts +1 -1
- 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 +49 -27
- package/src/dataMappers.ts +40 -0
- package/src/types/MobileServerFailureError.ts +2 -4
- package/src/types/clientTypes.ts +70 -0
- package/src/types/index.ts +1 -0
- package/src/types/mobileErrorCodes.ts +7 -3
- package/src/types/serverBaseTypes.ts +7 -28
- package/src/types/serverModelTypes.ts +93 -0
- package/src/types/serverQueryTypes.ts +83 -39
- package/src/types/serverRequestTypes.ts +68 -0
- package/src/utils/feed.ts +11 -0
- package/src/utils/index.ts +1 -0
- package/dist/MobileClient-9JSAzblH.cjs.map +0 -1
- package/dist/MobileServerFailureError-ZggEcEda.d.cts.map +0 -1
- package/dist/MobileServerFailureError-f9KhKnJj.d.ts.map +0 -1
- package/dist/canonicalize-Dm7sXwPg.d.cts.map +0 -1
- package/dist/canonicalize-PX6dTIdF.d.ts.map +0 -1
- package/dist/clientTypes-DWW2N66c.d.ts.map +0 -1
- package/dist/clientTypes-Et0PUa2d.d.cts.map +0 -1
- package/dist/eip712MethodByType-DJgXal9r.d.ts.map +0 -1
- package/dist/eip712MethodByType-DLh9MRsD.d.cts.map +0 -1
- package/dist/mobileErrorCodes-BeyBKmwh.d.cts.map +0 -1
- package/dist/mobileErrorCodes-QG5XbEY6.d.ts.map +0 -1
- package/dist/patterns-B9J2ldpx.d.cts.map +0 -1
- package/dist/patterns-BbxH3_VA.d.ts.map +0 -1
- package/dist/payloadHash-Bmhzs78N.d.ts.map +0 -1
- package/dist/payloadHash-nj8WuLUP.d.cts.map +0 -1
- package/dist/serverBaseTypes-BicXMrZV.d.cts +0 -43
- package/dist/serverBaseTypes-BicXMrZV.d.cts.map +0 -1
- package/dist/serverBaseTypes-ewbo8l4R.d.ts +0 -43
- package/dist/serverBaseTypes-ewbo8l4R.d.ts.map +0 -1
- package/dist/serverExecuteTypes-CXnMjKnt.d.ts.map +0 -1
- package/dist/serverExecuteTypes-DKYK1V7C.d.cts.map +0 -1
- package/dist/serverModelTypes-CQgfqgW3.d.cts +0 -69
- package/dist/serverModelTypes-CQgfqgW3.d.cts.map +0 -1
- package/dist/serverModelTypes-vEPhHIit.d.ts +0 -69
- package/dist/serverModelTypes-vEPhHIit.d.ts.map +0 -1
- package/dist/serverQueryTypes-BI-2TD8F.d.ts +0 -53
- package/dist/serverQueryTypes-BI-2TD8F.d.ts.map +0 -1
- package/dist/serverQueryTypes-D7Yharse.d.cts +0 -53
- package/dist/serverQueryTypes-D7Yharse.d.cts.map +0 -1
|
@@ -76,6 +76,26 @@ var MobileClient = class {
|
|
|
76
76
|
return require_dataMappers.mapMobilePublicProfile((await this.publicQuery(body)).profile);
|
|
77
77
|
}
|
|
78
78
|
/**
|
|
79
|
+
* Fetches a page of the global trade feed: public, named, perpetual trades, newest first, optionally
|
|
80
|
+
* filtered by a whole-dollar minimum notional (omitted means unfiltered). The feed is best-effort rather
|
|
81
|
+
* than authoritative history, and pagination is live (not snapshot), so deduplicate pages by
|
|
82
|
+
* {@link MobileFeedTrade.orderDigest}.
|
|
83
|
+
*
|
|
84
|
+
* @throws {MobileServerFailureError} With error code `INVALID_FEED_FILTER` if `minimumNotional` or
|
|
85
|
+
* `limit` is outside its allowed domain (fix the request; do not retry unchanged), or
|
|
86
|
+
* `INVALID_FEED_CURSOR` if the cursor is malformed or was issued for a different `minimumNotional`
|
|
87
|
+
* (discard the cursor and restart from the first page).
|
|
88
|
+
*/
|
|
89
|
+
async getFeed(params = {}) {
|
|
90
|
+
const body = {
|
|
91
|
+
type: "feed",
|
|
92
|
+
minimum_notional: params.minimumNotional,
|
|
93
|
+
limit: params.limit,
|
|
94
|
+
cursor: params.cursor
|
|
95
|
+
};
|
|
96
|
+
return require_dataMappers.mapMobileFeedPage(await this.publicQuery(body));
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
79
99
|
* Fetches the caller's own identity for a subaccount. Returns `null` if the subaccount has not claimed a
|
|
80
100
|
* username yet — this is normal data, not an error.
|
|
81
101
|
*/
|
|
@@ -215,4 +235,4 @@ Object.defineProperty(exports, "__toESM", {
|
|
|
215
235
|
}
|
|
216
236
|
});
|
|
217
237
|
|
|
218
|
-
//# sourceMappingURL=MobileClient-
|
|
238
|
+
//# sourceMappingURL=MobileClient-CfDtaEeL.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileClient-CfDtaEeL.cjs","names":["mapMobilePublicProfile","mapMobileFeedPage","mapMobileIdentity","mapMobileNotificationPreferences","mapMobileRegisteredDevice","mapMobileNotificationPreferencesToServer","WalletNotProvidedError","buildSignedMobileRequest","isMobileServerFailureResponse","MobileServerFailureError","isMobileServerSuccessResponse"],"sources":["../src/MobileClient.ts"],"sourcesContent":["import {\n WalletClientWithAccount,\n WalletNotProvidedError,\n} from '@nadohq/shared';\nimport axios, { AxiosInstance, AxiosResponse } from 'axios';\nimport {\n mapMobileFeedPage,\n mapMobileIdentity,\n mapMobileNotificationPreferences,\n mapMobileNotificationPreferencesToServer,\n mapMobilePublicProfile,\n mapMobileRegisteredDevice,\n} from './dataMappers';\nimport {\n buildSignedMobileRequest,\n MobileSignedInner,\n MobileSignedInnerParams,\n MobileSignedRequest,\n} from './signing';\nimport {\n GetMobileFeedParams,\n GetMobileNotificationPreferencesParams,\n GetMobilePublicProfileParams,\n GetMobileRegisteredDevicesParams,\n GetMobileSelfIdentityParams,\n GetMobileUsernameAvailabilityParams,\n MobileClaimUsernameParams,\n MobileFeedPage,\n MobileIdentity,\n MobileNotificationPreferences,\n MobilePublicProfile,\n MobileRegisteredDevice,\n MobileRegisterExpoTokenParams,\n MobileSetPrivateModeParams,\n MobileSignedRequestParams,\n MobileUnregisterExpoTokenParams,\n MobileUpdateNotificationPreferencesParams,\n MobileUpdateUsernameParams,\n MobileUsernameAvailability,\n} from './types/clientTypes';\nimport { MobileServerFailureError } from './types/MobileServerFailureError';\nimport { MobileServerSuccessResponse } from './types/serverBaseTypes';\nimport { MobileServerExecuteResult } from './types/serverExecuteTypes';\nimport {\n MobileServerPublicQueryRequest,\n MobileServerPublicQuerySuccessResponse,\n MobileServerSignedQuerySuccessResponse,\n} from './types/serverQueryTypes';\nimport {\n MobileServerPublicQueryRequestByType,\n MobileServerPublicQueryRequestType,\n MobileServerSignedQueryRequestType,\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\n/**\n * Client for the Nado mobile service API: username claims, public profile lookups, privacy settings, and\n * 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 });\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 a subaccount's public profile by username.\n *\n * @throws {MobileServerFailureError} With error code `PROFILE_NOT_FOUND` if no identity has claimed the\n * username or it is invalid. Private Mode does not hide the profile itself, only the account's activity.\n */\n async getPublicProfile(\n params: GetMobilePublicProfileParams,\n ): Promise<MobilePublicProfile> {\n const body: MobileServerPublicQueryRequest<'profile'> = {\n type: 'profile',\n username: params.username,\n };\n const data = await this.publicQuery(body);\n return mapMobilePublicProfile(data.profile);\n }\n\n /**\n * Fetches a page of the global trade feed: public, named, perpetual trades, newest first, optionally\n * filtered by a whole-dollar minimum notional (omitted means unfiltered). The feed is best-effort rather\n * than authoritative history, and pagination is live (not snapshot), so deduplicate pages by\n * {@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 Signed queries\n */\n\n /**\n * Fetches the caller's own identity for a subaccount. Returns `null` if the subaccount has not claimed a\n * username yet — this is normal data, not an error.\n */\n async getSelfIdentity(\n params: GetMobileSelfIdentityParams,\n ): Promise<MobileIdentity | null> {\n const signedRequest = await this.getSignedRequest(\n 'self_identity',\n params,\n {},\n );\n const data = await this.query<'self_identity'>(signedRequest);\n return data.identity ? mapMobileIdentity(data.identity) : null;\n }\n\n /**\n * Fetches a wallet's push notification preferences. Falls back to the backend's defaults if the wallet has\n * never updated its preferences.\n */\n async getNotificationPreferences(\n params: GetMobileNotificationPreferencesParams,\n ): Promise<MobileNotificationPreferences> {\n const signedRequest = await this.getSignedRequest(\n 'notification_preferences',\n params,\n {},\n );\n const data = await this.query<'notification_preferences'>(signedRequest);\n return mapMobileNotificationPreferences(data.preferences);\n }\n\n /**\n * Fetches the devices registered for push notifications for a wallet.\n */\n async getRegisteredDevices(\n params: GetMobileRegisteredDevicesParams,\n ): Promise<MobileRegisteredDevice[]> {\n const signedRequest = await this.getSignedRequest(\n 'registered_devices',\n params,\n {},\n );\n const data = await this.query<'registered_devices'>(signedRequest);\n return data.devices.map(mapMobileRegisteredDevice);\n }\n\n /*\n Signed executes\n */\n\n /**\n * Claims a username for a subaccount, derived from the given display name.\n */\n async claimUsername(\n params: MobileClaimUsernameParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'claim_username',\n params,\n {\n display_name: params.displayName,\n },\n );\n return this.execute(signedRequest);\n }\n\n /**\n * Updates the display name for a subaccount's already-claimed identity.\n */\n async updateUsername(\n params: MobileUpdateUsernameParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'update_username',\n 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 * Unregisters an Expo push token for the wallet. Idempotent — unregistering an unknown token succeeds.\n */\n async unregisterExpoToken(\n params: MobileUnregisterExpoTokenParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'unregister_expo_token',\n params,\n { expo_token: params.expoToken },\n );\n return this.execute(signedRequest);\n }\n\n /**\n * Replaces the wallet's push notification preferences. The backend requires `schemaVersion` of 1, exactly\n * one entry per known category, and empty `scopes` on every entry.\n *\n * @throws {MobileServerFailureError} With error code `INVALID_PREFERENCES` if those rules are violated.\n */\n async updateNotificationPreferences(\n params: MobileUpdateNotificationPreferencesParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'update_preferences',\n params,\n {\n preferences: mapMobileNotificationPreferencesToServer(\n params.preferences,\n ),\n },\n );\n return this.execute(signedRequest);\n }\n\n /*\n Base Fns\n */\n\n protected async getSignedRequest<T extends MobileSignedInner['type']>(\n type: T,\n params: MobileSignedRequestParams,\n innerParams: MobileSignedInnerParams<T>,\n ): Promise<MobileSignedRequest> {\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 = { type, ...innerParams } as MobileSignedInner;\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}/mobile/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 query<T extends MobileServerSignedQueryRequestType>(\n body: MobileSignedRequest,\n ): Promise<MobileServerSignedQuerySuccessResponse<T>> {\n const response = await this.axiosInstance.post<unknown>(\n `${this.opts.url}/mobile/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 MobileServerSignedQuerySuccessResponse<T>;\n }\n\n protected async execute(\n body: MobileSignedRequest,\n ): Promise<MobileServerSuccessResponse> {\n const response = await this.axiosInstance.post<MobileServerExecuteResult>(\n `${this.opts.url}/mobile/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 /**\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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"}
|
package/dist/MobileClient.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_MobileClient = require("./MobileClient-
|
|
2
|
+
const require_MobileClient = require("./MobileClient-CfDtaEeL.cjs");
|
|
3
3
|
require("./signing/index.cjs");
|
|
4
4
|
exports.MobileClient = require_MobileClient.MobileClient;
|
package/dist/MobileClient.d.cts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { i as MobileSignedRequest, n as MobileSignedInner, r as MobileSignedInnerParams } from "./types-
|
|
3
|
-
import {
|
|
1
|
+
import { C as MobileUsernameAvailability, S as MobileUpdateUsernameParams, _ as MobileRegisteredDevice, a as GetMobileSelfIdentityParams, b as MobileUnregisterExpoTokenParams, d as MobileIdentity, g as MobileRegisterExpoTokenParams, h as MobilePublicProfile, i as GetMobileRegisteredDevicesParams, l as MobileFeedPage, m as MobileNotificationPreferences, n as GetMobileNotificationPreferencesParams, o as GetMobileUsernameAvailabilityParams, r as GetMobilePublicProfileParams, s as MobileClaimUsernameParams, t as GetMobileFeedParams, v as MobileSetPrivateModeParams, x as MobileUpdateNotificationPreferencesParams, y as MobileSignedRequestParams } from "./clientTypes-UFInIAQd.cjs";
|
|
2
|
+
import { i as MobileSignedRequest, n as MobileSignedInner, r as MobileSignedInnerParams } from "./types-CzOeSYnW.cjs";
|
|
3
|
+
import { n as MobileServerPublicQueryRequestByType, o as MobileServerSignedQueryRequestType, r as MobileServerPublicQueryRequestType } from "./serverRequestTypes-DnU_FfMI.cjs";
|
|
4
|
+
import { n as MobileServerSuccessResponse } from "./serverBaseTypes-A16onlPN.cjs";
|
|
5
|
+
import { o as MobileServerPublicQuerySuccessResponse, u as MobileServerSignedQuerySuccessResponse } from "./serverQueryTypes-C_cCx0Ac.cjs";
|
|
4
6
|
import { WalletClientWithAccount } from "@nadohq/shared";
|
|
5
7
|
import { AxiosInstance } from "axios";
|
|
6
8
|
|
|
@@ -47,6 +49,18 @@ declare class MobileClient {
|
|
|
47
49
|
* username or it is invalid. Private Mode does not hide the profile itself, only the account's activity.
|
|
48
50
|
*/
|
|
49
51
|
getPublicProfile(params: GetMobilePublicProfileParams): Promise<MobilePublicProfile>;
|
|
52
|
+
/**
|
|
53
|
+
* Fetches a page of the global trade feed: public, named, perpetual trades, newest first, optionally
|
|
54
|
+
* filtered by a whole-dollar minimum notional (omitted means unfiltered). The feed is best-effort rather
|
|
55
|
+
* than authoritative history, and pagination is live (not snapshot), so deduplicate pages by
|
|
56
|
+
* {@link MobileFeedTrade.orderDigest}.
|
|
57
|
+
*
|
|
58
|
+
* @throws {MobileServerFailureError} With error code `INVALID_FEED_FILTER` if `minimumNotional` or
|
|
59
|
+
* `limit` is outside its allowed domain (fix the request; do not retry unchanged), or
|
|
60
|
+
* `INVALID_FEED_CURSOR` if the cursor is malformed or was issued for a different `minimumNotional`
|
|
61
|
+
* (discard the cursor and restart from the first page).
|
|
62
|
+
*/
|
|
63
|
+
getFeed(params?: GetMobileFeedParams): Promise<MobileFeedPage>;
|
|
50
64
|
/**
|
|
51
65
|
* Fetches the caller's own identity for a subaccount. Returns `null` if the subaccount has not claimed a
|
|
52
66
|
* username yet — this is normal data, not an error.
|
|
@@ -94,12 +108,10 @@ declare class MobileClient {
|
|
|
94
108
|
*/
|
|
95
109
|
updateNotificationPreferences(params: MobileUpdateNotificationPreferencesParams): Promise<MobileServerSuccessResponse>;
|
|
96
110
|
protected getSignedRequest<T extends MobileSignedInner['type']>(type: T, params: MobileSignedRequestParams, innerParams: MobileSignedInnerParams<T>): Promise<MobileSignedRequest>;
|
|
97
|
-
protected publicQuery<
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
protected query<
|
|
101
|
-
status: 'success';
|
|
102
|
-
}>(body: MobileSignedRequest): Promise<TResponse>;
|
|
111
|
+
protected publicQuery<T extends MobileServerPublicQueryRequestType>(body: {
|
|
112
|
+
type: T;
|
|
113
|
+
} & MobileServerPublicQueryRequestByType[T]): Promise<MobileServerPublicQuerySuccessResponse<T>>;
|
|
114
|
+
protected query<T extends MobileServerSignedQueryRequestType>(body: MobileSignedRequest): Promise<MobileServerSignedQuerySuccessResponse<T>>;
|
|
103
115
|
protected execute(body: MobileSignedRequest): Promise<MobileServerSuccessResponse>;
|
|
104
116
|
/**
|
|
105
117
|
* Validates the HTTP status before interpreting the body. Unlike the engine, the mobile backend returns
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobileClient.d.cts","names":[],"sources":["../src/src/MobileClient.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"MobileClient.d.cts","names":[],"sources":["../src/src/MobileClient.ts"],"mappings":";;;;;;;;;;;;UA6DiB,gBAAA;EAAgB;;;EAI/B,GAAA;EAIA;;;EAAA,YAAA,GAAe,uBAAA;EAImC;AAAA;AAOpD;EAPE,wBAAA,GAA2B,uBAAuB;AAAA;;;;;cAOvC,YAAA;EAAA,SACF,IAAA,EAAM,gBAAA;EAAA,SACN,aAAA,EAAe,aAAA;cAEZ,IAAA,EAAM,gBAAA;EA8CP;;;;;EAhCJ,eAAA,CACL,wBAAA,EAA0B,uBAAA;EAwEjB;;;EA5DL,uBAAA,CACJ,MAAA,EAAQ,mCAAA,GACP,OAAA,CAAQ,0BAAA;EA0ER;;;;;;EA3DG,gBAAA,CACJ,MAAA,EAAQ,4BAAA,GACP,OAAA,CAAQ,mBAAA;EA0GD;;;;;;;;;;;EAtFJ,OAAA,CAAQ,MAAA,GAAQ,mBAAA,GAA2B,OAAA,CAAQ,cAAA;EA2J/C;;;;EAxIJ,eAAA,CACJ,MAAA,EAAQ,2BAAA,GACP,OAAA,CAAQ,cAAA;EA0JD;;;;EA5IJ,0BAAA,CACJ,MAAA,EAAQ,sCAAA,GACP,OAAA,CAAQ,6BAAA;EA2J2B;;;EA9IhC,oBAAA,CACJ,MAAA,EAAQ,gCAAA,GACP,OAAA,CAAQ,sBAAA;EA8IuC;;;EA7H5C,aAAA,CACJ,MAAA,EAAQ,yBAAA,GACP,OAAA,CAAQ,2BAAA;EAyIH;;;EA3HF,cAAA,CACJ,MAAA,EAAQ,0BAAA,GACP,OAAA,CAAQ,2BAAA;EAwIH;;;EA5HF,cAAA,CACJ,MAAA,EAAQ,0BAAA,GACP,OAAA,CAAQ,2BAAA;EA2HD;;;;;;;;EA1GJ,iBAAA,CACJ,MAAA,EAAQ,6BAAA,GACP,OAAA,CAAQ,2BAAA;EA3KiB;;;EA4LtB,mBAAA,CACJ,MAAA,EAAQ,+BAAA,GACP,OAAA,CAAQ,2BAAA;EAjLT;;;;;;EAgMI,6BAAA,CACJ,MAAA,EAAQ,yCAAA,GACP,OAAA,CAAQ,2BAAA;EAAA,UAiBK,gBAAA,WAA2B,iBAAA,SAAA,CACzC,IAAA,EAAM,CAAA,EACN,MAAA,EAAQ,yBAAA,EACR,WAAA,EAAa,uBAAA,CAAwB,CAAA,IACpC,OAAA,CAAQ,mBAAA;EAAA,UAeK,WAAA,WAAsB,kCAAA,CAAA,CACpC,IAAA;IAAQ,IAAA,EAAM,CAAA;EAAA,IAAM,oCAAA,CAAqC,CAAA,IACxD,OAAA,CAAQ,sCAAA,CAAuC,CAAA;EAAA,UAalC,KAAA,WAAgB,kCAAA,CAAA,CAC9B,IAAA,EAAM,mBAAA,GACL,OAAA,CAAQ,sCAAA,CAAuC,CAAA;EAAA,UAalC,OAAA,CACd,IAAA,EAAM,mBAAA,GACL,OAAA,CAAQ,2BAAA;EA7ML;;;;;EAAA,QA+NE,mBAAA;EAAA,QAYA,iBAAA;AAAA"}
|
package/dist/MobileClient.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { i as MobileSignedRequest, n as MobileSignedInner, r as MobileSignedInnerParams } from "./types-
|
|
3
|
-
import {
|
|
1
|
+
import { C as MobileUsernameAvailability, S as MobileUpdateUsernameParams, _ as MobileRegisteredDevice, a as GetMobileSelfIdentityParams, b as MobileUnregisterExpoTokenParams, d as MobileIdentity, g as MobileRegisterExpoTokenParams, h as MobilePublicProfile, i as GetMobileRegisteredDevicesParams, l as MobileFeedPage, m as MobileNotificationPreferences, n as GetMobileNotificationPreferencesParams, o as GetMobileUsernameAvailabilityParams, r as GetMobilePublicProfileParams, s as MobileClaimUsernameParams, t as GetMobileFeedParams, v as MobileSetPrivateModeParams, x as MobileUpdateNotificationPreferencesParams, y as MobileSignedRequestParams } from "./clientTypes-BsOps_pY.js";
|
|
2
|
+
import { i as MobileSignedRequest, n as MobileSignedInner, r as MobileSignedInnerParams } from "./types-UHjZR-js.js";
|
|
3
|
+
import { n as MobileServerPublicQueryRequestByType, o as MobileServerSignedQueryRequestType, r as MobileServerPublicQueryRequestType } from "./serverRequestTypes-DQDy3K9O.js";
|
|
4
|
+
import { n as MobileServerSuccessResponse } from "./serverBaseTypes-m3zEi0X9.js";
|
|
5
|
+
import { o as MobileServerPublicQuerySuccessResponse, u as MobileServerSignedQuerySuccessResponse } from "./serverQueryTypes-CJLWWZBs.js";
|
|
4
6
|
import { WalletClientWithAccount } from "@nadohq/shared";
|
|
5
7
|
import { AxiosInstance } from "axios";
|
|
6
8
|
|
|
@@ -47,6 +49,18 @@ declare class MobileClient {
|
|
|
47
49
|
* username or it is invalid. Private Mode does not hide the profile itself, only the account's activity.
|
|
48
50
|
*/
|
|
49
51
|
getPublicProfile(params: GetMobilePublicProfileParams): Promise<MobilePublicProfile>;
|
|
52
|
+
/**
|
|
53
|
+
* Fetches a page of the global trade feed: public, named, perpetual trades, newest first, optionally
|
|
54
|
+
* filtered by a whole-dollar minimum notional (omitted means unfiltered). The feed is best-effort rather
|
|
55
|
+
* than authoritative history, and pagination is live (not snapshot), so deduplicate pages by
|
|
56
|
+
* {@link MobileFeedTrade.orderDigest}.
|
|
57
|
+
*
|
|
58
|
+
* @throws {MobileServerFailureError} With error code `INVALID_FEED_FILTER` if `minimumNotional` or
|
|
59
|
+
* `limit` is outside its allowed domain (fix the request; do not retry unchanged), or
|
|
60
|
+
* `INVALID_FEED_CURSOR` if the cursor is malformed or was issued for a different `minimumNotional`
|
|
61
|
+
* (discard the cursor and restart from the first page).
|
|
62
|
+
*/
|
|
63
|
+
getFeed(params?: GetMobileFeedParams): Promise<MobileFeedPage>;
|
|
50
64
|
/**
|
|
51
65
|
* Fetches the caller's own identity for a subaccount. Returns `null` if the subaccount has not claimed a
|
|
52
66
|
* username yet — this is normal data, not an error.
|
|
@@ -94,12 +108,10 @@ declare class MobileClient {
|
|
|
94
108
|
*/
|
|
95
109
|
updateNotificationPreferences(params: MobileUpdateNotificationPreferencesParams): Promise<MobileServerSuccessResponse>;
|
|
96
110
|
protected getSignedRequest<T extends MobileSignedInner['type']>(type: T, params: MobileSignedRequestParams, innerParams: MobileSignedInnerParams<T>): Promise<MobileSignedRequest>;
|
|
97
|
-
protected publicQuery<
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
protected query<
|
|
101
|
-
status: 'success';
|
|
102
|
-
}>(body: MobileSignedRequest): Promise<TResponse>;
|
|
111
|
+
protected publicQuery<T extends MobileServerPublicQueryRequestType>(body: {
|
|
112
|
+
type: T;
|
|
113
|
+
} & MobileServerPublicQueryRequestByType[T]): Promise<MobileServerPublicQuerySuccessResponse<T>>;
|
|
114
|
+
protected query<T extends MobileServerSignedQueryRequestType>(body: MobileSignedRequest): Promise<MobileServerSignedQuerySuccessResponse<T>>;
|
|
103
115
|
protected execute(body: MobileSignedRequest): Promise<MobileServerSuccessResponse>;
|
|
104
116
|
/**
|
|
105
117
|
* Validates the HTTP status before interpreting the body. Unlike the engine, the mobile backend returns
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobileClient.d.ts","names":[],"sources":["../src/src/MobileClient.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"MobileClient.d.ts","names":[],"sources":["../src/src/MobileClient.ts"],"mappings":";;;;;;;;;;;;UA6DiB,gBAAA;EAAgB;;;EAI/B,GAAA;EAIA;;;EAAA,YAAA,GAAe,uBAAA;EAImC;AAAA;AAOpD;EAPE,wBAAA,GAA2B,uBAAuB;AAAA;;;;;cAOvC,YAAA;EAAA,SACF,IAAA,EAAM,gBAAA;EAAA,SACN,aAAA,EAAe,aAAA;cAEZ,IAAA,EAAM,gBAAA;EA8CP;;;;;EAhCJ,eAAA,CACL,wBAAA,EAA0B,uBAAA;EAwEjB;;;EA5DL,uBAAA,CACJ,MAAA,EAAQ,mCAAA,GACP,OAAA,CAAQ,0BAAA;EA0ER;;;;;;EA3DG,gBAAA,CACJ,MAAA,EAAQ,4BAAA,GACP,OAAA,CAAQ,mBAAA;EA0GD;;;;;;;;;;;EAtFJ,OAAA,CAAQ,MAAA,GAAQ,mBAAA,GAA2B,OAAA,CAAQ,cAAA;EA2J/C;;;;EAxIJ,eAAA,CACJ,MAAA,EAAQ,2BAAA,GACP,OAAA,CAAQ,cAAA;EA0JD;;;;EA5IJ,0BAAA,CACJ,MAAA,EAAQ,sCAAA,GACP,OAAA,CAAQ,6BAAA;EA2J2B;;;EA9IhC,oBAAA,CACJ,MAAA,EAAQ,gCAAA,GACP,OAAA,CAAQ,sBAAA;EA8IuC;;;EA7H5C,aAAA,CACJ,MAAA,EAAQ,yBAAA,GACP,OAAA,CAAQ,2BAAA;EAyIH;;;EA3HF,cAAA,CACJ,MAAA,EAAQ,0BAAA,GACP,OAAA,CAAQ,2BAAA;EAwIH;;;EA5HF,cAAA,CACJ,MAAA,EAAQ,0BAAA,GACP,OAAA,CAAQ,2BAAA;EA2HD;;;;;;;;EA1GJ,iBAAA,CACJ,MAAA,EAAQ,6BAAA,GACP,OAAA,CAAQ,2BAAA;EA3KiB;;;EA4LtB,mBAAA,CACJ,MAAA,EAAQ,+BAAA,GACP,OAAA,CAAQ,2BAAA;EAjLT;;;;;;EAgMI,6BAAA,CACJ,MAAA,EAAQ,yCAAA,GACP,OAAA,CAAQ,2BAAA;EAAA,UAiBK,gBAAA,WAA2B,iBAAA,SAAA,CACzC,IAAA,EAAM,CAAA,EACN,MAAA,EAAQ,yBAAA,EACR,WAAA,EAAa,uBAAA,CAAwB,CAAA,IACpC,OAAA,CAAQ,mBAAA;EAAA,UAeK,WAAA,WAAsB,kCAAA,CAAA,CACpC,IAAA;IAAQ,IAAA,EAAM,CAAA;EAAA,IAAM,oCAAA,CAAqC,CAAA,IACxD,OAAA,CAAQ,sCAAA,CAAuC,CAAA;EAAA,UAalC,KAAA,WAAgB,kCAAA,CAAA,CAC9B,IAAA,EAAM,mBAAA,GACL,OAAA,CAAQ,sCAAA,CAAuC,CAAA;EAAA,UAalC,OAAA,CACd,IAAA,EAAM,mBAAA,GACL,OAAA,CAAQ,2BAAA;EA7ML;;;;;EAAA,QA+NE,mBAAA;EAAA,QAYA,iBAAA;AAAA"}
|
package/dist/MobileClient.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mapMobileIdentity, mapMobileNotificationPreferences, mapMobileNotificationPreferencesToServer, mapMobilePublicProfile, mapMobileRegisteredDevice } from "./dataMappers.js";
|
|
1
|
+
import { mapMobileFeedPage, mapMobileIdentity, mapMobileNotificationPreferences, mapMobileNotificationPreferencesToServer, mapMobilePublicProfile, mapMobileRegisteredDevice } from "./dataMappers.js";
|
|
2
2
|
import { buildSignedMobileRequest } from "./signing/buildSignedMobileRequest.js";
|
|
3
3
|
import "./signing/index.js";
|
|
4
4
|
import { MobileServerFailureError } from "./types/MobileServerFailureError.js";
|
|
@@ -54,6 +54,26 @@ var MobileClient = class {
|
|
|
54
54
|
return mapMobilePublicProfile((await this.publicQuery(body)).profile);
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
|
+
* Fetches a page of the global trade feed: public, named, perpetual trades, newest first, optionally
|
|
58
|
+
* filtered by a whole-dollar minimum notional (omitted means unfiltered). The feed is best-effort rather
|
|
59
|
+
* than authoritative history, and pagination is live (not snapshot), so deduplicate pages by
|
|
60
|
+
* {@link MobileFeedTrade.orderDigest}.
|
|
61
|
+
*
|
|
62
|
+
* @throws {MobileServerFailureError} With error code `INVALID_FEED_FILTER` if `minimumNotional` or
|
|
63
|
+
* `limit` is outside its allowed domain (fix the request; do not retry unchanged), or
|
|
64
|
+
* `INVALID_FEED_CURSOR` if the cursor is malformed or was issued for a different `minimumNotional`
|
|
65
|
+
* (discard the cursor and restart from the first page).
|
|
66
|
+
*/
|
|
67
|
+
async getFeed(params = {}) {
|
|
68
|
+
const body = {
|
|
69
|
+
type: "feed",
|
|
70
|
+
minimum_notional: params.minimumNotional,
|
|
71
|
+
limit: params.limit,
|
|
72
|
+
cursor: params.cursor
|
|
73
|
+
};
|
|
74
|
+
return mapMobileFeedPage(await this.publicQuery(body));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
57
77
|
* Fetches the caller's own identity for a subaccount. Returns `null` if the subaccount has not claimed a
|
|
58
78
|
* username yet — this is normal data, not an error.
|
|
59
79
|
*/
|
package/dist/MobileClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobileClient.js","names":[],"sources":["../src/MobileClient.ts"],"sourcesContent":["import {\n WalletClientWithAccount,\n WalletNotProvidedError,\n} from '@nadohq/shared';\nimport axios, { AxiosInstance, AxiosResponse } from 'axios';\nimport {\n mapMobileIdentity,\n mapMobileNotificationPreferences,\n mapMobileNotificationPreferencesToServer,\n mapMobilePublicProfile,\n mapMobileRegisteredDevice,\n} from './dataMappers';\nimport {\n buildSignedMobileRequest,\n MobileSignedInner,\n MobileSignedInnerParams,\n MobileSignedRequest,\n} from './signing';\nimport {\n GetMobileNotificationPreferencesParams,\n GetMobilePublicProfileParams,\n GetMobileRegisteredDevicesParams,\n GetMobileSelfIdentityParams,\n GetMobileUsernameAvailabilityParams,\n MobileClaimUsernameParams,\n MobileIdentity,\n MobileNotificationPreferences,\n MobilePublicProfile,\n MobileRegisteredDevice,\n MobileRegisterExpoTokenParams,\n MobileSetPrivateModeParams,\n MobileSignedRequestParams,\n MobileUnregisterExpoTokenParams,\n MobileUpdateNotificationPreferencesParams,\n MobileUpdateUsernameParams,\n MobileUsernameAvailability,\n} from './types/clientTypes';\nimport { MobileServerFailureError } from './types/MobileServerFailureError';\nimport { MobileServerSuccessResponse } from './types/serverBaseTypes';\nimport { MobileServerExecuteResult } from './types/serverExecuteTypes';\nimport {\n MobileServerNotificationPreferencesResponse,\n MobileServerProfileRequest,\n MobileServerProfileResponse,\n MobileServerRegisteredDevicesResponse,\n MobileServerSelfIdentityResponse,\n MobileServerUsernameAvailabilityRequest,\n MobileServerUsernameAvailabilityResponse,\n} from './types/serverQueryTypes';\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\n/**\n * Client for the Nado mobile service API: username claims, public profile lookups, privacy settings, and\n * 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 });\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: MobileServerUsernameAvailabilityRequest = {\n type: 'username_availability',\n display_name: params.displayName,\n };\n const data =\n await this.publicQuery<MobileServerUsernameAvailabilityResponse>(body);\n return { username: data.username, available: data.available };\n }\n\n /**\n * Looks up a subaccount's public profile by username.\n *\n * @throws {MobileServerFailureError} With error code `PROFILE_NOT_FOUND` if no identity has claimed the\n * username or it is invalid. Private Mode does not hide the profile itself, only the account's activity.\n */\n async getPublicProfile(\n params: GetMobilePublicProfileParams,\n ): Promise<MobilePublicProfile> {\n const body: MobileServerProfileRequest = {\n type: 'profile',\n username: params.username,\n };\n const data = await this.publicQuery<MobileServerProfileResponse>(body);\n return mapMobilePublicProfile(data.profile);\n }\n\n /*\n Signed queries\n */\n\n /**\n * Fetches the caller's own identity for a subaccount. Returns `null` if the subaccount has not claimed a\n * username yet — this is normal data, not an error.\n */\n async getSelfIdentity(\n params: GetMobileSelfIdentityParams,\n ): Promise<MobileIdentity | null> {\n const signedRequest = await this.getSignedRequest(\n 'self_identity',\n params,\n {},\n );\n const data =\n await this.query<MobileServerSelfIdentityResponse>(signedRequest);\n return data.identity ? mapMobileIdentity(data.identity) : null;\n }\n\n /**\n * Fetches a wallet's push notification preferences. Falls back to the backend's defaults if the wallet has\n * never updated its preferences.\n */\n async getNotificationPreferences(\n params: GetMobileNotificationPreferencesParams,\n ): Promise<MobileNotificationPreferences> {\n const signedRequest = await this.getSignedRequest(\n 'notification_preferences',\n params,\n {},\n );\n const data =\n await this.query<MobileServerNotificationPreferencesResponse>(\n signedRequest,\n );\n return mapMobileNotificationPreferences(data.preferences);\n }\n\n /**\n * Fetches the devices registered for push notifications for a wallet.\n */\n async getRegisteredDevices(\n params: GetMobileRegisteredDevicesParams,\n ): Promise<MobileRegisteredDevice[]> {\n const signedRequest = await this.getSignedRequest(\n 'registered_devices',\n params,\n {},\n );\n const data =\n await this.query<MobileServerRegisteredDevicesResponse>(signedRequest);\n return data.devices.map(mapMobileRegisteredDevice);\n }\n\n /*\n Signed executes\n */\n\n /**\n * Claims a username for a subaccount, derived from the given display name.\n */\n async claimUsername(\n params: MobileClaimUsernameParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'claim_username',\n params,\n {\n display_name: params.displayName,\n },\n );\n return this.execute(signedRequest);\n }\n\n /**\n * Updates the display name for a subaccount's already-claimed identity.\n */\n async updateUsername(\n params: MobileUpdateUsernameParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'update_username',\n 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 * Unregisters an Expo push token for the wallet. Idempotent — unregistering an unknown token succeeds.\n */\n async unregisterExpoToken(\n params: MobileUnregisterExpoTokenParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'unregister_expo_token',\n params,\n { expo_token: params.expoToken },\n );\n return this.execute(signedRequest);\n }\n\n /**\n * Replaces the wallet's push notification preferences. The backend requires `schemaVersion` of 1, exactly\n * one entry per known category, and empty `scopes` on every entry.\n *\n * @throws {MobileServerFailureError} With error code `INVALID_PREFERENCES` if those rules are violated.\n */\n async updateNotificationPreferences(\n params: MobileUpdateNotificationPreferencesParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'update_preferences',\n params,\n {\n preferences: mapMobileNotificationPreferencesToServer(\n params.preferences,\n ),\n },\n );\n return this.execute(signedRequest);\n }\n\n /*\n Base Fns\n */\n\n protected async getSignedRequest<T extends MobileSignedInner['type']>(\n type: T,\n params: MobileSignedRequestParams,\n innerParams: MobileSignedInnerParams<T>,\n ): Promise<MobileSignedRequest> {\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 = { type, ...innerParams } as MobileSignedInner;\n return buildSignedMobileRequest({ ...params, walletClient, inner });\n }\n\n protected async publicQuery<TResponse extends { status: 'success' }>(\n body: object,\n ): Promise<TResponse> {\n const response = await this.axiosInstance.post<unknown>(\n `${this.opts.url}/mobile/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 TResponse;\n }\n\n protected async query<TResponse extends { status: 'success' }>(\n body: MobileSignedRequest,\n ): Promise<TResponse> {\n const response = await this.axiosInstance.post<unknown>(\n `${this.opts.url}/mobile/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 TResponse;\n }\n\n protected async execute(\n body: MobileSignedRequest,\n ): Promise<MobileServerSuccessResponse> {\n const response = await this.axiosInstance.post<MobileServerExecuteResult>(\n `${this.opts.url}/mobile/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 /**\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":";;;;;;;;;;;;AA4EA,IAAa,eAAb,MAA0B;CAIxB,YAAY,MAAwB;EAClC,KAAK,OAAO;EACZ,KAAK,gBAAgB,MAAM,OAAO;GAChC,iBAAiB;GAEjB,sBAAsB;EACxB,CAAC;CACH;;;;;;CAOA,gBACE,0BACA;EACA,KAAK,KAAK,2BAA2B,4BAA4B,KAAA;CACnE;;;;CASA,MAAM,wBACJ,QACqC;EACrC,MAAM,OAAgD;GACpD,MAAM;GACN,cAAc,OAAO;EACvB;EACA,MAAM,OACJ,MAAM,KAAK,YAAsD,IAAI;EACvE,OAAO;GAAE,UAAU,KAAK;GAAU,WAAW,KAAK;EAAU;CAC9D;;;;;;;CAQA,MAAM,iBACJ,QAC8B;EAC9B,MAAM,OAAmC;GACvC,MAAM;GACN,UAAU,OAAO;EACnB;EAEA,OAAO,wBAAuB,MADX,KAAK,YAAyC,IAAI,GAClC,OAAO;CAC5C;;;;;CAUA,MAAM,gBACJ,QACgC;EAChC,MAAM,gBAAgB,MAAM,KAAK,iBAC/B,iBACA,QACA,CAAC,CACH;EACA,MAAM,OACJ,MAAM,KAAK,MAAwC,aAAa;EAClE,OAAO,KAAK,WAAW,kBAAkB,KAAK,QAAQ,IAAI;CAC5D;;;;;CAMA,MAAM,2BACJ,QACwC;EACxC,MAAM,gBAAgB,MAAM,KAAK,iBAC/B,4BACA,QACA,CAAC,CACH;EAKA,OAAO,kCAAiC,MAHhC,KAAK,MACT,aACF,GAC2C,WAAW;CAC1D;;;;CAKA,MAAM,qBACJ,QACmC;EACnC,MAAM,gBAAgB,MAAM,KAAK,iBAC/B,sBACA,QACA,CAAC,CACH;EAGA,QAAO,MADC,KAAK,MAA6C,aAAa,GAC3D,QAAQ,IAAI,yBAAyB;CACnD;;;;CASA,MAAM,cACJ,QACsC;EACtC,MAAM,gBAAgB,MAAM,KAAK,iBAC/B,kBACA,QACA,EACE,cAAc,OAAO,YACvB,CACF;EACA,OAAO,KAAK,QAAQ,aAAa;CACnC;;;;CAKA,MAAM,eACJ,QACsC;EACtC,MAAM,gBAAgB,MAAM,KAAK,iBAC/B,mBACA,QACA,EAAE,cAAc,OAAO,YAAY,CACrC;EACA,OAAO,KAAK,QAAQ,aAAa;CACnC;;;;CAKA,MAAM,eACJ,QACsC;EACtC,MAAM,gBAAgB,MAAM,KAAK,iBAC/B,oBACA,QACA,EAAE,cAAc,OAAO,YAAY,CACrC;EACA,OAAO,KAAK,QAAQ,aAAa;CACnC;;;;;;;;;CAUA,MAAM,kBACJ,QACsC;EACtC,MAAM,gBAAgB,MAAM,KAAK,iBAC/B,uBACA,QACA;GACE,YAAY,OAAO;GACnB,UAAU,OAAO;GACjB,QAAQ,OAAO,UAAU;GACzB,aAAa,OAAO,cAAc;EACpC,CACF;EACA,OAAO,KAAK,QAAQ,aAAa;CACnC;;;;CAKA,MAAM,oBACJ,QACsC;EACtC,MAAM,gBAAgB,MAAM,KAAK,iBAC/B,yBACA,QACA,EAAE,YAAY,OAAO,UAAU,CACjC;EACA,OAAO,KAAK,QAAQ,aAAa;CACnC;;;;;;;CAQA,MAAM,8BACJ,QACsC;EACtC,MAAM,gBAAgB,MAAM,KAAK,iBAC/B,sBACA,QACA,EACE,aAAa,yCACX,OAAO,WACT,EACF,CACF;EACA,OAAO,KAAK,QAAQ,aAAa;CACnC;CAMA,MAAgB,iBACd,MACA,QACA,aAC8B;EAE9B,MAAM,eACJ,KAAK,KAAK,4BAA4B,KAAK,KAAK;EAElD,IAAI,gBAAgB,MAClB,MAAM,IAAI,uBAAuB;EAGnC,MAAM,QAAQ;GAAE;GAAM,GAAG;EAAY;EACrC,OAAO,yBAAyB;GAAE,GAAG;GAAQ;GAAc;EAAM,CAAC;CACpE;CAEA,MAAgB,YACd,MACoB;EACpB,MAAM,WAAW,MAAM,KAAK,cAAc,KACxC,GAAG,KAAK,KAAK,IAAI,uBACjB,IACF;EAEA,KAAK,oBAAoB,QAAQ;EACjC,KAAK,kBAAkB,QAAQ;EAG/B,OAAO,SAAS;CAClB;CAEA,MAAgB,MACd,MACoB;EACpB,MAAM,WAAW,MAAM,KAAK,cAAc,KACxC,GAAG,KAAK,KAAK,IAAI,gBACjB,IACF;EAEA,KAAK,oBAAoB,QAAQ;EACjC,KAAK,kBAAkB,QAAQ;EAG/B,OAAO,SAAS;CAClB;CAEA,MAAgB,QACd,MACsC;EACtC,MAAM,WAAW,MAAM,KAAK,cAAc,KACxC,GAAG,KAAK,KAAK,IAAI,kBACjB,IACF;EAEA,KAAK,oBAAoB,QAAQ;EACjC,KAAK,kBAAkB,QAAQ;EAG/B,OAAO,SAAS;CAClB;;;;;;CAOA,oBAA4B,UAAkC;EAC5D,IAAI,SAAS,UAAU,OAAO,SAAS,SAAS,KAC9C;EAEF,IAAI,8BAA8B,SAAS,IAAI,GAC7C,MAAM,IAAI,yBAAyB,SAAS,MAAM,SAAS,MAAM;EAEnE,MAAM,IAAI,MACR,4CAA4C,SAAS,OAAO,GAAG,SAAS,WAAW,UAAU,KAAK,UAAU,SAAS,IAAI,GAC3H;CACF;CAEA,kBAA0B,UAAkC;EAC1D,MAAM,EAAE,SAAS;EAEjB,IAAI,8BAA8B,IAAI,GACpC,MAAM,IAAI,yBAAyB,MAAM,SAAS,MAAM;EAE1D,IAAI,CAAC,8BAA8B,IAAI,GACrC,MAAM,IAAI,MACR,4EAA4E,KAAK,UAAU,IAAI,GACjG;CAEJ;AACF"}
|
|
1
|
+
{"version":3,"file":"MobileClient.js","names":[],"sources":["../src/MobileClient.ts"],"sourcesContent":["import {\n WalletClientWithAccount,\n WalletNotProvidedError,\n} from '@nadohq/shared';\nimport axios, { AxiosInstance, AxiosResponse } from 'axios';\nimport {\n mapMobileFeedPage,\n mapMobileIdentity,\n mapMobileNotificationPreferences,\n mapMobileNotificationPreferencesToServer,\n mapMobilePublicProfile,\n mapMobileRegisteredDevice,\n} from './dataMappers';\nimport {\n buildSignedMobileRequest,\n MobileSignedInner,\n MobileSignedInnerParams,\n MobileSignedRequest,\n} from './signing';\nimport {\n GetMobileFeedParams,\n GetMobileNotificationPreferencesParams,\n GetMobilePublicProfileParams,\n GetMobileRegisteredDevicesParams,\n GetMobileSelfIdentityParams,\n GetMobileUsernameAvailabilityParams,\n MobileClaimUsernameParams,\n MobileFeedPage,\n MobileIdentity,\n MobileNotificationPreferences,\n MobilePublicProfile,\n MobileRegisteredDevice,\n MobileRegisterExpoTokenParams,\n MobileSetPrivateModeParams,\n MobileSignedRequestParams,\n MobileUnregisterExpoTokenParams,\n MobileUpdateNotificationPreferencesParams,\n MobileUpdateUsernameParams,\n MobileUsernameAvailability,\n} from './types/clientTypes';\nimport { MobileServerFailureError } from './types/MobileServerFailureError';\nimport { MobileServerSuccessResponse } from './types/serverBaseTypes';\nimport { MobileServerExecuteResult } from './types/serverExecuteTypes';\nimport {\n MobileServerPublicQueryRequest,\n MobileServerPublicQuerySuccessResponse,\n MobileServerSignedQuerySuccessResponse,\n} from './types/serverQueryTypes';\nimport {\n MobileServerPublicQueryRequestByType,\n MobileServerPublicQueryRequestType,\n MobileServerSignedQueryRequestType,\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\n/**\n * Client for the Nado mobile service API: username claims, public profile lookups, privacy settings, and\n * 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 });\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 a subaccount's public profile by username.\n *\n * @throws {MobileServerFailureError} With error code `PROFILE_NOT_FOUND` if no identity has claimed the\n * username or it is invalid. Private Mode does not hide the profile itself, only the account's activity.\n */\n async getPublicProfile(\n params: GetMobilePublicProfileParams,\n ): Promise<MobilePublicProfile> {\n const body: MobileServerPublicQueryRequest<'profile'> = {\n type: 'profile',\n username: params.username,\n };\n const data = await this.publicQuery(body);\n return mapMobilePublicProfile(data.profile);\n }\n\n /**\n * Fetches a page of the global trade feed: public, named, perpetual trades, newest first, optionally\n * filtered by a whole-dollar minimum notional (omitted means unfiltered). The feed is best-effort rather\n * than authoritative history, and pagination is live (not snapshot), so deduplicate pages by\n * {@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 Signed queries\n */\n\n /**\n * Fetches the caller's own identity for a subaccount. Returns `null` if the subaccount has not claimed a\n * username yet — this is normal data, not an error.\n */\n async getSelfIdentity(\n params: GetMobileSelfIdentityParams,\n ): Promise<MobileIdentity | null> {\n const signedRequest = await this.getSignedRequest(\n 'self_identity',\n params,\n {},\n );\n const data = await this.query<'self_identity'>(signedRequest);\n return data.identity ? mapMobileIdentity(data.identity) : null;\n }\n\n /**\n * Fetches a wallet's push notification preferences. Falls back to the backend's defaults if the wallet has\n * never updated its preferences.\n */\n async getNotificationPreferences(\n params: GetMobileNotificationPreferencesParams,\n ): Promise<MobileNotificationPreferences> {\n const signedRequest = await this.getSignedRequest(\n 'notification_preferences',\n params,\n {},\n );\n const data = await this.query<'notification_preferences'>(signedRequest);\n return mapMobileNotificationPreferences(data.preferences);\n }\n\n /**\n * Fetches the devices registered for push notifications for a wallet.\n */\n async getRegisteredDevices(\n params: GetMobileRegisteredDevicesParams,\n ): Promise<MobileRegisteredDevice[]> {\n const signedRequest = await this.getSignedRequest(\n 'registered_devices',\n params,\n {},\n );\n const data = await this.query<'registered_devices'>(signedRequest);\n return data.devices.map(mapMobileRegisteredDevice);\n }\n\n /*\n Signed executes\n */\n\n /**\n * Claims a username for a subaccount, derived from the given display name.\n */\n async claimUsername(\n params: MobileClaimUsernameParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'claim_username',\n params,\n {\n display_name: params.displayName,\n },\n );\n return this.execute(signedRequest);\n }\n\n /**\n * Updates the display name for a subaccount's already-claimed identity.\n */\n async updateUsername(\n params: MobileUpdateUsernameParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'update_username',\n 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 * Unregisters an Expo push token for the wallet. Idempotent — unregistering an unknown token succeeds.\n */\n async unregisterExpoToken(\n params: MobileUnregisterExpoTokenParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'unregister_expo_token',\n params,\n { expo_token: params.expoToken },\n );\n return this.execute(signedRequest);\n }\n\n /**\n * Replaces the wallet's push notification preferences. The backend requires `schemaVersion` of 1, exactly\n * one entry per known category, and empty `scopes` on every entry.\n *\n * @throws {MobileServerFailureError} With error code `INVALID_PREFERENCES` if those rules are violated.\n */\n async updateNotificationPreferences(\n params: MobileUpdateNotificationPreferencesParams,\n ): Promise<MobileServerSuccessResponse> {\n const signedRequest = await this.getSignedRequest(\n 'update_preferences',\n params,\n {\n preferences: mapMobileNotificationPreferencesToServer(\n params.preferences,\n ),\n },\n );\n return this.execute(signedRequest);\n }\n\n /*\n Base Fns\n */\n\n protected async getSignedRequest<T extends MobileSignedInner['type']>(\n type: T,\n params: MobileSignedRequestParams,\n innerParams: MobileSignedInnerParams<T>,\n ): Promise<MobileSignedRequest> {\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 = { type, ...innerParams } as MobileSignedInner;\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}/mobile/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 query<T extends MobileServerSignedQueryRequestType>(\n body: MobileSignedRequest,\n ): Promise<MobileServerSignedQuerySuccessResponse<T>> {\n const response = await this.axiosInstance.post<unknown>(\n `${this.opts.url}/mobile/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 MobileServerSignedQuerySuccessResponse<T>;\n }\n\n protected async execute(\n body: MobileSignedRequest,\n ): Promise<MobileServerSuccessResponse> {\n const response = await this.axiosInstance.post<MobileServerExecuteResult>(\n `${this.opts.url}/mobile/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 /**\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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"}
|
package/dist/{MobileServerFailureError-ZggEcEda.d.cts → MobileServerFailureError-B11rr9O5.d.cts}
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { i as MobileServerRequestType
|
|
1
|
+
import { i as MobileServerRequestType } from "./serverRequestTypes-DnU_FfMI.cjs";
|
|
2
|
+
import { t as MobileServerFailureResponse } from "./serverBaseTypes-A16onlPN.cjs";
|
|
2
3
|
import { BaseServerFailureError } from "@nadohq/shared";
|
|
3
4
|
|
|
4
5
|
//#region src/types/MobileServerFailureError.d.ts
|
|
@@ -19,4 +20,4 @@ declare class MobileServerFailureError extends BaseServerFailureError {
|
|
|
19
20
|
}
|
|
20
21
|
//#endregion
|
|
21
22
|
export { MobileServerFailureError as t };
|
|
22
|
-
//# sourceMappingURL=MobileServerFailureError-
|
|
23
|
+
//# sourceMappingURL=MobileServerFailureError-B11rr9O5.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileServerFailureError-B11rr9O5.d.cts","names":[],"sources":["../src/types/src/types/MobileServerFailureError.ts"],"mappings":";;;;;;;AASA;;;cAAa,wBAAA,SAAiC,sBAAA;EAAA,SAC3B,YAAA,EAAc,2BAAA;EAAA,SACd,WAAA,EAAa,uBAAA;EAFc;;;;EAAA,SAQnC,UAAA;cAEG,YAAA,EAAc,2BAAA,EAA6B,UAAA;AAAA"}
|
package/dist/{MobileServerFailureError-f9KhKnJj.d.ts → MobileServerFailureError-DoIvXqYV.d.ts}
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { i as MobileServerRequestType
|
|
1
|
+
import { i as MobileServerRequestType } from "./serverRequestTypes-DQDy3K9O.js";
|
|
2
|
+
import { t as MobileServerFailureResponse } from "./serverBaseTypes-m3zEi0X9.js";
|
|
2
3
|
import { BaseServerFailureError } from "@nadohq/shared";
|
|
3
4
|
|
|
4
5
|
//#region src/types/MobileServerFailureError.d.ts
|
|
@@ -19,4 +20,4 @@ declare class MobileServerFailureError extends BaseServerFailureError {
|
|
|
19
20
|
}
|
|
20
21
|
//#endregion
|
|
21
22
|
export { MobileServerFailureError as t };
|
|
22
|
-
//# sourceMappingURL=MobileServerFailureError-
|
|
23
|
+
//# sourceMappingURL=MobileServerFailureError-DoIvXqYV.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileServerFailureError-DoIvXqYV.d.ts","names":[],"sources":["../src/types/src/types/MobileServerFailureError.ts"],"mappings":";;;;;;;AASA;;;cAAa,wBAAA,SAAiC,sBAAA;EAAA,SAC3B,YAAA,EAAc,2BAAA;EAAA,SACd,WAAA,EAAa,uBAAA;EAFc;;;;EAAA,SAQnC,UAAA;cAEG,YAAA,EAAc,2BAAA,EAA6B,UAAA;AAAA"}
|
package/dist/{buildSignedMobileRequest-CDRsRNHm.d.ts → buildSignedMobileRequest-B4KJ6T1y.d.ts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as MobileSignedRequest, n as MobileSignedInner, t as BuildSignedMobileRequestParams } from "./types-
|
|
1
|
+
import { i as MobileSignedRequest, n as MobileSignedInner, t as BuildSignedMobileRequestParams } from "./types-UHjZR-js.js";
|
|
2
2
|
|
|
3
3
|
//#region src/signing/buildSignedMobileRequest.d.ts
|
|
4
4
|
/**
|
|
@@ -11,4 +11,4 @@ declare function buildSignedMobileRequest<T extends MobileSignedInner>(params: B
|
|
|
11
11
|
}): Promise<MobileSignedRequest<T>>;
|
|
12
12
|
//#endregion
|
|
13
13
|
export { buildSignedMobileRequest as t };
|
|
14
|
-
//# sourceMappingURL=buildSignedMobileRequest-
|
|
14
|
+
//# sourceMappingURL=buildSignedMobileRequest-B4KJ6T1y.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildSignedMobileRequest-
|
|
1
|
+
{"version":3,"file":"buildSignedMobileRequest-B4KJ6T1y.d.ts","names":[],"sources":["../src/signing/src/signing/buildSignedMobileRequest.ts"],"mappings":";;;;;AAgBA;;;iBAAsB,wBAAA,WAAmC,iBAAA,CAAA,CACvD,MAAA,EAAQ,8BAAA;EAAmC,KAAA,EAAO,CAAA;AAAA,IACjD,OAAA,CAAQ,mBAAA,CAAoB,CAAA"}
|
package/dist/{buildSignedMobileRequest-BsbBkU0K.d.cts → buildSignedMobileRequest-EEnDgZF8.d.cts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as MobileSignedRequest, n as MobileSignedInner, t as BuildSignedMobileRequestParams } from "./types-
|
|
1
|
+
import { i as MobileSignedRequest, n as MobileSignedInner, t as BuildSignedMobileRequestParams } from "./types-CzOeSYnW.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/signing/buildSignedMobileRequest.d.ts
|
|
4
4
|
/**
|
|
@@ -11,4 +11,4 @@ declare function buildSignedMobileRequest<T extends MobileSignedInner>(params: B
|
|
|
11
11
|
}): Promise<MobileSignedRequest<T>>;
|
|
12
12
|
//#endregion
|
|
13
13
|
export { buildSignedMobileRequest as t };
|
|
14
|
-
//# sourceMappingURL=buildSignedMobileRequest-
|
|
14
|
+
//# sourceMappingURL=buildSignedMobileRequest-EEnDgZF8.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildSignedMobileRequest-
|
|
1
|
+
{"version":3,"file":"buildSignedMobileRequest-EEnDgZF8.d.cts","names":[],"sources":["../src/signing/src/signing/buildSignedMobileRequest.ts"],"mappings":";;;;;AAgBA;;;iBAAsB,wBAAA,WAAmC,iBAAA,CAAA,CACvD,MAAA,EAAQ,8BAAA;EAAmC,KAAA,EAAO,CAAA;AAAA,IACjD,OAAA,CAAQ,mBAAA,CAAoB,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as MobileSignedInner } from "./types-
|
|
1
|
+
import { n as MobileSignedInner } from "./types-CzOeSYnW.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/signing/canonicalize.d.ts
|
|
4
4
|
/**
|
|
@@ -11,4 +11,4 @@ import { n as MobileSignedInner } from "./types-uCD4BNZR.cjs";
|
|
|
11
11
|
declare function canonicalizeMobileInner(inner: MobileSignedInner): MobileSignedInner;
|
|
12
12
|
//#endregion
|
|
13
13
|
export { canonicalizeMobileInner as t };
|
|
14
|
-
//# sourceMappingURL=canonicalize-
|
|
14
|
+
//# sourceMappingURL=canonicalize-CDdYnhL3.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonicalize-CDdYnhL3.d.cts","names":[],"sources":["../src/signing/src/signing/canonicalize.ts"],"mappings":";;;;;AAUA;;;;;iBAAgB,uBAAA,CACd,KAAA,EAAO,iBAAA,GACN,iBAAiB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as MobileSignedInner } from "./types-
|
|
1
|
+
import { n as MobileSignedInner } from "./types-UHjZR-js.js";
|
|
2
2
|
|
|
3
3
|
//#region src/signing/canonicalize.d.ts
|
|
4
4
|
/**
|
|
@@ -11,4 +11,4 @@ import { n as MobileSignedInner } from "./types-B76Pn7Sy.js";
|
|
|
11
11
|
declare function canonicalizeMobileInner(inner: MobileSignedInner): MobileSignedInner;
|
|
12
12
|
//#endregion
|
|
13
13
|
export { canonicalizeMobileInner as t };
|
|
14
|
-
//# sourceMappingURL=canonicalize-
|
|
14
|
+
//# sourceMappingURL=canonicalize-Cc7hdZLJ.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonicalize-Cc7hdZLJ.d.ts","names":[],"sources":["../src/signing/src/signing/canonicalize.ts"],"mappings":";;;;;AAUA;;;;;iBAAgB,uBAAA,CACd,KAAA,EAAO,iBAAA,GACN,iBAAiB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as MobileFeedTradePosition, c as MobileNotificationCategory, i as MobileFeedMarginMode, l as MobileNotificationPlatform } from "./serverModelTypes-CqnqHY5F.js";
|
|
2
2
|
import { SignatureParams, Subaccount } from "@nadohq/shared";
|
|
3
3
|
import { Hex } from "viem";
|
|
4
4
|
|
|
@@ -39,6 +39,53 @@ interface MobileUsernameAvailability {
|
|
|
39
39
|
username: string;
|
|
40
40
|
available: boolean;
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Margin of a feed trade. Branch on `mode` — do not infer isolated state from leverage presence:
|
|
44
|
+
* `estimatedLeverage` (a rounded whole-number estimate, not exact submitted leverage) is `undefined` on
|
|
45
|
+
* `cross`, and also `undefined` inside `isolated` when no estimate is available.
|
|
46
|
+
*/
|
|
47
|
+
interface MobileFeedMargin {
|
|
48
|
+
mode: MobileFeedMarginMode;
|
|
49
|
+
estimatedLeverage?: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A single feed trade: one row per order digest, enriched with the trader's current identity at read time
|
|
53
|
+
* (a rename can change an already-fetched trade on the next read). Amounts are display-oriented human-unit
|
|
54
|
+
* numbers — do not use them for accounting, order construction, or exact threshold decisions.
|
|
55
|
+
*/
|
|
56
|
+
interface MobileFeedTrade {
|
|
57
|
+
/** Order digest this trade is keyed by; the stable id for reconciling live pagination. */
|
|
58
|
+
orderDigest: Hex;
|
|
59
|
+
subaccount: Hex;
|
|
60
|
+
username: string;
|
|
61
|
+
displayName: string;
|
|
62
|
+
/** Reserved for a future avatar source; `null` until one is implemented. */
|
|
63
|
+
avatarUrl: string | null;
|
|
64
|
+
productId: number;
|
|
65
|
+
/** Executed quantity in human units. */
|
|
66
|
+
quantity: number;
|
|
67
|
+
/** Trade notional in whole-dollar human units. */
|
|
68
|
+
notional: number;
|
|
69
|
+
/** Average execution price in human units. */
|
|
70
|
+
averagePrice: number;
|
|
71
|
+
margin: MobileFeedMargin;
|
|
72
|
+
/** Resulting position change. `position.direction` is NOT the execution buy/sell side. */
|
|
73
|
+
position: MobileFeedTradePosition;
|
|
74
|
+
/** Realized PnL of the trade in human units; can be negative. */
|
|
75
|
+
realizedPnl: number;
|
|
76
|
+
/** Fill time as a Unix timestamp (milliseconds). */
|
|
77
|
+
filledAt: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* A page of feed trades. `nextCursor` is `null` when there was no additional candidate at query time.
|
|
81
|
+
* Pagination is live, not snapshot, so a later fill can move a trade between pages — deduplicate by
|
|
82
|
+
* {@link MobileFeedTrade.orderDigest} and treat the merged list as a short-lived view, not an authoritative
|
|
83
|
+
* cache (removals from Private Mode or blacklists are not signaled).
|
|
84
|
+
*/
|
|
85
|
+
interface MobileFeedPage {
|
|
86
|
+
trades: MobileFeedTrade[];
|
|
87
|
+
nextCursor: string | null;
|
|
88
|
+
}
|
|
42
89
|
/**
|
|
43
90
|
* Scope limiting a notification category preference. Scopes are part of the wire format but rejected by the
|
|
44
91
|
* backend for the MVP — `scopes` must be empty.
|
|
@@ -103,6 +150,23 @@ interface GetMobileUsernameAvailabilityParams {
|
|
|
103
150
|
interface GetMobilePublicProfileParams {
|
|
104
151
|
username: string;
|
|
105
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Params for {@link MobileClient.getFeed}.
|
|
155
|
+
*/
|
|
156
|
+
interface GetMobileFeedParams {
|
|
157
|
+
/**
|
|
158
|
+
* Minimum notional filter as a whole-dollar safe integer, at least `MOBILE_FEED_MIN_NOTIONAL_FLOOR`
|
|
159
|
+
* ($1,000). Omit for the unfiltered feed.
|
|
160
|
+
*/
|
|
161
|
+
minimumNotional?: number;
|
|
162
|
+
/** Page size, 1–`MOBILE_FEED_MAX_PAGE_SIZE` (50); the backend defaults to 50 when omitted. */
|
|
163
|
+
limit?: number;
|
|
164
|
+
/**
|
|
165
|
+
* Opaque keyset cursor from a prior page's {@link MobileFeedPage.nextCursor}. Send it back unchanged with
|
|
166
|
+
* the exact same `minimumNotional` it was issued for.
|
|
167
|
+
*/
|
|
168
|
+
cursor?: string;
|
|
169
|
+
}
|
|
106
170
|
/**
|
|
107
171
|
* Params for {@link MobileClient.getSelfIdentity}.
|
|
108
172
|
*/
|
|
@@ -164,5 +228,5 @@ type GetMobileNotificationPreferencesParams = MobileSignedRequestParams;
|
|
|
164
228
|
*/
|
|
165
229
|
type GetMobileRegisteredDevicesParams = MobileSignedRequestParams;
|
|
166
230
|
//#endregion
|
|
167
|
-
export {
|
|
168
|
-
//# sourceMappingURL=clientTypes-
|
|
231
|
+
export { MobileUsernameAvailability as C, MobileUpdateUsernameParams as S, MobileRegisteredDevice as _, GetMobileSelfIdentityParams as a, MobileUnregisterExpoTokenParams as b, MobileFeedMargin as c, MobileIdentity as d, MobileNotificationCategoryPreference as f, MobileRegisterExpoTokenParams as g, MobilePublicProfile as h, GetMobileRegisteredDevicesParams as i, MobileFeedPage as l, MobileNotificationPreferences as m, GetMobileNotificationPreferencesParams as n, GetMobileUsernameAvailabilityParams as o, MobileNotificationPreferenceScope as p, GetMobilePublicProfileParams as r, MobileClaimUsernameParams as s, GetMobileFeedParams as t, MobileFeedTrade as u, MobileSetPrivateModeParams as v, MobileUpdateNotificationPreferencesParams as x, MobileSignedRequestParams as y };
|
|
232
|
+
//# sourceMappingURL=clientTypes-BsOps_pY.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientTypes-BsOps_pY.d.ts","names":[],"sources":["../src/types/src/types/clientTypes.ts"],"mappings":";;;;;;;AAiBA;;;;;;UAAiB,cAAA;EACf,UAAA,EAAY,GAAG;EAUf;;AAAW;AAMb;EAXE,QAAA;;;;EAIA,WAAA;EACA,WAAA;AAAA;;AASW;AAMb;UATiB,mBAAA;EACf,UAAA,EAAY,GAAG;EACf,QAAA;EACA,WAAA;AAAA;;;;UAMe,0BAAA;EACf,QAAA;EACA,SAAS;AAAA;AAUQ;AAQnB;;;;AARmB,UAFF,gBAAA;EACf,IAAA,EAAM,oBAAoB;EAC1B,iBAAA;AAAA;;;;;;UAQe,eAAA;EAKf;EAHA,WAAA,EAAa,GAAA;EACb,UAAA,EAAY,GAAA;EACZ,QAAA;EACA,WAAA;EASA;EAPA,SAAA;EACA,SAAA;EASA;EAPA,QAAA;EASA;EAPA,QAAA;EASQ;EAPR,YAAA;EACA,MAAA,EAAQ,gBAAA;EAeqB;EAb7B,QAAA,EAAU,uBAAA;EAca;EAZvB,WAAA;EAYQ;EAVR,QAAA;AAAA;AAWU;AAOZ;;;;;AAPY,UAFK,cAAA;EACf,MAAA,EAAQ,eAAe;EACvB,UAAA;AAAA;;AAS8B;AAKhC;;KAPY,iCAAA;EACN,IAAA;EAAoB,UAAA,EAAY,GAAG;AAAA;EACnC,IAAA;EAAiB,SAAA;AAAA;;AAQoB;AAO3C;UAViB,oCAAA;EACf,QAAA,EAAU,0BAAA;EACV,OAAA;EACA,MAAA,EAAQ,iCAAiC;AAAA;;;AAUO;AAMlD;UATiB,6BAAA;;EAEf,aAAA;EACA,UAAA,EAAY,oCAAoC;AAAA;;;;UAMjC,sBAAA;EAeL;EAbV,QAAA,EAAU,0BAA0B;EAmBrB;EAjBf,MAAA;;EAEA,UAAA;EAgBmC;AAKrC;;;EAhBE,sBAAA;EAiBW;AAMb;;EAnBE,UAAA;AAAA;AAoBQ;AAMV;;AANU,UAdO,yBAAA,SACP,UAAA,EAAY,eAAe;;;;UAKpB,mCAAA;EACf,WAAW;AAAA;;;;UAMI,4BAAA;EACf,QAAQ;AAAA;;;AA8BG;UAxBI,mBAAA;EA8B2B;;;AAC/B;EA1BX,eAAA;EAgC0C;EA9B1C,KAAA;EA8BkD;AACvC;AAMb;;EAhCE,MAAA;AAAA;;;;KAMU,2BAAA,GAA8B,yBAAyB;;;;UAKlD,yBAAA,SAAkC,yBAAyB;EAC1E,WAAW;AAAA;;;AAwCF;UAlCM,0BAAA,SAAmC,yBAAyB;EAC3E,WAAW;AAAA;;;;UAMI,0BAAA,SAAmC,yBAAyB;EAC3E,WAAW;AAAA;AAuCb;;;AAAA,UAjCiB,6BAAA,SAAsC,yBAAyB;EAiCF;AAK9E;;EAlCE,SAAA;EACA,QAAA,EAAU,0BAAA;EAiC4D;;;EA7BtE,MAAA;;;;EAIA,UAAA;AAAA;;;;UAMe,+BAAA,SAAwC,yBAAyB;EAChF,SAAS;AAAA;;;;UAMM,yCAAA,SAAkD,yBAAyB;EAC1F,WAAA,EAAa,6BAAA;AAAA;;;;KAMH,sCAAA,GAAyC,yBAAyB;;;;KAKlE,gCAAA,GAAmC,yBAAyB"}
|