@oxy.so/core 4.5.0-oxy-one.1 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cjs/HttpService.js +63 -19
- package/dist/cjs/api/accounts.js +10 -3
- package/dist/cjs/api/agency.js +3 -1
- package/dist/cjs/api/apps.js +15 -4
- package/dist/cjs/api/assets.js +39 -11
- package/dist/cjs/api/auth.js +28 -8
- package/dist/cjs/api/billing.js +24 -7
- package/dist/cjs/api/civic.js +14 -4
- package/dist/cjs/api/follows.js +9 -2
- package/dist/cjs/api/identity.js +31 -9
- package/dist/cjs/api/nodes.js +3 -1
- package/dist/cjs/api/privacy.js +8 -2
- package/dist/cjs/api/session.js +15 -4
- package/dist/cjs/api/store.js +15 -5
- package/dist/cjs/api/topics.js +10 -3
- package/dist/cjs/api/users.js +16 -4
- package/dist/cjs/boot/sessionColdBoot.js +40 -13
- package/dist/cjs/constants/version.js +6 -6
- package/dist/cjs/crypto/identityMarker.js +3 -1
- package/dist/cjs/crypto/identityProof.js +6 -1
- package/dist/cjs/crypto/keyManager.js +87 -32
- package/dist/cjs/crypto/recoveryPhrase.js +2 -2
- package/dist/cjs/crypto/signatureService.js +3 -4
- package/dist/cjs/i18n/index.js +16 -3
- package/dist/cjs/i18n/locales/ar-SA.js +366 -366
- package/dist/cjs/i18n/locales/ca-ES.js +366 -366
- package/dist/cjs/i18n/locales/de-DE.js +366 -366
- package/dist/cjs/i18n/locales/en-US.js +1994 -1994
- package/dist/cjs/i18n/locales/es-ES.js +1994 -1994
- package/dist/cjs/i18n/locales/fr-FR.js +366 -366
- package/dist/cjs/i18n/locales/it-IT.js +366 -366
- package/dist/cjs/i18n/locales/ja-JP.js +366 -366
- package/dist/cjs/i18n/locales/ko-KR.js +366 -366
- package/dist/cjs/i18n/locales/pt-PT.js +366 -366
- package/dist/cjs/i18n/locales/zh-CN.js +366 -366
- package/dist/cjs/inference/OxyInferenceClient.js +12 -18
- package/dist/cjs/models/interfaces.js +11 -11
- package/dist/cjs/server/OxyServer.js +86 -28
- package/dist/cjs/server/agentAccount.js +6 -2
- package/dist/cjs/server/aliaMachineCredential.js +39 -14
- package/dist/cjs/server/auth.js +5 -4
- package/dist/cjs/server/capabilityTicket.js +5 -5
- package/dist/cjs/server/index.js +2 -1
- package/dist/cjs/server/liveCapabilityTicket.js +4 -1
- package/dist/cjs/server/middleware.js +61 -42
- package/dist/cjs/server/namespaces.js +28 -7
- package/dist/cjs/server/requesterAssertion.js +36 -30
- package/dist/cjs/server/serviceTokenLifetime.js +7 -4
- package/dist/cjs/server/traffic.js +53 -14
- package/dist/cjs/server/trafficNodeHttp.js +33 -8
- package/dist/cjs/server/workloadIdentity.client.js +4 -0
- package/dist/cjs/server/workloadIdentity.js +28 -1
- package/dist/cjs/session/SessionClient.js +54 -17
- package/dist/cjs/session/accountDelegationAccess.js +4 -6
- package/dist/cjs/session/accountDialogController.js +1 -1
- package/dist/cjs/session/authStateStore.js +18 -9
- package/dist/cjs/session/identityPin.js +6 -2
- package/dist/cjs/session/refresh.js +81 -23
- package/dist/cjs/session/sharedDeviceCredential.js +28 -15
- package/dist/cjs/shared/utils/errorUtils.js +1 -1
- package/dist/cjs/shared/utils/networkUtils.js +1 -1
- package/dist/cjs/shared/utils/themeUtils.js +1 -1
- package/dist/cjs/utils/accountCacheSweep.js +3 -1
- package/dist/cjs/utils/accountUtils.js +1 -3
- package/dist/cjs/utils/asyncUtils.js +1 -1
- package/dist/cjs/utils/authHelpers.js +2 -1
- package/dist/cjs/utils/avatarUtils.js +4 -2
- package/dist/cjs/utils/cache.js +1 -1
- package/dist/cjs/utils/cacheKey.js +3 -1
- package/dist/cjs/utils/deviceManager.js +4 -4
- package/dist/cjs/utils/errorUtils.js +6 -4
- package/dist/cjs/utils/languageUtils.js +404 -57
- package/dist/cjs/utils/profileLinks.js +1 -3
- package/dist/cjs/utils/requestUtils.js +7 -1
- package/dist/cjs/utils/userIdentity.js +1 -1
- package/dist/cjs/utils/validationUtils.js +5 -6
- package/dist/esm/HttpService.js +64 -20
- package/dist/esm/api/accounts.js +11 -4
- package/dist/esm/api/agency.js +3 -1
- package/dist/esm/api/apps.js +15 -4
- package/dist/esm/api/assets.js +39 -11
- package/dist/esm/api/auth.js +28 -8
- package/dist/esm/api/billing.js +25 -8
- package/dist/esm/api/civic.js +14 -4
- package/dist/esm/api/follows.js +9 -2
- package/dist/esm/api/identity.js +31 -9
- package/dist/esm/api/nodes.js +3 -1
- package/dist/esm/api/privacy.js +8 -2
- package/dist/esm/api/session.js +15 -4
- package/dist/esm/api/store.js +15 -5
- package/dist/esm/api/topics.js +10 -3
- package/dist/esm/api/users.js +16 -4
- package/dist/esm/boot/sessionColdBoot.js +41 -14
- package/dist/esm/constants/version.js +6 -6
- package/dist/esm/crypto/identityMarker.js +3 -1
- package/dist/esm/crypto/identityProof.js +6 -1
- package/dist/esm/crypto/internal.js +1 -1
- package/dist/esm/crypto/keyManager.js +87 -32
- package/dist/esm/crypto/recoveryPhrase.js +2 -2
- package/dist/esm/crypto/signatureService.js +3 -4
- package/dist/esm/i18n/index.js +16 -3
- package/dist/esm/i18n/locales/ar-SA.js +366 -366
- package/dist/esm/i18n/locales/ca-ES.js +366 -366
- package/dist/esm/i18n/locales/de-DE.js +366 -366
- package/dist/esm/i18n/locales/en-US.js +1994 -1994
- package/dist/esm/i18n/locales/es-ES.js +1994 -1994
- package/dist/esm/i18n/locales/fr-FR.js +366 -366
- package/dist/esm/i18n/locales/it-IT.js +366 -366
- package/dist/esm/i18n/locales/ja-JP.js +366 -366
- package/dist/esm/i18n/locales/ko-KR.js +366 -366
- package/dist/esm/i18n/locales/pt-PT.js +366 -366
- package/dist/esm/i18n/locales/zh-CN.js +366 -366
- package/dist/esm/index.js +1 -1
- package/dist/esm/inference/OxyInferenceClient.js +13 -19
- package/dist/esm/models/interfaces.js +11 -11
- package/dist/esm/server/OxyServer.js +87 -29
- package/dist/esm/server/agentAccount.js +6 -2
- package/dist/esm/server/aliaMachineCredential.js +39 -14
- package/dist/esm/server/auth.js +6 -5
- package/dist/esm/server/capabilityTicket.js +6 -6
- package/dist/esm/server/index.js +5 -5
- package/dist/esm/server/liveCapabilityTicket.js +6 -3
- package/dist/esm/server/middleware.js +62 -43
- package/dist/esm/server/namespaces.js +31 -10
- package/dist/esm/server/requesterAssertion.js +36 -30
- package/dist/esm/server/serviceTokenLifetime.js +7 -4
- package/dist/esm/server/traffic.js +55 -16
- package/dist/esm/server/trafficNodeHttp.js +34 -9
- package/dist/esm/server/userInvalidation.js +1 -1
- package/dist/esm/server/workloadIdentity.client.js +3 -0
- package/dist/esm/server/workloadIdentity.js +27 -1
- package/dist/esm/session/SessionClient.js +54 -17
- package/dist/esm/session/accountDelegationAccess.js +5 -7
- package/dist/esm/session/accountDialogController.js +1 -1
- package/dist/esm/session/authStateStore.js +18 -9
- package/dist/esm/session/identityPin.js +6 -2
- package/dist/esm/session/refresh.js +82 -24
- package/dist/esm/session/sharedDeviceCredential.js +28 -15
- package/dist/esm/shared/utils/errorUtils.js +1 -1
- package/dist/esm/shared/utils/networkUtils.js +1 -1
- package/dist/esm/shared/utils/themeUtils.js +1 -1
- package/dist/esm/utils/accountCacheSweep.js +3 -1
- package/dist/esm/utils/accountUtils.js +1 -3
- package/dist/esm/utils/asyncUtils.js +1 -1
- package/dist/esm/utils/authHelpers.js +2 -1
- package/dist/esm/utils/avatarUtils.js +4 -2
- package/dist/esm/utils/cache.js +1 -1
- package/dist/esm/utils/cacheKey.js +3 -1
- package/dist/esm/utils/deviceManager.js +4 -4
- package/dist/esm/utils/errorUtils.js +6 -4
- package/dist/esm/utils/languageUtils.js +404 -57
- package/dist/esm/utils/profileLinks.js +1 -3
- package/dist/esm/utils/requestUtils.js +7 -1
- package/dist/esm/utils/userIdentity.js +1 -1
- package/dist/esm/utils/validationUtils.js +5 -6
- package/dist/types/HttpService.d.ts +1 -1
- package/dist/types/api/accounts.d.ts +16 -3
- package/dist/types/api/apps.d.ts +4 -4
- package/dist/types/crypto/internal.d.ts +1 -1
- package/dist/types/index.d.ts +4 -4
- package/dist/types/models/interfaces.d.ts +9 -1
- package/dist/types/server/index.d.ts +6 -6
- package/dist/types/server/workloadIdentity.client.d.ts +5 -1
- package/dist/types/server/workloadIdentity.d.ts +26 -0
- package/dist/types/session/accountDelegationAccess.d.ts +1 -1
- package/dist/types/session/index.d.ts +1 -1
- package/dist/types/utils/userIdentity.d.ts +1 -1
- package/dist/types/utils/validationUtils.d.ts +4 -5
- package/package.json +3 -4
- package/src/HttpService.ts +183 -53
- package/src/OxyServices.errors.ts +7 -3
- package/src/OxyServices.ts +6 -2
- package/src/api/accounts.ts +96 -28
- package/src/api/agency.ts +24 -9
- package/src/api/appData.ts +12 -2
- package/src/api/apps.ts +81 -31
- package/src/api/assets.ts +113 -43
- package/src/api/auth.ts +145 -77
- package/src/api/billing.ts +112 -65
- package/src/api/civic.ts +61 -19
- package/src/api/contacts.ts +4 -1
- package/src/api/devices.ts +54 -21
- package/src/api/follows.ts +88 -31
- package/src/api/identity.ts +101 -33
- package/src/api/linkedAccounts.ts +26 -8
- package/src/api/nodes.ts +18 -6
- package/src/api/notifications.ts +26 -6
- package/src/api/privacy.ts +42 -8
- package/src/api/reputation.ts +18 -7
- package/src/api/session.ts +23 -5
- package/src/api/store.ts +81 -31
- package/src/api/topics.ts +18 -6
- package/src/api/users.ts +98 -35
- package/src/boot/sessionColdBoot.ts +60 -19
- package/src/civic/payloads.ts +1 -4
- package/src/client/context.ts +6 -1
- package/src/constants/version.ts +7 -6
- package/src/crypto/aead.ts +1 -5
- package/src/crypto/ecdh.ts +1 -4
- package/src/crypto/identityDerivations.ts +5 -1
- package/src/crypto/identityMarker.ts +3 -1
- package/src/crypto/identityProof.ts +6 -1
- package/src/crypto/index.ts +11 -11
- package/src/crypto/internal.ts +6 -1
- package/src/crypto/keyManager.ts +348 -98
- package/src/crypto/recoveryPhrase.ts +14 -9
- package/src/crypto/registrationPow.ts +1 -1
- package/src/crypto/signatureService.ts +14 -6
- package/src/i18n/accountCategoryLabels.ts +1 -4
- package/src/i18n/accountRoleLabels.ts +1 -4
- package/src/i18n/index.ts +25 -7
- package/src/i18n/locales/ar-SA.ts +375 -366
- package/src/i18n/locales/ca-ES.ts +382 -366
- package/src/i18n/locales/de-DE.ts +387 -366
- package/src/i18n/locales/en-US.ts +2034 -1994
- package/src/i18n/locales/es-ES.ts +2043 -1994
- package/src/i18n/locales/fr-FR.ts +387 -366
- package/src/i18n/locales/it-IT.ts +380 -366
- package/src/i18n/locales/ja-JP.ts +380 -366
- package/src/i18n/locales/ko-KR.ts +377 -366
- package/src/i18n/locales/pt-PT.ts +383 -366
- package/src/i18n/locales/zh-CN.ts +373 -366
- package/src/i18n/trustTierLabels.ts +1 -4
- package/src/index.ts +371 -349
- package/src/inference/OxyInferenceClient.ts +784 -780
- package/src/models/interfaces.ts +39 -27
- package/src/server/OxyServer.ts +227 -68
- package/src/server/agentAccount.ts +8 -2
- package/src/server/aliaMachineCredential.ts +57 -16
- package/src/server/auth.ts +9 -5
- package/src/server/capabilityTicket.ts +30 -21
- package/src/server/index.ts +29 -6
- package/src/server/liveCapabilityTicket.ts +31 -9
- package/src/server/middleware.ts +212 -121
- package/src/server/namespaces.ts +247 -94
- package/src/server/rateLimit.ts +2 -4
- package/src/server/requesterAssertion.ts +93 -54
- package/src/server/serviceTokenLifetime.ts +9 -4
- package/src/server/traffic.ts +117 -23
- package/src/server/trafficNodeHttp.ts +61 -14
- package/src/server/userInvalidation.ts +1 -4
- package/src/server/workloadIdentity.client.ts +12 -1
- package/src/server/workloadIdentity.ts +52 -5
- package/src/session/SessionClient.ts +170 -49
- package/src/session/accountDelegationAccess.ts +24 -31
- package/src/session/accountDialogController.ts +59 -14
- package/src/session/accountSwitchTargets.ts +10 -15
- package/src/session/authStateStore.ts +121 -81
- package/src/session/deviceDirectory.ts +1 -3
- package/src/session/identityPin.ts +10 -11
- package/src/session/identitySession.ts +3 -1
- package/src/session/index.ts +87 -82
- package/src/session/refresh.ts +138 -44
- package/src/session/sessionClientHost.ts +1 -3
- package/src/session/sharedDeviceCredential.ts +35 -14
- package/src/session/socketLoader.ts +9 -2
- package/src/shared/utils/errorUtils.ts +5 -2
- package/src/shared/utils/networkUtils.ts +5 -8
- package/src/shared/utils/themeUtils.ts +2 -6
- package/src/types/buffer.d.ts +66 -21
- package/src/types/expo-secure-store.d.ts +5 -1
- package/src/utils/accountCacheSweep.ts +4 -5
- package/src/utils/accountUtils.ts +107 -108
- package/src/utils/apiUtils.ts +3 -3
- package/src/utils/asyncUtils.ts +2 -2
- package/src/utils/authHelpers.ts +10 -5
- package/src/utils/avatarUtils.ts +11 -6
- package/src/utils/cache.ts +9 -10
- package/src/utils/cacheKey.ts +5 -1
- package/src/utils/coldBoot.ts +1 -3
- package/src/utils/commonsDelivery.ts +1 -4
- package/src/utils/deviceManager.ts +15 -14
- package/src/utils/errorUtils.ts +68 -86
- package/src/utils/languageUtils.ts +407 -58
- package/src/utils/oauthPkce.ts +1 -4
- package/src/utils/platform.ts +0 -1
- package/src/utils/profileLinks.ts +2 -5
- package/src/utils/requestUtils.ts +18 -14
- package/src/utils/sessionUtils.ts +34 -33
- package/src/utils/userHandle.ts +3 -1
- package/src/utils/userIdentity.ts +1 -1
- package/src/utils/validationUtils.ts +11 -9
package/src/api/billing.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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(
|
|
121
|
-
|
|
122
|
-
|
|
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(
|
|
128
|
-
'GET', '/billing/personal-plans', undefined, {
|
|
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>(
|
|
155
|
+
const response = await this.ctx.request<unknown>(
|
|
156
|
+
'GET',
|
|
135
157
|
`/v1/products/${encodeURIComponent(parsed.productId)}/access/${encodeURIComponent(parsed.subjectAccountId)}`,
|
|
136
|
-
undefined,
|
|
158
|
+
undefined,
|
|
159
|
+
{ cache: false },
|
|
160
|
+
);
|
|
137
161
|
return subjectProductAccessSchema.parse(response);
|
|
138
162
|
}
|
|
139
163
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
-
/**
|
|
175
|
-
async
|
|
176
|
-
return
|
|
177
|
-
'
|
|
178
|
-
|
|
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
|
-
|
|
184
|
-
|
|
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
|
-
|
|
189
|
-
|
|
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
|
-
|
|
198
|
-
|
|
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, {
|
|
242
|
+
return this.ctx.request<Wallet>('GET', `/wallet/${id}`, undefined, {
|
|
243
|
+
cache: true,
|
|
244
|
+
cacheTTL: WALLET_TTL,
|
|
245
|
+
});
|
|
201
246
|
}
|
|
202
247
|
|
|
203
|
-
|
|
204
|
-
|
|
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, {
|
|
256
|
+
return this.ctx.request<WalletTransactionsPage>('GET', `/wallet/transactions/${id}`, params, {
|
|
257
|
+
cache: false,
|
|
258
|
+
});
|
|
212
259
|
}
|
|
213
260
|
|
|
214
|
-
|
|
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>(
|
|
166
|
-
|
|
167
|
-
|
|
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, {
|
|
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>(
|
|
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>(
|
|
272
|
-
|
|
273
|
-
|
|
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[] }>(
|
|
302
|
-
|
|
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(
|
|
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)
|
|
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, {
|
|
373
|
-
|
|
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(
|
|
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, {
|
|
430
|
+
return this.ctx.request<CredentialListResult>('GET', url, undefined, {
|
|
431
|
+
cache: true,
|
|
432
|
+
cacheTTL: SHORT_TTL,
|
|
433
|
+
});
|
|
392
434
|
}
|
|
393
435
|
|
|
394
436
|
/**
|
package/src/api/contacts.ts
CHANGED
|
@@ -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(
|
|
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',
|
package/src/api/devices.ts
CHANGED
|
@@ -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(
|
|
76
|
-
|
|
77
|
-
|
|
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[]>(
|
|
152
|
-
|
|
153
|
-
|
|
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(
|
|
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>(
|
|
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(
|
|
178
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
}
|