@sogni-ai/sogni-client 5.0.0 → 5.1.0-alpha.10
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/CHANGELOG.md +96 -0
- package/README.md +42 -0
- package/dist/Account/CurrentAccount.d.ts +30 -0
- package/dist/Account/CurrentAccount.js +27 -1
- package/dist/Account/CurrentAccount.js.map +1 -1
- package/dist/Account/index.d.ts +171 -0
- package/dist/Account/index.js +362 -1
- package/dist/Account/index.js.map +1 -1
- package/dist/Account/subscription.types.d.ts +249 -0
- package/dist/Account/subscription.types.js +9 -0
- package/dist/Account/subscription.types.js.map +1 -0
- package/dist/Account/types.d.ts +12 -0
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.d.ts +1 -0
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js +19 -0
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js.map +1 -1
- package/dist/ApiClient/WebSocketClient/events.d.ts +74 -0
- package/dist/Chat/ChatJobError.d.ts +111 -0
- package/dist/Chat/ChatJobError.js +116 -0
- package/dist/Chat/ChatJobError.js.map +1 -0
- package/dist/Chat/ChatTools.js +1 -4
- package/dist/Chat/ChatTools.js.map +1 -1
- package/dist/Chat/_hostedToolsManifest.generated.js +5 -3
- package/dist/Chat/_hostedToolsManifest.generated.js.map +1 -1
- package/dist/Chat/hostedToolValidator.js +4 -3
- package/dist/Chat/hostedToolValidator.js.map +1 -1
- package/dist/Chat/index.d.ts +5 -0
- package/dist/Chat/index.js +99 -13
- package/dist/Chat/index.js.map +1 -1
- package/dist/Chat/modelRouting.d.ts +2 -0
- package/dist/Chat/modelRouting.js +2 -7
- package/dist/Chat/modelRouting.js.map +1 -1
- package/dist/Chat/tools.d.ts +14 -11
- package/dist/Chat/tools.js +15 -13
- package/dist/Chat/tools.js.map +1 -1
- package/dist/Chat/types.d.ts +18 -0
- package/dist/CreativeWorkflows/Templates/index.js +4 -2
- package/dist/CreativeWorkflows/Templates/index.js.map +1 -1
- package/dist/Projects/createJobRequestMessage.js +8 -1
- package/dist/Projects/createJobRequestMessage.js.map +1 -1
- package/dist/Projects/index.d.ts +5 -0
- package/dist/Projects/index.js +47 -0
- package/dist/Projects/index.js.map +1 -1
- package/dist/Projects/types/ControlNetParams.d.ts +3 -1
- package/dist/Projects/types/index.d.ts +22 -2
- package/dist/Projects/types/index.js.map +1 -1
- package/dist/Projects/utils/index.js +16 -8
- package/dist/Projects/utils/index.js.map +1 -1
- package/dist/Replay/index.js +5 -4
- package/dist/Replay/index.js.map +1 -1
- package/dist/index.d.ts +9 -5
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/isSubscriptionLimitError.d.ts +16 -0
- package/dist/lib/isSubscriptionLimitError.js +36 -0
- package/dist/lib/isSubscriptionLimitError.js.map +1 -0
- package/dist/types/ErrorData.d.ts +53 -0
- package/dist/types/ErrorData.js +25 -0
- package/dist/types/ErrorData.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist-esm/Account/CurrentAccount.js +27 -1
- package/dist-esm/Account/CurrentAccount.js.map +1 -1
- package/dist-esm/Account/index.js +362 -1
- package/dist-esm/Account/index.js.map +1 -1
- package/dist-esm/Account/subscription.types.js +8 -0
- package/dist-esm/Account/subscription.types.js.map +1 -0
- package/dist-esm/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js +19 -0
- package/dist-esm/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js.map +1 -1
- package/dist-esm/Chat/ChatJobError.js +111 -0
- package/dist-esm/Chat/ChatJobError.js.map +1 -0
- package/dist-esm/Chat/ChatTools.js +1 -4
- package/dist-esm/Chat/ChatTools.js.map +1 -1
- package/dist-esm/Chat/_hostedToolsManifest.generated.js +5 -3
- package/dist-esm/Chat/_hostedToolsManifest.generated.js.map +1 -1
- package/dist-esm/Chat/hostedToolValidator.js +4 -3
- package/dist-esm/Chat/hostedToolValidator.js.map +1 -1
- package/dist-esm/Chat/index.js +66 -13
- package/dist-esm/Chat/index.js.map +1 -1
- package/dist-esm/Chat/modelRouting.js +2 -7
- package/dist-esm/Chat/modelRouting.js.map +1 -1
- package/dist-esm/Chat/tools.js +15 -13
- package/dist-esm/Chat/tools.js.map +1 -1
- package/dist-esm/CreativeWorkflows/Templates/index.js +4 -2
- package/dist-esm/CreativeWorkflows/Templates/index.js.map +1 -1
- package/dist-esm/Projects/createJobRequestMessage.js +8 -1
- package/dist-esm/Projects/createJobRequestMessage.js.map +1 -1
- package/dist-esm/Projects/index.js +47 -0
- package/dist-esm/Projects/index.js.map +1 -1
- package/dist-esm/Projects/types/index.js.map +1 -1
- package/dist-esm/Projects/utils/index.js +16 -8
- package/dist-esm/Projects/utils/index.js.map +1 -1
- package/dist-esm/Replay/index.js +5 -4
- package/dist-esm/Replay/index.js.map +1 -1
- package/dist-esm/index.js +5 -1
- package/dist-esm/index.js.map +1 -1
- package/dist-esm/lib/isSubscriptionLimitError.js +33 -0
- package/dist-esm/lib/isSubscriptionLimitError.js.map +1 -0
- package/dist-esm/types/ErrorData.js +24 -1
- package/dist-esm/types/ErrorData.js.map +1 -1
- package/dist-esm/version.js +1 -1
- package/dist-esm/version.js.map +1 -1
- package/llms-full.txt +87 -9
- package/llms.txt +42 -8
- package/package.json +2 -1
- package/src/Account/CurrentAccount.ts +40 -1
- package/src/Account/index.ts +442 -2
- package/src/Account/subscription.types.ts +281 -0
- package/src/Account/types.ts +18 -0
- package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/index.ts +18 -0
- package/src/ApiClient/WebSocketClient/events.ts +75 -0
- package/src/Chat/ChatJobError.ts +188 -0
- package/src/Chat/ChatTools.ts +1 -4
- package/src/Chat/_hostedToolsManifest.generated.ts +5 -3
- package/src/Chat/hostedToolValidator.ts +7 -4
- package/src/Chat/index.ts +110 -35
- package/src/Chat/modelRouting.ts +2 -8
- package/src/Chat/tools.ts +22 -17
- package/src/Chat/types.ts +19 -0
- package/src/CreativeWorkflows/Templates/index.ts +6 -2
- package/src/Projects/createJobRequestMessage.ts +9 -0
- package/src/Projects/index.ts +42 -0
- package/src/Projects/types/ControlNetParams.ts +3 -1
- package/src/Projects/types/index.ts +24 -2
- package/src/Projects/utils/index.ts +16 -8
- package/src/Replay/index.ts +9 -21
- package/src/index.ts +44 -2
- package/src/lib/isSubscriptionLimitError.ts +36 -0
- package/src/types/ErrorData.ts +57 -0
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,99 @@
|
|
|
1
|
+
# [5.1.0-alpha.10](https://github.com/Sogni-AI/sogni-client/compare/v5.1.0-alpha.9...v5.1.0-alpha.10) (2026-06-18)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **audio:** prefer ACE-Step XL music models ([ec5a715](https://github.com/Sogni-AI/sogni-client/commit/ec5a71579d04b42863ce9627c8ea4935b0190f70))
|
|
7
|
+
* **projects:** expose LTX-2.3 v2v outpaint and inpaint controls ([1a60576](https://github.com/Sogni-AI/sogni-client/commit/1a605766e42b6fa5cdedf0a64425deb51cbf81b1))
|
|
8
|
+
|
|
9
|
+
# [5.1.0-alpha.9](https://github.com/Sogni-AI/sogni-client/compare/v5.1.0-alpha.8...v5.1.0-alpha.9) (2026-06-16)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* **subscription:** expose frontier vendor discount in types ([1e06f99](https://github.com/Sogni-AI/sogni-client/commit/1e06f99e54e39c2d09d65263c0ed6a5f52dbac18))
|
|
15
|
+
|
|
16
|
+
# [5.1.0-alpha.8](https://github.com/Sogni-AI/sogni-client/compare/v5.1.0-alpha.7...v5.1.0-alpha.8) (2026-06-16)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
* **chat:** carry subscription-limit fields on ChatJobError ([33c7ecd](https://github.com/Sogni-AI/sogni-client/commit/33c7ecdab22c571f6983fbb479bdbb5eb885a672))
|
|
22
|
+
* **chat:** forward 4081 limit fields at error call sites ([ef5b66a](https://github.com/Sogni-AI/sogni-client/commit/ef5b66a8b28dd52755f22cf76609258ecf2fe6dc))
|
|
23
|
+
* **projects:** surface 4081 limit fields on render errors ([13fa158](https://github.com/Sogni-AI/sogni-client/commit/13fa158f00c4e4415bb4d0f3c7eaf9979f1f7d40))
|
|
24
|
+
* **socket:** type 4081 limit fields on job error events ([0026438](https://github.com/Sogni-AI/sogni-client/commit/0026438ccbfb1cefe5be38861372d1430ade0eb2))
|
|
25
|
+
* **subscription:** add isSubscriptionLimitError helper ([139953b](https://github.com/Sogni-AI/sogni-client/commit/139953bc003aefc2f3ba09f8e4000982a071f7e8))
|
|
26
|
+
* **subscription:** recognize 4081 feature-gate denial code ([c513fe6](https://github.com/Sogni-AI/sogni-client/commit/c513fe67243c91e0ca8ccb5d301a3be20dcf1486))
|
|
27
|
+
|
|
28
|
+
# [5.1.0-alpha.7](https://github.com/Sogni-AI/sogni-client/compare/v5.1.0-alpha.6...v5.1.0-alpha.7) (2026-06-12)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* **account:** map real socket entitlement status domain without dropping fields ([c2e7499](https://github.com/Sogni-AI/sogni-client/commit/c2e7499c5d254e8ce61da257b44307bca97ea56c))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
* **account:** accept chat checkout redirect target ([3900336](https://github.com/Sogni-AI/sogni-client/commit/390033692aaa46eff521030d80ba712f15bd3302))
|
|
39
|
+
* **account:** guard subscription writes against stale transports ([c60af1f](https://github.com/Sogni-AI/sogni-client/commit/c60af1ff4e4a9a8af1a8e2393899026f176a3f53))
|
|
40
|
+
* **chat:** preserve job error codes via typed ChatJobError ([dd5ad1d](https://github.com/Sogni-AI/sogni-client/commit/dd5ad1d585c709382547bfa4cff2aa98d734414c))
|
|
41
|
+
* **chat:** serialize billingMode on all three chat transports ([787dd43](https://github.com/Sogni-AI/sogni-client/commit/787dd4391dee1735a6d3d3a7953f25ec6c722a4d))
|
|
42
|
+
* **types:** export subscription billing socket error-code constants ([2fd5af4](https://github.com/Sogni-AI/sogni-client/commit/2fd5af49ffa76d6f1a304c6a06577468f5865c2e))
|
|
43
|
+
|
|
44
|
+
# [5.1.0-alpha.6](https://github.com/Sogni-AI/sogni-client/compare/v5.1.0-alpha.5...v5.1.0-alpha.6) (2026-06-12)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### Features
|
|
48
|
+
|
|
49
|
+
* sync socket subscription entitlement ([fa5d24d](https://github.com/Sogni-AI/sogni-client/commit/fa5d24d307992993ac312c3b1e8ab94277529aa4))
|
|
50
|
+
|
|
51
|
+
# [5.1.0-alpha.5](https://github.com/Sogni-AI/sogni-client/compare/v5.1.0-alpha.4...v5.1.0-alpha.5) (2026-06-11)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
### Features
|
|
55
|
+
|
|
56
|
+
* **subscription:** pending plan-change snapshot fields and grace-period doc fix ([596e4a0](https://github.com/Sogni-AI/sogni-client/commit/596e4a030dc1114e5fdd90d3dce3dd799c5f1ede))
|
|
57
|
+
|
|
58
|
+
# [5.1.0-alpha.4](https://github.com/Sogni-AI/sogni-client/compare/v5.1.0-alpha.3...v5.1.0-alpha.4) (2026-06-11)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
### Bug Fixes
|
|
62
|
+
|
|
63
|
+
* **projects:** forward billing mode metadata ([975fdb0](https://github.com/Sogni-AI/sogni-client/commit/975fdb09adcbd74c11fa6786edb6f1d2392583eb))
|
|
64
|
+
|
|
65
|
+
# [5.1.0-alpha.3](https://github.com/Sogni-AI/sogni-client/compare/v5.1.0-alpha.2...v5.1.0-alpha.3) (2026-06-10)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### Features
|
|
69
|
+
|
|
70
|
+
* **subscription:** mirror term, google productId, and manual provider ([78b3114](https://github.com/Sogni-AI/sogni-client/commit/78b311457c71448578b8f561cc7865e7bcaf9f20))
|
|
71
|
+
|
|
72
|
+
# [5.1.0-alpha.2](https://github.com/Sogni-AI/sogni-client/compare/v5.1.0-alpha.1...v5.1.0-alpha.2) (2026-06-10)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
### Bug Fixes
|
|
76
|
+
|
|
77
|
+
* **account:** correct trial usage SDK surface and eligibility reason docs ([222252d](https://github.com/Sogni-AI/sogni-client/commit/222252d87305f72b0be71f23b26a6607ad25bf46))
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
### Features
|
|
81
|
+
|
|
82
|
+
* **account:** add trial eligibility, device-id, and startTrial checkout ([6564c82](https://github.com/Sogni-AI/sogni-client/commit/6564c8225aec37245a4c4a051119a48da6fc14a5))
|
|
83
|
+
|
|
84
|
+
# [5.1.0-alpha.1](https://github.com/Sogni-AI/sogni-client/compare/v5.0.0...v5.1.0-alpha.1) (2026-06-05)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
### Bug Fixes
|
|
88
|
+
|
|
89
|
+
* **subscription:** accept unlimited_pro tier in isUnlimited getter ([dd60513](https://github.com/Sogni-AI/sogni-client/commit/dd60513650071a46a2e43f7d81bae96026c4af93))
|
|
90
|
+
* **subscription:** align entitlement SDK surface ([df2b752](https://github.com/Sogni-AI/sogni-client/commit/df2b7527f479778f073ac8f05b39912e84874666))
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
### Features
|
|
94
|
+
|
|
95
|
+
* **account:** add subscription entitlement accessors ([22682c4](https://github.com/Sogni-AI/sogni-client/commit/22682c4ac8a970b4189ec94ea9f7bc3fa215533e))
|
|
96
|
+
|
|
1
97
|
# [5.0.0](https://github.com/Sogni-AI/sogni-client/compare/v4.1.1...v5.0.0) (2026-05-29)
|
|
2
98
|
|
|
3
99
|
|
package/README.md
CHANGED
|
@@ -176,6 +176,48 @@ sogni.client.on('disconnected', ({ code, reason }) => {
|
|
|
176
176
|
});
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
+
### Subscription entitlements
|
|
180
|
+
|
|
181
|
+
The account API exposes the public subscription plan catalog and the current wallet's entitlement snapshot:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
const plans = await sogni.account.getSubscriptionPlans();
|
|
185
|
+
|
|
186
|
+
const subscription = await sogni.account.refreshSubscription();
|
|
187
|
+
if (sogni.account.currentAccount.isUnlimited) {
|
|
188
|
+
console.log('Unlimited tier:', subscription.tier);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
`currentAccount.isUnlimited` is `true` when the latest entitlement snapshot has `active: true` and `tier` is either `unlimited` or `unlimited_pro`. The server keeps `active` true for entitled states until access actually ends: trials and cancel-at-period-end windows remain entitled, with `currentPeriodEnd` reflecting the paid-through date. Canceling during a free trial is the exception: it ends Unlimited access immediately by default, so the next snapshot reports `active: false`. A `grace_period` snapshot is never entitled and returns `active: false`: it means the provider (Apple billing grace / Google Play grace / Stripe retries) is retrying the renewal payment, and unlimited render access is paused while the retry is in progress — render submissions under the plan return a specific error from the platform explaining that the renewal payment is being retried and that unlimited access resumes once it succeeds. Renders can still be paid with Spark/SOGNI in the meantime, and unlimited access resumes automatically when the renewal succeeds. During grace the snapshot's effective period end indicates the payment-retry window, not access. Period dates are ISO timestamp strings.
|
|
193
|
+
|
|
194
|
+
A canceled-but-still-paid subscription carries `cancelAtPeriodEnd: true` and keeps access until `currentPeriodEnd`. When a downgrade or plan switch is scheduled for the next renewal, the snapshot may also carry `scheduledTier`, `scheduledTerm`, and `scheduledChangeAt` (ISO timestamp) — absent when no change is pending — so UIs can render "Your plan will change to X on date" messaging while the current tier keeps its benefits.
|
|
195
|
+
|
|
196
|
+
When a job is explicitly submitted with `billingMode: 'subscription'` and the subscription cannot cover it, the platform rejects the job with a subscription-specific error code, exported as `SUBSCRIPTION_ERROR_CODES` from the package root:
|
|
197
|
+
|
|
198
|
+
- `4078` (`NOT_ENTITLED`) — no active subscription entitlement covers the job.
|
|
199
|
+
- `4079` (`QUEUE_CAP`) — the subscription's concurrent job queue cap was reached.
|
|
200
|
+
- `4080` (`GRACE_RETRY`) — the subscription is in its billing-grace window: the renewal payment is being retried and unlimited access is paused until it succeeds. On `4080`, offer the user a "pay with Spark/SOGNI" fallback (token billing) instead of auto-retrying the subscription job in a loop — it will keep failing until the renewal succeeds.
|
|
201
|
+
|
|
202
|
+
`billingMode` (`'auto' | 'subscription' | 'tokens'`, exported as `BillingMode`) is accepted by project params and by all three chat transports: `sogni.chat.completions.create()` (socket), `sogni.chat.hosted.create()` (REST `/v1/chat/completions`), and `sogni.chat.runs.create()` (durable runs, where it serializes as `billing_mode`).
|
|
203
|
+
|
|
204
|
+
Chat job failures preserve this error contract. Streamed and non-streaming chat completions, hosted REST chat, and durable chat runs fail with a `ChatJobError` (exported from the package root): `.message` stays the human-readable server message, while `code`/`errorCode` carry the wire code string (e.g. `'4080'`), `errorType` carries the server's tag (e.g. `'subscription_unavailable'`), and the `subscriptionErrorCode` getter maps the code back to the numeric `SUBSCRIPTION_ERROR_CODES` value when applicable — so apps can branch without string-matching.
|
|
205
|
+
|
|
206
|
+
Unlimited fair-use accounting and enforcement are handled dynamically by the Sogni socket service. The SDK does not expose per-period usage counters or plan limit tables for clients to store or display as durable user-facing limits.
|
|
207
|
+
|
|
208
|
+
To start Stripe checkout, use a plan's `planId` (`unlimited` or `unlimited_pro`) and `term` (`monthly` or `annual`). Checkout and portal sessions require user authentication; API-key auth is rejected for those browser redirect operations.
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
const { url } = await sogni.account.createSubscriptionCheckout('unlimited_pro', 'annual', {
|
|
212
|
+
redirectType: 'web',
|
|
213
|
+
appSource: 'my-integration'
|
|
214
|
+
});
|
|
215
|
+
window.location.href = url;
|
|
216
|
+
|
|
217
|
+
const portal = await sogni.account.createSubscriptionPortalSession();
|
|
218
|
+
window.location.href = portal.url;
|
|
219
|
+
```
|
|
220
|
+
|
|
179
221
|
## Image Generation
|
|
180
222
|
|
|
181
223
|
Sogni supports a wide range of models for image generation. You can find a list of available models in
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import DataEntity from '../lib/DataEntity.js';
|
|
2
2
|
import { Balances } from './types.js';
|
|
3
|
+
import { SubscriptionEntitlementSnapshot } from './subscription.types.js';
|
|
3
4
|
import { SupernetType } from '../ApiClient/WebSocketClient/types.js';
|
|
4
5
|
/**
|
|
5
6
|
* @inline
|
|
@@ -20,6 +21,17 @@ export interface AccountData {
|
|
|
20
21
|
walletAddress?: string;
|
|
21
22
|
username?: string;
|
|
22
23
|
email?: string;
|
|
24
|
+
/**
|
|
25
|
+
* The most recently fetched subscription entitlement snapshot.
|
|
26
|
+
* `undefined` until the account receives a socket entitlement snapshot or
|
|
27
|
+
* {@link AccountApi.getSubscriptionStatus} / {@link AccountApi.refreshSubscription}
|
|
28
|
+
* has been called.
|
|
29
|
+
*
|
|
30
|
+
* Subscribe to the `'updated'` event (inherited from `DataEntity`) to react
|
|
31
|
+
* to changes; the `changedKeys` array will include `'subscription'` when
|
|
32
|
+
* this field is refreshed.
|
|
33
|
+
*/
|
|
34
|
+
subscription?: SubscriptionEntitlementSnapshot;
|
|
23
35
|
}
|
|
24
36
|
/**
|
|
25
37
|
* Current account data.
|
|
@@ -35,5 +47,23 @@ declare class CurrentAccount extends DataEntity<AccountData> {
|
|
|
35
47
|
get walletAddress(): string | undefined;
|
|
36
48
|
get username(): string | undefined;
|
|
37
49
|
get email(): string | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* The most recently cached subscription entitlement snapshot.
|
|
52
|
+
* `undefined` until the account receives a socket entitlement snapshot or
|
|
53
|
+
* {@link AccountApi.getSubscriptionStatus} / {@link AccountApi.refreshSubscription}
|
|
54
|
+
* has been called.
|
|
55
|
+
*/
|
|
56
|
+
get subscription(): SubscriptionEntitlementSnapshot | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Convenience getter - `true` when the account has an effective
|
|
59
|
+
* subscription entitlement on any Unlimited tier (`"unlimited"` or
|
|
60
|
+
* `"unlimited_pro"`).
|
|
61
|
+
*
|
|
62
|
+
* Returns `false` when no entitlement snapshot has been fetched yet, when
|
|
63
|
+
* the server reports no active entitlement, or when the tier is not an
|
|
64
|
+
* Unlimited tier. Call {@link AccountApi.refreshSubscription} to force a REST
|
|
65
|
+
* refresh when no socket entitlement snapshot has been received yet.
|
|
66
|
+
*/
|
|
67
|
+
get isUnlimited(): boolean;
|
|
38
68
|
}
|
|
39
69
|
export default CurrentAccount;
|
|
@@ -24,7 +24,8 @@ function getDefaults() {
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
walletAddress: undefined,
|
|
27
|
-
username: undefined
|
|
27
|
+
username: undefined,
|
|
28
|
+
subscription: undefined
|
|
28
29
|
};
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
@@ -59,6 +60,31 @@ class CurrentAccount extends DataEntity_js_1.default {
|
|
|
59
60
|
get email() {
|
|
60
61
|
return this.data.email;
|
|
61
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* The most recently cached subscription entitlement snapshot.
|
|
65
|
+
* `undefined` until the account receives a socket entitlement snapshot or
|
|
66
|
+
* {@link AccountApi.getSubscriptionStatus} / {@link AccountApi.refreshSubscription}
|
|
67
|
+
* has been called.
|
|
68
|
+
*/
|
|
69
|
+
get subscription() {
|
|
70
|
+
return this.data.subscription;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Convenience getter - `true` when the account has an effective
|
|
74
|
+
* subscription entitlement on any Unlimited tier (`"unlimited"` or
|
|
75
|
+
* `"unlimited_pro"`).
|
|
76
|
+
*
|
|
77
|
+
* Returns `false` when no entitlement snapshot has been fetched yet, when
|
|
78
|
+
* the server reports no active entitlement, or when the tier is not an
|
|
79
|
+
* Unlimited tier. Call {@link AccountApi.refreshSubscription} to force a REST
|
|
80
|
+
* refresh when no socket entitlement snapshot has been received yet.
|
|
81
|
+
*/
|
|
82
|
+
get isUnlimited() {
|
|
83
|
+
const sub = this.data.subscription;
|
|
84
|
+
if (!sub || !sub.active)
|
|
85
|
+
return false;
|
|
86
|
+
return sub.tier === 'unlimited' || sub.tier === 'unlimited_pro';
|
|
87
|
+
}
|
|
62
88
|
}
|
|
63
89
|
exports.default = CurrentAccount;
|
|
64
90
|
//# sourceMappingURL=CurrentAccount.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CurrentAccount.js","sourceRoot":"","sources":["../../src/Account/CurrentAccount.ts"],"names":[],"mappings":";;;;;AAAA,yEAA8C;
|
|
1
|
+
{"version":3,"file":"CurrentAccount.js","sourceRoot":"","sources":["../../src/Account/CurrentAccount.ts"],"names":[],"mappings":";;;;;AAAA,yEAA8C;AAoC9C,SAAS,WAAW;IAClB,OAAO;QACL,aAAa,EAAE,cAAc;QAC7B,OAAO,EAAE,IAAI;QACb,OAAO,EAAE;YACP,KAAK,EAAE;gBACL,MAAM,EAAE,GAAG;gBACX,KAAK,EAAE,GAAG;gBACV,GAAG,EAAE,GAAG;gBACR,OAAO,EAAE,GAAG;aACb;YACD,KAAK,EAAE;gBACL,MAAM,EAAE,GAAG;gBACX,KAAK,EAAE,GAAG;gBACV,GAAG,EAAE,GAAG;gBACR,OAAO,EAAE,GAAG;gBACZ,aAAa,EAAE,GAAG;aACnB;SACF;QACD,aAAa,EAAE,SAAS;QACxB,QAAQ,EAAE,SAAS;QACnB,YAAY,EAAE,SAAS;KACxB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,cAAe,SAAQ,uBAAuB;IAClD,YAAY,IAAkB;QAC5B,KAAK,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;IACnC,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;IACjC,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IAC3B,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IAC3B,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;IACjC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC5B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IACzB,CAAC;IAED;;;;;OAKG;IACH,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;IAChC,CAAC;IAED;;;;;;;;;OASG;IACH,IAAI,WAAW;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;QACnC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACtC,OAAO,GAAG,CAAC,IAAI,KAAK,WAAW,IAAI,GAAG,CAAC,IAAI,KAAK,eAAe,CAAC;IAClE,CAAC;CACF;AAED,kBAAe,cAAc,CAAC"}
|
package/dist/Account/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AccountCreateData, AccountCreateParams, Balances, ClaimOptions, FullBalances, LoginData, MeData, Reward, RewardsQuery, TxHistoryEntry, TxHistoryParams } from './types.js';
|
|
2
|
+
import { CreateSubscriptionCheckoutOptions, SubscriptionCheckoutResult, SubscriptionEntitlementSnapshot, SubscriptionPlanId, SubscriptionPlan, SubscriptionPortalSession, SubscriptionTerm, SubscriptionUsage, TrialEligibility } from './subscription.types.js';
|
|
2
3
|
import ApiGroup, { ApiConfig } from '../ApiGroup.js';
|
|
3
4
|
import { Wallet } from 'ethers';
|
|
4
5
|
import { ApiResponse } from '../ApiClient/index.js';
|
|
@@ -17,12 +18,44 @@ import { SupernetType } from '../ApiClient/WebSocketClient/types.js';
|
|
|
17
18
|
*/
|
|
18
19
|
declare class AccountApi extends ApiGroup {
|
|
19
20
|
readonly currentAccount: CurrentAccount;
|
|
21
|
+
/**
|
|
22
|
+
* Highest entitlement `version` applied to `currentAccount.subscription`.
|
|
23
|
+
* Socket payloads carry a monotonically increasing version; writes that
|
|
24
|
+
* carry an older version than the one already applied are discarded instead
|
|
25
|
+
* of overwriting fresher data.
|
|
26
|
+
*/
|
|
27
|
+
private lastAppliedSubscriptionVersion;
|
|
28
|
+
/**
|
|
29
|
+
* Logical clock counting applied socket entitlement writes. A REST refresh
|
|
30
|
+
* captures this counter before its request goes on the wire; if it advanced
|
|
31
|
+
* by the time the response arrives, a fresher socket push landed mid-flight
|
|
32
|
+
* and the REST snapshot is discarded as stale.
|
|
33
|
+
*/
|
|
34
|
+
private appliedSubscriptionSocketWrites;
|
|
20
35
|
constructor(config: ApiConfig);
|
|
21
36
|
private handleBalanceUpdate;
|
|
22
37
|
private handleChangeNetwork;
|
|
23
38
|
private handleServerConnected;
|
|
24
39
|
private handleServerConnecting;
|
|
25
40
|
private handleServerDisconnected;
|
|
41
|
+
private mapSocketSubscriptionEntitlement;
|
|
42
|
+
/**
|
|
43
|
+
* Single chokepoint through which every subscription entitlement writer
|
|
44
|
+
* (REST refresh, socket entitlement push, socket authenticated seeding)
|
|
45
|
+
* must route.
|
|
46
|
+
*
|
|
47
|
+
* Guards against last-writer-wins races between the two transports: writes
|
|
48
|
+
* carrying an older `version` than the one already applied are discarded,
|
|
49
|
+
* and an unversioned REST snapshot whose request started before a socket
|
|
50
|
+
* push was applied is discarded as stale. Snapshots deep-equal to the
|
|
51
|
+
* current one are accepted without re-applying, so reconnect re-seeds and
|
|
52
|
+
* tab replays do not emit redundant 'updated' events.
|
|
53
|
+
*
|
|
54
|
+
* @returns `true` when the snapshot was accepted (even if identical to the
|
|
55
|
+
* current one), `false` when it was discarded as stale.
|
|
56
|
+
*/
|
|
57
|
+
private applySubscriptionSnapshot;
|
|
58
|
+
private handleSubscriptionEntitlementUpdated;
|
|
26
59
|
private handleSocketAuthenticated;
|
|
27
60
|
private handleAuthUpdated;
|
|
28
61
|
/**
|
|
@@ -212,5 +245,143 @@ declare class AccountApi extends ApiGroup {
|
|
|
212
245
|
* @param provider - Provider name, defaults to 'base', can be 'base', 'etherlink', etc.
|
|
213
246
|
*/
|
|
214
247
|
approveTokenUsage(password: string, spender: 'account' | 'staker', provider?: string): Promise<void>;
|
|
248
|
+
/**
|
|
249
|
+
* Fetch the current user's subscription entitlement snapshot.
|
|
250
|
+
*
|
|
251
|
+
* Returns an object describing whether the account has an effective
|
|
252
|
+
* subscription entitlement, the tier, period boundaries, usage, limits, and
|
|
253
|
+
* enabled capabilities. When no subscription exists, `active` is `false` and
|
|
254
|
+
* `status` is `'none'`.
|
|
255
|
+
*
|
|
256
|
+
* Also updates `currentAccount.subscription` so callers can read the
|
|
257
|
+
* snapshot from the observable entity without re-fetching.
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* const snap = await sogni.account.getSubscriptionStatus();
|
|
262
|
+
* if (snap.active) {
|
|
263
|
+
* console.log('Plan:', snap.tier, 'until', snap.currentPeriodEnd);
|
|
264
|
+
* }
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
getSubscriptionStatus(): Promise<SubscriptionEntitlementSnapshot>;
|
|
268
|
+
/**
|
|
269
|
+
* Fetch the current user's usage for the active billing cycle.
|
|
270
|
+
*
|
|
271
|
+
* Returns the render/job counters for the subscriber's current billing cycle
|
|
272
|
+
* (not a calendar month). While the entitlement is `'trialing'`, the response
|
|
273
|
+
* also carries `trialEndsAt`, `trialCreditsLimit`, and `trialCreditsUsed` so
|
|
274
|
+
* you can render "X of N trial credits used" messaging; those fields are
|
|
275
|
+
* omitted for non-trial subscriptions.
|
|
276
|
+
*
|
|
277
|
+
* Note: these trial usage fields come from this endpoint, NOT from
|
|
278
|
+
* {@link getSubscriptionStatus} — the entitlement snapshot never carries
|
|
279
|
+
* trial usage.
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```typescript
|
|
283
|
+
* const usage = await sogni.account.getSubscriptionUsage();
|
|
284
|
+
* if (usage.trialCreditsLimit !== undefined) {
|
|
285
|
+
* console.log(`${usage.trialCreditsUsed} of ${usage.trialCreditsLimit} trial credits used`);
|
|
286
|
+
* }
|
|
287
|
+
* ```
|
|
288
|
+
*/
|
|
289
|
+
getSubscriptionUsage(): Promise<SubscriptionUsage>;
|
|
290
|
+
/**
|
|
291
|
+
* Check whether the current account is eligible to start a free trial.
|
|
292
|
+
*
|
|
293
|
+
* Returns `{ eligible, reasonCode }`. `reasonCode` is ALWAYS present: it is
|
|
294
|
+
* `'eligible'` when a trial may be started, or a deny reason otherwise (e.g.
|
|
295
|
+
* `'wallet_already_used'`, `'strong_signal_match'`, `'weak_combo'`). Use this
|
|
296
|
+
* before offering a "start free trial" flow.
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* ```typescript
|
|
300
|
+
* const { eligible, reasonCode } = await sogni.account.getTrialEligibility();
|
|
301
|
+
* if (eligible) {
|
|
302
|
+
* const { url } = await sogni.account.createSubscriptionCheckout('unlimited', 'monthly', {
|
|
303
|
+
* startTrial: true
|
|
304
|
+
* });
|
|
305
|
+
* }
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
getTrialEligibility(): Promise<TrialEligibility>;
|
|
309
|
+
/**
|
|
310
|
+
* Persist a raw persistent device identifier for the current account.
|
|
311
|
+
*
|
|
312
|
+
* Used for free-trial anti-abuse attribution so the server can detect device
|
|
313
|
+
* reuse across accounts. Requires an authenticated session.
|
|
314
|
+
*
|
|
315
|
+
* @param deviceId - Raw persistent device identifier.
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```typescript
|
|
319
|
+
* await sogni.account.setDeviceId(myPersistentDeviceId);
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
322
|
+
setDeviceId(deviceId: string): Promise<void>;
|
|
323
|
+
/**
|
|
324
|
+
* Fetch the list of available subscription plans.
|
|
325
|
+
*
|
|
326
|
+
* This is a public endpoint; no authentication is required.
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```typescript
|
|
330
|
+
* const plans = await sogni.account.getSubscriptionPlans();
|
|
331
|
+
* plans.forEach(p => console.log(p.displayName, p.priceUsd));
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
getSubscriptionPlans(): Promise<SubscriptionPlan[]>;
|
|
335
|
+
/**
|
|
336
|
+
* Create a Stripe checkout session to subscribe to a plan.
|
|
337
|
+
*
|
|
338
|
+
* Returns a `url` to which the user should be redirected to complete payment.
|
|
339
|
+
* After a successful checkout Stripe will redirect back to your configured
|
|
340
|
+
* return URL and the subscription entitlement will become active.
|
|
341
|
+
*
|
|
342
|
+
* Pass `options.startTrial` to control free-trial behavior: `true` starts a
|
|
343
|
+
* trial when the account is eligible, while `false` is sent verbatim to
|
|
344
|
+
* subscribe immediately with no trial even if the account is eligible.
|
|
345
|
+
* Pass `options.deviceId` to forward a raw persistent device identifier for
|
|
346
|
+
* trial anti-abuse attribution.
|
|
347
|
+
*
|
|
348
|
+
* @param planId - The plan identifier from {@link getSubscriptionPlans}
|
|
349
|
+
* @param term - Billing cadence: `'monthly'` or `'annual'`
|
|
350
|
+
* @param options - Optional checkout metadata, redirect target, and trial controls.
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* ```typescript
|
|
354
|
+
* const { url } = await sogni.account.createSubscriptionCheckout('unlimited', 'monthly');
|
|
355
|
+
* window.location.href = url;
|
|
356
|
+
* ```
|
|
357
|
+
*/
|
|
358
|
+
createSubscriptionCheckout(planId: SubscriptionPlanId, term: SubscriptionTerm, options?: CreateSubscriptionCheckoutOptions): Promise<SubscriptionCheckoutResult>;
|
|
359
|
+
/**
|
|
360
|
+
* Create a Stripe customer portal session for managing an existing subscription.
|
|
361
|
+
*
|
|
362
|
+
* Returns a `url` to which the user should be redirected. The portal lets
|
|
363
|
+
* them update payment methods, cancel, or view invoices.
|
|
364
|
+
*
|
|
365
|
+
* @example
|
|
366
|
+
* ```typescript
|
|
367
|
+
* const { url } = await sogni.account.createSubscriptionPortalSession();
|
|
368
|
+
* window.location.href = url;
|
|
369
|
+
* ```
|
|
370
|
+
*/
|
|
371
|
+
createSubscriptionPortalSession(): Promise<SubscriptionPortalSession>;
|
|
372
|
+
/**
|
|
373
|
+
* Refresh the cached subscription entitlement on `currentAccount`.
|
|
374
|
+
*
|
|
375
|
+
* Convenience wrapper around {@link getSubscriptionStatus} that makes the
|
|
376
|
+
* intent ("I want to pull fresh entitlement data into the observable
|
|
377
|
+
* account entity") explicit at the call site.
|
|
378
|
+
*
|
|
379
|
+
* @example
|
|
380
|
+
* ```typescript
|
|
381
|
+
* await sogni.account.refreshSubscription();
|
|
382
|
+
* console.log(sogni.account.currentAccount.isUnlimited);
|
|
383
|
+
* ```
|
|
384
|
+
*/
|
|
385
|
+
refreshSubscription(): Promise<SubscriptionEntitlementSnapshot>;
|
|
215
386
|
}
|
|
216
387
|
export default AccountApi;
|