@shuttle.technology/authorization 0.1.0 → 0.2.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/CHANGELOG.md +191 -0
- package/README.md +1082 -666
- package/dist/accountLists.d.ts +28 -0
- package/dist/accountLists.js +27 -0
- package/dist/auth.d.ts +11 -11
- package/dist/auth.js +28 -54
- package/dist/client.d.ts +62 -174
- package/dist/client.js +381 -354
- package/dist/clientTypes.d.ts +56 -0
- package/dist/clientTypes.js +5 -0
- package/dist/configuration.d.ts +48 -0
- package/dist/configuration.js +72 -0
- package/dist/consentDebit.d.ts +36 -0
- package/dist/consentDebit.js +95 -0
- package/dist/credentials.d.ts +116 -0
- package/dist/credentials.js +315 -0
- package/dist/debitPermissionWire.d.ts +90 -0
- package/dist/debitPermissionWire.js +118 -0
- package/dist/debitPermissions.d.ts +39 -0
- package/dist/debitPermissions.js +117 -0
- package/dist/deviceRecovery.d.ts +40 -0
- package/dist/deviceRecovery.js +143 -0
- package/dist/deviceShares.d.ts +91 -0
- package/dist/deviceShares.js +204 -0
- package/dist/errors.d.ts +280 -0
- package/dist/errors.js +85 -0
- package/dist/linkedRecovery.d.ts +40 -0
- package/dist/linkedRecovery.js +49 -0
- package/dist/linkedRegistrations.d.ts +11 -0
- package/dist/linkedRegistrations.js +109 -0
- package/dist/linkedWallets.d.ts +46 -18
- package/dist/linkedWallets.js +85 -120
- package/dist/me.d.ts +27 -0
- package/dist/me.js +30 -0
- package/dist/mobile.d.ts +64 -0
- package/dist/mobile.js +69 -0
- package/dist/redirects.d.ts +45 -0
- package/dist/redirects.js +108 -0
- package/dist/serviceGrants.d.ts +52 -0
- package/dist/serviceGrants.js +46 -0
- package/dist/slice4.d.ts +20 -6
- package/dist/slice4.js +22 -8
- package/dist/streams.js +1 -1
- package/dist/walletCreateGrant.d.ts +62 -0
- package/dist/walletCreateGrant.js +89 -0
- package/dist/walletDisplayParts.d.ts +2 -0
- package/dist/walletDisplayParts.js +4 -0
- package/dist/walletOperations.d.ts +23 -6
- package/dist/walletOperations.js +31 -22
- package/dist/webRenewal.d.ts +92 -0
- package/dist/webRenewal.js +179 -0
- package/package.json +25 -23
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface SessionProjection {
|
|
2
|
+
requestId: string;
|
|
3
|
+
items: Array<{
|
|
4
|
+
sessionId: string;
|
|
5
|
+
clientId: string;
|
|
6
|
+
state: string;
|
|
7
|
+
createdAt: string;
|
|
8
|
+
expiresAt: string;
|
|
9
|
+
current: boolean;
|
|
10
|
+
}>;
|
|
11
|
+
hasMore: boolean;
|
|
12
|
+
nextCursor?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface WalletProjection {
|
|
15
|
+
requestId: string;
|
|
16
|
+
items: Array<{
|
|
17
|
+
walletId: string;
|
|
18
|
+
network: string;
|
|
19
|
+
address: string;
|
|
20
|
+
state: string;
|
|
21
|
+
generation: string;
|
|
22
|
+
mappingVersion: string;
|
|
23
|
+
}>;
|
|
24
|
+
hasMore: boolean;
|
|
25
|
+
nextCursor?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function parseSessionPage(payload: unknown): SessionProjection;
|
|
28
|
+
export declare function parseWalletPage(payload: unknown): WalletProjection;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Two paged lists of the account's own: its sessions (`GET /v1/sessions`)
|
|
3
|
+
* and the wallets the provider created for it (`GET /v1/wallets`), each read
|
|
4
|
+
* as strictly as every other answer.
|
|
5
|
+
*/
|
|
6
|
+
import { ClientFlowError, canonicalDecimal, opaqueId, record } from "./auth.js";
|
|
7
|
+
import { pageEnvelope, pageProjection } from "./pages.js";
|
|
8
|
+
export function parseSessionPage(payload) {
|
|
9
|
+
const root = pageEnvelope(payload);
|
|
10
|
+
const items = root.items.map((value) => {
|
|
11
|
+
const item = record(value, ["session_id", "client_id", "state", "created_at", "expires_at", "current"]);
|
|
12
|
+
if (!opaqueId(item.session_id) || !opaqueId(item.client_id) || typeof item.state !== "string" || typeof item.created_at !== "string" || typeof item.expires_at !== "string" || typeof item.current !== "boolean")
|
|
13
|
+
throw new ClientFlowError("invalid_server_response");
|
|
14
|
+
return { sessionId: item.session_id, clientId: item.client_id, state: item.state, createdAt: item.created_at, expiresAt: item.expires_at, current: item.current };
|
|
15
|
+
});
|
|
16
|
+
return pageProjection(root.request_id, items, root.has_more, root.next_cursor);
|
|
17
|
+
}
|
|
18
|
+
export function parseWalletPage(payload) {
|
|
19
|
+
const root = pageEnvelope(payload);
|
|
20
|
+
const items = root.items.map((value) => {
|
|
21
|
+
const item = record(value, ["wallet_id", "network", "address", "state", "generation", "mapping_version"]);
|
|
22
|
+
if (!opaqueId(item.wallet_id) || typeof item.network !== "string" || typeof item.address !== "string" || typeof item.state !== "string" || !canonicalDecimal(item.generation) || !canonicalDecimal(item.mapping_version))
|
|
23
|
+
throw new ClientFlowError("invalid_server_response");
|
|
24
|
+
return { walletId: item.wallet_id, network: item.network, address: item.address, state: item.state, generation: item.generation, mappingVersion: item.mapping_version };
|
|
25
|
+
});
|
|
26
|
+
return pageProjection(root.request_id, items, root.has_more, root.next_cursor);
|
|
27
|
+
}
|
package/dist/auth.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type AuthorizationErrorCode } from "./errors.ts";
|
|
1
2
|
export declare const identityMethods: readonly ["google", "apple", "telegram", "passkey"];
|
|
2
3
|
export type IdentityMethod = (typeof identityMethods)[number];
|
|
3
4
|
export type AuthIntent = "signup" | "login";
|
|
@@ -7,8 +8,9 @@ export declare class ClientFlowError extends Error {
|
|
|
7
8
|
readonly code: string;
|
|
8
9
|
constructor(code: string);
|
|
9
10
|
}
|
|
11
|
+
/** A refusal the provider answered, with one code of its ErrorCode enum (`AuthorizationErrorCodes`). */
|
|
10
12
|
export declare class AuthorizationError extends Error {
|
|
11
|
-
readonly code:
|
|
13
|
+
readonly code: AuthorizationErrorCode;
|
|
12
14
|
readonly retryable: boolean;
|
|
13
15
|
readonly nextAction: NextAction;
|
|
14
16
|
readonly requestId: string;
|
|
@@ -19,7 +21,7 @@ export declare class AuthorizationError extends Error {
|
|
|
19
21
|
};
|
|
20
22
|
readonly status: number;
|
|
21
23
|
constructor(input: {
|
|
22
|
-
code:
|
|
24
|
+
code: AuthorizationErrorCode;
|
|
23
25
|
retryable: boolean;
|
|
24
26
|
nextAction: NextAction;
|
|
25
27
|
requestId: string;
|
|
@@ -31,15 +33,14 @@ export declare class AuthorizationError extends Error {
|
|
|
31
33
|
status: number;
|
|
32
34
|
});
|
|
33
35
|
}
|
|
36
|
+
/** isAuthorizationError tells a provider refusal, and with codes one of those. */
|
|
37
|
+
export declare function isAuthorizationError(error: unknown, ...codes: AuthorizationErrorCode[]): error is AuthorizationError;
|
|
38
|
+
/**
|
|
39
|
+
* abortable waits for work, or rejects with the signal's reason as soon as
|
|
40
|
+
* the signal aborts; the work itself goes on for whoever else waits for it.
|
|
41
|
+
*/
|
|
42
|
+
export declare function abortable<T>(work: Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
34
43
|
export declare function parseAuthorizationError(payload: unknown, status: number): AuthorizationError;
|
|
35
|
-
type ErrorExpectation = {
|
|
36
|
-
status: number;
|
|
37
|
-
retryable: boolean;
|
|
38
|
-
nextAction: NextAction;
|
|
39
|
-
};
|
|
40
|
-
declare const errorCatalog: Readonly<Record<string, ErrorExpectation>>;
|
|
41
|
-
export type AuthorizationErrorCode = keyof typeof errorCatalog;
|
|
42
|
-
export declare function isAuthorizationErrorCode(value: unknown): value is AuthorizationErrorCode;
|
|
43
44
|
export declare function newHandoffBinding(crypto: Crypto): Promise<{
|
|
44
45
|
state: string;
|
|
45
46
|
verifier: string;
|
|
@@ -65,4 +66,3 @@ export declare function deadlineAfter(created: string, expires: string): boolean
|
|
|
65
66
|
export declare function unexpiredRFC3339(value: unknown, nowMs: number): value is string;
|
|
66
67
|
export declare function record(value: unknown, required: readonly string[], optional?: readonly string[]): Record<string, unknown>;
|
|
67
68
|
export declare function isNextAction(value: unknown): value is NextAction;
|
|
68
|
-
export {};
|
package/dist/auth.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AuthorizationErrorContracts, isAuthorizationErrorCode, operationIdCodes, possibleCommitStatus } from "./errors.js";
|
|
1
2
|
export const identityMethods = ["google", "apple", "telegram", "passkey"];
|
|
2
3
|
export class ClientFlowError extends Error {
|
|
3
4
|
code;
|
|
@@ -7,6 +8,7 @@ export class ClientFlowError extends Error {
|
|
|
7
8
|
this.code = code;
|
|
8
9
|
}
|
|
9
10
|
}
|
|
11
|
+
/** A refusal the provider answered, with one code of its ErrorCode enum (`AuthorizationErrorCodes`). */
|
|
10
12
|
export class AuthorizationError extends Error {
|
|
11
13
|
code;
|
|
12
14
|
retryable;
|
|
@@ -27,6 +29,28 @@ export class AuthorizationError extends Error {
|
|
|
27
29
|
this.status = input.status;
|
|
28
30
|
}
|
|
29
31
|
}
|
|
32
|
+
/** isAuthorizationError tells a provider refusal, and with codes one of those. */
|
|
33
|
+
export function isAuthorizationError(error, ...codes) {
|
|
34
|
+
return error instanceof AuthorizationError && (codes.length === 0 || codes.includes(error.code));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* abortable waits for work, or rejects with the signal's reason as soon as
|
|
38
|
+
* the signal aborts; the work itself goes on for whoever else waits for it.
|
|
39
|
+
*/
|
|
40
|
+
export function abortable(work, signal) {
|
|
41
|
+
if (!signal)
|
|
42
|
+
return work;
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
const abort = () => reject(signal.reason);
|
|
45
|
+
if (signal.aborted) {
|
|
46
|
+
work.catch(() => { });
|
|
47
|
+
abort();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
51
|
+
work.then((value) => { signal.removeEventListener("abort", abort); resolve(value); }, (error) => { signal.removeEventListener("abort", abort); reject(error); });
|
|
52
|
+
});
|
|
53
|
+
}
|
|
30
54
|
export function parseAuthorizationError(payload, status) {
|
|
31
55
|
const outer = record(payload, ["error"]);
|
|
32
56
|
const error = record(outer.error, ["code", "retryable", "next_action", "request_id"], ["operation_id", "window"]);
|
|
@@ -36,9 +60,10 @@ export function parseAuthorizationError(payload, status) {
|
|
|
36
60
|
if (error.operation_id !== undefined && !opaqueId(error.operation_id)) {
|
|
37
61
|
throw new ClientFlowError("invalid_error_response");
|
|
38
62
|
}
|
|
39
|
-
const expected =
|
|
40
|
-
const possibleCommit =
|
|
41
|
-
|
|
63
|
+
const expected = isAuthorizationErrorCode(error.code) ? AuthorizationErrorContracts[error.code] : undefined;
|
|
64
|
+
const possibleCommit = expected !== undefined && error.operation_id !== undefined && error.retryable === false && error.next_action === "lookup_operation" &&
|
|
65
|
+
status === possibleCommitStatus(error.code);
|
|
66
|
+
if (!expected || (!possibleCommit && (expected.status !== status || error.retryable !== expected.retryable || error.next_action !== expected.nextAction))) {
|
|
42
67
|
throw new ClientFlowError("invalid_error_response");
|
|
43
68
|
}
|
|
44
69
|
if (error.operation_id !== undefined && !possibleCommit && !operationIdCodes.has(error.code)) {
|
|
@@ -74,57 +99,6 @@ export function parseAuthorizationError(payload, status) {
|
|
|
74
99
|
status,
|
|
75
100
|
});
|
|
76
101
|
}
|
|
77
|
-
const errorCatalog = Object.freeze({
|
|
78
|
-
INVALID_REQUEST: { status: 400, retryable: false, nextAction: "none" },
|
|
79
|
-
REGISTRATION_SCOPE_SELECTION_REQUIRED: { status: 409, retryable: false, nextAction: "none" },
|
|
80
|
-
CURSOR_INVALID: { status: 400, retryable: false, nextAction: "none" },
|
|
81
|
-
UNSUPPORTED_VERSION: { status: 400, retryable: false, nextAction: "none" },
|
|
82
|
-
UNAUTHORIZED: { status: 401, retryable: false, nextAction: "reauthenticate" },
|
|
83
|
-
SCOPE_DENIED: { status: 403, retryable: false, nextAction: "none" },
|
|
84
|
-
ORIGIN_NOT_ALLOWED: { status: 403, retryable: false, nextAction: "none" },
|
|
85
|
-
LIMIT_PER_TRANSFER_EXCEEDED: { status: 403, retryable: false, nextAction: "none" },
|
|
86
|
-
LIMIT_DAILY_EXCEEDED: { status: 403, retryable: false, nextAction: "none" },
|
|
87
|
-
RECIPIENT_NOT_ALLOWED: { status: 403, retryable: false, nextAction: "none" },
|
|
88
|
-
CONFIRMATION_METHOD_UNAVAILABLE: { status: 403, retryable: false, nextAction: "use_passkey" },
|
|
89
|
-
USER_PROOF_REQUIRED: { status: 403, retryable: false, nextAction: "sign_user_request" },
|
|
90
|
-
USER_PROOF_INVALID: { status: 403, retryable: false, nextAction: "sign_user_request" },
|
|
91
|
-
REQUEST_GRANT_INVALID: { status: 403, retryable: false, nextAction: "use_passkey" },
|
|
92
|
-
NOT_FOUND: { status: 404, retryable: false, nextAction: "none" },
|
|
93
|
-
IDENTITY_NOT_REGISTERED: { status: 409, retryable: false, nextAction: "start_signup" },
|
|
94
|
-
IDENTITY_ALREADY_REGISTERED: { status: 409, retryable: false, nextAction: "start_login" },
|
|
95
|
-
IDENTITY_ALREADY_LINKED: { status: 409, retryable: false, nextAction: "none" },
|
|
96
|
-
ACCOUNT_REFERENCE_UNBOUND: { status: 409, retryable: false, nextAction: "none" },
|
|
97
|
-
LAST_FACTOR: { status: 409, retryable: false, nextAction: "none" },
|
|
98
|
-
CONFIRMATION_REPLAYED: { status: 409, retryable: false, nextAction: "none" },
|
|
99
|
-
CANNOT_CANCEL: { status: 409, retryable: false, nextAction: "none" },
|
|
100
|
-
VERSION_CONFLICT: { status: 409, retryable: false, nextAction: "refresh_resource" },
|
|
101
|
-
AUTHORIZATION_STALE: { status: 409, retryable: false, nextAction: "refresh_resource" },
|
|
102
|
-
IDEMPOTENCY_CONFLICT: { status: 409, retryable: false, nextAction: "lookup_operation" },
|
|
103
|
-
USER_PROOF_REPLAYED: { status: 409, retryable: false, nextAction: "lookup_operation" },
|
|
104
|
-
OPERATION_NOT_AUTHORIZED: { status: 409, retryable: false, nextAction: "use_passkey" },
|
|
105
|
-
RESULT_NOT_READY: { status: 409, retryable: true, nextAction: "wait_for_result" },
|
|
106
|
-
TRANSFER_IN_FLIGHT: { status: 409, retryable: true, nextAction: "retry_same_request" },
|
|
107
|
-
ATTEMPT_EXPIRED: { status: 410, retryable: false, nextAction: "reauthenticate" },
|
|
108
|
-
OPERATION_EXPIRED: { status: 410, retryable: false, nextAction: "none" },
|
|
109
|
-
RESULT_EXPIRED: { status: 410, retryable: false, nextAction: "none" },
|
|
110
|
-
RESYNC_REQUIRED: { status: 410, retryable: false, nextAction: "resync_streams" },
|
|
111
|
-
USER_PROOF_EXPIRED: { status: 410, retryable: false, nextAction: "sign_user_request" },
|
|
112
|
-
CAPABILITY_UNAVAILABLE: { status: 422, retryable: false, nextAction: "none" },
|
|
113
|
-
RECOVERY_UNAVAILABLE: { status: 422, retryable: false, nextAction: "none" },
|
|
114
|
-
PAYLOAD_NOT_SUPPORTED: { status: 422, retryable: false, nextAction: "none" },
|
|
115
|
-
RATE_LIMITED: { status: 429, retryable: true, nextAction: "retry_same_request" },
|
|
116
|
-
DEPENDENCY_UNAVAILABLE: { status: 503, retryable: true, nextAction: "retry_same_request" },
|
|
117
|
-
NETWORK_FEE_TOO_HIGH: { status: 503, retryable: true, nextAction: "retry_same_request" },
|
|
118
|
-
TENANT_AUTH_UNAVAILABLE: { status: 503, retryable: true, nextAction: "retry_same_request" },
|
|
119
|
-
AUDIT_UNAVAILABLE: { status: 503, retryable: true, nextAction: "retry_same_request" },
|
|
120
|
-
ADAPTER_INTEGRITY_CONFLICT: { status: 503, retryable: false, nextAction: "none" },
|
|
121
|
-
INTERNAL_ERROR: { status: 500, retryable: true, nextAction: "retry_same_request" },
|
|
122
|
-
});
|
|
123
|
-
export function isAuthorizationErrorCode(value) {
|
|
124
|
-
return typeof value === "string" && Object.prototype.hasOwnProperty.call(errorCatalog, value);
|
|
125
|
-
}
|
|
126
|
-
const possibleCommitCodes = new Set(["DEPENDENCY_UNAVAILABLE", "TENANT_AUTH_UNAVAILABLE", "AUDIT_UNAVAILABLE", "INTERNAL_ERROR"]);
|
|
127
|
-
const operationIdCodes = new Set(["IDEMPOTENCY_CONFLICT", "USER_PROOF_REPLAYED", "RESULT_NOT_READY", "OPERATION_EXPIRED", "RESULT_EXPIRED", "OPERATION_NOT_AUTHORIZED", "ADAPTER_INTEGRITY_CONFLICT"]);
|
|
128
102
|
function opaqueCursor(value) {
|
|
129
103
|
return typeof value === "string" && value.length > 0;
|
|
130
104
|
}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,162 +1,53 @@
|
|
|
1
1
|
import { type ClientChannel, type IdentityMethod } from "./auth.ts";
|
|
2
|
-
import { type
|
|
2
|
+
import { type Session } from "./credentials.ts";
|
|
3
|
+
import { type ClientConfiguration, type ClientSettings, type PublicClientConfiguration } from "./configuration.ts";
|
|
4
|
+
import { type SessionProjection, type WalletProjection } from "./accountLists.ts";
|
|
5
|
+
import { type ServiceGrantInput, type ServiceGrantPage, type ServiceGrantTarget } from "./serviceGrants.ts";
|
|
6
|
+
import { type AccountIdentity, type ConfirmationChallenge, type HostedIdentityFlow, type IdentityVerificationMethod, type LocalOperation, type LocalOperationCreate, type LocalOperationResult, type PasskeyBootstrapResult, type VerifiedIdentityResult } from "./slice4.ts";
|
|
7
|
+
import { type MeProjection } from "./me.ts";
|
|
8
|
+
import { type HostedSignIn } from "./redirects.ts";
|
|
9
|
+
import { type MobileBrowserBridge, type MobileSecureStorage } from "./mobile.ts";
|
|
10
|
+
export type { MobileAssociationInput, MobileAssociationVerification, MobileBrowserBridge, MobileSecureStorage } from "./mobile.ts";
|
|
3
11
|
import { StreamsReads } from "./streams.ts";
|
|
4
12
|
import { LinkedWallets } from "./linkedWallets.ts";
|
|
5
|
-
export { LinkedWallets, eventOfTransaction, isWalletLimitRefusal, resumeCursor, sendEvents, transferFinal, WalletLimitRefusals } from "./linkedWallets.ts";
|
|
6
|
-
export type { AssetBalance, LinkedWalletBalances, NetworkBalanceStatus, NetworkBalances, ListedSend, SendPage, TransferOutcome, TransferState, TransferStatus, WalletConnection, LinkedWallet, WalletLinkChallenge, WalletLinkAssertion, LinkedRegistrationCreate, LinkedRegistrationOperation, LinkedRegistrationDisplay, LinkedRegistrationPurgedDisplay, LinkedRegistrationResult, LinkedRegistrationListOptions, LinkedEventsOptions, LinkedStreamsRegistration, LinkedStreamsRegistrationList, LinkedSendInput, LinkedReplaceInput, LinkedSendDisplay, ReplaceAction, LinkedTransportKey, LimitAsset, WalletCeiling, WalletLimitRefusal, WalletLimits, WalletLimitsDisplay, WalletLimitsInput } from "./linkedWallets.ts";
|
|
13
|
+
export { DebitPermissions, LinkedWallets, MaxDebitAssets, MaxDebitRecipients, eventOfTransaction, isWalletLimitRefusal, resumeCursor, sendEvents, transferFinal, WalletLimitRefusals } from "./linkedWallets.ts";
|
|
14
|
+
export type { AssetBalance, LinkedWalletBalances, NetworkBalanceStatus, NetworkBalances, ListedSend, SendPage, TransferOutcome, TransferState, TransferStatus, WalletConnection, LinkedWallet, WalletLinkChallenge, WalletLinkAssertion, LinkedRegistrationCreate, LinkedRegistrationOperation, LinkedRegistrationDisplay, LinkedRegistrationPurgedDisplay, LinkedRegistrationResult, LinkedRegistrationListOptions, LinkedEventsOptions, LinkedStreamsRegistration, LinkedStreamsRegistrationList, LinkedSendInput, LinkedReplaceInput, LinkedSendDisplay, ReplaceAction, LinkedTransportKey, LimitAsset, WalletCeiling, WalletLimitRefusal, WalletLimits, WalletLimitsDisplay, WalletLimitsInput, DebitAsset, DebitAssetBound, DebitPermission, DebitPermissionDisplay, DebitPermissionInput, DebitPermissionList, DebitPermissionRevokeDisplay, DebitPermissionState, DebitShareKeys } from "./linkedWallets.ts";
|
|
7
15
|
import { type UserWalletOperation, type UserWalletOperationCreate, type WalletResult } from "./walletOperations.ts";
|
|
16
|
+
import { type WalletCreateInput } from "./walletCreateGrant.ts";
|
|
17
|
+
export type { ConsentDebitOutcome, DebitTerms } from "./consentDebit.ts";
|
|
18
|
+
export type { WalletCreateGrant, WalletCreateGrantOutcome, WalletCreateInput } from "./walletCreateGrant.ts";
|
|
8
19
|
import { type PageOptions } from "./pages.ts";
|
|
9
20
|
export type { PageOptions } from "./pages.ts";
|
|
10
|
-
export {
|
|
21
|
+
export type { ClientConfiguration, ClientSettings, PublicClientConfiguration } from "./configuration.ts";
|
|
22
|
+
export type { SessionProjection, WalletProjection } from "./accountLists.ts";
|
|
23
|
+
export type { AccountServiceGrant, ServiceGrantInput, ServiceGrantPage, ServiceGrantState, ServiceGrantTarget } from "./serviceGrants.ts";
|
|
24
|
+
export { AuthorizationErrorCodes, AuthorizationErrorContracts, ModeCRefusals, isAuthorizationErrorCode, isModeCRefusal } from "./errors.ts";
|
|
25
|
+
export type { AuthorizationErrorCode, AuthorizationErrorContract, ModeCRefusal } from "./errors.ts";
|
|
26
|
+
export type { MeProjection, MeWallet } from "./me.ts";
|
|
27
|
+
export { AuthorizationError, ClientFlowError, isAuthorizationError } from "./auth.ts";
|
|
28
|
+
export { webRenewalRequiresNavigation } from "./webRenewal.ts";
|
|
11
29
|
export type { AuthIntent, ClientChannel, IdentityMethod, NextAction } from "./auth.ts";
|
|
30
|
+
export type { HostedSignIn } from "./redirects.ts";
|
|
12
31
|
export { pollAuthoritative } from "./poll.ts";
|
|
13
32
|
export type { PollDisposition, PollOptions, PollResult } from "./poll.ts";
|
|
14
33
|
export type { AccountIdentity, ConfirmationChallenge, HostedIdentityFlow, IdentityVerificationMethod, LocalOperation, LocalOperationCreate, LocalOperationResult, PasskeyBootstrapResult, ResultRecipient, ServiceReadScope, VerifiedIdentityResult, } from "./slice4.ts";
|
|
15
34
|
export { MaxTransferCommentBytes, MaxWalletMessageBytes, ReplaceActions, transferComment, walletMaterialPurged } from "./walletOperations.ts";
|
|
16
|
-
export type { UserWalletAuthorizationBasis, UserWalletDisplay, UserWalletEffectState, UserWalletOperation, UserWalletOperationCreate, UserWalletOperationKind, UserWalletPurgedDisplay, UserWalletState, WalletResult, WalletResultKind, } from "./walletOperations.ts";
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
redirectUri: string;
|
|
23
|
-
publishableClientId: string;
|
|
24
|
-
tenantId: string;
|
|
25
|
-
applicationId: string;
|
|
26
|
-
environmentId: string;
|
|
27
|
-
methods: readonly IdentityMethod[];
|
|
28
|
-
mobileApplicationIdentifier?: string;
|
|
29
|
-
}
|
|
30
|
-
export interface PublicClientConfiguration {
|
|
31
|
-
requestId: string;
|
|
32
|
-
id: string;
|
|
33
|
-
name: string;
|
|
34
|
-
environmentId: string;
|
|
35
|
-
methods: readonly IdentityMethod[];
|
|
36
|
-
providerOrigin: string;
|
|
37
|
-
rpId: string;
|
|
38
|
-
redirects: readonly string[];
|
|
39
|
-
platform: ClientChannel;
|
|
40
|
-
}
|
|
41
|
-
export interface FetchRequest {
|
|
42
|
-
url: string;
|
|
43
|
-
method?: string;
|
|
44
|
-
headers?: Record<string, string>;
|
|
45
|
-
body?: string;
|
|
46
|
-
credentials?: "include" | "omit";
|
|
47
|
-
cache?: "no-store";
|
|
48
|
-
signal?: AbortSignal;
|
|
49
|
-
}
|
|
50
|
-
export interface FetchResponse {
|
|
51
|
-
status: number;
|
|
52
|
-
ok: boolean;
|
|
53
|
-
json(): Promise<unknown>;
|
|
54
|
-
/** The answer as it arrives and its headers; only a signal stream reads them. */
|
|
55
|
-
body?: ReadableStream<Uint8Array> | null;
|
|
56
|
-
headers?: {
|
|
57
|
-
get(name: string): string | null;
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
export type FetchLike = (url: string, init?: Omit<FetchRequest, "url">) => Promise<FetchResponse>;
|
|
61
|
-
export interface MobileSecureStorage {
|
|
62
|
-
get(key: string): Promise<string | null>;
|
|
63
|
-
set(key: string, value: string): Promise<void>;
|
|
64
|
-
delete(key: string): Promise<void>;
|
|
65
|
-
}
|
|
66
|
-
export interface MobileAssociationInput {
|
|
67
|
-
redirectUri: string;
|
|
68
|
-
applicationIdentifier: string;
|
|
69
|
-
}
|
|
70
|
-
export interface MobileAssociationVerification {
|
|
71
|
-
source: "os_verified_https_association";
|
|
72
|
-
redirectUri: string;
|
|
73
|
-
applicationIdentifier: string;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Host/native trust boundary. Implementations must ask the operating system to
|
|
77
|
-
* verify the configured HTTPS app/universal-link association. This result is a
|
|
78
|
-
* port contract, not cryptographic proof produced by this TypeScript package.
|
|
79
|
-
*/
|
|
80
|
-
export interface MobileBrowserBridge {
|
|
81
|
-
verifyAssociatedRedirect(input: MobileAssociationInput): Promise<MobileAssociationVerification | null>;
|
|
82
|
-
openSystemBrowser(url: string): Promise<void> | void;
|
|
83
|
-
}
|
|
84
|
-
interface CommonDependencies {
|
|
85
|
-
fetch?: FetchLike;
|
|
86
|
-
crypto?: Crypto;
|
|
87
|
-
now?: () => number;
|
|
88
|
-
}
|
|
89
|
-
export interface WebDependencies extends CommonDependencies {
|
|
90
|
-
currentOrigin: () => string;
|
|
91
|
-
/**
|
|
92
|
-
* Opens a separate top-level browsing context. Restore requires the host to
|
|
93
|
-
* return the final registered app redirect while this caller stays alive so
|
|
94
|
-
* its state and PKCE verifier remain only in memory.
|
|
95
|
-
*/
|
|
96
|
-
openHosted: (url: string) => Promise<string | void> | string | void;
|
|
97
|
-
}
|
|
98
|
-
export interface MobileDependencies extends CommonDependencies {
|
|
99
|
-
browserBridge: MobileBrowserBridge;
|
|
100
|
-
secureStorage: MobileSecureStorage;
|
|
101
|
-
}
|
|
102
|
-
export type ClientDependencies = WebDependencies | MobileDependencies;
|
|
103
|
-
export interface AuthAttempt {
|
|
104
|
-
requestId: string;
|
|
105
|
-
attemptId: string;
|
|
106
|
-
launchUrl: string;
|
|
107
|
-
expiresAt: number;
|
|
108
|
-
}
|
|
109
|
-
export interface Session {
|
|
110
|
-
requestId: string;
|
|
111
|
-
accessExpiresAt: number;
|
|
112
|
-
accountId: string;
|
|
113
|
-
sessionId: string;
|
|
114
|
-
setupRequired?: boolean;
|
|
115
|
-
}
|
|
116
|
-
export interface MeProjection {
|
|
117
|
-
requestId: string;
|
|
118
|
-
account: {
|
|
119
|
-
accountId: string;
|
|
120
|
-
version: string;
|
|
121
|
-
setupRequired: boolean;
|
|
122
|
-
};
|
|
123
|
-
sessionId: string;
|
|
124
|
-
serverTime: number;
|
|
125
|
-
}
|
|
126
|
-
export interface SessionProjection {
|
|
127
|
-
requestId: string;
|
|
128
|
-
items: Array<{
|
|
129
|
-
sessionId: string;
|
|
130
|
-
clientId: string;
|
|
131
|
-
state: string;
|
|
132
|
-
createdAt: string;
|
|
133
|
-
expiresAt: string;
|
|
134
|
-
current: boolean;
|
|
135
|
-
}>;
|
|
136
|
-
hasMore: boolean;
|
|
137
|
-
nextCursor?: string;
|
|
138
|
-
}
|
|
139
|
-
export interface WalletProjection {
|
|
140
|
-
requestId: string;
|
|
141
|
-
items: Array<{
|
|
142
|
-
walletId: string;
|
|
143
|
-
network: string;
|
|
144
|
-
address: string;
|
|
145
|
-
state: string;
|
|
146
|
-
generation: string;
|
|
147
|
-
mappingVersion: string;
|
|
148
|
-
}>;
|
|
149
|
-
hasMore: boolean;
|
|
150
|
-
nextCursor?: string;
|
|
151
|
-
}
|
|
35
|
+
export type { UserWalletAuthorizationBasis, UserWalletDisplay, UserWalletEffectState, UserWalletOperation, UserWalletOperationCreate, UserWalletOperationKind, UserWalletPurgedDisplay, UserWalletState, WalletResult, WalletResultKind, DeviceSharePackage, } from "./walletOperations.ts";
|
|
36
|
+
export type { AuthAttempt, ClientDependencies, FetchLike, FetchRequest, FetchResponse, MobileDependencies, WebDependencies } from "./clientTypes.ts";
|
|
37
|
+
import { type DeviceShareStore } from "./deviceShares.ts";
|
|
38
|
+
export type { DeviceRecoveryOptions, DeviceShareRecord, DeviceShareStore } from "./deviceShares.ts";
|
|
39
|
+
import type { ClientDependencies, FetchLike, AuthAttempt } from "./clientTypes.ts";
|
|
40
|
+
export type { Session } from "./credentials.ts";
|
|
152
41
|
type NormalizedDependencies = {
|
|
153
42
|
fetch: FetchLike;
|
|
154
43
|
crypto: Crypto;
|
|
155
44
|
now: () => number;
|
|
156
|
-
launch: (url: string) => Promise<string | void>;
|
|
45
|
+
launch: (url: string, signal?: AbortSignal) => Promise<string | void>;
|
|
157
46
|
secureStorage?: MobileSecureStorage;
|
|
47
|
+
browserBridge?: MobileBrowserBridge;
|
|
48
|
+
deviceShares?: DeviceShareStore;
|
|
158
49
|
};
|
|
159
|
-
export declare function initializeAuthorizationClient(
|
|
50
|
+
export declare function initializeAuthorizationClient(settings: ClientSettings, dependencies: ClientDependencies): Promise<AuthorizationClient>;
|
|
160
51
|
export declare class AuthorizationClient {
|
|
161
52
|
#private;
|
|
162
53
|
readonly capabilities: {
|
|
@@ -167,7 +58,13 @@ export declare class AuthorizationClient {
|
|
|
167
58
|
readonly publicConfiguration?: PublicClientConfiguration;
|
|
168
59
|
constructor(configuration: ClientConfiguration, dependencies: NormalizedDependencies, publicConfiguration?: PublicClientConfiguration);
|
|
169
60
|
get hasSession(): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* signup and login open the hosted sign-in page (on mobile: verify the app link, open the system browser,
|
|
63
|
+
* exchange what it hands back and resolve with the session). Given a method, they begin that attempt.
|
|
64
|
+
*/
|
|
65
|
+
signup(): Promise<HostedSignIn>;
|
|
170
66
|
signup(method: IdentityMethod): Promise<AuthAttempt>;
|
|
67
|
+
login(): Promise<HostedSignIn>;
|
|
171
68
|
login(method: IdentityMethod): Promise<AuthAttempt>;
|
|
172
69
|
bootstrapPasskey(signal?: AbortSignal): Promise<HostedIdentityFlow>;
|
|
173
70
|
verifyIdentity(method: IdentityVerificationMethod, signal?: AbortSignal): Promise<HostedIdentityFlow>;
|
|
@@ -179,26 +76,19 @@ export declare class AuthorizationClient {
|
|
|
179
76
|
createIdentityLink(verifiedIdentityHandle: string, idempotencyKey: string, signal?: AbortSignal): Promise<LocalOperation>;
|
|
180
77
|
createIdentityUnlink(identityId: string, idempotencyKey: string, signal?: AbortSignal): Promise<LocalOperation>;
|
|
181
78
|
createSessionRevocation(sessionId: string, idempotencyKey: string, signal?: AbortSignal): Promise<LocalOperation>;
|
|
182
|
-
createServiceGrant
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}, idempotencyKey: string, signal?: AbortSignal): Promise<LocalOperation>;
|
|
79
|
+
/** createServiceGrant asks to give one service read access to one of the account's wallets, or to change it; the person confirms it with a passkey. */
|
|
80
|
+
createServiceGrant(input: ServiceGrantInput, idempotencyKey: string, signal?: AbortSignal): Promise<LocalOperation>;
|
|
81
|
+
/** revokeServiceGrant asks to withdraw the grant of one service on one wallet (`enabled: false`); the person confirms it with a passkey. */
|
|
82
|
+
revokeServiceGrant(target: ServiceGrantTarget, idempotencyKey: string, signal?: AbortSignal): Promise<LocalOperation>;
|
|
83
|
+
/** serviceGrants lists the grants the account gave services, in every state, newest first. */
|
|
84
|
+
serviceGrants(input?: AbortSignal | PageOptions): Promise<ServiceGrantPage>;
|
|
189
85
|
operation(operationId: string, signal?: AbortSignal): Promise<LocalOperation>;
|
|
190
86
|
challengeOperation(operationId: string, credentialId: string, signal?: AbortSignal): Promise<ConfirmationChallenge>;
|
|
191
87
|
completeOperationConfirmation(callbackUri: string, signal?: AbortSignal): Promise<LocalOperation>;
|
|
192
|
-
/**
|
|
193
|
-
* createWalletOperation admits one Mode B wallet intent on POST /v1/operations.
|
|
194
|
-
* The closed body is validated locally against the current session account
|
|
195
|
-
* before the request leaves the client (source §1.3, §2.2).
|
|
196
|
-
*/
|
|
88
|
+
/** createWalletOperation admits one Mode B wallet intent, its closed body checked locally first (source §1.3, §2.2). */
|
|
197
89
|
createWalletOperation(create: UserWalletOperationCreate, idempotencyKey: string, signal?: AbortSignal): Promise<UserWalletOperation>;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
recipientPublicKey: string;
|
|
201
|
-
}, idempotencyKey: string, signal?: AbortSignal): Promise<UserWalletOperation>;
|
|
90
|
+
/** Without recipientPublicKey the SDK makes the device key and keeps the share (deviceShares.ts); grant opens the wallet to a service in the same confirmation (walletCreateGrant.ts). */
|
|
91
|
+
createWallet(input: WalletCreateInput, idempotencyKey: string, signal?: AbortSignal): Promise<UserWalletOperation>;
|
|
202
92
|
signWithWallet(input: {
|
|
203
93
|
walletId: string;
|
|
204
94
|
network: string;
|
|
@@ -222,17 +112,10 @@ export declare class AuthorizationClient {
|
|
|
222
112
|
}, idempotencyKey: string, signal?: AbortSignal): Promise<UserWalletOperation>;
|
|
223
113
|
/** walletOperation reads the safe wallet status on GET /v1/operations/{operation_id}. */
|
|
224
114
|
walletOperation(operationId: string, signal?: AbortSignal): Promise<UserWalletOperation>;
|
|
225
|
-
/**
|
|
226
|
-
* challengeWalletOperation reuses the shared confirmation challenge route and
|
|
227
|
-
* pending-state bookkeeping; the wallet and local challenge contracts are the
|
|
228
|
-
* same closed response.
|
|
229
|
-
*/
|
|
115
|
+
/** challengeWalletOperation is challengeOperation: the wallet and local challenges are one closed response. */
|
|
230
116
|
challengeWalletOperation(operationId: string, credentialId: string, signal?: AbortSignal): Promise<ConfirmationChallenge>;
|
|
231
117
|
completeWalletOperationConfirmation(callbackUri: string, signal?: AbortSignal): Promise<UserWalletOperation>;
|
|
232
|
-
/**
|
|
233
|
-
* executeWalletOperation claims one confirmed wallet effect. The first claim
|
|
234
|
-
* answers 202 and an exact replay answers 200; both carry the same operation.
|
|
235
|
-
*/
|
|
118
|
+
/** executeWalletOperation claims one confirmed wallet effect: 202, or 200 for an exact replay, with the same operation. */
|
|
236
119
|
executeWalletOperation(operationId: string, version: string, idempotencyKey: string, signal?: AbortSignal): Promise<UserWalletOperation>;
|
|
237
120
|
/** walletOperationResult reads the protected wallet output for its frozen recipient. */
|
|
238
121
|
walletOperationResult(operationId: string, signal?: AbortSignal): Promise<WalletResult>;
|
|
@@ -240,25 +123,30 @@ export declare class AuthorizationClient {
|
|
|
240
123
|
/** HTTP-only Auth-owned links and session-authorized Streams registration. */
|
|
241
124
|
linkedWallets(): LinkedWallets;
|
|
242
125
|
/**
|
|
243
|
-
* streams binds the
|
|
244
|
-
*
|
|
245
|
-
* and refresh path. The read contract, its types and its bounds live in the
|
|
246
|
-
* `./streams` entry point, which this file deliberately does not re-export; a
|
|
247
|
-
* service caller constructs `StreamsReads` there with its own credentialed
|
|
248
|
-
* GET. The caller supplies the stable `idempotencyKey` in each read's options;
|
|
249
|
-
* it is forwarded unchanged on the original GET and any protected 401 retry.
|
|
126
|
+
* streams binds the authorized Streams reads (source §2.6, `./streams`) to this session's protected GET;
|
|
127
|
+
* each read's `idempotencyKey` is forwarded unchanged on the GET and any 401 retry.
|
|
250
128
|
*/
|
|
251
129
|
streams(): StreamsReads;
|
|
252
130
|
operationResult(operationId: string, signal?: AbortSignal): Promise<LocalOperationResult>;
|
|
253
131
|
cancel(attemptId: string): "local_canceled";
|
|
132
|
+
/** exchangeHandoff exchanges the redirect back for the session; a signal ends only this caller's wait, never the exchange. */
|
|
254
133
|
exchangeHandoff(callbackUri: string, signal?: AbortSignal): Promise<Session>;
|
|
134
|
+
/** restoreSession is the top-level restore on the web (webRenewal.ts); on mobile it is refreshSession. */
|
|
255
135
|
restoreSession(signal?: AbortSignal): Promise<Session>;
|
|
136
|
+
/** refreshSession renews in the background: on the web from the provider's cookie, on mobile with the stored refresh token. */
|
|
256
137
|
refreshSession(signal?: AbortSignal): Promise<Session>;
|
|
138
|
+
/** logout ends the session here at once and asks the provider to end it; a signal ends only this caller's wait, never the revocation. */
|
|
257
139
|
logout(signal?: AbortSignal): Promise<{
|
|
258
140
|
localCleared: true;
|
|
259
141
|
serverDisposition: "server_revoked" | "server_unconfirmed";
|
|
260
142
|
}>;
|
|
143
|
+
/**
|
|
144
|
+
* accessToken is the session's access token for the app's own backend, renewed first when it has
|
|
145
|
+
* less than 30 seconds to live or a read was refused with it. Never store it or put it in a URL.
|
|
146
|
+
*/
|
|
147
|
+
accessToken(signal?: AbortSignal): Promise<string>;
|
|
261
148
|
me(signal?: AbortSignal): Promise<MeProjection>;
|
|
262
149
|
sessions(input?: AbortSignal | PageOptions): Promise<SessionProjection>;
|
|
150
|
+
/** wallets pages the account's own wallets, kind "wallet" in me(), which lists them with the linked ones. */
|
|
263
151
|
wallets(input?: AbortSignal | PageOptions): Promise<WalletProjection>;
|
|
264
152
|
}
|