@oxy.so/core 4.5.0-oxy-one.0 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/HttpService.js +63 -19
  3. package/dist/cjs/api/accounts.js +10 -3
  4. package/dist/cjs/api/agency.js +3 -1
  5. package/dist/cjs/api/apps.js +15 -4
  6. package/dist/cjs/api/assets.js +49 -12
  7. package/dist/cjs/api/auth.js +37 -11
  8. package/dist/cjs/api/billing.js +24 -7
  9. package/dist/cjs/api/civic.js +14 -4
  10. package/dist/cjs/api/follows.js +9 -2
  11. package/dist/cjs/api/identity.js +31 -9
  12. package/dist/cjs/api/nodes.js +3 -1
  13. package/dist/cjs/api/privacy.js +8 -2
  14. package/dist/cjs/api/session.js +15 -4
  15. package/dist/cjs/api/store.js +15 -5
  16. package/dist/cjs/api/topics.js +10 -3
  17. package/dist/cjs/api/users.js +16 -4
  18. package/dist/cjs/boot/sessionColdBoot.js +40 -13
  19. package/dist/cjs/constants/version.js +6 -6
  20. package/dist/cjs/crypto/identityMarker.js +3 -1
  21. package/dist/cjs/crypto/identityProof.js +6 -1
  22. package/dist/cjs/crypto/keyManager.js +87 -32
  23. package/dist/cjs/crypto/recoveryPhrase.js +2 -2
  24. package/dist/cjs/crypto/signatureService.js +3 -4
  25. package/dist/cjs/i18n/index.js +16 -3
  26. package/dist/cjs/i18n/locales/ar-SA.js +366 -366
  27. package/dist/cjs/i18n/locales/ca-ES.js +366 -366
  28. package/dist/cjs/i18n/locales/de-DE.js +366 -366
  29. package/dist/cjs/i18n/locales/en-US.js +1994 -1994
  30. package/dist/cjs/i18n/locales/es-ES.js +1994 -1994
  31. package/dist/cjs/i18n/locales/fr-FR.js +366 -366
  32. package/dist/cjs/i18n/locales/it-IT.js +366 -366
  33. package/dist/cjs/i18n/locales/ja-JP.js +366 -366
  34. package/dist/cjs/i18n/locales/ko-KR.js +366 -366
  35. package/dist/cjs/i18n/locales/pt-PT.js +366 -366
  36. package/dist/cjs/i18n/locales/zh-CN.js +366 -366
  37. package/dist/cjs/inference/OxyInferenceClient.js +12 -18
  38. package/dist/cjs/models/interfaces.js +11 -11
  39. package/dist/cjs/server/OxyServer.js +86 -28
  40. package/dist/cjs/server/agentAccount.js +6 -2
  41. package/dist/cjs/server/aliaMachineCredential.js +39 -14
  42. package/dist/cjs/server/auth.js +5 -4
  43. package/dist/cjs/server/capabilityTicket.js +5 -5
  44. package/dist/cjs/server/index.js +2 -1
  45. package/dist/cjs/server/liveCapabilityTicket.js +4 -1
  46. package/dist/cjs/server/middleware.js +61 -42
  47. package/dist/cjs/server/namespaces.js +28 -7
  48. package/dist/cjs/server/requesterAssertion.js +36 -30
  49. package/dist/cjs/server/serviceTokenLifetime.js +7 -4
  50. package/dist/cjs/server/traffic.js +53 -14
  51. package/dist/cjs/server/trafficNodeHttp.js +33 -8
  52. package/dist/cjs/server/workloadIdentity.client.js +4 -0
  53. package/dist/cjs/server/workloadIdentity.js +28 -1
  54. package/dist/cjs/session/SessionClient.js +54 -17
  55. package/dist/cjs/session/accountDelegationAccess.js +4 -6
  56. package/dist/cjs/session/accountDialogController.js +1 -1
  57. package/dist/cjs/session/authStateStore.js +18 -9
  58. package/dist/cjs/session/identityPin.js +6 -2
  59. package/dist/cjs/session/refresh.js +81 -23
  60. package/dist/cjs/session/sharedDeviceCredential.js +28 -15
  61. package/dist/cjs/shared/utils/errorUtils.js +1 -1
  62. package/dist/cjs/shared/utils/networkUtils.js +1 -1
  63. package/dist/cjs/shared/utils/themeUtils.js +1 -1
  64. package/dist/cjs/utils/accountCacheSweep.js +3 -1
  65. package/dist/cjs/utils/accountUtils.js +1 -3
  66. package/dist/cjs/utils/asyncUtils.js +1 -1
  67. package/dist/cjs/utils/authHelpers.js +2 -1
  68. package/dist/cjs/utils/avatarUtils.js +4 -2
  69. package/dist/cjs/utils/cache.js +1 -1
  70. package/dist/cjs/utils/cacheKey.js +3 -1
  71. package/dist/cjs/utils/deviceManager.js +4 -4
  72. package/dist/cjs/utils/errorUtils.js +6 -4
  73. package/dist/cjs/utils/languageUtils.js +404 -57
  74. package/dist/cjs/utils/profileLinks.js +1 -3
  75. package/dist/cjs/utils/requestUtils.js +7 -1
  76. package/dist/cjs/utils/userIdentity.js +1 -1
  77. package/dist/cjs/utils/validationUtils.js +5 -6
  78. package/dist/esm/HttpService.js +64 -20
  79. package/dist/esm/api/accounts.js +11 -4
  80. package/dist/esm/api/agency.js +3 -1
  81. package/dist/esm/api/apps.js +15 -4
  82. package/dist/esm/api/assets.js +49 -12
  83. package/dist/esm/api/auth.js +37 -11
  84. package/dist/esm/api/billing.js +25 -8
  85. package/dist/esm/api/civic.js +14 -4
  86. package/dist/esm/api/follows.js +9 -2
  87. package/dist/esm/api/identity.js +31 -9
  88. package/dist/esm/api/nodes.js +3 -1
  89. package/dist/esm/api/privacy.js +8 -2
  90. package/dist/esm/api/session.js +15 -4
  91. package/dist/esm/api/store.js +15 -5
  92. package/dist/esm/api/topics.js +10 -3
  93. package/dist/esm/api/users.js +16 -4
  94. package/dist/esm/boot/sessionColdBoot.js +41 -14
  95. package/dist/esm/constants/version.js +6 -6
  96. package/dist/esm/crypto/identityMarker.js +3 -1
  97. package/dist/esm/crypto/identityProof.js +6 -1
  98. package/dist/esm/crypto/internal.js +1 -1
  99. package/dist/esm/crypto/keyManager.js +87 -32
  100. package/dist/esm/crypto/recoveryPhrase.js +2 -2
  101. package/dist/esm/crypto/signatureService.js +3 -4
  102. package/dist/esm/i18n/index.js +16 -3
  103. package/dist/esm/i18n/locales/ar-SA.js +366 -366
  104. package/dist/esm/i18n/locales/ca-ES.js +366 -366
  105. package/dist/esm/i18n/locales/de-DE.js +366 -366
  106. package/dist/esm/i18n/locales/en-US.js +1994 -1994
  107. package/dist/esm/i18n/locales/es-ES.js +1994 -1994
  108. package/dist/esm/i18n/locales/fr-FR.js +366 -366
  109. package/dist/esm/i18n/locales/it-IT.js +366 -366
  110. package/dist/esm/i18n/locales/ja-JP.js +366 -366
  111. package/dist/esm/i18n/locales/ko-KR.js +366 -366
  112. package/dist/esm/i18n/locales/pt-PT.js +366 -366
  113. package/dist/esm/i18n/locales/zh-CN.js +366 -366
  114. package/dist/esm/index.js +1 -1
  115. package/dist/esm/inference/OxyInferenceClient.js +13 -19
  116. package/dist/esm/models/interfaces.js +11 -11
  117. package/dist/esm/server/OxyServer.js +87 -29
  118. package/dist/esm/server/agentAccount.js +6 -2
  119. package/dist/esm/server/aliaMachineCredential.js +39 -14
  120. package/dist/esm/server/auth.js +6 -5
  121. package/dist/esm/server/capabilityTicket.js +6 -6
  122. package/dist/esm/server/index.js +5 -5
  123. package/dist/esm/server/liveCapabilityTicket.js +6 -3
  124. package/dist/esm/server/middleware.js +62 -43
  125. package/dist/esm/server/namespaces.js +31 -10
  126. package/dist/esm/server/requesterAssertion.js +36 -30
  127. package/dist/esm/server/serviceTokenLifetime.js +7 -4
  128. package/dist/esm/server/traffic.js +55 -16
  129. package/dist/esm/server/trafficNodeHttp.js +34 -9
  130. package/dist/esm/server/userInvalidation.js +1 -1
  131. package/dist/esm/server/workloadIdentity.client.js +3 -0
  132. package/dist/esm/server/workloadIdentity.js +27 -1
  133. package/dist/esm/session/SessionClient.js +54 -17
  134. package/dist/esm/session/accountDelegationAccess.js +5 -7
  135. package/dist/esm/session/accountDialogController.js +1 -1
  136. package/dist/esm/session/authStateStore.js +18 -9
  137. package/dist/esm/session/identityPin.js +6 -2
  138. package/dist/esm/session/refresh.js +82 -24
  139. package/dist/esm/session/sharedDeviceCredential.js +28 -15
  140. package/dist/esm/shared/utils/errorUtils.js +1 -1
  141. package/dist/esm/shared/utils/networkUtils.js +1 -1
  142. package/dist/esm/shared/utils/themeUtils.js +1 -1
  143. package/dist/esm/utils/accountCacheSweep.js +3 -1
  144. package/dist/esm/utils/accountUtils.js +1 -3
  145. package/dist/esm/utils/asyncUtils.js +1 -1
  146. package/dist/esm/utils/authHelpers.js +2 -1
  147. package/dist/esm/utils/avatarUtils.js +4 -2
  148. package/dist/esm/utils/cache.js +1 -1
  149. package/dist/esm/utils/cacheKey.js +3 -1
  150. package/dist/esm/utils/deviceManager.js +4 -4
  151. package/dist/esm/utils/errorUtils.js +6 -4
  152. package/dist/esm/utils/languageUtils.js +404 -57
  153. package/dist/esm/utils/profileLinks.js +1 -3
  154. package/dist/esm/utils/requestUtils.js +7 -1
  155. package/dist/esm/utils/userIdentity.js +1 -1
  156. package/dist/esm/utils/validationUtils.js +5 -6
  157. package/dist/types/HttpService.d.ts +1 -1
  158. package/dist/types/api/accounts.d.ts +1 -1
  159. package/dist/types/api/apps.d.ts +4 -4
  160. package/dist/types/api/assets.d.ts +2 -0
  161. package/dist/types/api/auth.d.ts +8 -3
  162. package/dist/types/crypto/internal.d.ts +1 -1
  163. package/dist/types/index.d.ts +4 -4
  164. package/dist/types/server/index.d.ts +6 -6
  165. package/dist/types/server/requesterAssertion.d.ts +2 -2
  166. package/dist/types/server/workloadIdentity.client.d.ts +5 -1
  167. package/dist/types/server/workloadIdentity.d.ts +26 -0
  168. package/dist/types/session/accountDelegationAccess.d.ts +1 -1
  169. package/dist/types/session/index.d.ts +1 -1
  170. package/dist/types/utils/userIdentity.d.ts +1 -1
  171. package/dist/types/utils/validationUtils.d.ts +4 -5
  172. package/package.json +2 -3
  173. package/src/HttpService.ts +183 -53
  174. package/src/OxyServices.errors.ts +7 -3
  175. package/src/OxyServices.ts +6 -2
  176. package/src/api/accounts.ts +76 -26
  177. package/src/api/agency.ts +24 -9
  178. package/src/api/appData.ts +12 -2
  179. package/src/api/apps.ts +81 -31
  180. package/src/api/assets.ts +122 -40
  181. package/src/api/auth.ts +154 -79
  182. package/src/api/billing.ts +112 -65
  183. package/src/api/civic.ts +61 -19
  184. package/src/api/contacts.ts +4 -1
  185. package/src/api/devices.ts +54 -21
  186. package/src/api/follows.ts +88 -31
  187. package/src/api/identity.ts +101 -33
  188. package/src/api/linkedAccounts.ts +26 -8
  189. package/src/api/nodes.ts +18 -6
  190. package/src/api/notifications.ts +26 -6
  191. package/src/api/privacy.ts +42 -8
  192. package/src/api/reputation.ts +18 -7
  193. package/src/api/session.ts +23 -5
  194. package/src/api/store.ts +81 -31
  195. package/src/api/topics.ts +18 -6
  196. package/src/api/users.ts +98 -35
  197. package/src/boot/sessionColdBoot.ts +60 -19
  198. package/src/civic/payloads.ts +1 -4
  199. package/src/client/context.ts +6 -1
  200. package/src/constants/version.ts +7 -6
  201. package/src/crypto/aead.ts +1 -5
  202. package/src/crypto/ecdh.ts +1 -4
  203. package/src/crypto/identityDerivations.ts +5 -1
  204. package/src/crypto/identityMarker.ts +3 -1
  205. package/src/crypto/identityProof.ts +6 -1
  206. package/src/crypto/index.ts +11 -11
  207. package/src/crypto/internal.ts +6 -1
  208. package/src/crypto/keyManager.ts +348 -98
  209. package/src/crypto/recoveryPhrase.ts +14 -9
  210. package/src/crypto/registrationPow.ts +1 -1
  211. package/src/crypto/signatureService.ts +14 -6
  212. package/src/i18n/accountCategoryLabels.ts +1 -4
  213. package/src/i18n/accountRoleLabels.ts +1 -4
  214. package/src/i18n/index.ts +25 -7
  215. package/src/i18n/locales/ar-SA.ts +375 -366
  216. package/src/i18n/locales/ca-ES.ts +382 -366
  217. package/src/i18n/locales/de-DE.ts +387 -366
  218. package/src/i18n/locales/en-US.ts +2034 -1994
  219. package/src/i18n/locales/es-ES.ts +2043 -1994
  220. package/src/i18n/locales/fr-FR.ts +387 -366
  221. package/src/i18n/locales/it-IT.ts +380 -366
  222. package/src/i18n/locales/ja-JP.ts +380 -366
  223. package/src/i18n/locales/ko-KR.ts +377 -366
  224. package/src/i18n/locales/pt-PT.ts +383 -366
  225. package/src/i18n/locales/zh-CN.ts +373 -366
  226. package/src/i18n/trustTierLabels.ts +1 -4
  227. package/src/index.ts +371 -349
  228. package/src/inference/OxyInferenceClient.ts +784 -780
  229. package/src/models/interfaces.ts +30 -27
  230. package/src/server/OxyServer.ts +227 -68
  231. package/src/server/agentAccount.ts +8 -2
  232. package/src/server/aliaMachineCredential.ts +57 -16
  233. package/src/server/auth.ts +9 -5
  234. package/src/server/capabilityTicket.ts +30 -21
  235. package/src/server/index.ts +29 -6
  236. package/src/server/liveCapabilityTicket.ts +31 -9
  237. package/src/server/middleware.ts +212 -121
  238. package/src/server/namespaces.ts +247 -94
  239. package/src/server/rateLimit.ts +2 -4
  240. package/src/server/requesterAssertion.ts +93 -54
  241. package/src/server/serviceTokenLifetime.ts +9 -4
  242. package/src/server/traffic.ts +117 -23
  243. package/src/server/trafficNodeHttp.ts +61 -14
  244. package/src/server/userInvalidation.ts +1 -4
  245. package/src/server/workloadIdentity.client.ts +12 -1
  246. package/src/server/workloadIdentity.ts +52 -5
  247. package/src/session/SessionClient.ts +170 -49
  248. package/src/session/accountDelegationAccess.ts +24 -31
  249. package/src/session/accountDialogController.ts +59 -14
  250. package/src/session/accountSwitchTargets.ts +10 -15
  251. package/src/session/authStateStore.ts +121 -81
  252. package/src/session/deviceDirectory.ts +1 -3
  253. package/src/session/identityPin.ts +10 -11
  254. package/src/session/identitySession.ts +3 -1
  255. package/src/session/index.ts +87 -82
  256. package/src/session/refresh.ts +138 -44
  257. package/src/session/sessionClientHost.ts +1 -3
  258. package/src/session/sharedDeviceCredential.ts +35 -14
  259. package/src/session/socketLoader.ts +9 -2
  260. package/src/shared/utils/errorUtils.ts +5 -2
  261. package/src/shared/utils/networkUtils.ts +5 -8
  262. package/src/shared/utils/themeUtils.ts +2 -6
  263. package/src/types/buffer.d.ts +66 -21
  264. package/src/types/expo-secure-store.d.ts +5 -1
  265. package/src/utils/accountCacheSweep.ts +4 -5
  266. package/src/utils/accountUtils.ts +107 -108
  267. package/src/utils/apiUtils.ts +3 -3
  268. package/src/utils/asyncUtils.ts +2 -2
  269. package/src/utils/authHelpers.ts +10 -5
  270. package/src/utils/avatarUtils.ts +11 -6
  271. package/src/utils/cache.ts +9 -10
  272. package/src/utils/cacheKey.ts +5 -1
  273. package/src/utils/coldBoot.ts +1 -3
  274. package/src/utils/commonsDelivery.ts +1 -4
  275. package/src/utils/deviceManager.ts +15 -14
  276. package/src/utils/errorUtils.ts +68 -86
  277. package/src/utils/languageUtils.ts +407 -58
  278. package/src/utils/oauthPkce.ts +1 -4
  279. package/src/utils/platform.ts +0 -1
  280. package/src/utils/profileLinks.ts +2 -5
  281. package/src/utils/requestUtils.ts +18 -14
  282. package/src/utils/sessionUtils.ts +34 -33
  283. package/src/utils/userHandle.ts +3 -1
  284. package/src/utils/userIdentity.ts +1 -1
  285. package/src/utils/validationUtils.ts +11 -9
