@lightconexyz/lightcone-sdk 0.8.4-rc.54 → 0.8.4-rc.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/auth/client.js +35 -3
- package/dist/auth/client.js.map +1 -1
- package/dist/auth/index.d.ts +7 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -484,6 +484,8 @@ than 10 using `client.auth().updateMaxSlippagePreference(value)`; the method
|
|
|
484
484
|
returns the canonical exact decimal string. Values at or above 10% remain valid
|
|
485
485
|
order protection but are not remembered through this API.
|
|
486
486
|
|
|
487
|
+
`session.user.telegram_invite_url` is the single-use Telegram group invite URL that the backend assigned to the Account. It is `null` when the Account holds no invite or when an older backend omits the field. The URL is a secret of the Account. Do not log it and do not send it to analytics.
|
|
488
|
+
|
|
487
489
|
### Cookie handling
|
|
488
490
|
|
|
489
491
|
After login succeeds, the SDK stores the session token internally and attaches it as `Cookie: lightcone-token=…` on every authenticated request. Behaviour depends on the runtime:
|
package/dist/auth/client.js
CHANGED
|
@@ -51,7 +51,7 @@ class Auth {
|
|
|
51
51
|
// verifying the signature, so a replayed login deterministically fails —
|
|
52
52
|
// and restoring credentials in order to log in is circular.
|
|
53
53
|
const session = await this.client.http.postWithoutCredentialRestore(url, body, http_1.RetryPolicy.None);
|
|
54
|
-
|
|
54
|
+
normalizeSessionUser(session);
|
|
55
55
|
this.client.authState.setCredentials(credentialsFromSession(session));
|
|
56
56
|
return session;
|
|
57
57
|
}
|
|
@@ -60,7 +60,7 @@ class Auth {
|
|
|
60
60
|
let session;
|
|
61
61
|
try {
|
|
62
62
|
session = await this.client.http.get(url, http_1.RetryPolicy.Idempotent);
|
|
63
|
-
|
|
63
|
+
normalizeSessionUser(session);
|
|
64
64
|
}
|
|
65
65
|
catch (error) {
|
|
66
66
|
this.client.authState.setCredentials(undefined);
|
|
@@ -107,7 +107,7 @@ class Auth {
|
|
|
107
107
|
async registerPrivy(request) {
|
|
108
108
|
const url = `${this.client.http.baseUrl()}/api/auth/register-privy`;
|
|
109
109
|
const session = await this.client.http.post(url, request, http_1.RetryPolicy.Idempotent);
|
|
110
|
-
|
|
110
|
+
normalizeSessionUser(session);
|
|
111
111
|
this.client.authState.setCredentials(credentialsFromSession(session));
|
|
112
112
|
return session;
|
|
113
113
|
}
|
|
@@ -136,6 +136,38 @@ class Auth {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
exports.Auth = Auth;
|
|
139
|
+
/**
|
|
140
|
+
* Enforces the session user's nullable-field contracts after every
|
|
141
|
+
* session-returning call. Login, session restoration, and Privy registration
|
|
142
|
+
* share it so that no entry point skips a field.
|
|
143
|
+
*/
|
|
144
|
+
function normalizeSessionUser(session) {
|
|
145
|
+
normalizeSessionMaxSlippagePreference(session);
|
|
146
|
+
session.user.telegram_invite_url = decodeTelegramInviteUrl(session.user);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Decodes the session user's Telegram invite URL. A missing key (older backend)
|
|
150
|
+
* and an explicit null (Account without an invite) both mean no invite. Any
|
|
151
|
+
* other non-string value is a contract violation. Error text never includes the
|
|
152
|
+
* value, because the URL is a secret of the Account.
|
|
153
|
+
*/
|
|
154
|
+
function decodeTelegramInviteUrl(user) {
|
|
155
|
+
if (typeof user !== "object" || user === null) {
|
|
156
|
+
throw error_1.SdkError.serde("Session user is malformed");
|
|
157
|
+
}
|
|
158
|
+
// An own-property read keeps an inherited value from counting as an invite.
|
|
159
|
+
if (!Object.prototype.hasOwnProperty.call(user, "telegram_invite_url")) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
const inviteUrl = user.telegram_invite_url;
|
|
163
|
+
if (inviteUrl === undefined || inviteUrl === null) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
if (typeof inviteUrl === "string") {
|
|
167
|
+
return inviteUrl;
|
|
168
|
+
}
|
|
169
|
+
throw error_1.SdkError.serde("Session user telegram_invite_url must contain a string or null");
|
|
170
|
+
}
|
|
139
171
|
function normalizeSessionMaxSlippagePreference(session) {
|
|
140
172
|
const preference = decodeMaxSlippagePreference(session?.user, true, "session user", true);
|
|
141
173
|
session.user.max_slippage_preference = preference;
|
package/dist/auth/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/auth/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { SdkError, isUnauthorized } from \"../error\";\nimport { RetryPolicy, type LightconeHttp } from \"../http\";\nimport { asPubkeyStr } from \"../shared\";\nimport { tradingWallet } from \"./index\";\nimport type {\n AuthCredentials,\n LoginRequest,\n MaxSlippagePreferenceBody,\n NonceResponse,\n LinkedIdentityType,\n RegisterPrivyRequest,\n SessionResponse,\n} from \"./index\";\n\n/** Bounded ownership conflicts safe for client recovery guidance. */\nexport type RegisterPrivyConflict =\n | {\n code: \"IDENTITY_OWNED_BY_ANOTHER_ACCOUNT\";\n existingMethod?: LinkedIdentityType;\n }\n | { code: \"IDENTITIES_OWNED_BY_MULTIPLE_ACCOUNTS\" }\n | {\n code: \"WALLET_OWNED_BY_ANOTHER_ACCOUNT\";\n existingMethod?: LinkedIdentityType;\n };\n\n/** Classify only stable register-or-sync ownership rejection codes. */\nexport function classifyRegisterPrivyConflict(\n error: unknown,\n): RegisterPrivyConflict | undefined {\n if (!(error instanceof SdkError) || error.variant !== \"ApiRejected\")\n return undefined;\n const details = error.apiRejectedDetails;\n switch (details?.errorCode) {\n case \"IDENTITY_OWNED_BY_ANOTHER_ACCOUNT\":\n return {\n code: details.errorCode,\n existingMethod: details.existingMethod,\n };\n case \"IDENTITIES_OWNED_BY_MULTIPLE_ACCOUNTS\":\n return { code: details.errorCode };\n case \"WALLET_OWNED_BY_ANOTHER_ACCOUNT\":\n return {\n code: details.errorCode,\n existingMethod: details.existingMethod,\n };\n default:\n return undefined;\n }\n}\n\ninterface AuthState {\n getCredentials(): AuthCredentials | undefined;\n setCredentials(credentials: AuthCredentials | undefined): void;\n clearCaches(): Promise<void>;\n}\n\ninterface ClientContext {\n http: LightconeHttp;\n authState: AuthState;\n}\n\nexport class Auth {\n constructor(private readonly client: ClientContext) {}\n\n async getNonce(): Promise<string> {\n const url = `${this.client.http.baseUrl()}/api/auth/nonce`;\n const response = await this.client.http.get<NonceResponse>(\n url,\n RetryPolicy.None,\n );\n return response.nonce;\n }\n\n async loginWithMessage(\n message: string,\n signatureBs58: string,\n pubkeyBytes: Uint8Array,\n useEmbeddedWallet?: boolean,\n ): Promise<SessionResponse> {\n const url = `${this.client.http.baseUrl()}/api/auth/login_or_register_with_message`;\n const body: LoginRequest = {\n message,\n signature_bs58: signatureBs58,\n pubkey_bytes: Array.from(pubkeyBytes),\n use_embedded_wallet: useEmbeddedWallet,\n };\n\n // Credential-management endpoint: opts out of the transport's 401\n // restore-and-replay. The backend consumes the login nonce before\n // verifying the signature, so a replayed login deterministically fails —\n // and restoring credentials in order to log in is circular.\n const session = await this.client.http.postWithoutCredentialRestore<\n SessionResponse,\n LoginRequest\n >(url, body, RetryPolicy.None);\n normalizeSessionMaxSlippagePreference(session);\n\n this.client.authState.setCredentials(credentialsFromSession(session));\n\n return session;\n }\n\n async checkSession(): Promise<SessionResponse> {\n const url = `${this.client.http.baseUrl()}/api/auth/me`;\n\n let session: SessionResponse;\n try {\n session = await this.client.http.get<SessionResponse>(\n url,\n RetryPolicy.Idempotent,\n );\n normalizeSessionMaxSlippagePreference(session);\n } catch (error) {\n this.client.authState.setCredentials(undefined);\n throw SdkError.from(error);\n }\n\n this.client.authState.setCredentials(credentialsFromSession(session));\n\n return session;\n }\n\n /**\n * Logout — clears the server-side cookie, internal token, and credentials.\n *\n * Local state is cleared even when the server call fails — the caller asked\n * to be signed out locally regardless — but the failure is then rethrown:\n * callers gating security decisions on teardown (e.g. whether an app may\n * restart an authenticated transport) must be able to see that the\n * server-side cookie may still be valid. A 401 counts as success: it means\n * \"already logged out\".\n */\n async logout(): Promise<void> {\n const url = `${this.client.http.baseUrl()}/api/auth/logout`;\n let logoutError: unknown = null;\n try {\n // Credential-management endpoint: opts out of the transport's 401\n // restore-and-replay — a 401 here means \"already logged out\".\n await this.client.http.postWithoutCredentialRestore<\n { success: boolean },\n Record<string, never>\n >(url, {}, RetryPolicy.None);\n } catch (error) {\n if (!isUnauthorized(error)) {\n logoutError = error;\n }\n }\n\n await this.client.http.clearAuthToken();\n this.client.authState.setCredentials(undefined);\n await this.client.authState.clearCaches();\n\n if (logoutError !== null) {\n throw logoutError;\n }\n }\n\n async disconnectX(): Promise<void> {\n const url = `${this.client.http.baseUrl()}/api/auth/disconnect_x`;\n await this.client.http.post<{ success: boolean }, Record<string, never>>(\n url,\n {},\n RetryPolicy.None,\n );\n }\n\n /** Create or synchronize a Privy Account and install the resulting session. */\n async registerPrivy(request: RegisterPrivyRequest): Promise<SessionResponse> {\n const url = `${this.client.http.baseUrl()}/api/auth/register-privy`;\n const session = await this.client.http.post<\n SessionResponse,\n RegisterPrivyRequest\n >(\n url,\n request,\n RetryPolicy.Idempotent,\n );\n normalizeSessionMaxSlippagePreference(session);\n this.client.authState.setCredentials(credentialsFromSession(session));\n return session;\n }\n\n /** Persist an account-wide max-slippage preference strictly below 10%. */\n async updateMaxSlippagePreference(\n maxSlippagePreference: string,\n ): Promise<string> {\n const url = `${this.client.http.baseUrl()}/api/auth/max_slippage_preference`;\n const response = await this.client.http.post<\n MaxSlippagePreferenceBody,\n MaxSlippagePreferenceBody\n >(\n url,\n { max_slippage_preference: maxSlippagePreference },\n RetryPolicy.Idempotent,\n );\n const preference = decodeMaxSlippagePreference(\n response,\n false,\n \"update response\",\n );\n if (preference === null) {\n throw SdkError.serde(\n \"Max-slippage update response must contain a decimal string\",\n );\n }\n return preference;\n }\n\n connectXUrl(): string {\n return `${this.client.http.baseUrl()}/api/auth/oauth/link/x`;\n }\n\n credentials(): AuthCredentials | undefined {\n return this.client.authState.getCredentials();\n }\n\n isAuthenticated(): boolean {\n const credentials = this.credentials();\n if (!credentials) {\n return false;\n }\n return Date.now() < credentials.expires_at.getTime();\n }\n}\n\nfunction normalizeSessionMaxSlippagePreference(session: SessionResponse): void {\n const preference = decodeMaxSlippagePreference(\n session?.user,\n true,\n \"session user\",\n true,\n );\n session.user.max_slippage_preference = preference;\n}\n\n/** Enforces the exact nullable/string JSON contract erased by TypeScript types. */\nfunction decodeMaxSlippagePreference(\n payload: unknown,\n allowNull: boolean,\n context: string,\n allowMissing = false,\n): string | null {\n if (typeof payload !== \"object\" || payload === null) {\n throw SdkError.serde(`Max-slippage ${context} is malformed`);\n }\n if (\n !Object.prototype.hasOwnProperty.call(payload, \"max_slippage_preference\")\n ) {\n if (allowMissing) {\n return null;\n }\n throw SdkError.serde(\n `Max-slippage ${context} is missing max_slippage_preference`,\n );\n }\n\n const preference = (payload as Record<string, unknown>)\n .max_slippage_preference;\n if (typeof preference === \"string\") {\n return preference;\n }\n if (allowNull && preference === null) {\n return null;\n }\n throw SdkError.serde(\n `Max-slippage ${context} must contain ${allowNull ? \"a string or null\" : \"a string\"}`,\n );\n}\n\n/**\n * Derive session credentials from the envelope. The trading wallet comes from\n * the identity + auth method.\n */\nfunction credentialsFromSession(session: SessionResponse): AuthCredentials {\n return {\n user_id: session.user.user_id,\n wallet_address: asPubkeyStr(\n tradingWallet(session.user, session.auth_method),\n ),\n expires_at: parseExpiry(session.expires_at),\n };\n}\n\nfunction parseExpiry(timestamp: number): Date {\n if (timestamp > 1_000_000_000_000) {\n return new Date(timestamp);\n }\n return new Date(timestamp * 1000);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/auth/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { SdkError, isUnauthorized } from \"../error\";\nimport { RetryPolicy, type LightconeHttp } from \"../http\";\nimport { asPubkeyStr } from \"../shared\";\nimport { tradingWallet } from \"./index\";\nimport type {\n AuthCredentials,\n LoginRequest,\n MaxSlippagePreferenceBody,\n NonceResponse,\n LinkedIdentityType,\n RegisterPrivyRequest,\n SessionResponse,\n} from \"./index\";\n\n/** Bounded ownership conflicts safe for client recovery guidance. */\nexport type RegisterPrivyConflict =\n | {\n code: \"IDENTITY_OWNED_BY_ANOTHER_ACCOUNT\";\n existingMethod?: LinkedIdentityType;\n }\n | { code: \"IDENTITIES_OWNED_BY_MULTIPLE_ACCOUNTS\" }\n | {\n code: \"WALLET_OWNED_BY_ANOTHER_ACCOUNT\";\n existingMethod?: LinkedIdentityType;\n };\n\n/** Classify only stable register-or-sync ownership rejection codes. */\nexport function classifyRegisterPrivyConflict(\n error: unknown,\n): RegisterPrivyConflict | undefined {\n if (!(error instanceof SdkError) || error.variant !== \"ApiRejected\")\n return undefined;\n const details = error.apiRejectedDetails;\n switch (details?.errorCode) {\n case \"IDENTITY_OWNED_BY_ANOTHER_ACCOUNT\":\n return {\n code: details.errorCode,\n existingMethod: details.existingMethod,\n };\n case \"IDENTITIES_OWNED_BY_MULTIPLE_ACCOUNTS\":\n return { code: details.errorCode };\n case \"WALLET_OWNED_BY_ANOTHER_ACCOUNT\":\n return {\n code: details.errorCode,\n existingMethod: details.existingMethod,\n };\n default:\n return undefined;\n }\n}\n\ninterface AuthState {\n getCredentials(): AuthCredentials | undefined;\n setCredentials(credentials: AuthCredentials | undefined): void;\n clearCaches(): Promise<void>;\n}\n\ninterface ClientContext {\n http: LightconeHttp;\n authState: AuthState;\n}\n\nexport class Auth {\n constructor(private readonly client: ClientContext) {}\n\n async getNonce(): Promise<string> {\n const url = `${this.client.http.baseUrl()}/api/auth/nonce`;\n const response = await this.client.http.get<NonceResponse>(\n url,\n RetryPolicy.None,\n );\n return response.nonce;\n }\n\n async loginWithMessage(\n message: string,\n signatureBs58: string,\n pubkeyBytes: Uint8Array,\n useEmbeddedWallet?: boolean,\n ): Promise<SessionResponse> {\n const url = `${this.client.http.baseUrl()}/api/auth/login_or_register_with_message`;\n const body: LoginRequest = {\n message,\n signature_bs58: signatureBs58,\n pubkey_bytes: Array.from(pubkeyBytes),\n use_embedded_wallet: useEmbeddedWallet,\n };\n\n // Credential-management endpoint: opts out of the transport's 401\n // restore-and-replay. The backend consumes the login nonce before\n // verifying the signature, so a replayed login deterministically fails —\n // and restoring credentials in order to log in is circular.\n const session = await this.client.http.postWithoutCredentialRestore<\n SessionResponse,\n LoginRequest\n >(url, body, RetryPolicy.None);\n normalizeSessionUser(session);\n\n this.client.authState.setCredentials(credentialsFromSession(session));\n\n return session;\n }\n\n async checkSession(): Promise<SessionResponse> {\n const url = `${this.client.http.baseUrl()}/api/auth/me`;\n\n let session: SessionResponse;\n try {\n session = await this.client.http.get<SessionResponse>(\n url,\n RetryPolicy.Idempotent,\n );\n normalizeSessionUser(session);\n } catch (error) {\n this.client.authState.setCredentials(undefined);\n throw SdkError.from(error);\n }\n\n this.client.authState.setCredentials(credentialsFromSession(session));\n\n return session;\n }\n\n /**\n * Logout — clears the server-side cookie, internal token, and credentials.\n *\n * Local state is cleared even when the server call fails — the caller asked\n * to be signed out locally regardless — but the failure is then rethrown:\n * callers gating security decisions on teardown (e.g. whether an app may\n * restart an authenticated transport) must be able to see that the\n * server-side cookie may still be valid. A 401 counts as success: it means\n * \"already logged out\".\n */\n async logout(): Promise<void> {\n const url = `${this.client.http.baseUrl()}/api/auth/logout`;\n let logoutError: unknown = null;\n try {\n // Credential-management endpoint: opts out of the transport's 401\n // restore-and-replay — a 401 here means \"already logged out\".\n await this.client.http.postWithoutCredentialRestore<\n { success: boolean },\n Record<string, never>\n >(url, {}, RetryPolicy.None);\n } catch (error) {\n if (!isUnauthorized(error)) {\n logoutError = error;\n }\n }\n\n await this.client.http.clearAuthToken();\n this.client.authState.setCredentials(undefined);\n await this.client.authState.clearCaches();\n\n if (logoutError !== null) {\n throw logoutError;\n }\n }\n\n async disconnectX(): Promise<void> {\n const url = `${this.client.http.baseUrl()}/api/auth/disconnect_x`;\n await this.client.http.post<{ success: boolean }, Record<string, never>>(\n url,\n {},\n RetryPolicy.None,\n );\n }\n\n /** Create or synchronize a Privy Account and install the resulting session. */\n async registerPrivy(request: RegisterPrivyRequest): Promise<SessionResponse> {\n const url = `${this.client.http.baseUrl()}/api/auth/register-privy`;\n const session = await this.client.http.post<\n SessionResponse,\n RegisterPrivyRequest\n >(\n url,\n request,\n RetryPolicy.Idempotent,\n );\n normalizeSessionUser(session);\n this.client.authState.setCredentials(credentialsFromSession(session));\n return session;\n }\n\n /** Persist an account-wide max-slippage preference strictly below 10%. */\n async updateMaxSlippagePreference(\n maxSlippagePreference: string,\n ): Promise<string> {\n const url = `${this.client.http.baseUrl()}/api/auth/max_slippage_preference`;\n const response = await this.client.http.post<\n MaxSlippagePreferenceBody,\n MaxSlippagePreferenceBody\n >(\n url,\n { max_slippage_preference: maxSlippagePreference },\n RetryPolicy.Idempotent,\n );\n const preference = decodeMaxSlippagePreference(\n response,\n false,\n \"update response\",\n );\n if (preference === null) {\n throw SdkError.serde(\n \"Max-slippage update response must contain a decimal string\",\n );\n }\n return preference;\n }\n\n connectXUrl(): string {\n return `${this.client.http.baseUrl()}/api/auth/oauth/link/x`;\n }\n\n credentials(): AuthCredentials | undefined {\n return this.client.authState.getCredentials();\n }\n\n isAuthenticated(): boolean {\n const credentials = this.credentials();\n if (!credentials) {\n return false;\n }\n return Date.now() < credentials.expires_at.getTime();\n }\n}\n\n/**\n * Enforces the session user's nullable-field contracts after every\n * session-returning call. Login, session restoration, and Privy registration\n * share it so that no entry point skips a field.\n */\nfunction normalizeSessionUser(session: SessionResponse): void {\n normalizeSessionMaxSlippagePreference(session);\n session.user.telegram_invite_url = decodeTelegramInviteUrl(session.user);\n}\n\n/**\n * Decodes the session user's Telegram invite URL. A missing key (older backend)\n * and an explicit null (Account without an invite) both mean no invite. Any\n * other non-string value is a contract violation. Error text never includes the\n * value, because the URL is a secret of the Account.\n */\nfunction decodeTelegramInviteUrl(user: unknown): string | null {\n if (typeof user !== \"object\" || user === null) {\n throw SdkError.serde(\"Session user is malformed\");\n }\n // An own-property read keeps an inherited value from counting as an invite.\n if (!Object.prototype.hasOwnProperty.call(user, \"telegram_invite_url\")) {\n return null;\n }\n const inviteUrl = (user as Record<string, unknown>).telegram_invite_url;\n if (inviteUrl === undefined || inviteUrl === null) {\n return null;\n }\n if (typeof inviteUrl === \"string\") {\n return inviteUrl;\n }\n throw SdkError.serde(\n \"Session user telegram_invite_url must contain a string or null\",\n );\n}\n\nfunction normalizeSessionMaxSlippagePreference(session: SessionResponse): void {\n const preference = decodeMaxSlippagePreference(\n session?.user,\n true,\n \"session user\",\n true,\n );\n session.user.max_slippage_preference = preference;\n}\n\n/** Enforces the exact nullable/string JSON contract erased by TypeScript types. */\nfunction decodeMaxSlippagePreference(\n payload: unknown,\n allowNull: boolean,\n context: string,\n allowMissing = false,\n): string | null {\n if (typeof payload !== \"object\" || payload === null) {\n throw SdkError.serde(`Max-slippage ${context} is malformed`);\n }\n if (\n !Object.prototype.hasOwnProperty.call(payload, \"max_slippage_preference\")\n ) {\n if (allowMissing) {\n return null;\n }\n throw SdkError.serde(\n `Max-slippage ${context} is missing max_slippage_preference`,\n );\n }\n\n const preference = (payload as Record<string, unknown>)\n .max_slippage_preference;\n if (typeof preference === \"string\") {\n return preference;\n }\n if (allowNull && preference === null) {\n return null;\n }\n throw SdkError.serde(\n `Max-slippage ${context} must contain ${allowNull ? \"a string or null\" : \"a string\"}`,\n );\n}\n\n/**\n * Derive session credentials from the envelope. The trading wallet comes from\n * the identity + auth method.\n */\nfunction credentialsFromSession(session: SessionResponse): AuthCredentials {\n return {\n user_id: session.user.user_id,\n wallet_address: asPubkeyStr(\n tradingWallet(session.user, session.auth_method),\n ),\n expires_at: parseExpiry(session.expires_at),\n };\n}\n\nfunction parseExpiry(timestamp: number): Date {\n if (timestamp > 1_000_000_000_000) {\n return new Date(timestamp);\n }\n return new Date(timestamp * 1000);\n}\n"]}
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -124,6 +124,13 @@ export interface User {
|
|
|
124
124
|
max_slippage_preference: string | null;
|
|
125
125
|
/** X account connected by a non-X-identity user; absent when identity is X. */
|
|
126
126
|
connected_x?: XAccountData;
|
|
127
|
+
/**
|
|
128
|
+
* Single-use Telegram group invite URL assigned to the Account. It is null
|
|
129
|
+
* when the Account holds no invite. Session decoding normalizes a value that
|
|
130
|
+
* an older backend omits to null. The URL is a secret of the Account. Do not
|
|
131
|
+
* log it or send it to analytics.
|
|
132
|
+
*/
|
|
133
|
+
telegram_invite_url?: string | null;
|
|
127
134
|
}
|
|
128
135
|
/**
|
|
129
136
|
* Session envelope returned by `loginWithMessage`, `register-privy`, and
|
package/dist/auth/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PubkeyStr } from \"../shared\";\nimport { shorten } from \"../shared/fmt/str\";\n\nexport * from \"./client\";\nexport * from \"./native\";\n\n/**\n * How a session authenticated, as reported by the backend (derived from which\n * token verified the request).\n */\nexport enum AuthMethod {\n Privy = \"privy\",\n Lightcone = \"lightcone\",\n}\n\nexport enum ChainType {\n Solana = \"solana\",\n Ethereum = \"ethereum\",\n}\n\n/** A Privy-managed embedded wallet. */\nexport interface PrivyEmbeddedWallet {\n privy_id: string;\n chain: ChainType;\n address: string;\n}\n\n/** Privy account data attached to an identity. */\nexport interface UserPrivyData {\n /** The Privy DID (`did:privy:...`). */\n id: string;\n /**\n * Always present: Privy registration provisions the embedded wallet in the\n * same transaction that creates the user.\n */\n wallet: PrivyEmbeddedWallet;\n}\n\n/**\n * X account data — the same shape whether X is the login identity or a\n * connected account on a Google/wallet identity.\n */\nexport interface XAccountData {\n /** X numeric user id (Privy `subject`); absent on legacy rows. */\n user_id?: string;\n username: string;\n display_name?: string;\n avatar_url?: string;\n}\n\n/** Google account data for a Google login identity. */\nexport interface GoogleAccountData {\n email: string;\n name?: string;\n given_name?: string;\n family_name?: string;\n avatar_url?: string;\n}\n\n/** Canonical address for a passwordless Email login identity. */\nexport interface EmailAccountData {\n email: string;\n}\n\n/** Public login-method names exposed in profiles and bounded conflicts. */\nexport type LinkedIdentityType = \"email\" | \"google\" | \"x\" | \"wallet\";\n\n/** Connected Login Identity without repeated Account-level Privy wallet data. */\nexport type LinkedIdentity =\n | { type: \"email\"; account: EmailAccountData }\n | { type: \"google\"; account: GoogleAccountData }\n | { type: \"x\"; account: XAccountData }\n | { type: \"wallet\"; address: string; chain: ChainType };\n\n/** Verified method and canonical identifier that initiated Privy authentication. */\nexport type LinkedIdentitySelector =\n | { type: \"email\"; email: string }\n | { type: \"google\"; email: string }\n | { type: \"x\"; username: string }\n | { type: \"wallet\"; address: string; chain: ChainType };\n\n/** Register-or-sync request naming the verified attempted identity. */\nexport interface RegisterPrivyRequest {\n attempted_identity: LinkedIdentitySelector;\n}\n\n/**\n * The login identity — how the user authenticates. `type` narrows the variant.\n *\n * Privy data lives on the variant because its presence is determined by the\n * identity type: Google/X login only exists via Privy OAuth (guaranteed DID +\n * embedded wallet), while wallet users opt into Privy (SIWS) or stay\n * self-custody.\n */\nexport type UserIdentity =\n | { type: \"email\"; account: EmailAccountData; privy: UserPrivyData }\n | { type: \"google\"; account: GoogleAccountData; privy: UserPrivyData }\n | { type: \"x\"; account: XAccountData; privy: UserPrivyData }\n | {\n type: \"wallet\";\n address: string;\n chain: ChainType;\n privy?: UserPrivyData;\n };\n\n/** Full user profile — the `user` object of {@link SessionResponse}. */\nexport interface User {\n user_id: string;\n identity: UserIdentity;\n /** Every verified login identity connected to the Account, primary first. */\n linked_identities?: LinkedIdentity[];\n /** Remembered account-wide percentage below 10%; null until one is stored. */\n max_slippage_preference: string | null;\n /** X account connected by a non-X-identity user; absent when identity is X. */\n connected_x?: XAccountData;\n}\n\n/**\n * Session envelope returned by `loginWithMessage`, `register-privy`, and\n * `GET /api/auth/me`. There is no `wallet_address` field — derive the\n * session's trading wallet with {@link tradingWallet}.\n */\nexport interface SessionResponse {\n user: User;\n expires_at: number;\n auth_method: AuthMethod;\n is_beta: boolean;\n}\n\n/** Exact decimal-string body used to update and return max slippage. */\nexport interface MaxSlippagePreferenceBody {\n max_slippage_preference: string;\n}\n\n/** Human-readable login-method label (\"Email\" / \"Google\" / \"X\" / \"Solana\"). */\nexport function identityText(\n identity: UserIdentity,\n): \"Email\" | \"Google\" | \"X\" | \"Solana\" {\n switch (identity.type) {\n case \"email\":\n return \"Email\";\n case \"google\":\n return \"Google\";\n case \"x\":\n return \"X\";\n case \"wallet\":\n return \"Solana\";\n default: {\n const exhaustive: never = identity;\n throw new Error(`Unknown identity: ${JSON.stringify(exhaustive)}`);\n }\n }\n}\n\n/** Privy account data, regardless of identity type. */\nexport function userPrivy(user: User): UserPrivyData | undefined {\n switch (user.identity.type) {\n case \"email\":\n case \"google\":\n case \"x\":\n return user.identity.privy;\n case \"wallet\":\n return user.identity.privy;\n }\n}\n\n/** The X account, whether it is the login identity or a connected account. */\nexport function userXAccount(user: User): XAccountData | undefined {\n return user.identity.type === \"x\" ? user.identity.account : user.connected_x;\n}\n\n/**\n * The wallet a session operates as.\n *\n * Google/X identities only exist via Privy registration, which always\n * provisions an embedded wallet — that wallet is the answer regardless of\n * auth method. Wallet identities depend on the session: a Privy (SIWS)\n * session trades via the embedded wallet, a Lightcone session trades via the\n * wallet that signed in.\n */\nexport function tradingWallet(user: User, authMethod: AuthMethod): string {\n switch (user.identity.type) {\n case \"email\":\n case \"google\":\n case \"x\":\n return user.identity.privy.wallet.address;\n case \"wallet\":\n return authMethod === AuthMethod.Privy\n ? (user.identity.privy?.wallet.address ?? user.identity.address)\n : user.identity.address;\n }\n}\n\n/** Short display label for the wallet a session operates as. */\nexport function walletDisplayName(user: User, authMethod: AuthMethod): string {\n return shorten(tradingWallet(user, authMethod), 8);\n}\n\n/** Keeps Email labels compact while preserving the recognizable address ends. */\nfunction emailDisplayName(email: string): string {\n const maxChars = 20;\n const chars = [...email];\n if (chars.length <= maxChars) {\n return email;\n }\n\n const visibleChars = maxChars - 3;\n const prefixChars = Math.floor(visibleChars / 2);\n return `${chars.slice(0, prefixChars).join(\"\")}...${chars\n .slice(-(visibleChars - prefixChars))\n .join(\"\")}`;\n}\n\n/**\n * Best display name for the user. Email addresses are limited to 20 characters;\n * Google uses `name` with an email fallback; X uses `display_name` with a\n * username fallback; wallet identities show the shortened address (`FRGk...WcPR`).\n */\nexport function displayName(user: User): string {\n switch (user.identity.type) {\n case \"email\":\n return emailDisplayName(user.identity.account.email);\n case \"google\":\n return user.identity.account.name ?? user.identity.account.email;\n case \"x\":\n return (\n user.identity.account.display_name ?? user.identity.account.username\n );\n case \"wallet\":\n return shorten(user.identity.address, 8);\n }\n}\n\n/** Avatar URL from the login identity's OAuth provider, if any. */\nexport function avatarUrl(user: User): string | undefined {\n switch (user.identity.type) {\n case \"email\":\n return undefined;\n case \"google\":\n case \"x\":\n return user.identity.account.avatar_url;\n case \"wallet\":\n return undefined;\n }\n}\n\nexport interface AuthCredentials {\n user_id: string;\n wallet_address: PubkeyStr;\n expires_at: Date;\n}\n\nexport function isAuthenticated(credentials?: AuthCredentials): boolean {\n if (!credentials) {\n return false;\n }\n return Date.now() < credentials.expires_at.getTime();\n}\n\nexport function generateSigninMessage(nonce: string): Uint8Array {\n return new TextEncoder().encode(`Sign in to Lightcone\\nNonce: ${nonce}`);\n}\n\nexport interface LoginRequest {\n message: string;\n signature_bs58: string;\n pubkey_bytes: number[];\n use_embedded_wallet?: boolean;\n}\n\nexport interface NonceResponse {\n nonce: string;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PubkeyStr } from \"../shared\";\nimport { shorten } from \"../shared/fmt/str\";\n\nexport * from \"./client\";\nexport * from \"./native\";\n\n/**\n * How a session authenticated, as reported by the backend (derived from which\n * token verified the request).\n */\nexport enum AuthMethod {\n Privy = \"privy\",\n Lightcone = \"lightcone\",\n}\n\nexport enum ChainType {\n Solana = \"solana\",\n Ethereum = \"ethereum\",\n}\n\n/** A Privy-managed embedded wallet. */\nexport interface PrivyEmbeddedWallet {\n privy_id: string;\n chain: ChainType;\n address: string;\n}\n\n/** Privy account data attached to an identity. */\nexport interface UserPrivyData {\n /** The Privy DID (`did:privy:...`). */\n id: string;\n /**\n * Always present: Privy registration provisions the embedded wallet in the\n * same transaction that creates the user.\n */\n wallet: PrivyEmbeddedWallet;\n}\n\n/**\n * X account data — the same shape whether X is the login identity or a\n * connected account on a Google/wallet identity.\n */\nexport interface XAccountData {\n /** X numeric user id (Privy `subject`); absent on legacy rows. */\n user_id?: string;\n username: string;\n display_name?: string;\n avatar_url?: string;\n}\n\n/** Google account data for a Google login identity. */\nexport interface GoogleAccountData {\n email: string;\n name?: string;\n given_name?: string;\n family_name?: string;\n avatar_url?: string;\n}\n\n/** Canonical address for a passwordless Email login identity. */\nexport interface EmailAccountData {\n email: string;\n}\n\n/** Public login-method names exposed in profiles and bounded conflicts. */\nexport type LinkedIdentityType = \"email\" | \"google\" | \"x\" | \"wallet\";\n\n/** Connected Login Identity without repeated Account-level Privy wallet data. */\nexport type LinkedIdentity =\n | { type: \"email\"; account: EmailAccountData }\n | { type: \"google\"; account: GoogleAccountData }\n | { type: \"x\"; account: XAccountData }\n | { type: \"wallet\"; address: string; chain: ChainType };\n\n/** Verified method and canonical identifier that initiated Privy authentication. */\nexport type LinkedIdentitySelector =\n | { type: \"email\"; email: string }\n | { type: \"google\"; email: string }\n | { type: \"x\"; username: string }\n | { type: \"wallet\"; address: string; chain: ChainType };\n\n/** Register-or-sync request naming the verified attempted identity. */\nexport interface RegisterPrivyRequest {\n attempted_identity: LinkedIdentitySelector;\n}\n\n/**\n * The login identity — how the user authenticates. `type` narrows the variant.\n *\n * Privy data lives on the variant because its presence is determined by the\n * identity type: Google/X login only exists via Privy OAuth (guaranteed DID +\n * embedded wallet), while wallet users opt into Privy (SIWS) or stay\n * self-custody.\n */\nexport type UserIdentity =\n | { type: \"email\"; account: EmailAccountData; privy: UserPrivyData }\n | { type: \"google\"; account: GoogleAccountData; privy: UserPrivyData }\n | { type: \"x\"; account: XAccountData; privy: UserPrivyData }\n | {\n type: \"wallet\";\n address: string;\n chain: ChainType;\n privy?: UserPrivyData;\n };\n\n/** Full user profile — the `user` object of {@link SessionResponse}. */\nexport interface User {\n user_id: string;\n identity: UserIdentity;\n /** Every verified login identity connected to the Account, primary first. */\n linked_identities?: LinkedIdentity[];\n /** Remembered account-wide percentage below 10%; null until one is stored. */\n max_slippage_preference: string | null;\n /** X account connected by a non-X-identity user; absent when identity is X. */\n connected_x?: XAccountData;\n /**\n * Single-use Telegram group invite URL assigned to the Account. It is null\n * when the Account holds no invite. Session decoding normalizes a value that\n * an older backend omits to null. The URL is a secret of the Account. Do not\n * log it or send it to analytics.\n */\n telegram_invite_url?: string | null;\n}\n\n/**\n * Session envelope returned by `loginWithMessage`, `register-privy`, and\n * `GET /api/auth/me`. There is no `wallet_address` field — derive the\n * session's trading wallet with {@link tradingWallet}.\n */\nexport interface SessionResponse {\n user: User;\n expires_at: number;\n auth_method: AuthMethod;\n is_beta: boolean;\n}\n\n/** Exact decimal-string body used to update and return max slippage. */\nexport interface MaxSlippagePreferenceBody {\n max_slippage_preference: string;\n}\n\n/** Human-readable login-method label (\"Email\" / \"Google\" / \"X\" / \"Solana\"). */\nexport function identityText(\n identity: UserIdentity,\n): \"Email\" | \"Google\" | \"X\" | \"Solana\" {\n switch (identity.type) {\n case \"email\":\n return \"Email\";\n case \"google\":\n return \"Google\";\n case \"x\":\n return \"X\";\n case \"wallet\":\n return \"Solana\";\n default: {\n const exhaustive: never = identity;\n throw new Error(`Unknown identity: ${JSON.stringify(exhaustive)}`);\n }\n }\n}\n\n/** Privy account data, regardless of identity type. */\nexport function userPrivy(user: User): UserPrivyData | undefined {\n switch (user.identity.type) {\n case \"email\":\n case \"google\":\n case \"x\":\n return user.identity.privy;\n case \"wallet\":\n return user.identity.privy;\n }\n}\n\n/** The X account, whether it is the login identity or a connected account. */\nexport function userXAccount(user: User): XAccountData | undefined {\n return user.identity.type === \"x\" ? user.identity.account : user.connected_x;\n}\n\n/**\n * The wallet a session operates as.\n *\n * Google/X identities only exist via Privy registration, which always\n * provisions an embedded wallet — that wallet is the answer regardless of\n * auth method. Wallet identities depend on the session: a Privy (SIWS)\n * session trades via the embedded wallet, a Lightcone session trades via the\n * wallet that signed in.\n */\nexport function tradingWallet(user: User, authMethod: AuthMethod): string {\n switch (user.identity.type) {\n case \"email\":\n case \"google\":\n case \"x\":\n return user.identity.privy.wallet.address;\n case \"wallet\":\n return authMethod === AuthMethod.Privy\n ? (user.identity.privy?.wallet.address ?? user.identity.address)\n : user.identity.address;\n }\n}\n\n/** Short display label for the wallet a session operates as. */\nexport function walletDisplayName(user: User, authMethod: AuthMethod): string {\n return shorten(tradingWallet(user, authMethod), 8);\n}\n\n/** Keeps Email labels compact while preserving the recognizable address ends. */\nfunction emailDisplayName(email: string): string {\n const maxChars = 20;\n const chars = [...email];\n if (chars.length <= maxChars) {\n return email;\n }\n\n const visibleChars = maxChars - 3;\n const prefixChars = Math.floor(visibleChars / 2);\n return `${chars.slice(0, prefixChars).join(\"\")}...${chars\n .slice(-(visibleChars - prefixChars))\n .join(\"\")}`;\n}\n\n/**\n * Best display name for the user. Email addresses are limited to 20 characters;\n * Google uses `name` with an email fallback; X uses `display_name` with a\n * username fallback; wallet identities show the shortened address (`FRGk...WcPR`).\n */\nexport function displayName(user: User): string {\n switch (user.identity.type) {\n case \"email\":\n return emailDisplayName(user.identity.account.email);\n case \"google\":\n return user.identity.account.name ?? user.identity.account.email;\n case \"x\":\n return (\n user.identity.account.display_name ?? user.identity.account.username\n );\n case \"wallet\":\n return shorten(user.identity.address, 8);\n }\n}\n\n/** Avatar URL from the login identity's OAuth provider, if any. */\nexport function avatarUrl(user: User): string | undefined {\n switch (user.identity.type) {\n case \"email\":\n return undefined;\n case \"google\":\n case \"x\":\n return user.identity.account.avatar_url;\n case \"wallet\":\n return undefined;\n }\n}\n\nexport interface AuthCredentials {\n user_id: string;\n wallet_address: PubkeyStr;\n expires_at: Date;\n}\n\nexport function isAuthenticated(credentials?: AuthCredentials): boolean {\n if (!credentials) {\n return false;\n }\n return Date.now() < credentials.expires_at.getTime();\n}\n\nexport function generateSigninMessage(nonce: string): Uint8Array {\n return new TextEncoder().encode(`Sign in to Lightcone\\nNonce: ${nonce}`);\n}\n\nexport interface LoginRequest {\n message: string;\n signature_bs58: string;\n pubkey_bytes: number[];\n use_embedded_wallet?: boolean;\n}\n\nexport interface NonceResponse {\n nonce: string;\n}\n"]}
|