@polyester/sdk 0.25.1 → 0.26.1
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 +34 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -2
- package/dist/server-client.d.ts +12 -1
- package/dist/server-client.d.ts.map +1 -1
- package/dist/server-client.js +8 -3
- package/dist/server-client.js.map +1 -1
- package/dist/server-session.d.ts +3 -2
- package/dist/server-session.js +2 -1
- package/dist/services/auth/account-signer-auth.d.ts.map +1 -1
- package/dist/services/auth/account-signer-auth.js +78 -44
- package/dist/services/auth/account-signer-auth.js.map +1 -1
- package/dist/services/auth/cookie-constants.d.ts +14 -1
- package/dist/services/auth/cookie-constants.d.ts.map +1 -1
- package/dist/services/auth/cookie-constants.js +13 -1
- package/dist/services/auth/cookie-constants.js.map +1 -1
- package/dist/services/auth/session.d.ts +10 -2
- package/dist/services/auth/session.d.ts.map +1 -1
- package/dist/services/auth/session.js +9 -11
- package/dist/services/auth/session.js.map +1 -1
- package/dist/services/auth/token-storage.js +5 -5
- package/dist/services/auth/token-storage.js.map +1 -1
- package/dist/services/candles/candles.schemas.d.ts +10 -10
- package/dist/services/heatmap/heatmap.schemas.d.ts +13 -13
- package/dist/services/market-overview/market-overview.schemas.d.ts +3 -3
- package/dist/services/orderbook/orderbook.schemas.d.ts +1 -1
- package/dist/services/orders/orders-output.schemas.d.ts +6 -6
- package/dist/services/subaccounts/subaccounts.schemas.d.ts +5 -5
- package/dist/services/trades/trades.schemas.d.ts +1 -1
- package/dist/services/triggers/trigger-input.schemas.d.ts +2 -2
- package/dist/services/triggers/triggers-output.schemas.d.ts +18 -18
- package/dist/smart-account/index.d.ts +2 -2
- package/dist/smart-account/index.js +2 -2
- package/dist/smart-account/smart-account.d.ts +3095 -7
- package/dist/smart-account/smart-account.d.ts.map +1 -1
- package/dist/smart-account/smart-account.js +169 -45
- package/dist/smart-account/smart-account.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-signer-auth.js","names":["#accountSignerConfig","#environmentFingerprint","#subaccounts","#tokenStorage","#realtime","#sessionStore","#assertAccountSignerEnvironment","#accountSigner","#accountIdentity","#identityFromSigner","#notifyStateChange","#login","#resolveAccountSigner","#challengeUri","#getEnvironmentSession","#loginMethod","#isAuthenticated","#mainAccountId","#activeAccountId","#walletProvider","#getEnvironmentBoundToken","#clearExpiredSessionState","#getCurrentTokenStorageOptions","#resolveRefreshProvider"],"sources":["../../../src/services/auth/account-signer-auth.ts"],"sourcesContent":["import { AuthService } from \"./auth.js\";\nimport { AuthenticationError, ConfigurationError } from \"../../shared/errors.js\";\nimport { AuthSessionStore } from \"./session.js\";\nimport type { AccountSigner, AccountSignerConfig, HexAddress } from \"../../account-signer/types.js\";\nimport { assertAccountSigner, resolveAccountSigner } from \"../../account-signer/types.js\";\nimport { EventEmitter } from \"../../utils/event-emitter.js\";\nimport { isJwtValid, getJwtTimeToExpiry } from \"../../utils/jwt.js\";\nimport type { SubaccountsService } from \"../subaccounts/index.js\";\nimport type {\n AuthState,\n AuthHydrationData,\n AuthLoginMethod,\n SessionData,\n ActiveAccountInfo,\n} from \"./session.types.js\";\nimport type { PolyesterRealtime } from \"../../realtime/index.js\";\nimport type { PolyesterEnvironment } from \"../../environment.js\";\nimport type { AuthAndPublicApiTransports } from \"../../shared/transports.js\";\nimport {\n createAuthTokenStorageSetOptions,\n type AuthTokenStorage,\n type AuthTokenStorageSetOptions,\n} from \"./token-storage.js\";\n\nexport interface AccountSignerAuthEvents {\n authenticated: { accountId: string; username: string };\n loggedOut: void;\n error: { code: string; message: string };\n servicesReady: void;\n stateChange: AuthState;\n}\n\nexport interface LoginResult {\n accountId: string;\n username: string;\n expiresAt: Date;\n}\n\nexport interface LoginOptions {\n /**\n * The wallet provider to use for login.\n */\n provider: \"metamask\" | \"turnkey\" | \"other\";\n /** Browser origin requesting the signature; defaults to location.origin in browsers. Required outside browsers. */\n uri?: string;\n loginMethod?: AuthLoginMethod | null;\n}\n\nexport interface CreateSubaccountParams {\n /** The account signer for the new subaccount (caller derives this, e.g. via Turnkey saltNonce) */\n accountSigner: AccountSigner;\n /** Optional human-readable label for this subaccount */\n label?: string;\n /** Browser origin requesting the signature; defaults to location.origin in browsers. Required outside browsers. */\n uri?: string;\n}\n\nexport interface CreateSubaccountResult {\n subaccountId: string;\n smartAccountSaltNonce: number;\n revision: string;\n}\n\ninterface AccountIdentity {\n accountAddress: HexAddress;\n ownerAddress?: HexAddress;\n}\n\n/**\n * Coordinates wallet/account-signer authentication, session storage, subaccount selection, and session refresh.\n */\nexport class AccountSignerAuthService extends AuthService {\n readonly events = new EventEmitter<AccountSignerAuthEvents>();\n\n #accountSignerConfig: AccountSignerConfig | undefined;\n #accountSigner: AccountSigner | null = null;\n #accountIdentity: AccountIdentity | null = null;\n #isAuthenticated = false;\n #mainAccountId: string | null = null;\n #activeAccountId: string | null = null;\n #subaccounts: SubaccountsService;\n #walletProvider: \"metamask\" | \"turnkey\" | \"other\" | undefined = undefined;\n #loginMethod: AuthLoginMethod | null = null;\n #challengeUri: string | undefined = undefined;\n #environmentFingerprint: string;\n #tokenStorage: AuthTokenStorage;\n #sessionStore: AuthSessionStore;\n #realtime: PolyesterRealtime;\n\n constructor({\n transports,\n accountSignerConfig,\n environment,\n subaccounts,\n realtime,\n tokenStorage,\n sessionStore,\n }: {\n transports: AuthAndPublicApiTransports;\n accountSignerConfig?: AccountSignerConfig;\n environment: PolyesterEnvironment;\n subaccounts: SubaccountsService;\n realtime: PolyesterRealtime;\n tokenStorage: AuthTokenStorage;\n sessionStore?: AuthSessionStore;\n }) {\n super(transports, realtime);\n\n this.#accountSignerConfig = accountSignerConfig;\n this.#environmentFingerprint = environment.fingerprint;\n this.#subaccounts = subaccounts;\n this.#tokenStorage = tokenStorage;\n this.#realtime = realtime;\n this.#sessionStore =\n sessionStore ??\n new AuthSessionStore({\n environmentFingerprint: environment.fingerprint,\n });\n }\n\n /**\n * Attaches the subaccounts service used when creating a subaccount during authenticated flows.\n */\n setSubaccountsService(subaccounts: SubaccountsService): void {\n this.#subaccounts = subaccounts;\n }\n\n /**\n * Sets the account signer used to sign login and account-switch challenges.\n */\n setAccountSigner(accountSigner: AccountSigner | null): void {\n if (accountSigner) this.#assertAccountSignerEnvironment(accountSigner);\n this.#accountSigner = accountSigner;\n this.#accountIdentity = accountSigner ? this.#identityFromSigner(accountSigner) : null;\n this.#notifyStateChange();\n }\n\n /**\n * Returns the active account signer, throwing if one has not been configured.\n */\n getAccountSigner(): AccountSigner | null {\n return this.#accountSigner;\n }\n\n /**\n * Signs a server-issued SIWE message with the configured account signer, exchanges it for a session token, and stores the hydrated account/subaccount session state.\n */\n async login(options: LoginOptions): Promise<LoginResult> {\n return this.#login(options);\n }\n\n async #login(\n options: LoginOptions,\n previousActiveAccount?: ActiveAccountInfo,\n ): Promise<LoginResult> {\n const { provider, loginMethod } = options;\n\n const accountSigner = await this.#resolveAccountSigner();\n\n if (!accountSigner) {\n throw new ConfigurationError(\n \"No account signer configured. Call setAccountSigner() or pass accountSigner in config.\",\n );\n }\n\n const smartAccountAddress = accountSigner.accountAddress;\n const ownerAddress = accountSigner.ownerAddress ?? accountSigner.accountAddress;\n\n const uri = resolveChallengeUri(options.uri ?? this.#challengeUri);\n const { message } = await this.createWalletChallenge({\n smartAccountAddress,\n signerAddress: ownerAddress,\n uri,\n purpose: \"login\",\n });\n const signature = await accountSigner.signMessage(message);\n\n const response = await this.loginWithWallet({\n smartAccountAddress,\n message,\n signature,\n walletProvider: provider,\n });\n\n const environmentSession = this.#getEnvironmentSession();\n const resolvedLoginMethod =\n loginMethod ??\n this.#loginMethod ??\n environmentSession?.loginMethod ??\n (provider === \"metamask\" ? \"metamask\" : null);\n\n const tokenOptions = createAuthTokenStorageSetOptions(response.accessToken);\n const activeAccount =\n previousActiveAccount?.mainAccountId === response.accountId\n ? previousActiveAccount\n : undefined;\n this.#sessionStore.commitLogin(\n {\n accessToken: response.accessToken,\n tokenOptions,\n provider,\n loginMethod: resolvedLoginMethod,\n primaryWallet: ownerAddress,\n smartAccount: smartAccountAddress,\n accountId: response.accountId,\n activeAccount,\n username: response.username ?? undefined,\n },\n this.#tokenStorage,\n );\n this.#isAuthenticated = true;\n this.#mainAccountId = response.accountId;\n this.#activeAccountId = activeAccount?.accountId ?? response.accountId;\n this.#walletProvider = provider;\n this.#loginMethod = resolvedLoginMethod;\n this.#challengeUri = uri;\n this.#accountIdentity = this.#identityFromSigner(accountSigner);\n\n this.#notifyStateChange();\n\n this.events.emit(\"authenticated\", {\n accountId: response.accountId,\n username: response.username,\n });\n\n const expiresAt = response.expiresAt\n ? new Date(\n Number(response.expiresAt.seconds) * 1000 +\n (response.expiresAt.nanos ?? 0) / 1_000_000,\n )\n : new Date();\n\n return {\n accountId: response.accountId,\n username: response.username,\n expiresAt,\n };\n }\n\n /**\n * Builds auth state from a session token and optional active account override.\n */\n hydrateAuthState(state: AuthHydrationData): void {\n const existingToken = this.#getEnvironmentBoundToken();\n if (!existingToken || !isJwtValid(existingToken)) return;\n\n const existingSession = this.#getEnvironmentSession();\n this.#walletProvider = existingSession?.provider ?? this.#walletProvider;\n this.#loginMethod = existingSession?.loginMethod ?? this.#loginMethod;\n\n this.#isAuthenticated = true;\n this.#mainAccountId = state.mainAccountId;\n this.#activeAccountId = state.activeAccountId ?? state.mainAccountId;\n this.#accountIdentity = state.smartAccountAddress\n ? {\n accountAddress: state.smartAccountAddress,\n ownerAddress: state.ownerAddress,\n }\n : null;\n\n this.#notifyStateChange();\n }\n\n /**\n * Loads the stored token, validates that it still belongs to this environment, and restores auth state when possible.\n */\n async restoreSession(): Promise<{ accountId: string; username: string } | null> {\n const existingToken = this.#getEnvironmentBoundToken();\n\n if (!existingToken || !isJwtValid(existingToken)) {\n this.#clearExpiredSessionState();\n return null;\n }\n\n try {\n const me = await this.me();\n this.#isAuthenticated = true;\n this.#mainAccountId = me.accountId;\n\n // preserve active account if already set (e.g. via hydration), otherwise use main\n const existingSession = this.#getEnvironmentSession();\n this.#walletProvider = existingSession?.provider ?? this.#walletProvider;\n this.#loginMethod = existingSession?.loginMethod ?? this.#loginMethod;\n if (!this.#activeAccountId) {\n this.#activeAccountId = existingSession?.activeAccount?.accountId ?? me.accountId;\n }\n\n // use existing account signer if set, otherwise try to resolve from config\n if (!this.#accountSigner) {\n this.#accountSigner = await resolveAccountSigner(this.#accountSignerConfig);\n if (this.#accountSigner) {\n this.#assertAccountSignerEnvironment(this.#accountSigner);\n this.#accountIdentity = this.#identityFromSigner(this.#accountSigner);\n }\n }\n\n // keep the display session available for SSR hydration\n if (this.#accountSigner?.accountAddress) {\n const session = this.#sessionStore.ensureSession(\n {\n provider: this.#walletProvider ? this.#walletProvider : \"other\",\n loginMethod:\n this.#loginMethod ??\n (this.#walletProvider === \"metamask\" ? \"metamask\" : null),\n primaryWallet:\n this.#accountSigner.ownerAddress ?? this.#accountSigner.accountAddress,\n smartAccount: this.#accountSigner.accountAddress,\n accountId: me.accountId,\n username: me.username ?? undefined,\n },\n { maxAgeSeconds: this.#getCurrentTokenStorageOptions().maxAgeSeconds },\n );\n this.#walletProvider = session.provider;\n this.#loginMethod = session.loginMethod ?? this.#loginMethod;\n }\n\n this.#notifyStateChange();\n return { accountId: me.accountId, username: me.username };\n } catch {\n this.#clearExpiredSessionState();\n return null;\n }\n }\n\n /**\n * Clears stored auth state and removes the persisted auth token.\n */\n async logout(): Promise<void> {\n this.#realtime.disconnectPrivate();\n this.#tokenStorage.clear();\n this.#isAuthenticated = false;\n this.#mainAccountId = null;\n this.#activeAccountId = null;\n this.#loginMethod = null;\n this.#challengeUri = undefined;\n this.#accountIdentity = null;\n\n this.#sessionStore.clear();\n\n this.#notifyStateChange();\n this.events.emit(\"loggedOut\", undefined);\n }\n\n #clearExpiredSessionState(): void {\n const shouldEmitLoggedOut = this.#isAuthenticated;\n this.#realtime.disconnectPrivate();\n this.#tokenStorage.clear();\n this.#sessionStore.clear();\n this.#isAuthenticated = false;\n this.#mainAccountId = null;\n this.#activeAccountId = null;\n this.#loginMethod = null;\n this.#challengeUri = undefined;\n this.#accountIdentity = null;\n this.#notifyStateChange();\n if (shouldEmitLoggedOut) {\n this.events.emit(\"loggedOut\", undefined);\n }\n }\n\n /**\n * Returns the remaining lifetime of the stored session token in milliseconds.\n */\n getSessionTimeToExpiry(): number {\n const token = this.#getEnvironmentBoundToken();\n if (!token) return 0;\n return getJwtTimeToExpiry(token);\n }\n\n /**\n * Refreshes the active account-signer session and updates persisted auth state.\n */\n async refreshSession(params?: {\n /** Overrides the origin remembered from login. */\n uri?: string;\n provider?: \"metamask\" | \"turnkey\" | \"other\";\n loginMethod?: AuthLoginMethod | null;\n }): Promise<LoginResult> {\n if (!this.#isAuthenticated) {\n throw new AuthenticationError(\"Must be authenticated to refresh session\");\n }\n\n const currentSession = this.#getEnvironmentSession();\n return this.#login(\n {\n provider: this.#resolveRefreshProvider(params?.provider),\n uri: params?.uri,\n loginMethod: params?.loginMethod ?? this.#loginMethod,\n },\n currentSession?.activeAccount,\n );\n }\n\n /**\n * Switches the active account/subaccount by signing the required account switch flow.\n */\n switchAccount(\n accountId: string,\n options?: { smartAccountAddress?: string; label?: string },\n ): { accountId: string; isMain: boolean } {\n if (!this.#isAuthenticated || !this.#mainAccountId) {\n throw new AuthenticationError(\"Must be authenticated to switch accounts\");\n }\n\n this.#activeAccountId = accountId;\n const isMain = accountId === this.#mainAccountId;\n\n this.#sessionStore.setActiveAccount(\n {\n accountId,\n isMain,\n smartAccountAddress: options?.smartAccountAddress,\n label: options?.label,\n },\n { maxAgeSeconds: this.#getCurrentTokenStorageOptions().maxAgeSeconds },\n );\n this.#notifyStateChange();\n\n return { accountId, isMain };\n }\n\n /** Keeps the display-session identity current for the next server render. */\n syncSessionUsername(username: string | null): void {\n this.#sessionStore.setUsername(username, {\n maxAgeSeconds: this.#getCurrentTokenStorageOptions().maxAgeSeconds,\n });\n }\n\n /**\n * Creates a subaccount for the authenticated account and makes it available to the session state.\n */\n async createSubaccount(params: CreateSubaccountParams): Promise<CreateSubaccountResult> {\n if (!this.#isAuthenticated) {\n throw new AuthenticationError(\"Must be authenticated to create subaccounts\");\n }\n\n if (!this.#subaccounts) {\n throw new ConfigurationError(\n \"SubaccountsService not configured. Pass it to constructor or call setSubaccountsService().\",\n );\n }\n\n const { accountSigner, label = \"\" } = params;\n this.#assertAccountSignerEnvironment(accountSigner);\n\n const { message } = await this.createWalletChallenge({\n smartAccountAddress: accountSigner.accountAddress,\n signerAddress: accountSigner.accountAddress,\n uri: resolveChallengeUri(params.uri ?? this.#challengeUri),\n purpose: \"create_subaccount\",\n });\n const signature = await accountSigner.signMessage(message);\n\n const response = await this.#subaccounts.create({\n label,\n smartAccountAddress: accountSigner.accountAddress,\n message,\n signature,\n });\n\n return {\n subaccountId: response.subaccountId,\n smartAccountSaltNonce: response.smartAccountSaltNonce,\n revision: response.revision,\n };\n }\n\n /**\n * Returns the current account-signer auth state snapshot.\n */\n getState(): AuthState {\n const accountIdentity = this.#accountSigner ?? this.#accountIdentity;\n\n return {\n isAuthenticated: this.#isAuthenticated,\n accountAddress: accountIdentity?.accountAddress ?? null,\n ownerAddress: accountIdentity?.ownerAddress ?? null,\n mainAccountId: this.#mainAccountId,\n activeAccount:\n this.#activeAccountId && this.#mainAccountId\n ? {\n accountId: this.#activeAccountId,\n isMain: this.#activeAccountId === this.#mainAccountId,\n mainAccountId: this.#mainAccountId,\n smartAccountAddress: accountIdentity?.accountAddress,\n }\n : null,\n };\n }\n\n async #resolveAccountSigner(): Promise<AccountSigner | null> {\n if (this.#accountSigner) {\n this.#assertAccountSignerEnvironment(this.#accountSigner);\n return this.#accountSigner;\n }\n\n const resolved = await resolveAccountSigner(this.#accountSignerConfig);\n if (resolved) {\n this.#assertAccountSignerEnvironment(resolved);\n this.#accountSigner = resolved;\n this.#accountIdentity = this.#identityFromSigner(resolved);\n }\n return this.#accountSigner;\n }\n\n #notifyStateChange(): void {\n this.events.emit(\"stateChange\", this.getState());\n }\n\n #getEnvironmentBoundToken(): string | null {\n return this.#sessionStore.getEnvironmentBoundToken(this.#tokenStorage);\n }\n\n #getCurrentTokenStorageOptions(): AuthTokenStorageSetOptions {\n const token = this.#tokenStorage.get();\n if (!token) return { expiresAt: null, maxAgeSeconds: null };\n return createAuthTokenStorageSetOptions(token);\n }\n\n #resolveRefreshProvider(\n provider?: \"metamask\" | \"turnkey\" | \"other\",\n ): \"metamask\" | \"turnkey\" | \"other\" {\n return (\n provider ?? this.#walletProvider ?? this.#getEnvironmentSession()?.provider ?? \"other\"\n );\n }\n\n #assertAccountSignerEnvironment(accountSigner: AccountSigner): void {\n assertAccountSigner(accountSigner);\n if (accountSigner.environmentFingerprint !== this.#environmentFingerprint) {\n throw new ConfigurationError(\n \"Account signer environment does not match client environment.\",\n );\n }\n }\n\n #identityFromSigner(accountSigner: AccountSigner): AccountIdentity {\n return {\n accountAddress: accountSigner.accountAddress,\n ownerAddress: accountSigner.ownerAddress,\n };\n }\n\n #getEnvironmentSession(): SessionData | null {\n return this.#sessionStore.get();\n }\n}\n\nfunction resolveChallengeUri(uri: string | undefined): string {\n const resolved = uri ?? (typeof location === \"undefined\" ? undefined : location.origin);\n if (!resolved)\n throw new ConfigurationError(\n \"Wallet authentication requires a browser origin URI. Pass uri outside a browser.\",\n );\n return resolved;\n}\n"],"mappings":";;;;;;;;;;;AAuEA,IAAa,2BAAb,cAA8C,YAAY;CACtD,SAAkB,IAAI,aAAsC;CAE5D;CACA,iBAAuC;CACvC,mBAA2C;CAC3C,mBAAmB;CACnB,iBAAgC;CAChC,mBAAkC;CAClC;CACA,kBAAgE,KAAA;CAChE,eAAuC;CACvC,gBAAoC,KAAA;CACpC;CACA;CACA;CACA;CAEA,YAAY,EACR,YACA,qBACA,aACA,aACA,UACA,cACA,gBASD;EACC,MAAM,YAAY,QAAQ;EAE1B,KAAKA,uBAAuB;EAC5B,KAAKC,0BAA0B,YAAY;EAC3C,KAAKC,eAAe;EACpB,KAAKC,gBAAgB;EACrB,KAAKC,YAAY;EACjB,KAAKC,gBACD,gBACA,IAAI,iBAAiB,EACjB,wBAAwB,YAAY,YACxC,CAAC;CACT;;;;CAKA,sBAAsB,aAAuC;EACzD,KAAKH,eAAe;CACxB;;;;CAKA,iBAAiB,eAA2C;EACxD,IAAI,eAAe,KAAKI,gCAAgC,aAAa;EACrE,KAAKC,iBAAiB;EACtB,KAAKC,mBAAmB,gBAAgB,KAAKC,oBAAoB,aAAa,IAAI;EAClF,KAAKC,mBAAmB;CAC5B;;;;CAKA,mBAAyC;EACrC,OAAO,KAAKH;CAChB;;;;CAKA,MAAM,MAAM,SAA6C;EACrD,OAAO,KAAKI,OAAO,OAAO;CAC9B;CAEA,MAAMA,OACF,SACA,uBACoB;EACpB,MAAM,EAAE,UAAU,gBAAgB;EAElC,MAAM,gBAAgB,MAAM,KAAKC,sBAAsB;EAEvD,IAAI,CAAC,eACD,MAAM,IAAI,mBACN,wFACJ;EAGJ,MAAM,sBAAsB,cAAc;EAC1C,MAAM,eAAe,cAAc,gBAAgB,cAAc;EAEjE,MAAM,MAAM,oBAAoB,QAAQ,OAAO,KAAKC,aAAa;EACjE,MAAM,EAAE,YAAY,MAAM,KAAK,sBAAsB;GACjD;GACA,eAAe;GACf;GACA,SAAS;EACb,CAAC;EACD,MAAM,YAAY,MAAM,cAAc,YAAY,OAAO;EAEzD,MAAM,WAAW,MAAM,KAAK,gBAAgB;GACxC;GACA;GACA;GACA,gBAAgB;EACpB,CAAC;EAED,MAAM,qBAAqB,KAAKC,uBAAuB;EACvD,MAAM,sBACF,eACA,KAAKC,gBACL,oBAAoB,gBACnB,aAAa,aAAa,aAAa;EAE5C,MAAM,eAAe,iCAAiC,SAAS,WAAW;EAC1E,MAAM,gBACF,uBAAuB,kBAAkB,SAAS,YAC5C,wBACA,KAAA;EACV,KAAKV,cAAc,YACf;GACI,aAAa,SAAS;GACtB;GACA;GACA,aAAa;GACb,eAAe;GACf,cAAc;GACd,WAAW,SAAS;GACpB;GACA,UAAU,SAAS,YAAY,KAAA;EACnC,GACA,KAAKF,aACT;EACA,KAAKa,mBAAmB;EACxB,KAAKC,iBAAiB,SAAS;EAC/B,KAAKC,mBAAmB,eAAe,aAAa,SAAS;EAC7D,KAAKC,kBAAkB;EACvB,KAAKJ,eAAe;EACpB,KAAKF,gBAAgB;EACrB,KAAKL,mBAAmB,KAAKC,oBAAoB,aAAa;EAE9D,KAAKC,mBAAmB;EAExB,KAAK,OAAO,KAAK,iBAAiB;GAC9B,WAAW,SAAS;GACpB,UAAU,SAAS;EACvB,CAAC;EAED,MAAM,YAAY,SAAS,4BACrB,IAAI,KACA,OAAO,SAAS,UAAU,OAAO,IAAI,OAChC,SAAS,UAAU,SAAS,KAAK,GAC1C,oBACA,IAAI,KAAK;EAEf,OAAO;GACH,WAAW,SAAS;GACpB,UAAU,SAAS;GACnB;EACJ;CACJ;;;;CAKA,iBAAiB,OAAgC;EAC7C,MAAM,gBAAgB,KAAKU,0BAA0B;EACrD,IAAI,CAAC,iBAAiB,CAAC,WAAW,aAAa,GAAG;EAElD,MAAM,kBAAkB,KAAKN,uBAAuB;EACpD,KAAKK,kBAAkB,iBAAiB,YAAY,KAAKA;EACzD,KAAKJ,eAAe,iBAAiB,eAAe,KAAKA;EAEzD,KAAKC,mBAAmB;EACxB,KAAKC,iBAAiB,MAAM;EAC5B,KAAKC,mBAAmB,MAAM,mBAAmB,MAAM;EACvD,KAAKV,mBAAmB,MAAM,sBACxB;GACI,gBAAgB,MAAM;GACtB,cAAc,MAAM;EACxB,IACA;EAEN,KAAKE,mBAAmB;CAC5B;;;;CAKA,MAAM,iBAA0E;EAC5E,MAAM,gBAAgB,KAAKU,0BAA0B;EAErD,IAAI,CAAC,iBAAiB,CAAC,WAAW,aAAa,GAAG;GAC9C,KAAKC,0BAA0B;GAC/B,OAAO;EACX;EAEA,IAAI;GACA,MAAM,KAAK,MAAM,KAAK,GAAG;GACzB,KAAKL,mBAAmB;GACxB,KAAKC,iBAAiB,GAAG;GAGzB,MAAM,kBAAkB,KAAKH,uBAAuB;GACpD,KAAKK,kBAAkB,iBAAiB,YAAY,KAAKA;GACzD,KAAKJ,eAAe,iBAAiB,eAAe,KAAKA;GACzD,IAAI,CAAC,KAAKG,kBACN,KAAKA,mBAAmB,iBAAiB,eAAe,aAAa,GAAG;GAI5E,IAAI,CAAC,KAAKX,gBAAgB;IACtB,KAAKA,iBAAiB,MAAM,qBAAqB,KAAKP,oBAAoB;IAC1E,IAAI,KAAKO,gBAAgB;KACrB,KAAKD,gCAAgC,KAAKC,cAAc;KACxD,KAAKC,mBAAmB,KAAKC,oBAAoB,KAAKF,cAAc;IACxE;GACJ;GAGA,IAAI,KAAKA,gBAAgB,gBAAgB;IACrC,MAAM,UAAU,KAAKF,cAAc,cAC/B;KACI,UAAU,KAAKc,kBAAkB,KAAKA,kBAAkB;KACxD,aACI,KAAKJ,iBACJ,KAAKI,oBAAoB,aAAa,aAAa;KACxD,eACI,KAAKZ,eAAe,gBAAgB,KAAKA,eAAe;KAC5D,cAAc,KAAKA,eAAe;KAClC,WAAW,GAAG;KACd,UAAU,GAAG,YAAY,KAAA;IAC7B,GACA,EAAE,eAAe,KAAKe,+BAA+B,CAAC,CAAC,cAAc,CACzE;IACA,KAAKH,kBAAkB,QAAQ;IAC/B,KAAKJ,eAAe,QAAQ,eAAe,KAAKA;GACpD;GAEA,KAAKL,mBAAmB;GACxB,OAAO;IAAE,WAAW,GAAG;IAAW,UAAU,GAAG;GAAS;EAC5D,QAAQ;GACJ,KAAKW,0BAA0B;GAC/B,OAAO;EACX;CACJ;;;;CAKA,MAAM,SAAwB;EAC1B,KAAKjB,UAAU,kBAAkB;EACjC,KAAKD,cAAc,MAAM;EACzB,KAAKa,mBAAmB;EACxB,KAAKC,iBAAiB;EACtB,KAAKC,mBAAmB;EACxB,KAAKH,eAAe;EACpB,KAAKF,gBAAgB,KAAA;EACrB,KAAKL,mBAAmB;EAExB,KAAKH,cAAc,MAAM;EAEzB,KAAKK,mBAAmB;EACxB,KAAK,OAAO,KAAK,aAAa,KAAA,CAAS;CAC3C;CAEA,4BAAkC;EAC9B,MAAM,sBAAsB,KAAKM;EACjC,KAAKZ,UAAU,kBAAkB;EACjC,KAAKD,cAAc,MAAM;EACzB,KAAKE,cAAc,MAAM;EACzB,KAAKW,mBAAmB;EACxB,KAAKC,iBAAiB;EACtB,KAAKC,mBAAmB;EACxB,KAAKH,eAAe;EACpB,KAAKF,gBAAgB,KAAA;EACrB,KAAKL,mBAAmB;EACxB,KAAKE,mBAAmB;EACxB,IAAI,qBACA,KAAK,OAAO,KAAK,aAAa,KAAA,CAAS;CAE/C;;;;CAKA,yBAAiC;EAC7B,MAAM,QAAQ,KAAKU,0BAA0B;EAC7C,IAAI,CAAC,OAAO,OAAO;EACnB,OAAO,mBAAmB,KAAK;CACnC;;;;CAKA,MAAM,eAAe,QAKI;EACrB,IAAI,CAAC,KAAKJ,kBACN,MAAM,IAAI,oBAAoB,0CAA0C;EAG5E,MAAM,iBAAiB,KAAKF,uBAAuB;EACnD,OAAO,KAAKH,OACR;GACI,UAAU,KAAKY,wBAAwB,QAAQ,QAAQ;GACvD,KAAK,QAAQ;GACb,aAAa,QAAQ,eAAe,KAAKR;EAC7C,GACA,gBAAgB,aACpB;CACJ;;;;CAKA,cACI,WACA,SACsC;EACtC,IAAI,CAAC,KAAKC,oBAAoB,CAAC,KAAKC,gBAChC,MAAM,IAAI,oBAAoB,0CAA0C;EAG5E,KAAKC,mBAAmB;EACxB,MAAM,SAAS,cAAc,KAAKD;EAElC,KAAKZ,cAAc,iBACf;GACI;GACA;GACA,qBAAqB,SAAS;GAC9B,OAAO,SAAS;EACpB,GACA,EAAE,eAAe,KAAKiB,+BAA+B,CAAC,CAAC,cAAc,CACzE;EACA,KAAKZ,mBAAmB;EAExB,OAAO;GAAE;GAAW;EAAO;CAC/B;;CAGA,oBAAoB,UAA+B;EAC/C,KAAKL,cAAc,YAAY,UAAU,EACrC,eAAe,KAAKiB,+BAA+B,CAAC,CAAC,cACzD,CAAC;CACL;;;;CAKA,MAAM,iBAAiB,QAAiE;EACpF,IAAI,CAAC,KAAKN,kBACN,MAAM,IAAI,oBAAoB,6CAA6C;EAG/E,IAAI,CAAC,KAAKd,cACN,MAAM,IAAI,mBACN,4FACJ;EAGJ,MAAM,EAAE,eAAe,QAAQ,OAAO;EACtC,KAAKI,gCAAgC,aAAa;EAElD,MAAM,EAAE,YAAY,MAAM,KAAK,sBAAsB;GACjD,qBAAqB,cAAc;GACnC,eAAe,cAAc;GAC7B,KAAK,oBAAoB,OAAO,OAAO,KAAKO,aAAa;GACzD,SAAS;EACb,CAAC;EACD,MAAM,YAAY,MAAM,cAAc,YAAY,OAAO;EAEzD,MAAM,WAAW,MAAM,KAAKX,aAAa,OAAO;GAC5C;GACA,qBAAqB,cAAc;GACnC;GACA;EACJ,CAAC;EAED,OAAO;GACH,cAAc,SAAS;GACvB,uBAAuB,SAAS;GAChC,UAAU,SAAS;EACvB;CACJ;;;;CAKA,WAAsB;EAClB,MAAM,kBAAkB,KAAKK,kBAAkB,KAAKC;EAEpD,OAAO;GACH,iBAAiB,KAAKQ;GACtB,gBAAgB,iBAAiB,kBAAkB;GACnD,cAAc,iBAAiB,gBAAgB;GAC/C,eAAe,KAAKC;GACpB,eACI,KAAKC,oBAAoB,KAAKD,iBACxB;IACI,WAAW,KAAKC;IAChB,QAAQ,KAAKA,qBAAqB,KAAKD;IACvC,eAAe,KAAKA;IACpB,qBAAqB,iBAAiB;GAC1C,IACA;EACd;CACJ;CAEA,MAAML,wBAAuD;EACzD,IAAI,KAAKL,gBAAgB;GACrB,KAAKD,gCAAgC,KAAKC,cAAc;GACxD,OAAO,KAAKA;EAChB;EAEA,MAAM,WAAW,MAAM,qBAAqB,KAAKP,oBAAoB;EACrE,IAAI,UAAU;GACV,KAAKM,gCAAgC,QAAQ;GAC7C,KAAKC,iBAAiB;GACtB,KAAKC,mBAAmB,KAAKC,oBAAoB,QAAQ;EAC7D;EACA,OAAO,KAAKF;CAChB;CAEA,qBAA2B;EACvB,KAAK,OAAO,KAAK,eAAe,KAAK,SAAS,CAAC;CACnD;CAEA,4BAA2C;EACvC,OAAO,KAAKF,cAAc,yBAAyB,KAAKF,aAAa;CACzE;CAEA,iCAA6D;EACzD,MAAM,QAAQ,KAAKA,cAAc,IAAI;EACrC,IAAI,CAAC,OAAO,OAAO;GAAE,WAAW;GAAM,eAAe;EAAK;EAC1D,OAAO,iCAAiC,KAAK;CACjD;CAEA,wBACI,UACgC;EAChC,OACI,YAAY,KAAKgB,mBAAmB,KAAKL,uBAAuB,CAAC,EAAE,YAAY;CAEvF;CAEA,gCAAgC,eAAoC;EAChE,oBAAoB,aAAa;EACjC,IAAI,cAAc,2BAA2B,KAAKb,yBAC9C,MAAM,IAAI,mBACN,+DACJ;CAER;CAEA,oBAAoB,eAA+C;EAC/D,OAAO;GACH,gBAAgB,cAAc;GAC9B,cAAc,cAAc;EAChC;CACJ;CAEA,yBAA6C;EACzC,OAAO,KAAKI,cAAc,IAAI;CAClC;AACJ;AAEA,SAAS,oBAAoB,KAAiC;CAC1D,MAAM,WAAW,QAAQ,OAAO,aAAa,cAAc,KAAA,IAAY,SAAS;CAChF,IAAI,CAAC,UACD,MAAM,IAAI,mBACN,kFACJ;CACJ,OAAO;AACX"}
|
|
1
|
+
{"version":3,"file":"account-signer-auth.js","names":["#accountSignerConfig","#environmentFingerprint","#subaccounts","#tokenStorage","#realtime","#sessionStore","#assertAccountSignerEnvironment","#beginAuthOperation","#accountSigner","#accountIdentity","#identityFromSigner","#notifyStateChange","#login","#resolveAccountSigner","#challengeUri","#isCurrentAuthOperation","#getEnvironmentSession","#loginMethod","#isAuthenticated","#mainAccountId","#activeAccountId","#walletProvider","#loginResult","#getEnvironmentBoundToken","#clearExpiredSessionState","#getCurrentTokenStorageOptions","#resolveRefreshProvider","#authOperationGeneration"],"sources":["../../../src/services/auth/account-signer-auth.ts"],"sourcesContent":["import { AuthService, type LoginWithWalletResponse } from \"./auth.js\";\nimport { AuthenticationError, ConfigurationError } from \"../../shared/errors.js\";\nimport { toPolyesterError } from \"../../shared/connect-error-mapping.js\";\nimport { AuthSessionStore } from \"./session.js\";\nimport type { AccountSigner, AccountSignerConfig, HexAddress } from \"../../account-signer/types.js\";\nimport { assertAccountSigner, resolveAccountSigner } from \"../../account-signer/types.js\";\nimport { EventEmitter } from \"../../utils/event-emitter.js\";\nimport { isJwtValid, getJwtTimeToExpiry } from \"../../utils/jwt.js\";\nimport type { SubaccountsService } from \"../subaccounts/index.js\";\nimport type {\n AuthState,\n AuthHydrationData,\n AuthLoginMethod,\n SessionData,\n ActiveAccountInfo,\n} from \"./session.types.js\";\nimport type { PolyesterRealtime } from \"../../realtime/index.js\";\nimport type { PolyesterEnvironment } from \"../../environment.js\";\nimport type { AuthAndPublicApiTransports } from \"../../shared/transports.js\";\nimport {\n createAuthTokenStorageSetOptions,\n type AuthTokenStorage,\n type AuthTokenStorageSetOptions,\n} from \"./token-storage.js\";\n\nexport interface AccountSignerAuthEvents {\n authenticated: { accountId: string; username: string };\n loggedOut: void;\n error: { code: string; message: string };\n servicesReady: void;\n stateChange: AuthState;\n}\n\nexport interface LoginResult {\n accountId: string;\n username: string;\n expiresAt: Date;\n}\n\nexport interface LoginOptions {\n /**\n * The wallet provider to use for login.\n */\n provider: \"metamask\" | \"turnkey\" | \"other\";\n /** Browser origin requesting the signature; defaults to location.origin in browsers. Required outside browsers. */\n uri?: string;\n loginMethod?: AuthLoginMethod | null;\n}\n\nexport interface CreateSubaccountParams {\n /** The account signer for the new subaccount (caller derives this, e.g. via Turnkey saltNonce) */\n accountSigner: AccountSigner;\n /** Optional human-readable label for this subaccount */\n label?: string;\n /** Browser origin requesting the signature; defaults to location.origin in browsers. Required outside browsers. */\n uri?: string;\n}\n\nexport interface CreateSubaccountResult {\n subaccountId: string;\n smartAccountSaltNonce: number;\n revision: string;\n}\n\ninterface AccountIdentity {\n accountAddress: HexAddress;\n ownerAddress?: HexAddress;\n}\n\n/**\n * Coordinates wallet/account-signer authentication, session storage, subaccount selection, and session refresh.\n */\nexport class AccountSignerAuthService extends AuthService {\n readonly events = new EventEmitter<AccountSignerAuthEvents>();\n\n #accountSignerConfig: AccountSignerConfig | undefined;\n #accountSigner: AccountSigner | null = null;\n #accountIdentity: AccountIdentity | null = null;\n #isAuthenticated = false;\n #mainAccountId: string | null = null;\n #activeAccountId: string | null = null;\n #subaccounts: SubaccountsService;\n #walletProvider: \"metamask\" | \"turnkey\" | \"other\" | undefined = undefined;\n #loginMethod: AuthLoginMethod | null = null;\n #challengeUri: string | undefined = undefined;\n #environmentFingerprint: string;\n #tokenStorage: AuthTokenStorage;\n #sessionStore: AuthSessionStore;\n #realtime: PolyesterRealtime;\n // Every asynchronous auth transition captures this generation. A later login,\n // logout, signer change, or restore makes older work observational only.\n #authOperationGeneration = 0;\n\n constructor({\n transports,\n accountSignerConfig,\n environment,\n subaccounts,\n realtime,\n tokenStorage,\n sessionStore,\n }: {\n transports: AuthAndPublicApiTransports;\n accountSignerConfig?: AccountSignerConfig;\n environment: PolyesterEnvironment;\n subaccounts: SubaccountsService;\n realtime: PolyesterRealtime;\n tokenStorage: AuthTokenStorage;\n sessionStore?: AuthSessionStore;\n }) {\n super(transports, realtime);\n\n this.#accountSignerConfig = accountSignerConfig;\n this.#environmentFingerprint = environment.fingerprint;\n this.#subaccounts = subaccounts;\n this.#tokenStorage = tokenStorage;\n this.#realtime = realtime;\n this.#sessionStore =\n sessionStore ??\n new AuthSessionStore({\n environmentFingerprint: environment.fingerprint,\n });\n }\n\n /**\n * Attaches the subaccounts service used when creating a subaccount during authenticated flows.\n */\n setSubaccountsService(subaccounts: SubaccountsService): void {\n this.#subaccounts = subaccounts;\n }\n\n /**\n * Sets the account signer used to sign login and account-switch challenges.\n */\n setAccountSigner(accountSigner: AccountSigner | null): void {\n if (accountSigner) this.#assertAccountSignerEnvironment(accountSigner);\n this.#beginAuthOperation();\n this.#accountSigner = accountSigner;\n this.#accountIdentity = accountSigner ? this.#identityFromSigner(accountSigner) : null;\n this.#notifyStateChange();\n }\n\n /**\n * Returns the active account signer, throwing if one has not been configured.\n */\n getAccountSigner(): AccountSigner | null {\n return this.#accountSigner;\n }\n\n /**\n * Signs a server-issued SIWE message with the configured account signer, exchanges it for a session token, and stores the hydrated account/subaccount session state.\n */\n async login(options: LoginOptions): Promise<LoginResult> {\n return this.#login(options);\n }\n\n async #login(\n options: LoginOptions,\n previousActiveAccount?: ActiveAccountInfo,\n ): Promise<LoginResult> {\n const generation = this.#beginAuthOperation();\n const startingToken = this.#tokenStorage.get();\n const { provider, loginMethod } = options;\n\n const accountSigner = await this.#resolveAccountSigner();\n\n if (!accountSigner) {\n throw new ConfigurationError(\n \"No account signer configured. Call setAccountSigner() or pass accountSigner in config.\",\n );\n }\n\n const smartAccountAddress = accountSigner.accountAddress;\n const ownerAddress = accountSigner.ownerAddress ?? accountSigner.accountAddress;\n\n const uri = resolveChallengeUri(options.uri ?? this.#challengeUri);\n const { message } = await this.createWalletChallenge({\n smartAccountAddress,\n signerAddress: ownerAddress,\n uri,\n purpose: \"login\",\n });\n const signature = await accountSigner.signMessage(message);\n\n const response = await this.loginWithWallet({\n smartAccountAddress,\n message,\n signature,\n walletProvider: provider,\n });\n\n if (!this.#isCurrentAuthOperation(generation, startingToken)) {\n throw new DOMException(\"Authentication operation superseded\", \"AbortError\");\n }\n const environmentSession = this.#getEnvironmentSession();\n const resolvedLoginMethod =\n loginMethod ??\n this.#loginMethod ??\n environmentSession?.loginMethod ??\n (provider === \"metamask\" ? \"metamask\" : null);\n\n const tokenOptions = createAuthTokenStorageSetOptions(response.accessToken);\n const activeAccount =\n previousActiveAccount?.mainAccountId === response.accountId\n ? previousActiveAccount\n : undefined;\n this.#sessionStore.commitLogin(\n {\n accessToken: response.accessToken,\n tokenOptions,\n provider,\n loginMethod: resolvedLoginMethod,\n primaryWallet: ownerAddress,\n smartAccount: smartAccountAddress,\n accountId: response.accountId,\n activeAccount,\n username: response.username ?? undefined,\n },\n this.#tokenStorage,\n );\n this.#isAuthenticated = true;\n this.#mainAccountId = response.accountId;\n this.#activeAccountId = activeAccount?.accountId ?? response.accountId;\n this.#walletProvider = provider;\n this.#loginMethod = resolvedLoginMethod;\n this.#challengeUri = uri;\n this.#accountSigner = accountSigner;\n this.#accountIdentity = this.#identityFromSigner(accountSigner);\n\n this.#notifyStateChange();\n\n this.events.emit(\"authenticated\", {\n accountId: response.accountId,\n username: response.username,\n });\n\n return this.#loginResult(response);\n }\n\n /**\n * Builds auth state from a session token and optional active account override.\n */\n hydrateAuthState(state: AuthHydrationData): void {\n this.#beginAuthOperation();\n const existingToken = this.#getEnvironmentBoundToken();\n if (!existingToken || !isJwtValid(existingToken)) return;\n\n const existingSession = this.#getEnvironmentSession();\n this.#walletProvider = existingSession?.provider ?? this.#walletProvider;\n this.#loginMethod = existingSession?.loginMethod ?? this.#loginMethod;\n\n this.#isAuthenticated = true;\n this.#mainAccountId = state.mainAccountId;\n this.#activeAccountId = state.activeAccountId ?? state.mainAccountId;\n this.#accountIdentity = state.smartAccountAddress\n ? {\n accountAddress: state.smartAccountAddress,\n ownerAddress: state.ownerAddress,\n }\n : null;\n\n this.#notifyStateChange();\n }\n\n /**\n * Loads the stored token, validates that it still belongs to this environment, and restores auth state when possible.\n */\n async restoreSession(): Promise<{ accountId: string; username: string } | null> {\n const generation = this.#beginAuthOperation();\n const existingToken = this.#getEnvironmentBoundToken();\n\n if (!existingToken || !isJwtValid(existingToken)) {\n if (this.#isCurrentAuthOperation(generation)) this.#clearExpiredSessionState();\n return null;\n }\n\n let me: Awaited<ReturnType<AuthService[\"me\"]>>;\n try {\n me = await this.me();\n } catch (error) {\n if (!this.#isCurrentAuthOperation(generation, existingToken)) return null;\n const mappedError = toPolyesterError(error);\n if (mappedError instanceof AuthenticationError) {\n this.#clearExpiredSessionState();\n return null;\n }\n throw mappedError;\n }\n if (!this.#isCurrentAuthOperation(generation, existingToken)) return null;\n\n let accountSigner = this.#accountSigner;\n if (!accountSigner) {\n try {\n accountSigner = await resolveAccountSigner(this.#accountSignerConfig);\n } catch (error) {\n if (!this.#isCurrentAuthOperation(generation, existingToken)) return null;\n throw error;\n }\n if (!this.#isCurrentAuthOperation(generation, existingToken)) return null;\n if (accountSigner) this.#assertAccountSignerEnvironment(accountSigner);\n }\n\n if (!isJwtValid(existingToken) || this.#getEnvironmentBoundToken() !== existingToken) {\n this.#clearExpiredSessionState();\n return null;\n }\n\n const existingSession = this.#getEnvironmentSession();\n const walletProvider = existingSession?.provider ?? this.#walletProvider;\n const loginMethod = existingSession?.loginMethod ?? this.#loginMethod;\n const activeAccountId =\n this.#activeAccountId ?? existingSession?.activeAccount?.accountId ?? me.accountId;\n\n // Publish runtime state only after asynchronous restoration has completed.\n if (accountSigner) {\n this.#sessionStore.ensureSession(\n {\n provider: walletProvider ?? \"other\",\n loginMethod: loginMethod ?? (walletProvider === \"metamask\" ? \"metamask\" : null),\n primaryWallet: accountSigner.ownerAddress ?? accountSigner.accountAddress,\n smartAccount: accountSigner.accountAddress,\n accountId: me.accountId,\n username: me.username ?? undefined,\n },\n { maxAgeSeconds: this.#getCurrentTokenStorageOptions().maxAgeSeconds },\n );\n this.#accountSigner = accountSigner;\n this.#accountIdentity = this.#identityFromSigner(accountSigner);\n }\n this.#isAuthenticated = true;\n this.#mainAccountId = me.accountId;\n this.#activeAccountId = activeAccountId;\n this.#walletProvider = walletProvider ?? (accountSigner ? \"other\" : undefined);\n this.#loginMethod = loginMethod;\n this.#notifyStateChange();\n return { accountId: me.accountId, username: me.username };\n }\n\n /**\n * Clears stored auth state and removes the persisted auth token.\n */\n async logout(): Promise<void> {\n this.#beginAuthOperation();\n this.#realtime.disconnectPrivate();\n this.#tokenStorage.clear();\n this.#isAuthenticated = false;\n this.#mainAccountId = null;\n this.#activeAccountId = null;\n this.#loginMethod = null;\n this.#challengeUri = undefined;\n this.#accountIdentity = null;\n\n this.#sessionStore.clear();\n\n this.#notifyStateChange();\n this.events.emit(\"loggedOut\", undefined);\n }\n\n #clearExpiredSessionState(): void {\n const shouldEmitLoggedOut = this.#isAuthenticated;\n this.#realtime.disconnectPrivate();\n this.#tokenStorage.clear();\n this.#sessionStore.clear();\n this.#isAuthenticated = false;\n this.#mainAccountId = null;\n this.#activeAccountId = null;\n this.#loginMethod = null;\n this.#challengeUri = undefined;\n this.#accountIdentity = null;\n this.#notifyStateChange();\n if (shouldEmitLoggedOut) {\n this.events.emit(\"loggedOut\", undefined);\n }\n }\n\n /**\n * Returns the remaining lifetime of the stored session token in milliseconds.\n */\n getSessionTimeToExpiry(): number {\n const token = this.#getEnvironmentBoundToken();\n if (!token || !isJwtValid(token)) return 0;\n return getJwtTimeToExpiry(token);\n }\n\n /**\n * Refreshes the active account-signer session and updates persisted auth state.\n */\n async refreshSession(params?: {\n /** Overrides the origin remembered from login. */\n uri?: string;\n provider?: \"metamask\" | \"turnkey\" | \"other\";\n loginMethod?: AuthLoginMethod | null;\n }): Promise<LoginResult> {\n if (!this.#isAuthenticated) {\n throw new AuthenticationError(\"Must be authenticated to refresh session\");\n }\n\n const currentSession = this.#getEnvironmentSession();\n return this.#login(\n {\n provider: this.#resolveRefreshProvider(params?.provider),\n uri: params?.uri,\n loginMethod: params?.loginMethod ?? this.#loginMethod,\n },\n currentSession?.activeAccount,\n );\n }\n\n /**\n * Switches the active account/subaccount by signing the required account switch flow.\n */\n switchAccount(\n accountId: string,\n options?: { smartAccountAddress?: string; label?: string },\n ): { accountId: string; isMain: boolean } {\n if (!this.#isAuthenticated || !this.#mainAccountId) {\n throw new AuthenticationError(\"Must be authenticated to switch accounts\");\n }\n\n this.#activeAccountId = accountId;\n const isMain = accountId === this.#mainAccountId;\n\n this.#sessionStore.setActiveAccount(\n {\n accountId,\n isMain,\n smartAccountAddress: options?.smartAccountAddress,\n label: options?.label,\n },\n { maxAgeSeconds: this.#getCurrentTokenStorageOptions().maxAgeSeconds },\n );\n this.#notifyStateChange();\n\n return { accountId, isMain };\n }\n\n /** Keeps the display-session identity current for the next server render. */\n syncSessionUsername(username: string | null): void {\n this.#sessionStore.setUsername(username, {\n maxAgeSeconds: this.#getCurrentTokenStorageOptions().maxAgeSeconds,\n });\n }\n\n /**\n * Creates a subaccount for the authenticated account and makes it available to the session state.\n */\n async createSubaccount(params: CreateSubaccountParams): Promise<CreateSubaccountResult> {\n if (!this.#isAuthenticated) {\n throw new AuthenticationError(\"Must be authenticated to create subaccounts\");\n }\n\n if (!this.#subaccounts) {\n throw new ConfigurationError(\n \"SubaccountsService not configured. Pass it to constructor or call setSubaccountsService().\",\n );\n }\n\n const { accountSigner, label = \"\" } = params;\n this.#assertAccountSignerEnvironment(accountSigner);\n\n const { message } = await this.createWalletChallenge({\n smartAccountAddress: accountSigner.accountAddress,\n signerAddress: accountSigner.accountAddress,\n uri: resolveChallengeUri(params.uri ?? this.#challengeUri),\n purpose: \"create_subaccount\",\n });\n const signature = await accountSigner.signMessage(message);\n\n const response = await this.#subaccounts.create({\n label,\n smartAccountAddress: accountSigner.accountAddress,\n message,\n signature,\n });\n\n return {\n subaccountId: response.subaccountId,\n smartAccountSaltNonce: response.smartAccountSaltNonce,\n revision: response.revision,\n };\n }\n\n /**\n * Returns the current account-signer auth state snapshot.\n */\n getState(): AuthState {\n const accountIdentity = this.#accountSigner ?? this.#accountIdentity;\n\n return {\n isAuthenticated: this.#isAuthenticated,\n accountAddress: accountIdentity?.accountAddress ?? null,\n ownerAddress: accountIdentity?.ownerAddress ?? null,\n mainAccountId: this.#mainAccountId,\n activeAccount:\n this.#activeAccountId && this.#mainAccountId\n ? {\n accountId: this.#activeAccountId,\n isMain: this.#activeAccountId === this.#mainAccountId,\n mainAccountId: this.#mainAccountId,\n smartAccountAddress: accountIdentity?.accountAddress,\n }\n : null,\n };\n }\n\n async #resolveAccountSigner(): Promise<AccountSigner | null> {\n if (this.#accountSigner) {\n this.#assertAccountSignerEnvironment(this.#accountSigner);\n return this.#accountSigner;\n }\n\n const resolved = await resolveAccountSigner(this.#accountSignerConfig);\n if (resolved) {\n this.#assertAccountSignerEnvironment(resolved);\n }\n return resolved;\n }\n\n #notifyStateChange(): void {\n this.events.emit(\"stateChange\", this.getState());\n }\n\n #beginAuthOperation(): number {\n this.#authOperationGeneration += 1;\n return this.#authOperationGeneration;\n }\n\n #isCurrentAuthOperation(generation: number, token?: string | null): boolean {\n return (\n generation === this.#authOperationGeneration &&\n (token === undefined || this.#tokenStorage.get() === token)\n );\n }\n\n #loginResult(response: LoginWithWalletResponse): LoginResult {\n const expiresAt = response.expiresAt\n ? new Date(\n Number(response.expiresAt.seconds) * 1000 +\n (response.expiresAt.nanos ?? 0) / 1_000_000,\n )\n : new Date();\n return { accountId: response.accountId, username: response.username, expiresAt };\n }\n\n #getEnvironmentBoundToken(): string | null {\n return this.#sessionStore.getEnvironmentBoundToken(this.#tokenStorage);\n }\n\n #getCurrentTokenStorageOptions(): AuthTokenStorageSetOptions {\n const token = this.#tokenStorage.get();\n if (!token) return { expiresAt: null, maxAgeSeconds: null };\n return createAuthTokenStorageSetOptions(token);\n }\n\n #resolveRefreshProvider(\n provider?: \"metamask\" | \"turnkey\" | \"other\",\n ): \"metamask\" | \"turnkey\" | \"other\" {\n return (\n provider ?? this.#walletProvider ?? this.#getEnvironmentSession()?.provider ?? \"other\"\n );\n }\n\n #assertAccountSignerEnvironment(accountSigner: AccountSigner): void {\n assertAccountSigner(accountSigner);\n if (accountSigner.environmentFingerprint !== this.#environmentFingerprint) {\n throw new ConfigurationError(\n \"Account signer environment does not match client environment.\",\n );\n }\n }\n\n #identityFromSigner(accountSigner: AccountSigner): AccountIdentity {\n return {\n accountAddress: accountSigner.accountAddress,\n ownerAddress: accountSigner.ownerAddress,\n };\n }\n\n #getEnvironmentSession(): SessionData | null {\n return this.#sessionStore.get();\n }\n}\n\nfunction resolveChallengeUri(uri: string | undefined): string {\n const resolved = uri ?? (typeof location === \"undefined\" ? undefined : location.origin);\n if (!resolved)\n throw new ConfigurationError(\n \"Wallet authentication requires a browser origin URI. Pass uri outside a browser.\",\n );\n return resolved;\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
//#region src/services/auth/cookie-constants.d.ts
|
|
2
2
|
declare const POLYESTER_SESSION_COOKIE_NAME = "polyester_session_4";
|
|
3
3
|
declare const POLYESTER_AUTH_TOKEN_COOKIE_NAME = "polyester_auth_token";
|
|
4
|
+
/** The request or browser location that determines a local auth-cookie name. */
|
|
5
|
+
interface AuthCookieLocation {
|
|
6
|
+
hostname: string;
|
|
7
|
+
port: string;
|
|
8
|
+
protocol: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Keeps local development servers on different ports from sharing auth cookies.
|
|
12
|
+
* Public hosts retain the stable production cookie names. A missing location is
|
|
13
|
+
* intentionally treated as production; server callers handling a local request
|
|
14
|
+
* must pass that request's URL or location.
|
|
15
|
+
*/
|
|
16
|
+
declare function resolveAuthCookieName(name: string, location?: AuthCookieLocation): string;
|
|
4
17
|
//#endregion
|
|
5
|
-
export { POLYESTER_AUTH_TOKEN_COOKIE_NAME, POLYESTER_SESSION_COOKIE_NAME };
|
|
18
|
+
export { AuthCookieLocation, POLYESTER_AUTH_TOKEN_COOKIE_NAME, POLYESTER_SESSION_COOKIE_NAME, resolveAuthCookieName };
|
|
6
19
|
//# sourceMappingURL=cookie-constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookie-constants.d.ts","names":[],"sources":["../../../src/services/auth/cookie-constants.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"cookie-constants.d.ts","names":[],"sources":["../../../src/services/auth/cookie-constants.ts"],"mappings":";cAEa;cAEA;;UAGI;EACb;EACA;EACA;;;;;;;;iBASY,sBAAsB,cAAc,WAAW"}
|
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
import { isLocalNetworkHost } from "../../utils/is-dev.js";
|
|
1
2
|
//#region src/services/auth/cookie-constants.ts
|
|
2
3
|
const POLYESTER_SESSION_COOKIE_NAME = "polyester_session_4";
|
|
3
4
|
const POLYESTER_LOGIN_COOKIE_MAX_AGE = 604800;
|
|
4
5
|
const POLYESTER_AUTH_TOKEN_COOKIE_NAME = "polyester_auth_token";
|
|
6
|
+
/**
|
|
7
|
+
* Keeps local development servers on different ports from sharing auth cookies.
|
|
8
|
+
* Public hosts retain the stable production cookie names. A missing location is
|
|
9
|
+
* intentionally treated as production; server callers handling a local request
|
|
10
|
+
* must pass that request's URL or location.
|
|
11
|
+
*/
|
|
12
|
+
function resolveAuthCookieName(name, location) {
|
|
13
|
+
const currentLocation = location ?? (typeof window === "undefined" ? void 0 : window.location);
|
|
14
|
+
if (!currentLocation || !isLocalNetworkHost(currentLocation.hostname)) return name;
|
|
15
|
+
return `${name}_port_${currentLocation.port || (currentLocation.protocol === "https:" ? "443" : "80")}`;
|
|
16
|
+
}
|
|
5
17
|
//#endregion
|
|
6
|
-
export { POLYESTER_AUTH_TOKEN_COOKIE_NAME, POLYESTER_LOGIN_COOKIE_MAX_AGE, POLYESTER_SESSION_COOKIE_NAME };
|
|
18
|
+
export { POLYESTER_AUTH_TOKEN_COOKIE_NAME, POLYESTER_LOGIN_COOKIE_MAX_AGE, POLYESTER_SESSION_COOKIE_NAME, resolveAuthCookieName };
|
|
7
19
|
|
|
8
20
|
//# sourceMappingURL=cookie-constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookie-constants.js","names":[],"sources":["../../../src/services/auth/cookie-constants.ts"],"sourcesContent":["// v4: environment fingerprints no longer include API or WebSocket URLs.\nexport const POLYESTER_SESSION_COOKIE_NAME = \"polyester_session_4\";\nexport const POLYESTER_LOGIN_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; // 7 days\nexport const POLYESTER_AUTH_TOKEN_COOKIE_NAME = \"polyester_auth_token\";\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"cookie-constants.js","names":[],"sources":["../../../src/services/auth/cookie-constants.ts"],"sourcesContent":["// v4: environment fingerprints no longer include API or WebSocket URLs.\nimport { isLocalNetworkHost } from \"../../utils/is-dev.js\";\nexport const POLYESTER_SESSION_COOKIE_NAME = \"polyester_session_4\";\nexport const POLYESTER_LOGIN_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; // 7 days\nexport const POLYESTER_AUTH_TOKEN_COOKIE_NAME = \"polyester_auth_token\";\n\n/** The request or browser location that determines a local auth-cookie name. */\nexport interface AuthCookieLocation {\n hostname: string;\n port: string;\n protocol: string;\n}\n\n/**\n * Keeps local development servers on different ports from sharing auth cookies.\n * Public hosts retain the stable production cookie names. A missing location is\n * intentionally treated as production; server callers handling a local request\n * must pass that request's URL or location.\n */\nexport function resolveAuthCookieName(name: string, location?: AuthCookieLocation): string {\n const currentLocation =\n location ??\n (typeof window === \"undefined\" ? undefined : (window.location as AuthCookieLocation));\n if (!currentLocation || !isLocalNetworkHost(currentLocation.hostname)) return name;\n\n const port = currentLocation.port || (currentLocation.protocol === \"https:\" ? \"443\" : \"80\");\n return `${name}_port_${port}`;\n}\n"],"mappings":";;AAEA,MAAa,gCAAgC;AAC7C,MAAa,iCAAiC;AAC9C,MAAa,mCAAmC;;;;;;;AAehD,SAAgB,sBAAsB,MAAc,UAAuC;CACvF,MAAM,kBACF,aACC,OAAO,WAAW,cAAc,KAAA,IAAa,OAAO;CACzD,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,gBAAgB,QAAQ,GAAG,OAAO;CAG9E,OAAO,GAAG,KAAK,QADF,gBAAgB,SAAS,gBAAgB,aAAa,WAAW,QAAQ;AAE1F"}
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { PolyesterEnvironment } from "../../environment.js";
|
|
2
2
|
import { CookieGetter } from "../../utils/cookies.js";
|
|
3
|
+
import { AuthCookieLocation } from "./cookie-constants.js";
|
|
3
4
|
import { AuthTokenStorage, AuthTokenStorageSetOptions } from "./token-storage.js";
|
|
4
5
|
import { ActiveAccountInfo, AuthLoginMethod, ServerSessionSnapshot, SessionData } from "./session.types.js";
|
|
5
6
|
//#region src/services/auth/session.d.ts
|
|
6
7
|
interface SessionCookieOptions {
|
|
7
8
|
maxAgeSeconds?: number | null;
|
|
8
9
|
}
|
|
10
|
+
/** Options for reading browser auth cookies from a server runtime. */
|
|
11
|
+
interface ServerSessionCookieOptions {
|
|
12
|
+
/** Location of the page or request that supplied the cookies. */
|
|
13
|
+
cookieLocation?: AuthCookieLocation;
|
|
14
|
+
/** Base name configured for the browser bearer-token cookie. */
|
|
15
|
+
tokenCookieName?: string;
|
|
16
|
+
}
|
|
9
17
|
interface CommitLoginSessionParams {
|
|
10
18
|
accessToken: string;
|
|
11
19
|
tokenOptions: AuthTokenStorageSetOptions;
|
|
@@ -29,7 +37,7 @@ declare function emptyServerSessionSnapshot(): ServerSessionSnapshot;
|
|
|
29
37
|
/**
|
|
30
38
|
* Parses bearer authentication and display-only session cookies into a server snapshot.
|
|
31
39
|
*/
|
|
32
|
-
declare function parseServerSessionSnapshot(cookies: CookieGetter, environment: PolyesterEnvironment): ServerSessionSnapshot;
|
|
40
|
+
declare function parseServerSessionSnapshot(cookies: CookieGetter, environment: PolyesterEnvironment, options?: ServerSessionCookieOptions): ServerSessionSnapshot;
|
|
33
41
|
/**
|
|
34
42
|
* Owns environment-bound auth session transitions for browser clients.
|
|
35
43
|
*/
|
|
@@ -47,5 +55,5 @@ declare class AuthSessionStore {
|
|
|
47
55
|
clear(): void;
|
|
48
56
|
}
|
|
49
57
|
//#endregion
|
|
50
|
-
export { type ActiveAccountInfo, type AuthLoginMethod, AuthSessionStore, CommitLoginSessionParams, EnsureSessionParams, type ServerSessionSnapshot, SessionCookieOptions, type SessionData, emptyServerSessionSnapshot, parseServerSessionSnapshot };
|
|
58
|
+
export { type ActiveAccountInfo, type AuthLoginMethod, AuthSessionStore, CommitLoginSessionParams, EnsureSessionParams, ServerSessionCookieOptions, type ServerSessionSnapshot, SessionCookieOptions, type SessionData, emptyServerSessionSnapshot, parseServerSessionSnapshot };
|
|
51
59
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","names":[],"sources":["../../../src/services/auth/session.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"session.d.ts","names":[],"sources":["../../../src/services/auth/session.ts"],"mappings":";;;;;;UA2BiB;EACb;;;UAIa;;EAEb,iBAAiB;;EAEjB;;UAGa;EACb;EACA,cAAc;EACd,UAAU;EACV,aAAa;EACb;EACA;EACA;EACA,gBAAgB;EAChB;;UAGa;EACb,UAAU;EACV,aAAa;EACb;EACA;EACA;EACA;;iBAoEY,8BAA8B;;;;iBAgB9B,2BACZ,SAAS,cACT,aAAa,sBACb,UAAS,6BACV;;;;cA2CU;;EAIG,cAAE;IAA4B;;EAK1C,OAAO;EAUP,yBAAyB,cAAc;EAgBvC,YAAY,QAAQ,0BAA0B,cAAc;EAsB5D,cAAc,QAAQ,qBAAqB,UAAU,uBAAuB;EA8B5E,YAAY,yBAAyB,UAAU;EAO/C,iBACI,eAAe,KAAK,qCACpB,UAAU;EAoBd"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { deleteCookie, getCookie, getCookieValue, setCookie, shouldSecureCookies } from "../../utils/cookies.js";
|
|
2
|
-
import { POLYESTER_LOGIN_COOKIE_MAX_AGE, POLYESTER_SESSION_COOKIE_NAME } from "./cookie-constants.js";
|
|
2
|
+
import { POLYESTER_LOGIN_COOKIE_MAX_AGE, POLYESTER_SESSION_COOKIE_NAME, resolveAuthCookieName } from "./cookie-constants.js";
|
|
3
3
|
import { SessionCodec } from "./session-codec.js";
|
|
4
4
|
//#region src/services/auth/session.ts
|
|
5
5
|
function resolveSessionCookieMaxAge(options) {
|
|
@@ -15,7 +15,7 @@ var PolyesterSessionManager = class {
|
|
|
15
15
|
*/
|
|
16
16
|
set(session, options) {
|
|
17
17
|
setCookie({
|
|
18
|
-
name: POLYESTER_SESSION_COOKIE_NAME,
|
|
18
|
+
name: resolveAuthCookieName(POLYESTER_SESSION_COOKIE_NAME),
|
|
19
19
|
value: SessionCodec.encode(session),
|
|
20
20
|
options: {
|
|
21
21
|
path: "/",
|
|
@@ -31,7 +31,7 @@ var PolyesterSessionManager = class {
|
|
|
31
31
|
* Returns the current session state, or null when no session is active.
|
|
32
32
|
*/
|
|
33
33
|
get() {
|
|
34
|
-
const value = getCookie(POLYESTER_SESSION_COOKIE_NAME);
|
|
34
|
+
const value = getCookie(resolveAuthCookieName(POLYESTER_SESSION_COOKIE_NAME));
|
|
35
35
|
if (!value) {
|
|
36
36
|
this.#lastRawValue = null;
|
|
37
37
|
this.#lastDecoded = null;
|
|
@@ -53,7 +53,7 @@ var PolyesterSessionManager = class {
|
|
|
53
53
|
* Clears the current session state.
|
|
54
54
|
*/
|
|
55
55
|
clear() {
|
|
56
|
-
deleteCookie(POLYESTER_SESSION_COOKIE_NAME);
|
|
56
|
+
deleteCookie(resolveAuthCookieName(POLYESTER_SESSION_COOKIE_NAME));
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
59
|
const polyesterSession = new PolyesterSessionManager();
|
|
@@ -72,9 +72,10 @@ function emptyServerSessionSnapshot() {
|
|
|
72
72
|
/**
|
|
73
73
|
* Parses bearer authentication and display-only session cookies into a server snapshot.
|
|
74
74
|
*/
|
|
75
|
-
function parseServerSessionSnapshot(cookies, environment) {
|
|
76
|
-
const
|
|
77
|
-
const
|
|
75
|
+
function parseServerSessionSnapshot(cookies, environment, options = {}) {
|
|
76
|
+
const cookieLocation = options.cookieLocation ?? (cookies instanceof Request ? new URL(cookies.url) : void 0);
|
|
77
|
+
const sessionValue = getCookieValue(cookies, resolveAuthCookieName(POLYESTER_SESSION_COOKIE_NAME, cookieLocation));
|
|
78
|
+
const bearerToken = getCookieValue(cookies, resolveAuthCookieName(options.tokenCookieName ?? "polyester_auth_token", cookieLocation)) ?? null;
|
|
78
79
|
const session = sessionValue ? SessionCodec.decode(sessionValue) : null;
|
|
79
80
|
if (!session) return {
|
|
80
81
|
...emptyServerSessionSnapshot(),
|
|
@@ -108,10 +109,7 @@ var AuthSessionStore = class {
|
|
|
108
109
|
get() {
|
|
109
110
|
const session = this.#session.get();
|
|
110
111
|
if (!session) return null;
|
|
111
|
-
if (session.environmentFingerprint !== this.#environmentFingerprint)
|
|
112
|
-
this.#session.clear();
|
|
113
|
-
return null;
|
|
114
|
-
}
|
|
112
|
+
if (session.environmentFingerprint !== this.#environmentFingerprint) return null;
|
|
115
113
|
return session;
|
|
116
114
|
}
|
|
117
115
|
getEnvironmentBoundToken(tokenStorage) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","names":["#lastRawValue","#lastDecoded","#environmentFingerprint","#session"],"sources":["../../../src/services/auth/session.ts"],"sourcesContent":["import {\n setCookie,\n deleteCookie,\n getCookie,\n getCookieValue,\n shouldSecureCookies,\n type CookieGetter,\n} from \"../../utils/cookies.js\";\nimport {\n POLYESTER_AUTH_TOKEN_COOKIE_NAME,\n POLYESTER_SESSION_COOKIE_NAME,\n POLYESTER_LOGIN_COOKIE_MAX_AGE,\n} from \"./cookie-constants.js\";\nimport { SessionCodec } from \"./session-codec.js\";\nimport type { PolyesterEnvironment } from \"../../environment.js\";\nimport type { AuthTokenStorage, AuthTokenStorageSetOptions } from \"./token-storage.js\";\nimport type {\n ActiveAccountInfo,\n AuthLoginMethod,\n ServerSessionSnapshot,\n SessionData,\n} from \"./session.types.js\";\n\nexport type { ActiveAccountInfo, AuthLoginMethod, ServerSessionSnapshot, SessionData };\n\nexport interface SessionCookieOptions {\n maxAgeSeconds?: number | null;\n}\n\nexport interface CommitLoginSessionParams {\n accessToken: string;\n tokenOptions: AuthTokenStorageSetOptions;\n provider: SessionData[\"provider\"];\n loginMethod: AuthLoginMethod | null;\n primaryWallet: string;\n smartAccount: string;\n accountId: string;\n activeAccount?: ActiveAccountInfo;\n username?: string;\n}\n\nexport interface EnsureSessionParams {\n provider: SessionData[\"provider\"];\n loginMethod: AuthLoginMethod | null;\n primaryWallet: string;\n smartAccount: string;\n accountId: string;\n username?: string;\n}\n\nfunction resolveSessionCookieMaxAge(options?: SessionCookieOptions): number | undefined {\n if (!options) return POLYESTER_LOGIN_COOKIE_MAX_AGE;\n return options.maxAgeSeconds ?? undefined;\n}\n\n/**\n * Reads and writes the browser display-session cookie.\n */\nclass PolyesterSessionManager {\n /**\n * Replaces the current session state.\n */\n set(session: SessionData, options?: SessionCookieOptions): void {\n setCookie({\n name: POLYESTER_SESSION_COOKIE_NAME,\n value: SessionCodec.encode(session),\n options: {\n path: \"/\",\n maxAge: resolveSessionCookieMaxAge(options),\n secure: shouldSecureCookies(),\n sameSite: \"lax\",\n },\n });\n }\n\n // The session is re-read on every authenticated RPC; memoize the decode\n // (JSON.parse + schema validation) on the raw cookie value.\n #lastRawValue: string | null = null;\n #lastDecoded: SessionData | null = null;\n\n /**\n * Returns the current session state, or null when no session is active.\n */\n get(): SessionData | null {\n const value = getCookie(POLYESTER_SESSION_COOKIE_NAME);\n if (!value) {\n this.#lastRawValue = null;\n this.#lastDecoded = null;\n return null;\n }\n if (value === this.#lastRawValue) return this.#lastDecoded;\n\n const session = SessionCodec.decode(value);\n if (!session) {\n this.clear();\n this.#lastRawValue = null;\n this.#lastDecoded = null;\n return null;\n }\n\n this.#lastRawValue = value;\n this.#lastDecoded = session;\n return session;\n }\n\n /**\n * Clears the current session state.\n */\n clear(): void {\n deleteCookie(POLYESTER_SESSION_COOKIE_NAME);\n }\n}\n\nexport const polyesterSession = new PolyesterSessionManager();\n\nexport function emptyServerSessionSnapshot(): ServerSessionSnapshot {\n return {\n environmentFingerprint: null,\n hasDisplaySession: false,\n provider: null,\n loginMethod: null,\n accountAddresses: null,\n activeAccount: null,\n bearerToken: null,\n username: null,\n };\n}\n\n/**\n * Parses bearer authentication and display-only session cookies into a server snapshot.\n */\nexport function parseServerSessionSnapshot(\n cookies: CookieGetter,\n environment: PolyesterEnvironment,\n): ServerSessionSnapshot {\n const sessionValue = getCookieValue(cookies, POLYESTER_SESSION_COOKIE_NAME);\n const bearerToken = getCookieValue(cookies, POLYESTER_AUTH_TOKEN_COOKIE_NAME) ?? null;\n const session = sessionValue ? SessionCodec.decode(sessionValue) : null;\n\n if (!session) {\n return { ...emptyServerSessionSnapshot(), bearerToken };\n }\n\n if (session.environmentFingerprint !== environment.fingerprint) {\n return emptyServerSessionSnapshot();\n }\n\n return {\n environmentFingerprint: session.environmentFingerprint,\n hasDisplaySession: true,\n provider: session.provider,\n loginMethod: session.loginMethod,\n accountAddresses: {\n ownerAddress: session.primaryWallet,\n accountAddress: session.smartAccount,\n },\n activeAccount: session.activeAccount ?? null,\n bearerToken,\n username: session.username ?? null,\n };\n}\n\n/**\n * Owns environment-bound auth session transitions for browser clients.\n */\nexport class AuthSessionStore {\n #environmentFingerprint: string;\n #session: PolyesterSessionManager;\n\n constructor({ environmentFingerprint }: { environmentFingerprint: string }) {\n this.#environmentFingerprint = environmentFingerprint;\n this.#session = polyesterSession;\n }\n\n get(): SessionData | null {\n const session = this.#session.get();\n if (!session) return null;\n if (session.environmentFingerprint !== this.#environmentFingerprint) {\n this.#session.clear();\n return null;\n }\n return session;\n }\n\n getEnvironmentBoundToken(tokenStorage: AuthTokenStorage): string | null {\n const token = tokenStorage.get();\n if (!token) return null;\n\n const session = this.#session.get();\n if (!session) return token;\n\n if (session.environmentFingerprint !== this.#environmentFingerprint) {\n this.#session.clear();\n tokenStorage.clear();\n return null;\n }\n\n return token;\n }\n\n commitLogin(params: CommitLoginSessionParams, tokenStorage: AuthTokenStorage): void {\n tokenStorage.set(params.accessToken, params.tokenOptions);\n this.#session.set(\n {\n environmentFingerprint: this.#environmentFingerprint,\n provider: params.provider,\n loginMethod: params.loginMethod,\n primaryWallet: params.primaryWallet,\n smartAccount: params.smartAccount,\n activeAccount: {\n accountId: params.activeAccount?.accountId ?? params.accountId,\n isMain: params.activeAccount?.isMain ?? true,\n mainAccountId: params.accountId,\n smartAccountAddress: params.activeAccount?.smartAccountAddress,\n label: params.activeAccount?.label,\n },\n username: params.username,\n },\n { maxAgeSeconds: params.tokenOptions.maxAgeSeconds },\n );\n }\n\n ensureSession(params: EnsureSessionParams, options?: SessionCookieOptions): SessionData {\n const existingSession = this.get();\n if (existingSession) {\n const username = params.username || undefined;\n if (username === undefined || username === existingSession.username) {\n return existingSession;\n }\n\n const session = { ...existingSession, username };\n this.#session.set(session, options);\n return session;\n }\n\n const session: SessionData = {\n environmentFingerprint: this.#environmentFingerprint,\n provider: params.provider,\n loginMethod: params.loginMethod,\n primaryWallet: params.primaryWallet,\n smartAccount: params.smartAccount,\n activeAccount: {\n accountId: params.accountId,\n isMain: true,\n mainAccountId: params.accountId,\n },\n username: params.username,\n };\n this.#session.set(session, options);\n return session;\n }\n\n setUsername(username: string | null, options?: SessionCookieOptions): void {\n const session = this.get();\n if (!session) return;\n\n this.#session.set({ ...session, username: username || undefined }, options);\n }\n\n setActiveAccount(\n activeAccount: Omit<ActiveAccountInfo, \"mainAccountId\">,\n options?: SessionCookieOptions,\n ): void {\n const session = this.get();\n if (!session) return;\n\n const mainAccountId = session.activeAccount?.mainAccountId ?? activeAccount.accountId;\n const smartAccountAddress = activeAccount.isMain\n ? session.smartAccount\n : activeAccount.smartAccountAddress;\n const label = activeAccount.isMain ? undefined : activeAccount.label;\n this.#session.set(\n {\n ...session,\n activeAccount: { ...activeAccount, mainAccountId, smartAccountAddress, label },\n username: session.username,\n },\n options,\n );\n }\n\n clear(): void {\n this.#session.clear();\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"session.js","names":["#lastRawValue","#lastDecoded","#environmentFingerprint","#session"],"sources":["../../../src/services/auth/session.ts"],"sourcesContent":["import {\n setCookie,\n deleteCookie,\n getCookie,\n getCookieValue,\n shouldSecureCookies,\n type CookieGetter,\n} from \"../../utils/cookies.js\";\nimport {\n POLYESTER_AUTH_TOKEN_COOKIE_NAME,\n POLYESTER_SESSION_COOKIE_NAME,\n POLYESTER_LOGIN_COOKIE_MAX_AGE,\n resolveAuthCookieName,\n type AuthCookieLocation,\n} from \"./cookie-constants.js\";\nimport { SessionCodec } from \"./session-codec.js\";\nimport type { PolyesterEnvironment } from \"../../environment.js\";\nimport type { AuthTokenStorage, AuthTokenStorageSetOptions } from \"./token-storage.js\";\nimport type {\n ActiveAccountInfo,\n AuthLoginMethod,\n ServerSessionSnapshot,\n SessionData,\n} from \"./session.types.js\";\n\nexport type { ActiveAccountInfo, AuthLoginMethod, ServerSessionSnapshot, SessionData };\n\nexport interface SessionCookieOptions {\n maxAgeSeconds?: number | null;\n}\n\n/** Options for reading browser auth cookies from a server runtime. */\nexport interface ServerSessionCookieOptions {\n /** Location of the page or request that supplied the cookies. */\n cookieLocation?: AuthCookieLocation;\n /** Base name configured for the browser bearer-token cookie. */\n tokenCookieName?: string;\n}\n\nexport interface CommitLoginSessionParams {\n accessToken: string;\n tokenOptions: AuthTokenStorageSetOptions;\n provider: SessionData[\"provider\"];\n loginMethod: AuthLoginMethod | null;\n primaryWallet: string;\n smartAccount: string;\n accountId: string;\n activeAccount?: ActiveAccountInfo;\n username?: string;\n}\n\nexport interface EnsureSessionParams {\n provider: SessionData[\"provider\"];\n loginMethod: AuthLoginMethod | null;\n primaryWallet: string;\n smartAccount: string;\n accountId: string;\n username?: string;\n}\n\nfunction resolveSessionCookieMaxAge(options?: SessionCookieOptions): number | undefined {\n if (!options) return POLYESTER_LOGIN_COOKIE_MAX_AGE;\n return options.maxAgeSeconds ?? undefined;\n}\n\n/**\n * Reads and writes the browser display-session cookie.\n */\nclass PolyesterSessionManager {\n /**\n * Replaces the current session state.\n */\n set(session: SessionData, options?: SessionCookieOptions): void {\n setCookie({\n name: resolveAuthCookieName(POLYESTER_SESSION_COOKIE_NAME),\n value: SessionCodec.encode(session),\n options: {\n path: \"/\",\n maxAge: resolveSessionCookieMaxAge(options),\n secure: shouldSecureCookies(),\n sameSite: \"lax\",\n },\n });\n }\n\n // The session is re-read on every authenticated RPC; memoize the decode\n // (JSON.parse + schema validation) on the raw cookie value.\n #lastRawValue: string | null = null;\n #lastDecoded: SessionData | null = null;\n\n /**\n * Returns the current session state, or null when no session is active.\n */\n get(): SessionData | null {\n const value = getCookie(resolveAuthCookieName(POLYESTER_SESSION_COOKIE_NAME));\n if (!value) {\n this.#lastRawValue = null;\n this.#lastDecoded = null;\n return null;\n }\n if (value === this.#lastRawValue) return this.#lastDecoded;\n\n const session = SessionCodec.decode(value);\n if (!session) {\n this.clear();\n this.#lastRawValue = null;\n this.#lastDecoded = null;\n return null;\n }\n\n this.#lastRawValue = value;\n this.#lastDecoded = session;\n return session;\n }\n\n /**\n * Clears the current session state.\n */\n clear(): void {\n deleteCookie(resolveAuthCookieName(POLYESTER_SESSION_COOKIE_NAME));\n }\n}\n\nexport const polyesterSession = new PolyesterSessionManager();\n\nexport function emptyServerSessionSnapshot(): ServerSessionSnapshot {\n return {\n environmentFingerprint: null,\n hasDisplaySession: false,\n provider: null,\n loginMethod: null,\n accountAddresses: null,\n activeAccount: null,\n bearerToken: null,\n username: null,\n };\n}\n\n/**\n * Parses bearer authentication and display-only session cookies into a server snapshot.\n */\nexport function parseServerSessionSnapshot(\n cookies: CookieGetter,\n environment: PolyesterEnvironment,\n options: ServerSessionCookieOptions = {},\n): ServerSessionSnapshot {\n const cookieLocation =\n options.cookieLocation ?? (cookies instanceof Request ? new URL(cookies.url) : undefined);\n const sessionValue = getCookieValue(\n cookies,\n resolveAuthCookieName(POLYESTER_SESSION_COOKIE_NAME, cookieLocation),\n );\n const bearerToken =\n getCookieValue(\n cookies,\n resolveAuthCookieName(\n options.tokenCookieName ?? POLYESTER_AUTH_TOKEN_COOKIE_NAME,\n cookieLocation,\n ),\n ) ?? null;\n const session = sessionValue ? SessionCodec.decode(sessionValue) : null;\n\n if (!session) {\n return { ...emptyServerSessionSnapshot(), bearerToken };\n }\n\n if (session.environmentFingerprint !== environment.fingerprint) {\n return emptyServerSessionSnapshot();\n }\n\n return {\n environmentFingerprint: session.environmentFingerprint,\n hasDisplaySession: true,\n provider: session.provider,\n loginMethod: session.loginMethod,\n accountAddresses: {\n ownerAddress: session.primaryWallet,\n accountAddress: session.smartAccount,\n },\n activeAccount: session.activeAccount ?? null,\n bearerToken,\n username: session.username ?? null,\n };\n}\n\n/**\n * Owns environment-bound auth session transitions for browser clients.\n */\nexport class AuthSessionStore {\n #environmentFingerprint: string;\n #session: PolyesterSessionManager;\n\n constructor({ environmentFingerprint }: { environmentFingerprint: string }) {\n this.#environmentFingerprint = environmentFingerprint;\n this.#session = polyesterSession;\n }\n\n get(): SessionData | null {\n const session = this.#session.get();\n if (!session) return null;\n if (session.environmentFingerprint !== this.#environmentFingerprint) {\n // Retain the binding until the token read can discard both cookies.\n return null;\n }\n return session;\n }\n\n getEnvironmentBoundToken(tokenStorage: AuthTokenStorage): string | null {\n const token = tokenStorage.get();\n if (!token) return null;\n\n const session = this.#session.get();\n if (!session) return token;\n\n if (session.environmentFingerprint !== this.#environmentFingerprint) {\n this.#session.clear();\n tokenStorage.clear();\n return null;\n }\n\n return token;\n }\n\n commitLogin(params: CommitLoginSessionParams, tokenStorage: AuthTokenStorage): void {\n tokenStorage.set(params.accessToken, params.tokenOptions);\n this.#session.set(\n {\n environmentFingerprint: this.#environmentFingerprint,\n provider: params.provider,\n loginMethod: params.loginMethod,\n primaryWallet: params.primaryWallet,\n smartAccount: params.smartAccount,\n activeAccount: {\n accountId: params.activeAccount?.accountId ?? params.accountId,\n isMain: params.activeAccount?.isMain ?? true,\n mainAccountId: params.accountId,\n smartAccountAddress: params.activeAccount?.smartAccountAddress,\n label: params.activeAccount?.label,\n },\n username: params.username,\n },\n { maxAgeSeconds: params.tokenOptions.maxAgeSeconds },\n );\n }\n\n ensureSession(params: EnsureSessionParams, options?: SessionCookieOptions): SessionData {\n const existingSession = this.get();\n if (existingSession) {\n const username = params.username || undefined;\n if (username === undefined || username === existingSession.username) {\n return existingSession;\n }\n\n const session = { ...existingSession, username };\n this.#session.set(session, options);\n return session;\n }\n\n const session: SessionData = {\n environmentFingerprint: this.#environmentFingerprint,\n provider: params.provider,\n loginMethod: params.loginMethod,\n primaryWallet: params.primaryWallet,\n smartAccount: params.smartAccount,\n activeAccount: {\n accountId: params.accountId,\n isMain: true,\n mainAccountId: params.accountId,\n },\n username: params.username,\n };\n this.#session.set(session, options);\n return session;\n }\n\n setUsername(username: string | null, options?: SessionCookieOptions): void {\n const session = this.get();\n if (!session) return;\n\n this.#session.set({ ...session, username: username || undefined }, options);\n }\n\n setActiveAccount(\n activeAccount: Omit<ActiveAccountInfo, \"mainAccountId\">,\n options?: SessionCookieOptions,\n ): void {\n const session = this.get();\n if (!session) return;\n\n const mainAccountId = session.activeAccount?.mainAccountId ?? activeAccount.accountId;\n const smartAccountAddress = activeAccount.isMain\n ? session.smartAccount\n : activeAccount.smartAccountAddress;\n const label = activeAccount.isMain ? undefined : activeAccount.label;\n this.#session.set(\n {\n ...session,\n activeAccount: { ...activeAccount, mainAccountId, smartAccountAddress, label },\n username: session.username,\n },\n options,\n );\n }\n\n clear(): void {\n this.#session.clear();\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CookieManager } from "../../utils/cookies.js";
|
|
2
|
-
import "./cookie-constants.js";
|
|
2
|
+
import { resolveAuthCookieName } from "./cookie-constants.js";
|
|
3
3
|
import { getJwtExpiration } from "../../utils/jwt.js";
|
|
4
4
|
//#region src/services/auth/token-storage.ts
|
|
5
5
|
/**
|
|
@@ -38,11 +38,11 @@ function createMemoryAuthTokenStorage(initialToken) {
|
|
|
38
38
|
function createCookieAuthTokenStorage(options = {}) {
|
|
39
39
|
const cookieName = options.cookieName ?? "polyester_auth_token";
|
|
40
40
|
const path = options.path ?? "/";
|
|
41
|
-
const cookie = new CookieManager({ name: cookieName });
|
|
41
|
+
const cookie = () => new CookieManager({ name: resolveAuthCookieName(cookieName) });
|
|
42
42
|
return {
|
|
43
|
-
get: () => cookie.get(),
|
|
43
|
+
get: () => cookie().get(),
|
|
44
44
|
set: (token, setOptions) => {
|
|
45
|
-
cookie.set(token, {
|
|
45
|
+
cookie().set(token, {
|
|
46
46
|
path,
|
|
47
47
|
secure: options.secure,
|
|
48
48
|
sameSite: options.sameSite,
|
|
@@ -51,7 +51,7 @@ function createCookieAuthTokenStorage(options = {}) {
|
|
|
51
51
|
});
|
|
52
52
|
},
|
|
53
53
|
clear: () => {
|
|
54
|
-
cookie.clear({ path });
|
|
54
|
+
cookie().clear({ path });
|
|
55
55
|
}
|
|
56
56
|
};
|
|
57
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-storage.js","names":[],"sources":["../../../src/services/auth/token-storage.ts"],"sourcesContent":["import { CookieManager } from \"../../utils/cookies.js\";\nimport { getJwtExpiration } from \"../../utils/jwt.js\";\nimport { POLYESTER_AUTH_TOKEN_COOKIE_NAME } from \"./cookie-constants.js\";\n\nexport interface AuthTokenStorageSetOptions {\n expiresAt: Date | null;\n maxAgeSeconds: number | null;\n}\n\nexport interface AuthTokenStorage {\n get(): string | null;\n set(token: string, options: AuthTokenStorageSetOptions): void;\n clear(): void;\n}\n\nexport interface CookieAuthTokenStorageOptions {\n cookieName?: string;\n path?: string;\n secure?: boolean;\n sameSite?: \"lax\" | \"strict\" | \"none\";\n}\n\n/**\n * Builds cookie write options for auth token storage.\n */\nexport function createAuthTokenStorageSetOptions(token: string): AuthTokenStorageSetOptions {\n const exp = getJwtExpiration(token);\n if (exp === null) {\n return { expiresAt: null, maxAgeSeconds: null };\n }\n\n const nowSeconds = Date.now() / 1000;\n return {\n expiresAt: new Date(exp * 1000),\n maxAgeSeconds: Math.max(0, Math.floor(exp - nowSeconds)),\n };\n}\n\n/**\n * Creates in-memory auth token storage.\n */\nexport function createMemoryAuthTokenStorage(initialToken?: string | null): AuthTokenStorage {\n let storedToken = initialToken ?? null;\n\n return {\n get: () => storedToken,\n set: (token: string) => {\n storedToken = token;\n },\n clear: () => {\n storedToken = null;\n },\n };\n}\n\n/**\n * Creates cookie-backed auth token storage.\n */\nexport function createCookieAuthTokenStorage(\n options: CookieAuthTokenStorageOptions = {},\n): AuthTokenStorage {\n const cookieName = options.cookieName ?? POLYESTER_AUTH_TOKEN_COOKIE_NAME;\n const path = options.path ?? \"/\";\n const cookie = new CookieManager({ name: cookieName });\n\n return {\n get: () => cookie.get(),\n set: (token: string, setOptions: AuthTokenStorageSetOptions) => {\n cookie.set(token, {\n path,\n secure: options.secure,\n sameSite: options.sameSite,\n maxAge: setOptions.maxAgeSeconds ?? undefined,\n expires: setOptions.expiresAt ?? undefined,\n });\n },\n clear: () => {\n cookie.clear({ path });\n },\n };\n}\n"],"mappings":";;;;;;;AAyBA,SAAgB,iCAAiC,OAA2C;CACxF,MAAM,MAAM,iBAAiB,KAAK;CAClC,IAAI,QAAQ,MACR,OAAO;EAAE,WAAW;EAAM,eAAe;CAAK;CAGlD,MAAM,aAAa,KAAK,IAAI,IAAI;CAChC,OAAO;EACH,2BAAW,IAAI,KAAK,MAAM,GAAI;EAC9B,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,UAAU,CAAC;CAC3D;AACJ;;;;AAKA,SAAgB,6BAA6B,cAAgD;CACzF,IAAI,cAAc,gBAAgB;CAElC,OAAO;EACH,WAAW;EACX,MAAM,UAAkB;GACpB,cAAc;EAClB;EACA,aAAa;GACT,cAAc;EAClB;CACJ;AACJ;;;;AAKA,SAAgB,6BACZ,UAAyC,CAAC,GAC1B;CAChB,MAAM,aAAa,QAAQ,cAAA;CAC3B,MAAM,OAAO,QAAQ,QAAQ;
|
|
1
|
+
{"version":3,"file":"token-storage.js","names":[],"sources":["../../../src/services/auth/token-storage.ts"],"sourcesContent":["import { CookieManager } from \"../../utils/cookies.js\";\nimport { getJwtExpiration } from \"../../utils/jwt.js\";\nimport { POLYESTER_AUTH_TOKEN_COOKIE_NAME, resolveAuthCookieName } from \"./cookie-constants.js\";\n\nexport interface AuthTokenStorageSetOptions {\n expiresAt: Date | null;\n maxAgeSeconds: number | null;\n}\n\nexport interface AuthTokenStorage {\n get(): string | null;\n set(token: string, options: AuthTokenStorageSetOptions): void;\n clear(): void;\n}\n\nexport interface CookieAuthTokenStorageOptions {\n cookieName?: string;\n path?: string;\n secure?: boolean;\n sameSite?: \"lax\" | \"strict\" | \"none\";\n}\n\n/**\n * Builds cookie write options for auth token storage.\n */\nexport function createAuthTokenStorageSetOptions(token: string): AuthTokenStorageSetOptions {\n const exp = getJwtExpiration(token);\n if (exp === null) {\n return { expiresAt: null, maxAgeSeconds: null };\n }\n\n const nowSeconds = Date.now() / 1000;\n return {\n expiresAt: new Date(exp * 1000),\n maxAgeSeconds: Math.max(0, Math.floor(exp - nowSeconds)),\n };\n}\n\n/**\n * Creates in-memory auth token storage.\n */\nexport function createMemoryAuthTokenStorage(initialToken?: string | null): AuthTokenStorage {\n let storedToken = initialToken ?? null;\n\n return {\n get: () => storedToken,\n set: (token: string) => {\n storedToken = token;\n },\n clear: () => {\n storedToken = null;\n },\n };\n}\n\n/**\n * Creates cookie-backed auth token storage.\n */\nexport function createCookieAuthTokenStorage(\n options: CookieAuthTokenStorageOptions = {},\n): AuthTokenStorage {\n const cookieName = options.cookieName ?? POLYESTER_AUTH_TOKEN_COOKIE_NAME;\n const path = options.path ?? \"/\";\n // Resolve for every operation so test/browser navigation to another local\n // port cannot read, overwrite, or delete this port's sibling cookie.\n const cookie = () => new CookieManager({ name: resolveAuthCookieName(cookieName) });\n\n return {\n get: () => cookie().get(),\n set: (token: string, setOptions: AuthTokenStorageSetOptions) => {\n cookie().set(token, {\n path,\n secure: options.secure,\n sameSite: options.sameSite,\n maxAge: setOptions.maxAgeSeconds ?? undefined,\n expires: setOptions.expiresAt ?? undefined,\n });\n },\n clear: () => {\n cookie().clear({ path });\n },\n };\n}\n"],"mappings":";;;;;;;AAyBA,SAAgB,iCAAiC,OAA2C;CACxF,MAAM,MAAM,iBAAiB,KAAK;CAClC,IAAI,QAAQ,MACR,OAAO;EAAE,WAAW;EAAM,eAAe;CAAK;CAGlD,MAAM,aAAa,KAAK,IAAI,IAAI;CAChC,OAAO;EACH,2BAAW,IAAI,KAAK,MAAM,GAAI;EAC9B,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,UAAU,CAAC;CAC3D;AACJ;;;;AAKA,SAAgB,6BAA6B,cAAgD;CACzF,IAAI,cAAc,gBAAgB;CAElC,OAAO;EACH,WAAW;EACX,MAAM,UAAkB;GACpB,cAAc;EAClB;EACA,aAAa;GACT,cAAc;EAClB;CACJ;AACJ;;;;AAKA,SAAgB,6BACZ,UAAyC,CAAC,GAC1B;CAChB,MAAM,aAAa,QAAQ,cAAA;CAC3B,MAAM,OAAO,QAAQ,QAAQ;CAG7B,MAAM,eAAe,IAAI,cAAc,EAAE,MAAM,sBAAsB,UAAU,EAAE,CAAC;CAElF,OAAO;EACH,WAAW,OAAO,CAAC,CAAC,IAAI;EACxB,MAAM,OAAe,eAA2C;GAC5D,OAAO,CAAC,CAAC,IAAI,OAAO;IAChB;IACA,QAAQ,QAAQ;IAChB,UAAU,QAAQ;IAClB,QAAQ,WAAW,iBAAiB,KAAA;IACpC,SAAS,WAAW,aAAa,KAAA;GACrC,CAAC;EACL;EACA,aAAa;GACT,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC;EAC3B;CACJ;AACJ"}
|
|
@@ -11,7 +11,7 @@ type TimestampInit = {
|
|
|
11
11
|
};
|
|
12
12
|
declare function createCandleRowSchema(scales: SdkScales): v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
13
13
|
readonly symbolId: v.NumberSchema<undefined>;
|
|
14
|
-
readonly timeframe: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"1d" | "
|
|
14
|
+
readonly timeframe: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"1d" | "1s" | "1m" | "5m" | "15m" | "30m" | "1h" | "4h" | "12h" | "1w" | "1mo">>]>;
|
|
15
15
|
readonly tsSec: v.BigintSchema<undefined>;
|
|
16
16
|
readonly open: v.BigintSchema<undefined>;
|
|
17
17
|
readonly high: v.BigintSchema<undefined>;
|
|
@@ -22,7 +22,7 @@ declare function createCandleRowSchema(scales: SdkScales): v.SchemaWithPipe<read
|
|
|
22
22
|
readonly isClosed: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
23
23
|
}, undefined>, v.TransformAction<{
|
|
24
24
|
symbolId: number;
|
|
25
|
-
timeframe: DecodedEnum<"1d" | "
|
|
25
|
+
timeframe: DecodedEnum<"1d" | "1s" | "1m" | "5m" | "15m" | "30m" | "1h" | "4h" | "12h" | "1w" | "1mo">;
|
|
26
26
|
tsSec: bigint;
|
|
27
27
|
open: bigint;
|
|
28
28
|
high: bigint;
|
|
@@ -33,7 +33,7 @@ declare function createCandleRowSchema(scales: SdkScales): v.SchemaWithPipe<read
|
|
|
33
33
|
isClosed: boolean;
|
|
34
34
|
}, {
|
|
35
35
|
symbolId: number;
|
|
36
|
-
timeframe: DecodedEnum<"1d" | "
|
|
36
|
+
timeframe: DecodedEnum<"1d" | "1s" | "1m" | "5m" | "15m" | "30m" | "1h" | "4h" | "12h" | "1w" | "1mo">;
|
|
37
37
|
time: number;
|
|
38
38
|
open: string;
|
|
39
39
|
high: string;
|
|
@@ -46,7 +46,7 @@ declare function createCandleRowSchema(scales: SdkScales): v.SchemaWithPipe<read
|
|
|
46
46
|
declare const createCandleRowIntSchema: typeof createCandleRowSchema;
|
|
47
47
|
declare function createCandleColumnarSchema(scales: SdkScales): v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
48
48
|
readonly symbolId: v.NumberSchema<undefined>;
|
|
49
|
-
readonly timeframe: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"1d" | "
|
|
49
|
+
readonly timeframe: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"1d" | "1s" | "1m" | "5m" | "15m" | "30m" | "1h" | "4h" | "12h" | "1w" | "1mo">>]>;
|
|
50
50
|
readonly tsSec: v.ArraySchema<v.BigintSchema<undefined>, undefined>;
|
|
51
51
|
readonly open: v.ArraySchema<v.BigintSchema<undefined>, undefined>;
|
|
52
52
|
readonly high: v.ArraySchema<v.BigintSchema<undefined>, undefined>;
|
|
@@ -63,7 +63,7 @@ declare function createCandleColumnarSchema(scales: SdkScales): v.SchemaWithPipe
|
|
|
63
63
|
readonly nextPageToken: v.OptionalSchema<v.StringSchema<undefined>, "">;
|
|
64
64
|
}, undefined>, v.TransformAction<{
|
|
65
65
|
symbolId: number;
|
|
66
|
-
timeframe: DecodedEnum<"1d" | "
|
|
66
|
+
timeframe: DecodedEnum<"1d" | "1s" | "1m" | "5m" | "15m" | "30m" | "1h" | "4h" | "12h" | "1w" | "1mo">;
|
|
67
67
|
tsSec: bigint[];
|
|
68
68
|
open: bigint[];
|
|
69
69
|
high: bigint[];
|
|
@@ -80,7 +80,7 @@ declare function createCandleColumnarSchema(scales: SdkScales): v.SchemaWithPipe
|
|
|
80
80
|
nextPageToken: string;
|
|
81
81
|
}, {
|
|
82
82
|
symbolId: number;
|
|
83
|
-
timeframe: DecodedEnum<"1d" | "
|
|
83
|
+
timeframe: DecodedEnum<"1d" | "1s" | "1m" | "5m" | "15m" | "30m" | "1h" | "4h" | "12h" | "1w" | "1mo">;
|
|
84
84
|
time: number[];
|
|
85
85
|
open: string[];
|
|
86
86
|
high: string[];
|
|
@@ -100,7 +100,7 @@ declare function createCandleColumnarSchema(scales: SdkScales): v.SchemaWithPipe
|
|
|
100
100
|
}>]>;
|
|
101
101
|
declare function createCandleColumnarIntSchema(scales: SdkScales): v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
102
102
|
readonly symbolId: v.NumberSchema<undefined>;
|
|
103
|
-
readonly timeframe: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"1d" | "
|
|
103
|
+
readonly timeframe: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"1d" | "1s" | "1m" | "5m" | "15m" | "30m" | "1h" | "4h" | "12h" | "1w" | "1mo">>]>;
|
|
104
104
|
readonly tsSec: v.ArraySchema<v.BigintSchema<undefined>, undefined>;
|
|
105
105
|
readonly open: v.ArraySchema<v.BigintSchema<undefined>, undefined>;
|
|
106
106
|
readonly high: v.ArraySchema<v.BigintSchema<undefined>, undefined>;
|
|
@@ -117,7 +117,7 @@ declare function createCandleColumnarIntSchema(scales: SdkScales): v.SchemaWithP
|
|
|
117
117
|
readonly nextPageToken: v.OptionalSchema<v.StringSchema<undefined>, "">;
|
|
118
118
|
}, undefined>, v.TransformAction<{
|
|
119
119
|
symbolId: number;
|
|
120
|
-
timeframe: DecodedEnum<"1d" | "
|
|
120
|
+
timeframe: DecodedEnum<"1d" | "1s" | "1m" | "5m" | "15m" | "30m" | "1h" | "4h" | "12h" | "1w" | "1mo">;
|
|
121
121
|
tsSec: bigint[];
|
|
122
122
|
open: bigint[];
|
|
123
123
|
high: bigint[];
|
|
@@ -134,7 +134,7 @@ declare function createCandleColumnarIntSchema(scales: SdkScales): v.SchemaWithP
|
|
|
134
134
|
nextPageToken: string;
|
|
135
135
|
}, {
|
|
136
136
|
symbolId: number;
|
|
137
|
-
timeframe: DecodedEnum<"1d" | "
|
|
137
|
+
timeframe: DecodedEnum<"1d" | "1s" | "1m" | "5m" | "15m" | "30m" | "1h" | "4h" | "12h" | "1w" | "1mo">;
|
|
138
138
|
tsSec: number[];
|
|
139
139
|
open: string[];
|
|
140
140
|
high: string[];
|
|
@@ -158,7 +158,7 @@ type CandleColumnar = v.InferOutput<ReturnType<typeof createCandleColumnarSchema
|
|
|
158
158
|
type CandleColumnarInt = v.InferOutput<ReturnType<typeof createCandleColumnarIntSchema>>;
|
|
159
159
|
declare function createListCandlesInputSchema(): v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
160
160
|
readonly symbolId: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.GtValueAction<number, 0, undefined>, v.MaxValueAction<number, 4294967295, undefined>]>;
|
|
161
|
-
readonly timeframe: v.SchemaWithPipe<readonly [v.PicklistSchema<readonly ["1s", "1m", "5m", "15m", "30m", "1h", "4h", "12h", "1d", "1w", "1mo"], undefined>, v.TransformAction<"1d" | "
|
|
161
|
+
readonly timeframe: v.SchemaWithPipe<readonly [v.PicklistSchema<readonly ["1s", "1m", "5m", "15m", "30m", "1h", "4h", "12h", "1d", "1w", "1mo"], undefined>, v.TransformAction<"1d" | "1s" | "1m" | "5m" | "15m" | "30m" | "1h" | "4h" | "12h" | "1w" | "1mo", Timeframe$1.SEC_1 | Timeframe$1.MIN_1 | Timeframe$1.MIN_5 | Timeframe$1.MIN_15 | Timeframe$1.MIN_30 | Timeframe$1.HOUR_1 | Timeframe$1.HOUR_4 | Timeframe$1.DAY_1 | Timeframe$1.HOUR_12 | Timeframe$1.WEEK_1 | Timeframe$1.MONTH_1>]>;
|
|
162
162
|
readonly limit: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.GtValueAction<number, 0, undefined>, v.MaxValueAction<number, 10000, undefined>]>, undefined>;
|
|
163
163
|
readonly includeIncomplete: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
164
164
|
readonly includeReference: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
@@ -13,8 +13,8 @@ type TimestampInit = {
|
|
|
13
13
|
};
|
|
14
14
|
declare const GetOrderbookHeatmapInputSchema: v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
15
15
|
readonly symbolId: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.GtValueAction<number, 0, undefined>, v.MaxValueAction<number, 4294967295, undefined>]>;
|
|
16
|
-
readonly interval: v.SchemaWithPipe<readonly [v.OptionalSchema<v.PicklistSchema<readonly ["1s", "1m", "5m", "1h"], undefined>, "1s">, v.TransformAction<"
|
|
17
|
-
readonly depth: v.SchemaWithPipe<readonly [v.OptionalSchema<v.PicklistSchema<readonly [1, 5, 10, 20, 50, 100, 200, 500, 1000], undefined>, 50>, v.TransformAction<1 | 10 | 5 | 20 | 200 |
|
|
16
|
+
readonly interval: v.SchemaWithPipe<readonly [v.OptionalSchema<v.PicklistSchema<readonly ["1s", "1m", "5m", "1h"], undefined>, "1s">, v.TransformAction<"1s" | "1m" | "5m" | "1h", HeatmapInterval>]>;
|
|
17
|
+
readonly depth: v.SchemaWithPipe<readonly [v.OptionalSchema<v.PicklistSchema<readonly [1, 5, 10, 20, 50, 100, 200, 500, 1000], undefined>, 50>, v.TransformAction<1 | 10 | 5 | 20 | 200 | 500 | 1000 | 100 | 50, HeatmapDepth>]>;
|
|
18
18
|
readonly quantityMode: v.SchemaWithPipe<readonly [v.OptionalSchema<v.PicklistSchema<readonly ["close", "peak"], undefined>, "close">, v.TransformAction<"close" | "peak", HeatmapQuantityMode>]>;
|
|
19
19
|
readonly limit: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.GtValueAction<number, 0, undefined>, v.MaxValueAction<number, 20000, undefined>]>;
|
|
20
20
|
readonly startTsSec: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, number, undefined>, v.TransformAction<number, bigint>]>, undefined>;
|
|
@@ -122,7 +122,7 @@ declare function convertHeatmapDeltaBucket(bucket: OrderbookHeatmapDeltaBucketRa
|
|
|
122
122
|
type OrderbookHeatmapDeltaBucket = ReturnType<typeof convertHeatmapDeltaBucket>;
|
|
123
123
|
declare const OrderbookHeatmapLiveBucketRawSchema: v.ObjectSchema<{
|
|
124
124
|
readonly symbolId: v.NumberSchema<undefined>;
|
|
125
|
-
readonly interval: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"
|
|
125
|
+
readonly interval: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"1s" | "1m" | "5m" | "1h">>]>;
|
|
126
126
|
readonly tsSec: v.SchemaWithPipe<readonly [v.BigintSchema<undefined>, v.TransformAction<bigint, number>]>;
|
|
127
127
|
readonly isFinal: v.BooleanSchema<undefined>;
|
|
128
128
|
readonly bids: v.OptionalSchema<v.ObjectSchema<{
|
|
@@ -142,7 +142,7 @@ declare const OrderbookHeatmapLiveBucketRawSchema: v.ObjectSchema<{
|
|
|
142
142
|
type OrderbookHeatmapLiveBucketRaw = v.InferOutput<typeof OrderbookHeatmapLiveBucketRawSchema>;
|
|
143
143
|
declare function convertHeatmapLiveBucket(bucket: OrderbookHeatmapLiveBucketRaw, scales: SdkScales): {
|
|
144
144
|
symbolId: number;
|
|
145
|
-
interval: DecodedEnum<"
|
|
145
|
+
interval: DecodedEnum<"1s" | "1m" | "5m" | "1h">;
|
|
146
146
|
tsSec: number;
|
|
147
147
|
isFinal: boolean;
|
|
148
148
|
bids: {
|
|
@@ -226,8 +226,8 @@ declare function convertHeatmapDeltaChain(chain: OrderbookHeatmapDeltaChainRaw,
|
|
|
226
226
|
type OrderbookHeatmapDeltaChain = ReturnType<typeof convertHeatmapDeltaChain>;
|
|
227
227
|
declare function createOrderbookHeatmapResponseSchema(scales: SdkScales): v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
228
228
|
readonly symbolId: v.NumberSchema<undefined>;
|
|
229
|
-
readonly interval: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"
|
|
230
|
-
readonly depth: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, 1 | "unspecified" | 10 | 5 | 20 | 200 |
|
|
229
|
+
readonly interval: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"1s" | "1m" | "5m" | "1h">>]>;
|
|
230
|
+
readonly depth: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, 1 | "unspecified" | 10 | 5 | 20 | 200 | 500 | 1000 | 100 | 50>]>;
|
|
231
231
|
readonly chain: v.OptionalSchema<v.ObjectSchema<{
|
|
232
232
|
readonly baseKeyframe: v.OptionalSchema<v.ObjectSchema<{
|
|
233
233
|
readonly tsSec: v.SchemaWithPipe<readonly [v.BigintSchema<undefined>, v.TransformAction<bigint, number>]>;
|
|
@@ -267,7 +267,7 @@ declare function createOrderbookHeatmapResponseSchema(scales: SdkScales): v.Sche
|
|
|
267
267
|
readonly quantityMode: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"close" | "peak">>]>;
|
|
268
268
|
readonly liveBucket: v.OptionalSchema<v.ObjectSchema<{
|
|
269
269
|
readonly symbolId: v.NumberSchema<undefined>;
|
|
270
|
-
readonly interval: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"
|
|
270
|
+
readonly interval: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.TransformAction<number, DecodedEnum<"1s" | "1m" | "5m" | "1h">>]>;
|
|
271
271
|
readonly tsSec: v.SchemaWithPipe<readonly [v.BigintSchema<undefined>, v.TransformAction<bigint, number>]>;
|
|
272
272
|
readonly isFinal: v.BooleanSchema<undefined>;
|
|
273
273
|
readonly bids: v.OptionalSchema<v.ObjectSchema<{
|
|
@@ -286,8 +286,8 @@ declare function createOrderbookHeatmapResponseSchema(scales: SdkScales): v.Sche
|
|
|
286
286
|
}, undefined>, undefined>;
|
|
287
287
|
}, undefined>, v.TransformAction<{
|
|
288
288
|
symbolId: number;
|
|
289
|
-
interval: DecodedEnum<"
|
|
290
|
-
depth: 1 | "unspecified" | 10 | 5 | 20 | 200 |
|
|
289
|
+
interval: DecodedEnum<"1s" | "1m" | "5m" | "1h">;
|
|
290
|
+
depth: 1 | "unspecified" | 10 | 5 | 20 | 200 | 500 | 1000 | 100 | 50;
|
|
291
291
|
chain?: {
|
|
292
292
|
baseKeyframe?: {
|
|
293
293
|
tsSec: number;
|
|
@@ -327,7 +327,7 @@ declare function createOrderbookHeatmapResponseSchema(scales: SdkScales): v.Sche
|
|
|
327
327
|
quantityMode: DecodedEnum<"close" | "peak">;
|
|
328
328
|
liveBucket?: {
|
|
329
329
|
symbolId: number;
|
|
330
|
-
interval: DecodedEnum<"
|
|
330
|
+
interval: DecodedEnum<"1s" | "1m" | "5m" | "1h">;
|
|
331
331
|
tsSec: number;
|
|
332
332
|
isFinal: boolean;
|
|
333
333
|
bids?: {
|
|
@@ -346,8 +346,8 @@ declare function createOrderbookHeatmapResponseSchema(scales: SdkScales): v.Sche
|
|
|
346
346
|
} | undefined;
|
|
347
347
|
}, {
|
|
348
348
|
symbolId: number;
|
|
349
|
-
interval: DecodedEnum<"
|
|
350
|
-
depth: 1 | "unspecified" | 10 | 5 | 20 | 200 |
|
|
349
|
+
interval: DecodedEnum<"1s" | "1m" | "5m" | "1h">;
|
|
350
|
+
depth: 1 | "unspecified" | 10 | 5 | 20 | 200 | 500 | 1000 | 100 | 50;
|
|
351
351
|
chain: {
|
|
352
352
|
baseKeyframe: {
|
|
353
353
|
tsSec: number;
|
|
@@ -387,7 +387,7 @@ declare function createOrderbookHeatmapResponseSchema(scales: SdkScales): v.Sche
|
|
|
387
387
|
quantityMode: DecodedEnum<"close" | "peak">;
|
|
388
388
|
liveBucket: {
|
|
389
389
|
symbolId: number;
|
|
390
|
-
interval: DecodedEnum<"
|
|
390
|
+
interval: DecodedEnum<"1s" | "1m" | "5m" | "1h">;
|
|
391
391
|
tsSec: number;
|
|
392
392
|
isFinal: boolean;
|
|
393
393
|
bids: {
|