@@ -1,4 +1,9 @@
1
- import { personalPlanCheckoutRequestSchema, personalPlanCheckoutResultSchema, type PersonalPlanCheckoutRequest, type PersonalPlanCheckoutResult } from '@oxy.so/contracts';
1
+ import {
2
+ personalPlanCheckoutRequestSchema,
3
+ personalPlanCheckoutResultSchema,
4
+ type PersonalPlanCheckoutRequest,
5
+ type PersonalPlanCheckoutResult,
6
+ } from '@oxy.so/contracts';
2
7
  /**
3
8
  * `oxy.billing` — the signed-in user's subscription, wallet and payment history.
4
9
  *
@@ -11,15 +16,20 @@ import { personalPlanCheckoutRequestSchema, personalPlanCheckoutResultSchema, ty
11
16
  * arrive as ISO-8601 strings.
12
17
  */
13
18
  import { personalPlanCatalogueSchema, type PersonalPlanCatalogue } from '@oxy.so/contracts';
14
- import { type SubjectProductAccess,
15
- type SubjectProductAccessQuery,
16
- subjectProductAccessQuerySchema, subjectProductAccessSchema, } from '@oxy.so/contracts';
17
19
  import {
18
- type ProductSubscriptionSummary, type SubscriptionCreditGrant, type ProductSubscriptionCancellationResult,
20
+ type SubjectProductAccess,
21
+ type SubjectProductAccessQuery,
22
+ subjectProductAccessQuerySchema,
23
+ subjectProductAccessSchema,
24
+ } from '@oxy.so/contracts';
25
+ import {
26
+ type ProductSubscriptionSummary,
27
+ type SubscriptionCreditGrant,
28
+ type ProductSubscriptionCancellationResult,
19
29
  productSubscriptionCancellationResultSchema,
20
- cancelProductSubscriptionSchema,
21
- productSubscriptionsResponseSchema,
22
- subscriptionCreditGrantsResponseSchema,
30
+ cancelProductSubscriptionSchema,
31
+ productSubscriptionsResponseSchema,
32
+ subscriptionCreditGrantsResponseSchema,
23
33
  } from '@oxy.so/contracts';
