@witnium-tech/witniumchain 0.8.0 → 0.10.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.
@@ -118,6 +118,36 @@ await client.login({ email, password }); // sets wac_session cookie
118
118
  In a browser the `wac_session` cookie is set automatically (the SDK uses
119
119
  `credentials: 'include'`). Server-side callers must capture + replay the cookie.
120
120
 
121
+ ### Cookie-only dashboard → bearer calls (automatic, no OAuth needed)
122
+
123
+ You do **not** need to run the OAuth code flow to call the operational API
124
+ (delegated keys, witness writes, chain reads). After `login()`, just call them:
125
+
126
+ ```ts
127
+ await client.login({ email, password }); // sets wac_session
128
+ await client.listDelegatedKeys(); // ← works; SDK mints a bearer token
129
+ ```
130
+
131
+ How: those endpoints are bearer-only (they never accept the ambient cookie, so
132
+ there's **no CSRF surface** even with `SameSite=None`). On the first such call
133
+ the SDK transparently exchanges the session cookie for a short-lived access
134
+ token via `POST /v1/auth/access-token`, caches it, and re-mints on a 401. You
135
+ never see the token unless you want it:
136
+
137
+ ```ts
138
+ const { accessToken, expiresAt } = await client.exchangeSessionForToken(); // optional pre-warm
139
+ ```
140
+
141
+ Requirements: in the browser the `wac_session` cookie rides automatically
142
+ (`credentials: 'include'`). Node/SSR callers pass `sessionCookie: '<value>'` to
143
+ the constructor. If there's no valid session, the call throws a descriptive
144
+ "requires an OAuth access token … or provide `sessionCookie`" error — that's
145
+ your cue to send the user back to login.
146
+
147
+ This is the recommended path for a first-party dashboard. Reach for the full
148
+ OAuth flow below only when the dashboard is itself a registered OAuth client
149
+ (e.g. third-party apps, or you want long-lived refresh tokens).
150
+
121
151
  ### Magic-link sign-in
122
152
 
123
153
  `beginOAuthLogin` / passwordless paths exist; see the SDK's `OauthNamespace`
package/dist/index.d.mts CHANGED
@@ -5605,6 +5605,128 @@ interface paths$1 {
5605
5605
  patch?: never;
5606
5606
  trace?: never;
5607
5607
  };
5608
+ "/v1/account/provisioning-token/reissue": {
5609
+ parameters: {
5610
+ query?: never;
5611
+ header?: never;
5612
+ path?: never;
5613
+ cookie?: never;
5614
+ };
5615
+ get?: never;
5616
+ put?: never;
5617
+ /**
5618
+ * Re-mint a provisioning token (verified-but-not-provisioned recovery)
5619
+ * @description Mints a fresh single-use provisioning token for a signed-in user whose email is verified but who has no contract yet — recovery for when the token from email-verify was lost (e.g. verify opened on another device). Returns 409 if email is unverified or a contract already exists. Rate limited per account.
5620
+ */
5621
+ post: {
5622
+ parameters: {
5623
+ query?: never;
5624
+ header?: never;
5625
+ path?: never;
5626
+ cookie?: never;
5627
+ };
5628
+ requestBody?: never;
5629
+ responses: {
5630
+ /** @description Success */
5631
+ 200: {
5632
+ headers: {
5633
+ [name: string]: unknown;
5634
+ };
5635
+ content: {
5636
+ "application/json": {
5637
+ provisioningToken: string;
5638
+ /**
5639
+ * Format: date-time
5640
+ * @description ISO 8601 date-time string
5641
+ * @example 2026-05-20T10:30:00.000Z
5642
+ */
5643
+ expiresAt: string;
5644
+ };
5645
+ };
5646
+ };
5647
+ /** @description Unauthorized — authentication required or invalid */
5648
+ 401: {
5649
+ headers: {
5650
+ [name: string]: unknown;
5651
+ };
5652
+ content: {
5653
+ "application/json": {
5654
+ /**
5655
+ * @description HTTP status code
5656
+ * @example 400
5657
+ */
5658
+ statusCode?: number;
5659
+ /**
5660
+ * @description Short error label
5661
+ * @example Bad Request
5662
+ */
5663
+ error?: string;
5664
+ /**
5665
+ * @description Human-readable error message. Validation errors from `ZodError.flatten()` may be returned as an array.
5666
+ * @example Validation failed
5667
+ */
5668
+ message: string | string[];
5669
+ };
5670
+ };
5671
+ };
5672
+ /** @description Conflict */
5673
+ 409: {
5674
+ headers: {
5675
+ [name: string]: unknown;
5676
+ };
5677
+ content: {
5678
+ "application/json": {
5679
+ /**
5680
+ * @description HTTP status code
5681
+ * @example 400
5682
+ */
5683
+ statusCode?: number;
5684
+ /**
5685
+ * @description Short error label
5686
+ * @example Bad Request
5687
+ */
5688
+ error?: string;
5689
+ /**
5690
+ * @description Human-readable error message. Validation errors from `ZodError.flatten()` may be returned as an array.
5691
+ * @example Validation failed
5692
+ */
5693
+ message: string | string[];
5694
+ };
5695
+ };
5696
+ };
5697
+ /** @description Too Many Requests */
5698
+ 429: {
5699
+ headers: {
5700
+ [name: string]: unknown;
5701
+ };
5702
+ content: {
5703
+ "application/json": {
5704
+ /**
5705
+ * @description HTTP status code
5706
+ * @example 400
5707
+ */
5708
+ statusCode?: number;
5709
+ /**
5710
+ * @description Short error label
5711
+ * @example Bad Request
5712
+ */
5713
+ error?: string;
5714
+ /**
5715
+ * @description Human-readable error message. Validation errors from `ZodError.flatten()` may be returned as an array.
5716
+ * @example Validation failed
5717
+ */
5718
+ message: string | string[];
5719
+ };
5720
+ };
5721
+ };
5722
+ };
5723
+ };
5724
+ delete?: never;
5725
+ options?: never;
5726
+ head?: never;
5727
+ patch?: never;
5728
+ trace?: never;
5729
+ };
5608
5730
  "/v1/account": {
5609
5731
  parameters: {
5610
5732
  query?: never;
@@ -10217,6 +10339,7 @@ type RevokeWitnessV5Request = Req<'/v5/contracts/{contractAddress}/witnesses/{wi
10217
10339
  type RevokeWitnessV5Response = Res<'/v5/contracts/{contractAddress}/witnesses/{witnessId}/revoke', 'post'>;
10218
10340
  type AccountResponse = Res<'/v1/account', 'get'>;
10219
10341
  type ResetAccountResponse = Res<'/v1/account', 'delete'>;
10342
+ type ReissueProvisioningTokenResponse = Res<'/v1/account/provisioning-token/reissue', 'post'>;
10220
10343
  type LedgerResponse = Res<'/v1/account/ledger', 'get'>;
10221
10344
  type TotpEnrollResponse = Res<'/v1/account/mfa/totp/enroll', 'post'>;
10222
10345
  type TotpConfirmRequest = Req<'/v1/account/mfa/totp/confirm', 'post'>;
@@ -10457,6 +10580,8 @@ declare class WitniumchainClient {
10457
10580
  private readonly verifierStorage;
10458
10581
  private discoveryCache;
10459
10582
  private refreshInFlight;
10583
+ private accessTokenFromSession;
10584
+ private sessionExchangeInFlight;
10460
10585
  /** Subscriptions / billing helpers. See {@link Subscriptions}. */
10461
10586
  readonly subscriptions: Subscriptions;
10462
10587
  /** Delegated-key namespace including the one-call {@link DelegatedKeys.provision} flow. */
@@ -10543,6 +10668,13 @@ declare class WitniumchainClient {
10543
10668
  * do not build product UI on this; it's a dev-loop convenience.
10544
10669
  */
10545
10670
  deleteAccount(): Promise<ResetAccountResponse>;
10671
+ /**
10672
+ * Re-mint a provisioning token for a verified-but-not-yet-provisioned
10673
+ * account. Use when the token from `verifyEmail` was lost (e.g. the verify
10674
+ * link was opened on a different device). Throws 409 if the email isn't
10675
+ * verified or a contract already exists; rate-limited per account.
10676
+ */
10677
+ reissueProvisioningToken(): Promise<ReissueProvisioningTokenResponse>;
10546
10678
  enrollTotp(): Promise<TotpEnrollResponse>;
10547
10679
  confirmTotp(body: TotpConfirmRequest): Promise<TotpConfirmResponse>;
10548
10680
  disableTotp(): Promise<TotpDisableResponse>;
@@ -10624,6 +10756,41 @@ declare class WitniumchainClient {
10624
10756
  * instead of retrying with a now-invalid token.
10625
10757
  */
10626
10758
  refreshAccessToken(): Promise<OAuthTokenSnapshot>;
10759
+ /**
10760
+ * Exchange the logged-in session (the `wac_session` cookie) for a short-lived
10761
+ * bearer access token and cache it as the client's `accessToken`.
10762
+ *
10763
+ * This is the SDK side of the session→token model (accounts'
10764
+ * `POST /v1/auth/access-token`): the dashboard authenticates with the
10765
+ * cookie, but the operational API (delegated keys, witness writes, chain
10766
+ * reads) is bearer-only — no endpoint accepts the ambient cookie, so there's
10767
+ * no CSRF surface even with `SameSite=None`. The minted token is
10768
+ * byte-compatible with an OAuth user token (same signing key, `iss`, `aud`,
10769
+ * scope + org/role/contracts claims), so every `BearerJWT` route accepts it.
10770
+ *
10771
+ * Callers rarely invoke this directly — {@link applyAuth} mints transparently
10772
+ * on the first `BearerJWT` call when no token is set and re-mints on a 401.
10773
+ * It's exposed so a dashboard can pre-warm the token right after login.
10774
+ *
10775
+ * Requires a session: either `sessionCookie` on the constructor (Node) or an
10776
+ * ambient `wac_session` cookie carried by the browser (`credentials:
10777
+ * 'include'`). Throws {@link WitniumchainApiError} (401) when there's no
10778
+ * valid session.
10779
+ */
10780
+ exchangeSessionForToken(): Promise<OAuthTokenSnapshot>;
10781
+ /**
10782
+ * Best-effort transparent mint for the `BearerJWT` path: if no access token
10783
+ * is cached, try the session exchange (single-flight). Swallows failure so
10784
+ * the caller in {@link applyAuth} surfaces the actionable "no token / no
10785
+ * session" guidance rather than a raw 401 from the exchange endpoint.
10786
+ */
10787
+ private ensureSessionAccessToken;
10788
+ /**
10789
+ * Obtain a fresh access token for a 401-retry, picking the right mechanism:
10790
+ * an OAuth refresh when a refresh credential exists, else a session re-mint
10791
+ * for a session-exchanged token. Returns true when a fresh token is in hand.
10792
+ */
10793
+ private reauthenticateForRetry;
10627
10794
  /**
10628
10795
  * End the OAuth session.
10629
10796
  *
@@ -11072,4 +11239,4 @@ declare function buildRevokeSigningKeyPayload(args: {
11072
11239
  key: string;
11073
11240
  }): string;
11074
11241
 
11075
- export { type AccountResponse, type AccountType, type paths$1 as AccountsPaths, type AddSigningKeyRequest$1 as AddSigningKeyRequest, type AddSigningKeyResponse, type AdjustCreditsRequest, type AdjustCreditsResponse, type BeginOAuthLoginArgs, type BeginOAuthLoginResult, type paths as ChainPaths, type CheckoutRequest, type CheckoutResponse, type CreateOrgRequest, type CreateOrgResponse, type CreateOrganizationRequest, type CreateOrganizationResponse, type CreateUserRequest, type CreateUserResponse, DelegatedKeys, type FinalizeWitnessResponse, type ForgotPasswordRequest, type ForgotPasswordResponse, type GetWitnessResponse, type HealthLiveResponse, type HealthReadyResponse, type InviteMemberRequest, type InviteMemberResponse, type LedgerResponse, type ListDelegatedKeysResponse, type ListOauthSessionsResponse, type ListUsersResponse, type LoginRequest, type LoginResponse, type LogoutResponse, type MembersListResponse, MfaNamespace, MfaRecoveryCodes, MfaTotp, type OAuthTokenSnapshot, OWNER_OP, OauthNamespace, OauthSessions, OrgMembers, OrgUsers, type OwnerOpName, type OwnerSigner, type PauseRequest$1 as PauseRequest, type PauseResponse, type PkceVerifierStorage, type PortalResponse, type PrepareDelegatedKeyRequest, type PreparedDelegatedKeyResponse, type ProposeWitnessRequest, type ProposeWitnessResponse, type ProvisionContractRequest, type ProvisionContractResponse, type ProvisionDelegatedKeyArgs, type ProvisionDelegatedKeyResult, type PublicOrgResponse, type RecoveryCodesRegenerateResponse, type RemoveMemberResponse, type ResendInviteResponse, type ResetAccountResponse, type ResetPasswordRequest, type ResetPasswordResponse, type RevokeDelegatedKeyResponse, type RevokeSigningKeyRequest$1 as RevokeSigningKeyRequest, type RevokeSigningKeyResponse, type RevokeWitnessRequest, type RevokeWitnessResponse, type RotateApiKeyResponse, type SetAccountTypeRequest, type SetAccountTypeResponse, type SetMemberRoleRequest, type SetMemberRoleResponse, type SignRequest, type SignResponse, type SignWitnessRequest, type SignWitnessResponse, type SignedRequestSigner, SigningKeys, type SignupRequest, type SignupResponse, type SubmitDelegatedKeyRequest, type SubmitDelegatedKeyResponse, Subscriptions, type SuspendMemberResponse, type TotpConfirmRequest, type TotpConfirmResponse, type TotpDisableResponse, type TotpEnrollResponse, type UnpauseRequest, type UnpauseResponse, type VerifyEmailResponse, type VerifyOrganizationResponse, WitniumchainAdminClient, type WitniumchainAdminClientConfig, WitniumchainApiError, WitniumchainChainAdminClient, type WitniumchainChainAdminClientConfig, WitniumchainClient, type WitniumchainClientConfig, WitniumchainOrgClient, type WitniumchainOrgClientConfig, buildAddSigningKeyPayload, buildPausePayload, buildRevokeSigningKeyPayload, buildUnpausePayload, defaultVerifierStorage };
11242
+ export { type AccountResponse, type AccountType, type paths$1 as AccountsPaths, type AddSigningKeyRequest$1 as AddSigningKeyRequest, type AddSigningKeyResponse, type AdjustCreditsRequest, type AdjustCreditsResponse, type BeginOAuthLoginArgs, type BeginOAuthLoginResult, type paths as ChainPaths, type CheckoutRequest, type CheckoutResponse, type CreateOrgRequest, type CreateOrgResponse, type CreateOrganizationRequest, type CreateOrganizationResponse, type CreateUserRequest, type CreateUserResponse, DelegatedKeys, type FinalizeWitnessResponse, type ForgotPasswordRequest, type ForgotPasswordResponse, type GetWitnessResponse, type HealthLiveResponse, type HealthReadyResponse, type InviteMemberRequest, type InviteMemberResponse, type LedgerResponse, type ListDelegatedKeysResponse, type ListOauthSessionsResponse, type ListUsersResponse, type LoginRequest, type LoginResponse, type LogoutResponse, type MembersListResponse, MfaNamespace, MfaRecoveryCodes, MfaTotp, type OAuthTokenSnapshot, OWNER_OP, OauthNamespace, OauthSessions, OrgMembers, OrgUsers, type OwnerOpName, type OwnerSigner, type PauseRequest$1 as PauseRequest, type PauseResponse, type PkceVerifierStorage, type PortalResponse, type PrepareDelegatedKeyRequest, type PreparedDelegatedKeyResponse, type ProposeWitnessRequest, type ProposeWitnessResponse, type ProvisionContractRequest, type ProvisionContractResponse, type ProvisionDelegatedKeyArgs, type ProvisionDelegatedKeyResult, type PublicOrgResponse, type RecoveryCodesRegenerateResponse, type ReissueProvisioningTokenResponse, type RemoveMemberResponse, type ResendInviteResponse, type ResetAccountResponse, type ResetPasswordRequest, type ResetPasswordResponse, type RevokeDelegatedKeyResponse, type RevokeSigningKeyRequest$1 as RevokeSigningKeyRequest, type RevokeSigningKeyResponse, type RevokeWitnessRequest, type RevokeWitnessResponse, type RotateApiKeyResponse, type SetAccountTypeRequest, type SetAccountTypeResponse, type SetMemberRoleRequest, type SetMemberRoleResponse, type SignRequest, type SignResponse, type SignWitnessRequest, type SignWitnessResponse, type SignedRequestSigner, SigningKeys, type SignupRequest, type SignupResponse, type SubmitDelegatedKeyRequest, type SubmitDelegatedKeyResponse, Subscriptions, type SuspendMemberResponse, type TotpConfirmRequest, type TotpConfirmResponse, type TotpDisableResponse, type TotpEnrollResponse, type UnpauseRequest, type UnpauseResponse, type VerifyEmailResponse, type VerifyOrganizationResponse, WitniumchainAdminClient, type WitniumchainAdminClientConfig, WitniumchainApiError, WitniumchainChainAdminClient, type WitniumchainChainAdminClientConfig, WitniumchainClient, type WitniumchainClientConfig, WitniumchainOrgClient, type WitniumchainOrgClientConfig, buildAddSigningKeyPayload, buildPausePayload, buildRevokeSigningKeyPayload, buildUnpausePayload, defaultVerifierStorage };
package/dist/index.d.ts CHANGED
@@ -5605,6 +5605,128 @@ interface paths$1 {
5605
5605
  patch?: never;
5606
5606
  trace?: never;
5607
5607
  };
5608
+ "/v1/account/provisioning-token/reissue": {
5609
+ parameters: {
5610
+ query?: never;
5611
+ header?: never;
5612
+ path?: never;
5613
+ cookie?: never;
5614
+ };
5615
+ get?: never;
5616
+ put?: never;
5617
+ /**
5618
+ * Re-mint a provisioning token (verified-but-not-provisioned recovery)
5619
+ * @description Mints a fresh single-use provisioning token for a signed-in user whose email is verified but who has no contract yet — recovery for when the token from email-verify was lost (e.g. verify opened on another device). Returns 409 if email is unverified or a contract already exists. Rate limited per account.
5620
+ */
5621
+ post: {
5622
+ parameters: {
5623
+ query?: never;
5624
+ header?: never;
5625
+ path?: never;
5626
+ cookie?: never;
5627
+ };
5628
+ requestBody?: never;
5629
+ responses: {
5630
+ /** @description Success */
5631
+ 200: {
5632
+ headers: {
5633
+ [name: string]: unknown;
5634
+ };
5635
+ content: {
5636
+ "application/json": {
5637
+ provisioningToken: string;
5638
+ /**
5639
+ * Format: date-time
5640
+ * @description ISO 8601 date-time string
5641
+ * @example 2026-05-20T10:30:00.000Z
5642
+ */
5643
+ expiresAt: string;
5644
+ };
5645
+ };
5646
+ };
5647
+ /** @description Unauthorized — authentication required or invalid */
5648
+ 401: {
5649
+ headers: {
5650
+ [name: string]: unknown;
5651
+ };
5652
+ content: {
5653
+ "application/json": {
5654
+ /**
5655
+ * @description HTTP status code
5656
+ * @example 400
5657
+ */
5658
+ statusCode?: number;
5659
+ /**
5660
+ * @description Short error label
5661
+ * @example Bad Request
5662
+ */
5663
+ error?: string;
5664
+ /**
5665
+ * @description Human-readable error message. Validation errors from `ZodError.flatten()` may be returned as an array.
5666
+ * @example Validation failed
5667
+ */
5668
+ message: string | string[];
5669
+ };
5670
+ };
5671
+ };
5672
+ /** @description Conflict */
5673
+ 409: {
5674
+ headers: {
5675
+ [name: string]: unknown;
5676
+ };
5677
+ content: {
5678
+ "application/json": {
5679
+ /**
5680
+ * @description HTTP status code
5681
+ * @example 400
5682
+ */
5683
+ statusCode?: number;
5684
+ /**
5685
+ * @description Short error label
5686
+ * @example Bad Request
5687
+ */
5688
+ error?: string;
5689
+ /**
5690
+ * @description Human-readable error message. Validation errors from `ZodError.flatten()` may be returned as an array.
5691
+ * @example Validation failed
5692
+ */
5693
+ message: string | string[];
5694
+ };
5695
+ };
5696
+ };
5697
+ /** @description Too Many Requests */
5698
+ 429: {
5699
+ headers: {
5700
+ [name: string]: unknown;
5701
+ };
5702
+ content: {
5703
+ "application/json": {
5704
+ /**
5705
+ * @description HTTP status code
5706
+ * @example 400
5707
+ */
5708
+ statusCode?: number;
5709
+ /**
5710
+ * @description Short error label
5711
+ * @example Bad Request
5712
+ */
5713
+ error?: string;
5714
+ /**
5715
+ * @description Human-readable error message. Validation errors from `ZodError.flatten()` may be returned as an array.
5716
+ * @example Validation failed
5717
+ */
5718
+ message: string | string[];
5719
+ };
5720
+ };
5721
+ };
5722
+ };
5723
+ };
5724
+ delete?: never;
5725
+ options?: never;
5726
+ head?: never;
5727
+ patch?: never;
5728
+ trace?: never;
5729
+ };
5608
5730
  "/v1/account": {
5609
5731
  parameters: {
5610
5732
  query?: never;
@@ -10217,6 +10339,7 @@ type RevokeWitnessV5Request = Req<'/v5/contracts/{contractAddress}/witnesses/{wi
10217
10339
  type RevokeWitnessV5Response = Res<'/v5/contracts/{contractAddress}/witnesses/{witnessId}/revoke', 'post'>;
10218
10340
  type AccountResponse = Res<'/v1/account', 'get'>;
10219
10341
  type ResetAccountResponse = Res<'/v1/account', 'delete'>;
10342
+ type ReissueProvisioningTokenResponse = Res<'/v1/account/provisioning-token/reissue', 'post'>;
10220
10343
  type LedgerResponse = Res<'/v1/account/ledger', 'get'>;
10221
10344
  type TotpEnrollResponse = Res<'/v1/account/mfa/totp/enroll', 'post'>;
10222
10345
  type TotpConfirmRequest = Req<'/v1/account/mfa/totp/confirm', 'post'>;
@@ -10457,6 +10580,8 @@ declare class WitniumchainClient {
10457
10580
  private readonly verifierStorage;
10458
10581
  private discoveryCache;
10459
10582
  private refreshInFlight;
10583
+ private accessTokenFromSession;
10584
+ private sessionExchangeInFlight;
10460
10585
  /** Subscriptions / billing helpers. See {@link Subscriptions}. */
10461
10586
  readonly subscriptions: Subscriptions;
10462
10587
  /** Delegated-key namespace including the one-call {@link DelegatedKeys.provision} flow. */
@@ -10543,6 +10668,13 @@ declare class WitniumchainClient {
10543
10668
  * do not build product UI on this; it's a dev-loop convenience.
10544
10669
  */
10545
10670
  deleteAccount(): Promise<ResetAccountResponse>;
10671
+ /**
10672
+ * Re-mint a provisioning token for a verified-but-not-yet-provisioned
10673
+ * account. Use when the token from `verifyEmail` was lost (e.g. the verify
10674
+ * link was opened on a different device). Throws 409 if the email isn't
10675
+ * verified or a contract already exists; rate-limited per account.
10676
+ */
10677
+ reissueProvisioningToken(): Promise<ReissueProvisioningTokenResponse>;
10546
10678
  enrollTotp(): Promise<TotpEnrollResponse>;
10547
10679
  confirmTotp(body: TotpConfirmRequest): Promise<TotpConfirmResponse>;
10548
10680
  disableTotp(): Promise<TotpDisableResponse>;
@@ -10624,6 +10756,41 @@ declare class WitniumchainClient {
10624
10756
  * instead of retrying with a now-invalid token.
10625
10757
  */
10626
10758
  refreshAccessToken(): Promise<OAuthTokenSnapshot>;
10759
+ /**
10760
+ * Exchange the logged-in session (the `wac_session` cookie) for a short-lived
10761
+ * bearer access token and cache it as the client's `accessToken`.
10762
+ *
10763
+ * This is the SDK side of the session→token model (accounts'
10764
+ * `POST /v1/auth/access-token`): the dashboard authenticates with the
10765
+ * cookie, but the operational API (delegated keys, witness writes, chain
10766
+ * reads) is bearer-only — no endpoint accepts the ambient cookie, so there's
10767
+ * no CSRF surface even with `SameSite=None`. The minted token is
10768
+ * byte-compatible with an OAuth user token (same signing key, `iss`, `aud`,
10769
+ * scope + org/role/contracts claims), so every `BearerJWT` route accepts it.
10770
+ *
10771
+ * Callers rarely invoke this directly — {@link applyAuth} mints transparently
10772
+ * on the first `BearerJWT` call when no token is set and re-mints on a 401.
10773
+ * It's exposed so a dashboard can pre-warm the token right after login.
10774
+ *
10775
+ * Requires a session: either `sessionCookie` on the constructor (Node) or an
10776
+ * ambient `wac_session` cookie carried by the browser (`credentials:
10777
+ * 'include'`). Throws {@link WitniumchainApiError} (401) when there's no
10778
+ * valid session.
10779
+ */
10780
+ exchangeSessionForToken(): Promise<OAuthTokenSnapshot>;
10781
+ /**
10782
+ * Best-effort transparent mint for the `BearerJWT` path: if no access token
10783
+ * is cached, try the session exchange (single-flight). Swallows failure so
10784
+ * the caller in {@link applyAuth} surfaces the actionable "no token / no
10785
+ * session" guidance rather than a raw 401 from the exchange endpoint.
10786
+ */
10787
+ private ensureSessionAccessToken;
10788
+ /**
10789
+ * Obtain a fresh access token for a 401-retry, picking the right mechanism:
10790
+ * an OAuth refresh when a refresh credential exists, else a session re-mint
10791
+ * for a session-exchanged token. Returns true when a fresh token is in hand.
10792
+ */
10793
+ private reauthenticateForRetry;
10627
10794
  /**
10628
10795
  * End the OAuth session.
10629
10796
  *
@@ -11072,4 +11239,4 @@ declare function buildRevokeSigningKeyPayload(args: {
11072
11239
  key: string;
11073
11240
  }): string;
11074
11241
 
11075
- export { type AccountResponse, type AccountType, type paths$1 as AccountsPaths, type AddSigningKeyRequest$1 as AddSigningKeyRequest, type AddSigningKeyResponse, type AdjustCreditsRequest, type AdjustCreditsResponse, type BeginOAuthLoginArgs, type BeginOAuthLoginResult, type paths as ChainPaths, type CheckoutRequest, type CheckoutResponse, type CreateOrgRequest, type CreateOrgResponse, type CreateOrganizationRequest, type CreateOrganizationResponse, type CreateUserRequest, type CreateUserResponse, DelegatedKeys, type FinalizeWitnessResponse, type ForgotPasswordRequest, type ForgotPasswordResponse, type GetWitnessResponse, type HealthLiveResponse, type HealthReadyResponse, type InviteMemberRequest, type InviteMemberResponse, type LedgerResponse, type ListDelegatedKeysResponse, type ListOauthSessionsResponse, type ListUsersResponse, type LoginRequest, type LoginResponse, type LogoutResponse, type MembersListResponse, MfaNamespace, MfaRecoveryCodes, MfaTotp, type OAuthTokenSnapshot, OWNER_OP, OauthNamespace, OauthSessions, OrgMembers, OrgUsers, type OwnerOpName, type OwnerSigner, type PauseRequest$1 as PauseRequest, type PauseResponse, type PkceVerifierStorage, type PortalResponse, type PrepareDelegatedKeyRequest, type PreparedDelegatedKeyResponse, type ProposeWitnessRequest, type ProposeWitnessResponse, type ProvisionContractRequest, type ProvisionContractResponse, type ProvisionDelegatedKeyArgs, type ProvisionDelegatedKeyResult, type PublicOrgResponse, type RecoveryCodesRegenerateResponse, type RemoveMemberResponse, type ResendInviteResponse, type ResetAccountResponse, type ResetPasswordRequest, type ResetPasswordResponse, type RevokeDelegatedKeyResponse, type RevokeSigningKeyRequest$1 as RevokeSigningKeyRequest, type RevokeSigningKeyResponse, type RevokeWitnessRequest, type RevokeWitnessResponse, type RotateApiKeyResponse, type SetAccountTypeRequest, type SetAccountTypeResponse, type SetMemberRoleRequest, type SetMemberRoleResponse, type SignRequest, type SignResponse, type SignWitnessRequest, type SignWitnessResponse, type SignedRequestSigner, SigningKeys, type SignupRequest, type SignupResponse, type SubmitDelegatedKeyRequest, type SubmitDelegatedKeyResponse, Subscriptions, type SuspendMemberResponse, type TotpConfirmRequest, type TotpConfirmResponse, type TotpDisableResponse, type TotpEnrollResponse, type UnpauseRequest, type UnpauseResponse, type VerifyEmailResponse, type VerifyOrganizationResponse, WitniumchainAdminClient, type WitniumchainAdminClientConfig, WitniumchainApiError, WitniumchainChainAdminClient, type WitniumchainChainAdminClientConfig, WitniumchainClient, type WitniumchainClientConfig, WitniumchainOrgClient, type WitniumchainOrgClientConfig, buildAddSigningKeyPayload, buildPausePayload, buildRevokeSigningKeyPayload, buildUnpausePayload, defaultVerifierStorage };
11242
+ export { type AccountResponse, type AccountType, type paths$1 as AccountsPaths, type AddSigningKeyRequest$1 as AddSigningKeyRequest, type AddSigningKeyResponse, type AdjustCreditsRequest, type AdjustCreditsResponse, type BeginOAuthLoginArgs, type BeginOAuthLoginResult, type paths as ChainPaths, type CheckoutRequest, type CheckoutResponse, type CreateOrgRequest, type CreateOrgResponse, type CreateOrganizationRequest, type CreateOrganizationResponse, type CreateUserRequest, type CreateUserResponse, DelegatedKeys, type FinalizeWitnessResponse, type ForgotPasswordRequest, type ForgotPasswordResponse, type GetWitnessResponse, type HealthLiveResponse, type HealthReadyResponse, type InviteMemberRequest, type InviteMemberResponse, type LedgerResponse, type ListDelegatedKeysResponse, type ListOauthSessionsResponse, type ListUsersResponse, type LoginRequest, type LoginResponse, type LogoutResponse, type MembersListResponse, MfaNamespace, MfaRecoveryCodes, MfaTotp, type OAuthTokenSnapshot, OWNER_OP, OauthNamespace, OauthSessions, OrgMembers, OrgUsers, type OwnerOpName, type OwnerSigner, type PauseRequest$1 as PauseRequest, type PauseResponse, type PkceVerifierStorage, type PortalResponse, type PrepareDelegatedKeyRequest, type PreparedDelegatedKeyResponse, type ProposeWitnessRequest, type ProposeWitnessResponse, type ProvisionContractRequest, type ProvisionContractResponse, type ProvisionDelegatedKeyArgs, type ProvisionDelegatedKeyResult, type PublicOrgResponse, type RecoveryCodesRegenerateResponse, type ReissueProvisioningTokenResponse, type RemoveMemberResponse, type ResendInviteResponse, type ResetAccountResponse, type ResetPasswordRequest, type ResetPasswordResponse, type RevokeDelegatedKeyResponse, type RevokeSigningKeyRequest$1 as RevokeSigningKeyRequest, type RevokeSigningKeyResponse, type RevokeWitnessRequest, type RevokeWitnessResponse, type RotateApiKeyResponse, type SetAccountTypeRequest, type SetAccountTypeResponse, type SetMemberRoleRequest, type SetMemberRoleResponse, type SignRequest, type SignResponse, type SignWitnessRequest, type SignWitnessResponse, type SignedRequestSigner, SigningKeys, type SignupRequest, type SignupResponse, type SubmitDelegatedKeyRequest, type SubmitDelegatedKeyResponse, Subscriptions, type SuspendMemberResponse, type TotpConfirmRequest, type TotpConfirmResponse, type TotpDisableResponse, type TotpEnrollResponse, type UnpauseRequest, type UnpauseResponse, type VerifyEmailResponse, type VerifyOrganizationResponse, WitniumchainAdminClient, type WitniumchainAdminClientConfig, WitniumchainApiError, WitniumchainChainAdminClient, type WitniumchainChainAdminClientConfig, WitniumchainClient, type WitniumchainClientConfig, WitniumchainOrgClient, type WitniumchainOrgClientConfig, buildAddSigningKeyPayload, buildPausePayload, buildRevokeSigningKeyPayload, buildUnpausePayload, defaultVerifierStorage };
package/dist/index.js CHANGED
@@ -111,6 +111,16 @@ var WitniumchainClient = class {
111
111
  // tokens rotate on use (D10), so a second concurrent refresh would race the
112
112
  // first and one of them would 401.
113
113
  refreshInFlight;
114
+ // True when the current `accessToken` was minted by the session→token
115
+ // exchange (`exchangeSessionForToken`) rather than the OAuth code/refresh
116
+ // flow. Drives the 401-retry: a session-exchanged token has no refresh
117
+ // credential, so on expiry the SDK re-mints from the cookie instead of
118
+ // refreshing. Reset to false whenever an OAuth /token response lands.
119
+ accessTokenFromSession = false;
120
+ // Single-flight gate for the session→token exchange. A cookie-only client's
121
+ // first BearerJWT call (and any concurrent fan-out) awaits one in-flight
122
+ // mint rather than minting N tokens.
123
+ sessionExchangeInFlight;
114
124
  /** Subscriptions / billing helpers. See {@link Subscriptions}. */
115
125
  subscriptions;
116
126
  /** Delegated-key namespace including the one-call {@link DelegatedKeys.provision} flow. */
@@ -475,6 +485,17 @@ var WitniumchainClient = class {
475
485
  deleteAccount() {
476
486
  return this.req("DELETE", "/v1/account", { auth: "SessionCookie" });
477
487
  }
488
+ /**
489
+ * Re-mint a provisioning token for a verified-but-not-yet-provisioned
490
+ * account. Use when the token from `verifyEmail` was lost (e.g. the verify
491
+ * link was opened on a different device). Throws 409 if the email isn't
492
+ * verified or a contract already exists; rate-limited per account.
493
+ */
494
+ reissueProvisioningToken() {
495
+ return this.req("POST", "/v1/account/provisioning-token/reissue", {
496
+ auth: "SessionCookie"
497
+ });
498
+ }
478
499
  // ────────────────────────────────────────────────────────────────────────
479
500
  // MFA (/v1/account/mfa/*)
480
501
  //
@@ -776,6 +797,84 @@ var WitniumchainClient = class {
776
797
  })();
777
798
  return this.refreshInFlight;
778
799
  }
800
+ /**
801
+ * Exchange the logged-in session (the `wac_session` cookie) for a short-lived
802
+ * bearer access token and cache it as the client's `accessToken`.
803
+ *
804
+ * This is the SDK side of the session→token model (accounts'
805
+ * `POST /v1/auth/access-token`): the dashboard authenticates with the
806
+ * cookie, but the operational API (delegated keys, witness writes, chain
807
+ * reads) is bearer-only — no endpoint accepts the ambient cookie, so there's
808
+ * no CSRF surface even with `SameSite=None`. The minted token is
809
+ * byte-compatible with an OAuth user token (same signing key, `iss`, `aud`,
810
+ * scope + org/role/contracts claims), so every `BearerJWT` route accepts it.
811
+ *
812
+ * Callers rarely invoke this directly — {@link applyAuth} mints transparently
813
+ * on the first `BearerJWT` call when no token is set and re-mints on a 401.
814
+ * It's exposed so a dashboard can pre-warm the token right after login.
815
+ *
816
+ * Requires a session: either `sessionCookie` on the constructor (Node) or an
817
+ * ambient `wac_session` cookie carried by the browser (`credentials:
818
+ * 'include'`). Throws {@link WitniumchainApiError} (401) when there's no
819
+ * valid session.
820
+ */
821
+ async exchangeSessionForToken() {
822
+ if (this.sessionExchangeInFlight) return this.sessionExchangeInFlight;
823
+ this.sessionExchangeInFlight = (async () => {
824
+ try {
825
+ const res = await this.req("POST", "/v1/auth/access-token", { auth: "SessionCookie" });
826
+ this.accessToken = res.accessToken;
827
+ this.accessTokenFromSession = true;
828
+ this.refreshToken = void 0;
829
+ this.hasRefreshCookie = false;
830
+ return {
831
+ accessToken: res.accessToken,
832
+ expiresAt: Math.floor(new Date(res.expiresAt).getTime() / 1e3)
833
+ };
834
+ } finally {
835
+ this.sessionExchangeInFlight = void 0;
836
+ }
837
+ })();
838
+ return this.sessionExchangeInFlight;
839
+ }
840
+ /**
841
+ * Best-effort transparent mint for the `BearerJWT` path: if no access token
842
+ * is cached, try the session exchange (single-flight). Swallows failure so
843
+ * the caller in {@link applyAuth} surfaces the actionable "no token / no
844
+ * session" guidance rather than a raw 401 from the exchange endpoint.
845
+ */
846
+ async ensureSessionAccessToken() {
847
+ if (this.accessToken) return;
848
+ try {
849
+ await this.exchangeSessionForToken();
850
+ } catch {
851
+ }
852
+ }
853
+ /**
854
+ * Obtain a fresh access token for a 401-retry, picking the right mechanism:
855
+ * an OAuth refresh when a refresh credential exists, else a session re-mint
856
+ * for a session-exchanged token. Returns true when a fresh token is in hand.
857
+ */
858
+ async reauthenticateForRetry() {
859
+ if (this.refreshToken || this.hasRefreshCookie) {
860
+ try {
861
+ await this.refreshAccessToken();
862
+ return true;
863
+ } catch {
864
+ return false;
865
+ }
866
+ }
867
+ if (this.accessTokenFromSession) {
868
+ this.accessToken = void 0;
869
+ try {
870
+ await this.exchangeSessionForToken();
871
+ return true;
872
+ } catch {
873
+ return false;
874
+ }
875
+ }
876
+ return false;
877
+ }
779
878
  /**
780
879
  * End the OAuth session.
781
880
  *
@@ -790,6 +889,7 @@ var WitniumchainClient = class {
790
889
  */
791
890
  signOut() {
792
891
  this.accessToken = void 0;
892
+ this.accessTokenFromSession = false;
793
893
  this.refreshToken = void 0;
794
894
  this.hasRefreshCookie = false;
795
895
  this.pendingLogins.clear();
@@ -887,6 +987,7 @@ var WitniumchainClient = class {
887
987
  });
888
988
  }
889
989
  this.accessToken = tokens.access_token;
990
+ this.accessTokenFromSession = false;
890
991
  if (tokens.refresh_token) {
891
992
  this.refreshToken = tokens.refresh_token;
892
993
  } else {
@@ -1017,13 +1118,9 @@ var WitniumchainClient = class {
1017
1118
  if (opts._isRetry) return false;
1018
1119
  if (opts.auth !== "BearerJWT") return false;
1019
1120
  if (res.status !== 401) return false;
1020
- if (!this.refreshToken && !this.hasRefreshCookie) return false;
1021
- try {
1022
- await this.refreshAccessToken();
1023
- return true;
1024
- } catch {
1121
+ if (!this.refreshToken && !this.hasRefreshCookie && !this.accessTokenFromSession)
1025
1122
  return false;
1026
- }
1123
+ return this.reauthenticateForRetry();
1027
1124
  }
1028
1125
  /**
1029
1126
  * Same decision as `shouldRefreshAndRetry` but for the JSON-parsed path,
@@ -1037,18 +1134,14 @@ var WitniumchainClient = class {
1037
1134
  if (opts._isRetry) return false;
1038
1135
  if (opts.auth !== "BearerJWT") return false;
1039
1136
  if (status !== 401) return false;
1040
- if (!this.refreshToken && !this.hasRefreshCookie) return false;
1137
+ if (!this.refreshToken && !this.hasRefreshCookie && !this.accessTokenFromSession)
1138
+ return false;
1041
1139
  const body = parsed;
1042
1140
  const label = typeof body?.error === "string" ? body.error : void 0;
1043
1141
  if (label !== void 0 && label !== "token_expired" && label !== "invalid_token") {
1044
1142
  return false;
1045
1143
  }
1046
- try {
1047
- await this.refreshAccessToken();
1048
- return true;
1049
- } catch {
1050
- return false;
1051
- }
1144
+ return this.reauthenticateForRetry();
1052
1145
  }
1053
1146
  /**
1054
1147
  * Resolve which base URL to call. Default is accounts (`baseUrl`). When a
@@ -1088,9 +1181,12 @@ var WitniumchainClient = class {
1088
1181
  return;
1089
1182
  }
1090
1183
  case "BearerJWT": {
1184
+ if (!this.accessToken) {
1185
+ await this.ensureSessionAccessToken();
1186
+ }
1091
1187
  if (!this.accessToken) {
1092
1188
  throw new Error(
1093
- `WitniumchainClient: ${method} ${path} requires an OAuth access token. Pass \`accessToken\` to the constructor, or call \`beginOAuthLogin\`/\`completeOAuthLogin\` to obtain one.`
1189
+ `WitniumchainClient: ${method} ${path} requires an OAuth access token. Pass \`accessToken\` to the constructor, call \`beginOAuthLogin\`/\`completeOAuthLogin\`, or \u2014 for a logged-in dashboard \u2014 provide \`sessionCookie\` (Node) or rely on the browser \`wac_session\` cookie so the SDK can mint one.`
1094
1190
  );
1095
1191
  }
1096
1192
  headers["authorization"] = `Bearer ${this.accessToken}`;