24
34
  import type { OxyContext } from '../client/context';
25
35
 
@@ -117,76 +127,108 @@ export interface WalletTransactionsPage {
117
127
  export class BillingApi {
118
128
  constructor(protected readonly ctx: OxyContext) {}
119
129
 
120
- async startPersonalPlanCheckout(request: PersonalPlanCheckoutRequest): Promise<PersonalPlanCheckoutResult> {
121
- return personalPlanCheckoutResultSchema.parse(await this.ctx.request<unknown>('POST', '/billing/checkout/personal-plan',
122
- personalPlanCheckoutRequestSchema.parse(request), { cache: false }));
130
+ async startPersonalPlanCheckout(
131
+ request: PersonalPlanCheckoutRequest,
132
+ ): Promise<PersonalPlanCheckoutResult> {
133
+ return personalPlanCheckoutResultSchema.parse(
134
+ await this.ctx.request<unknown>(
135
+ 'POST',
136
+ '/billing/checkout/personal-plan',
137
+ personalPlanCheckoutRequestSchema.parse(request),
138
+ { cache: false },
139
+ ),
140
+ );
123
141
  }
124
142
 
125
143
  /** Public versioned personal plans. Discovery never proves customer access. */
126
144
  async personalPlans(): Promise<PersonalPlanCatalogue> {
127
- return personalPlanCatalogueSchema.parse(await this.ctx.request<unknown>(
128
- 'GET', '/billing/personal-plans', undefined, { cache: false }));
145
+ return personalPlanCatalogueSchema.parse(
146
+ await this.ctx.request<unknown>('GET', '/billing/personal-plans', undefined, {
147
+ cache: false,
148
+ }),
149
+ );
129
150
  }
130
151
 
131
152
  /** Product rights only; requires a production application-bound user session. Never cached. */
132
153
  async productAccess(query: SubjectProductAccessQuery): Promise<SubjectProductAccess> {
133
154
  const parsed = subjectProductAccessQuerySchema.parse(query);
134
- const response = await this.ctx.request<unknown>('GET',
155
+ const response = await this.ctx.request<unknown>(
156
+ 'GET',
135
157
  `/v1/products/${encodeURIComponent(parsed.productId)}/access/${encodeURIComponent(parsed.subjectAccountId)}`,
136
- undefined, { cache: false });
158
+ undefined,
159
+ { cache: false },
160
+ );
137
161
  return subjectProductAccessSchema.parse(response);
138
162
  }
139
163
 
140
- /** Named commercial sources for the current subject; no inferred plan collapse. */
141
- async productSubscriptions(expectedSubjectAccountId?: string): Promise<ProductSubscriptionSummary[]> {
142
- return productSubscriptionsResponseSchema.parse(
143
- await this.ctx.request<unknown>(
144
- "GET",
145
- expectedSubjectAccountId ? `/billing/product-subscriptions?expectedSubjectAccountId=${encodeURIComponent(expectedSubjectAccountId)}` : "/billing/product-subscriptions",
146
- undefined,
147
- { cache: false },
148
- ),
149
- ).subscriptions;
150
- }
151
-
152
- /** Per-grant credit provenance; no interpretation of the historical mixed balance. */
153
- async creditGrants(): Promise<SubscriptionCreditGrant[]> {
154
- return subscriptionCreditGrantsResponseSchema.parse(
155
- await this.ctx.request<unknown>(
156
- "GET",
157
- "/billing/credit-grants",
158
- undefined,
159
- { cache: false },
160
- ),
161
- ).grants;
162
- }
163
-
164
- /** Payer-only named-source cancellation. Resolves on provider acceptance, including pending local reconciliation. Use cancelProductSubscriptionWithStatus for detailed completion state. */
165
- async cancelProductSubscription(sourceId: string, expectedSubjectAccountId?: string, actionId?:string): Promise<void> {
166
- await this.ctx.request(
167
- "POST",
168
- "/billing/product-subscriptions/cancel",
169
- cancelProductSubscriptionSchema.parse({ sourceId, ...(actionId?{actionId}:{}), ...(expectedSubjectAccountId ? { expectedSubjectAccountId } : {}) }),
170
- { cache: false },
171
- );
172
- }
164
+ /** Named commercial sources for the current subject; no inferred plan collapse. */
165
+ async productSubscriptions(
166
+ expectedSubjectAccountId?: string,
167
+ ): Promise<ProductSubscriptionSummary[]> {
168
+ return productSubscriptionsResponseSchema.parse(
169
+ await this.ctx.request<unknown>(
170
+ 'GET',
171
+ expectedSubjectAccountId
172
+ ? `/billing/product-subscriptions?expectedSubjectAccountId=${encodeURIComponent(expectedSubjectAccountId)}`
173
+ : '/billing/product-subscriptions',
174
+ undefined,
175
+ { cache: false },
176
+ ),
177
+ ).subscriptions;
178
+ }
173
179
 
174
- /** Provider acceptance versus completed local cancellation, for user-facing flows. */
175
- async cancelProductSubscriptionWithStatus(sourceId: string, expectedSubjectAccountId?: string, actionId?:string): Promise<ProductSubscriptionCancellationResult> {
176
- return productSubscriptionCancellationResultSchema.parse(await this.ctx.request<unknown>(
177
- 'POST', '/billing/product-subscriptions/cancel',
178
- cancelProductSubscriptionSchema.parse({ sourceId, ...(actionId?{actionId}:{}), ...(expectedSubjectAccountId ? { expectedSubjectAccountId } : {}) }),
180
+ /** Per-grant credit provenance; no interpretation of the historical mixed balance. */
181
+ async creditGrants(): Promise<SubscriptionCreditGrant[]> {
182
+ return subscriptionCreditGrantsResponseSchema.parse(
183
+ await this.ctx.request<unknown>('GET', '/billing/credit-grants', undefined, { cache: false }),
184
+ ).grants;
185
+ }
186
+
187
+ /** Payer-only named-source cancellation. Resolves on provider acceptance, including pending local reconciliation. Use cancelProductSubscriptionWithStatus for detailed completion state. */
188
+ async cancelProductSubscription(
189
+ sourceId: string,
190
+ expectedSubjectAccountId?: string,
191
+ actionId?: string,
192
+ ): Promise<void> {
193
+ await this.ctx.request(
194
+ 'POST',
195
+ '/billing/product-subscriptions/cancel',
196
+ cancelProductSubscriptionSchema.parse({
197
+ sourceId,
198
+ ...(actionId ? { actionId } : {}),
199
+ ...(expectedSubjectAccountId ? { expectedSubjectAccountId } : {}),
200
+ }),
179
201
  { cache: false },
180
- ));
202
+ );
203
+ }
204
+
205
+ /** Provider acceptance versus completed local cancellation, for user-facing flows. */
206
+ async cancelProductSubscriptionWithStatus(
207
+ sourceId: string,
208
+ expectedSubjectAccountId?: string,
209
+ actionId?: string,
210
+ ): Promise<ProductSubscriptionCancellationResult> {
211
+ return productSubscriptionCancellationResultSchema.parse(
212
+ await this.ctx.request<unknown>(
213
+ 'POST',
214
+ '/billing/product-subscriptions/cancel',
215
+ cancelProductSubscriptionSchema.parse({
216
+ sourceId,
217
+ ...(actionId ? { actionId } : {}),
218
+ ...(expectedSubjectAccountId ? { expectedSubjectAccountId } : {}),
219
+ }),
220
+ { cache: false },
221
+ ),
222
+ );
181
223
  }
182
224
 
183
- /** The signed-in user's payment history. Never cached. */
184
- async payments(): Promise<Payment[]> {
225
+ /** The signed-in user's payment history. Never cached. */
226
+ async payments(): Promise<Payment[]> {
185
227
  return this.ctx.request<Payment[]>('GET', '/payments/user', undefined, { cache: false });
186
228
  }
187
229
 
188
- /** A user's subscription (default: the signed-in user's). */
189
- async subscription(userId?: string): Promise<Subscription> {
230
+ /** A user's subscription (default: the signed-in user's). */
231
+ async subscription(userId?: string): Promise<Subscription> {
190
232
  const id = this.resolveUserId(userId);
191
233
  return this.ctx.request<Subscription>('GET', `/subscription/${id}`, undefined, {
192
234
  cache: true,
@@ -194,24 +236,29 @@ export class BillingApi {
194
236
  });
195
237
  }
196
238
 
197
- /** A user's wallet (default: the signed-in user's). Cached briefly: the balance moves. */
198
- async wallet(userId?: string): Promise<Wallet> {
239
+ /** A user's wallet (default: the signed-in user's). Cached briefly: the balance moves. */
240
+ async wallet(userId?: string): Promise<Wallet> {
199
241
  const id = this.resolveUserId(userId);
200
- return this.ctx.request<Wallet>('GET', `/wallet/${id}`, undefined, { cache: true, cacheTTL: WALLET_TTL });
242
+ return this.ctx.request<Wallet>('GET', `/wallet/${id}`, undefined, {
243
+ cache: true,
244
+ cacheTTL: WALLET_TTL,
245
+ });
201
246
  }
202
247
 
203
- /** A page of a user's wallet transactions (default: the signed-in user's). Never cached. */
204
- async walletTransactions(
248
+ /** A page of a user's wallet transactions (default: the signed-in user's). Never cached. */
249
+ async walletTransactions(
205
250
  options: { userId?: string; limit?: number; offset?: number } = {},
206
251
  ): Promise<WalletTransactionsPage> {
207
252
  const id = this.resolveUserId(options.userId);
208
253
  const params: Record<string, number> = {};
209
254
  if (options.limit) params.limit = options.limit;
210
255
  if (options.offset) params.offset = options.offset;
211
- return this.ctx.request<WalletTransactionsPage>('GET', `/wallet/transactions/${id}`, params, { cache: false });
256
+ return this.ctx.request<WalletTransactionsPage>('GET', `/wallet/transactions/${id}`, params, {
257
+ cache: false,
258
+ });
212
259
  }
213
260
 
214
- private resolveUserId(userId?: string): string {
261
+ private resolveUserId(userId?: string): string {
215
262
  const id = userId || this.ctx.oxy.session.userId;
216
263
  if (!id) throw new Error('User not authenticated');
217
264
  return id;
package/src/api/civic.ts CHANGED
@@ -162,10 +162,15 @@ export class CivicApi {
162
162
  * reject — it yields `verified: false`.
163
163
  */
164
164
  async publicCard(userId: string): Promise<CivicCardResult> {
165
- const signed = await this.ctx.request<SignedPublicCard>('GET', `/civic/${encodeURIComponent(userId)}/card`, undefined, {
166
- cache: true,
167
- cacheTTL: SHORT_TTL,
168
- });
165
+ const signed = await this.ctx.request<SignedPublicCard>(
166
+ 'GET',
167
+ `/civic/${encodeURIComponent(userId)}/card`,
168
+ undefined,
169
+ {
170
+ cache: true,
171
+ cacheTTL: SHORT_TTL,
172
+ },
173
+ );
169
174
  const verified = await verifyPublicCardAttestation(signed.card, signed.attestation);
170
175
  return { card: signed.card, attestation: signed.attestation, verified };
171
176
  }
@@ -219,7 +224,9 @@ export class CivicApi {
219
224
  },
220
225
  { collection: ATTEST_COLLECTION, rkey: input.nonce },
221
226
  );
222
- return this.ctx.request<RealLifeAttestationResult>('POST', '/civic/attestations', envelope, { cache: false });
227
+ return this.ctx.request<RealLifeAttestationResult>('POST', '/civic/attestations', envelope, {
228
+ cache: false,
229
+ });
223
230
  }
224
231
 
225
232
  /**
@@ -240,7 +247,12 @@ export class CivicApi {
240
247
  },
241
248
  { collection: VOUCH_COLLECTION, rkey: input.subjectDid },
242
249
  );
243
- const result = await this.ctx.request<VouchResult>('POST', '/civic/personhood/vouch', envelope, { cache: false });
250
+ const result = await this.ctx.request<VouchResult>(
251
+ 'POST',
252
+ '/civic/personhood/vouch',
253
+ envelope,
254
+ { cache: false },
255
+ );
244
256
  this.sweepPersonhood();
245
257
  return result;
246
258
  }
@@ -268,10 +280,15 @@ export class CivicApi {
268
280
  */
269
281
  async personhood(userId?: string): Promise<PersonhoodStatusResult> {
270
282
  const id = userId ?? this.myUserId('resolve personhood status');
271
- return this.ctx.request<PersonhoodStatusResult>('GET', `/civic/personhood/${encodeURIComponent(id)}`, undefined, {
272
- cache: true,
273
- cacheTTL: SHORT_TTL,
274
- });
283
+ return this.ctx.request<PersonhoodStatusResult>(
284
+ 'GET',
285
+ `/civic/personhood/${encodeURIComponent(id)}`,
286
+ undefined,
287
+ {
288
+ cache: true,
289
+ cacheTTL: SHORT_TTL,
290
+ },
291
+ );
275
292
  }
276
293
 
277
294
  /** A vouch / withdraw changes personhood reads and (via `verified`) `/users/me`. */
@@ -298,9 +315,14 @@ export class CivicValidationApi {
298
315
 
299
316
  /** The signed-in user's pending jury duties. Never cached; `[]` when on no juries. */
300
317
  async inbox(): Promise<ValidationRequestSummary[]> {
301
- const res = await this.ctx.request<{ requests?: ValidationRequestSummary[] }>('GET', '/civic/validations/inbox', undefined, {
302
- cache: false,
303
- });
318
+ const res = await this.ctx.request<{ requests?: ValidationRequestSummary[] }>(
319
+ 'GET',
320
+ '/civic/validations/inbox',
321
+ undefined,
322
+ {
323
+ cache: false,
324
+ },
325
+ );
304
326
  return res.requests ?? [];
305
327
  }
306
328
 
@@ -311,7 +333,11 @@ export class CivicValidationApi {
311
333
  *
312
334
  * @param payloadHash - The request's canonical payload hash (from the inbox).
313
335
  */
314
- async vote(requestId: string, payloadHash: string, verdict: ValidationVerdict): Promise<ValidationVoteResult> {
336
+ async vote(
337
+ requestId: string,
338
+ payloadHash: string,
339
+ verdict: ValidationVerdict,
340
+ ): Promise<ValidationVoteResult> {
315
341
  const envelope = await signOwnChainRecord(
316
342
  this.ctx,
317
343
  'validation_verdict',
@@ -348,7 +374,9 @@ export class CivicCredentialsApi {
348
374
  * base type; an `expiresAt` ISO string becomes epoch ms. NATIVE-ONLY.
349
375
  */
350
376
  async issue(input: IssueCredentialInput): Promise<CredentialIssueResult> {
351
- const types = input.types.includes(CREDENTIAL_BASE_TYPE) ? input.types : [CREDENTIAL_BASE_TYPE, ...input.types];
377
+ const types = input.types.includes(CREDENTIAL_BASE_TYPE)
378
+ ? input.types
379
+ : [CREDENTIAL_BASE_TYPE, ...input.types];
352
380
 
353
381
  let expiresAtMs: number | undefined;
354
382
  if (input.expiresAt !== undefined) {
@@ -369,8 +397,16 @@ export class CivicCredentialsApi {
369
397
  // A fresh crypto-random rkey: every credential is its own chain entry.
370
398
  const { SignatureService } = await import('../crypto/internal');
371
399
  const rkey = await SignatureService.generateChallenge();
372
- const envelope = await signOwnChainRecord(this.ctx, 'credential', record, { collection: CREDENTIAL_COLLECTION, rkey });
373
- const result = await this.ctx.request<CredentialIssueResult>('POST', '/civic/credentials', envelope, { cache: false });
400
+ const envelope = await signOwnChainRecord(this.ctx, 'credential', record, {
401
+ collection: CREDENTIAL_COLLECTION,
402
+ rkey,
403
+ });
404
+ const result = await this.ctx.request<CredentialIssueResult>(
405
+ 'POST',
406
+ '/civic/credentials',
407
+ envelope,
408
+ { cache: false },
409
+ );
374
410
  this.sweep();
375
411
  return result;
376
412
  }
@@ -381,14 +417,20 @@ export class CivicCredentialsApi {
381
417
  *
382
418
  * @param holderUserId - The holder's account id (NOT a DID).
383
419
  */
384
- async list(holderUserId?: string, opts: { status?: CredentialStatus } = {}): Promise<CredentialListResult> {
420
+ async list(
421
+ holderUserId?: string,
422
+ opts: { status?: CredentialStatus } = {},
423
+ ): Promise<CredentialListResult> {
385
424
  const holder = holderUserId ?? this.ctx.oxy.session.userId;
386
425
  if (!holder) {
387
426
  throw new Error('No authenticated user — cannot list credentials.');
388
427
  }
389
428
  const base = `/civic/credentials/${encodeURIComponent(holder)}`;
390
429
  const url = opts.status ? `${base}?status=${encodeURIComponent(opts.status)}` : base;
391
- return this.ctx.request<CredentialListResult>('GET', url, undefined, { cache: true, cacheTTL: SHORT_TTL });
430
+ return this.ctx.request<CredentialListResult>('GET', url, undefined, {
431
+ cache: true,
432
+ cacheTTL: SHORT_TTL,
433
+ });
392
434
  }
393
435
 
394
436
  /**
@@ -30,7 +30,10 @@ export class ContactsApi {
30
30
  * Which of these hashed contacts are on Oxy. Either list may be empty, not
31
31
  * both; at most 200 hashes per list per call (batch larger books).
32
32
  */
33
- async discover(hashedEmails: string[], hashedPhones: string[]): Promise<ContactDiscoveryResponse> {
33
+ async discover(
34
+ hashedEmails: string[],
35
+ hashedPhones: string[],
36
+ ): Promise<ContactDiscoveryResponse> {
34
37
  return this.ctx.request<ContactDiscoveryResponse>(
35
38
  'POST',
36
39
  '/contacts/discover',
@@ -57,7 +57,6 @@ export interface SecurityInfo {
57
57
  recoveryEmail: string | null;
58
58
  }
59
59
 
60
-
61
60
  /**
62
61
  * The server's `401 account_not_on_device` for a PINNED mint: the requested
63
62
  * `accountId` is not (or is no longer) a live account of this device session.
@@ -72,10 +71,11 @@ export class AccountNotOnDeviceError extends Error {
72
71
  override readonly name = 'AccountNotOnDeviceError';
73
72
  /** HTTP status of the originating response; mirrors the ApiError shape. */
74
73
  readonly status = 401;
75
- constructor(readonly accountId: string, readonly cause?: unknown) {
76
- super(
77
- `account_not_on_device: ${accountId} is not a live account of this device session`,
78
- );
74
+ constructor(
75
+ readonly accountId: string,
76
+ readonly cause?: unknown,
77
+ ) {
78
+ super(`account_not_on_device: ${accountId} is not a live account of this device session`);
79
79
  }
80
80
  }
81
81
 
@@ -94,7 +94,6 @@ function isAccountNotOnDevice(error: unknown): boolean {
94
94
  return typeof message === 'string' && message.includes('account_not_on_device');
95
95
  }
96
96
 
97
-
98
97
  /**
99
98
  * The bridge calls share their transport rules with the mint: no bearer
100
99
  * (`skipAuth`, so a 401 surfaces directly), one attempt, and never parked
@@ -148,10 +147,15 @@ export class DevicesApi {
148
147
  */
149
148
  async sessions(sessionId: string): Promise<DeviceLinkedSession[]> {
150
149
  // Cache disabled by default to ensure fresh session data
151
- return this.ctx.request<DeviceLinkedSession[]>('GET', `/session/device/sessions/${sessionId}`, undefined, {
152
- cache: false, // Don't cache sessions - always get fresh data
153
- deduplicate: true, // Deduplicate concurrent requests for same sessionId
154
- });
150
+ return this.ctx.request<DeviceLinkedSession[]>(
151
+ 'GET',
152
+ `/session/device/sessions/${sessionId}`,
153
+ undefined,
154
+ {
155
+ cache: false, // Don't cache sessions - always get fresh data
156
+ deduplicate: true, // Deduplicate concurrent requests for same sessionId
157
+ },
158
+ );
155
159
  }
156
160
 
157
161
  /**
@@ -161,11 +165,20 @@ export class DevicesApi {
161
165
  * @param excludeCurrent - Whether to exclude the current session
162
166
  * @returns Logout result
163
167
  */
164
- async logoutAll(sessionId: string, deviceId?: string, excludeCurrent?: boolean): Promise<DeviceLinkedSessionLogoutResponse> {
168
+ async logoutAll(
169
+ sessionId: string,
170
+ deviceId?: string,
171
+ excludeCurrent?: boolean,
172
+ ): Promise<DeviceLinkedSessionLogoutResponse> {
165
173
  const urlParams: Record<string, string> = {};
166
174
  if (deviceId) urlParams.deviceId = deviceId;
167
175
  if (excludeCurrent) urlParams.excludeCurrent = 'true';
168
- return this.ctx.request<DeviceLinkedSessionLogoutResponse>('POST', `/session/device/logout-all/${sessionId}`, urlParams, { cache: false });
176
+ return this.ctx.request<DeviceLinkedSessionLogoutResponse>(
177
+ 'POST',
178
+ `/session/device/logout-all/${sessionId}`,
179
+ urlParams,
180
+ { cache: false },
181
+ );
169
182
  }
170
183
 
171
184
  /**
@@ -174,8 +187,16 @@ export class DevicesApi {
174
187
  * @param deviceName - New device name
175
188
  * @returns Updated device object
176
189
  */
177
- async rename(sessionId: string, deviceName: string): Promise<{ success: boolean; message: string; deviceName: string }> {
178
- return this.ctx.request('PUT', `/session/device/name/${sessionId}`, { deviceName }, { cache: false });
190
+ async rename(
191
+ sessionId: string,
192
+ deviceName: string,
193
+ ): Promise<{ success: boolean; message: string; deviceName: string }> {
194
+ return this.ctx.request(
195
+ 'PUT',
196
+ `/session/device/name/${sessionId}`,
197
+ { deviceName },
198
+ { cache: false },
199
+ );
179
200
  }
180
201
 
181
202
  /**
@@ -198,7 +219,7 @@ export class DevicesApi {
198
219
  async securityActivity(
199
220
  limit?: number,
200
221
  offset?: number,
201
- eventType?: SecurityEventType
222
+ eventType?: SecurityEventType,
202
223
  ): Promise<SecurityActivityResponse> {
203
224
  const params: Record<string, unknown> = {};
204
225
  if (limit !== undefined) params.limit = limit;
@@ -236,12 +257,16 @@ export class DevicesApi {
236
257
  'POST',
237
258
  '/security/activity/private-key-exported',
238
259
  { deviceId },
239
- { cache: false }
260
+ { cache: false },
240
261
  );
241
262
  } catch (error) {
242
263
  // Don't throw - logging failures shouldn't break user flow, but surface
243
264
  // for monitoring via the shared logger sink.
244
- logger.warn('[OxyServices] Failed to log private key exported event', { component: 'oxy.devices' }, error);
265
+ logger.warn(
266
+ '[OxyServices] Failed to log private key exported event',
267
+ { component: 'oxy.devices' },
268
+ error,
269
+ );
245
270
  }
246
271
  }
247
272
 
@@ -256,12 +281,16 @@ export class DevicesApi {
256
281
  'POST',
257
282
  '/security/activity/backup-created',
258
283
  { deviceId },
259
- { cache: false }
284
+ { cache: false },
260
285
  );
261
286
  } catch (error) {
262
287
  // Don't throw - logging failures shouldn't break user flow, but surface
263
288
  // for monitoring via the shared logger sink.
264
- logger.warn('[OxyServices] Failed to log backup created event', { component: 'oxy.devices' }, error);
289
+ logger.warn(
290
+ '[OxyServices] Failed to log backup created event',
291
+ { component: 'oxy.devices' },
292
+ error,
293
+ );
265
294
  }
266
295
  }
267
296
 
@@ -347,7 +376,12 @@ export class DevicesApi {
347
376
  * carries `invalid_device_secret`.
348
377
  */
349
378
  async requestJoinCode(request: DeviceJoinCodeRequest): Promise<DeviceJoinCodeResponse> {
350
- return bridgeRequest(this.ctx, '/session/device/join-code', request, deviceJoinCodeResponseSchema);
379
+ return bridgeRequest(
380
+ this.ctx,
381
+ '/session/device/join-code',
382
+ request,
383
+ deviceJoinCodeResponseSchema,
384
+ );
351
385
  }
352
386
 
353
387
  /**
@@ -434,5 +468,4 @@ export class DevicesApi {
434
468
  throw error;
435
469
  }
436
470
  }
437
-
438
471
  }