decane-connect-kit 2.19.0 → 2.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +200 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -5
- package/dist/index.d.ts +34 -5
- package/dist/index.js +200 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -92,7 +92,7 @@ interface DecaneConnectConfig {
|
|
|
92
92
|
appId: string;
|
|
93
93
|
apiKey: string;
|
|
94
94
|
chains: Chain[];
|
|
95
|
-
authMethods: Array<'google' | 'email' | 'phone' | 'kingschat'>;
|
|
95
|
+
authMethods: Array<'google' | 'email' | 'phone' | 'kingschat' | 'x'>;
|
|
96
96
|
/**
|
|
97
97
|
* Scopes requested from KingsChat at sign-in. Defaults to
|
|
98
98
|
* `['send_chat_message']`, which is what KingsChat's own SDK asks for and is
|
|
@@ -303,6 +303,23 @@ interface DecaneConnect {
|
|
|
303
303
|
* Decane session; it is never treated as one on its own.
|
|
304
304
|
*/
|
|
305
305
|
connectWithKingsChat(): Promise<ConnectResult>;
|
|
306
|
+
/**
|
|
307
|
+
* Sign in with X (Twitter).
|
|
308
|
+
*
|
|
309
|
+
* A redirect, like Google and unlike KingsChat's popup: calling it navigates
|
|
310
|
+
* away, and the promise never resolves. Call it again on the page X returns
|
|
311
|
+
* to and it finishes the sign-in from the URL instead of starting a new one.
|
|
312
|
+
*
|
|
313
|
+
* X releases no email address, so `result.profile` carries a name and a
|
|
314
|
+
* picture and nothing else. Anything that needs an address must ask the user
|
|
315
|
+
* for one.
|
|
316
|
+
*/
|
|
317
|
+
connectWithX(): Promise<ConnectResult>;
|
|
318
|
+
/**
|
|
319
|
+
* Finish a redirect sign-in already present in the URL, whichever provider
|
|
320
|
+
* started it. Throws when there is nothing to finish — it never starts one.
|
|
321
|
+
*/
|
|
322
|
+
completeRedirectSignIn(): Promise<ConnectResult>;
|
|
306
323
|
/**
|
|
307
324
|
* Sign in with a KingsChat access token the app already holds — from
|
|
308
325
|
* kingschat-web-sdk, a native SDK, or any other flow. Use when you want to
|
|
@@ -548,6 +565,14 @@ declare class ApiClient {
|
|
|
548
565
|
getGoogleInitUrl(): Promise<{
|
|
549
566
|
url: string;
|
|
550
567
|
}>;
|
|
568
|
+
/**
|
|
569
|
+
* The X consent URL. Same contract as Google's: the backend holds the client
|
|
570
|
+
* secret and the PKCE verifier, and answers 503 X_NOT_CONFIGURED when the
|
|
571
|
+
* deployment has no X credentials.
|
|
572
|
+
*/
|
|
573
|
+
getXInitUrl(): Promise<{
|
|
574
|
+
url: string;
|
|
575
|
+
}>;
|
|
551
576
|
/**
|
|
552
577
|
* Exchange a Google ID token the app already holds for a Decane session.
|
|
553
578
|
* Resolves to the SAME identity as the redirect flow, so one Google account
|
|
@@ -755,7 +780,7 @@ interface DecaneProvider {
|
|
|
755
780
|
type ConnectMode = "all" | "social" | "wallets" | "evm" | "solana" | "tron" | "evm+social" | "solana+social" | "tron+social" | "evm+tron" | "evm+tron+social";
|
|
756
781
|
interface SocialConfig {
|
|
757
782
|
apiKey: string;
|
|
758
|
-
authMethods?: ("google" | "email" | "phone" | "kingschat")[];
|
|
783
|
+
authMethods?: ("google" | "email" | "phone" | "kingschat" | "x")[];
|
|
759
784
|
/**
|
|
760
785
|
* Scopes requested from KingsChat. Defaults to `['send_chat_message']`, which
|
|
761
786
|
* is what KingsChat's own SDK asks for and is enough to establish identity.
|
|
@@ -1159,9 +1184,10 @@ interface WalletSelectorProps {
|
|
|
1159
1184
|
theme?: "light" | "dark" | "auto";
|
|
1160
1185
|
networks?: "evm" | "solana" | "tron" | "bitcoin" | "all";
|
|
1161
1186
|
mode?: ConnectMode;
|
|
1162
|
-
socialAuthMethods?: ("google" | "email" | "phone" | "kingschat")[];
|
|
1187
|
+
socialAuthMethods?: ("google" | "email" | "phone" | "kingschat" | "x")[];
|
|
1163
1188
|
onGoogleSignIn?: () => Promise<void>;
|
|
1164
1189
|
onKingsChatSignIn?: () => Promise<void>;
|
|
1190
|
+
onXSignIn?: () => Promise<void>;
|
|
1165
1191
|
onEmailStart?: (email: string) => Promise<{
|
|
1166
1192
|
codeRequired: true;
|
|
1167
1193
|
}>;
|
|
@@ -1179,7 +1205,7 @@ interface WalletSelectorProps {
|
|
|
1179
1205
|
passkeyAddress?: string | null;
|
|
1180
1206
|
onPasskeySignIn?: () => Promise<unknown>;
|
|
1181
1207
|
}
|
|
1182
|
-
declare function WalletSelector({ provider, open, onClose, onConnect, theme, networks, mode, socialAuthMethods, onGoogleSignIn, onKingsChatSignIn, onEmailStart, onEmailVerify, onPhoneStart, onPhoneVerify, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, }: WalletSelectorProps): React.ReactPortal | null;
|
|
1208
|
+
declare function WalletSelector({ provider, open, onClose, onConnect, theme, networks, mode, socialAuthMethods, onGoogleSignIn, onKingsChatSignIn, onXSignIn, onEmailStart, onEmailVerify, onPhoneStart, onPhoneVerify, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, }: WalletSelectorProps): React.ReactPortal | null;
|
|
1183
1209
|
|
|
1184
1210
|
type Theme = "light" | "dark" | "auto";
|
|
1185
1211
|
interface SocialAuthState {
|
|
@@ -1243,6 +1269,7 @@ interface SocialWalletModalProps {
|
|
|
1243
1269
|
onDisconnect: () => Promise<void>;
|
|
1244
1270
|
onGoogleSignIn: () => Promise<void>;
|
|
1245
1271
|
onKingsChatSignIn?: () => Promise<void>;
|
|
1272
|
+
onXSignIn?: () => Promise<void>;
|
|
1246
1273
|
onEmailStart: (email: string) => Promise<{
|
|
1247
1274
|
codeRequired: true;
|
|
1248
1275
|
}>;
|
|
@@ -1251,7 +1278,7 @@ interface SocialWalletModalProps {
|
|
|
1251
1278
|
codeRequired: true;
|
|
1252
1279
|
}>;
|
|
1253
1280
|
onPhoneVerify?: (phone: string, code: string) => Promise<void>;
|
|
1254
|
-
authMethods?: Array<"google" | "email" | "phone" | "kingschat">;
|
|
1281
|
+
authMethods?: Array<"google" | "email" | "phone" | "kingschat" | "x">;
|
|
1255
1282
|
customAuthLabel?: string;
|
|
1256
1283
|
onCustomAuthSignIn?: () => Promise<void>;
|
|
1257
1284
|
canUsePasskey?: boolean;
|
|
@@ -1300,6 +1327,7 @@ declare function useSocialAuth(): {
|
|
|
1300
1327
|
needsReconnect: boolean;
|
|
1301
1328
|
googleLoading: boolean;
|
|
1302
1329
|
kingschatLoading: boolean;
|
|
1330
|
+
xLoading: boolean;
|
|
1303
1331
|
emailLoading: boolean;
|
|
1304
1332
|
phoneLoading: boolean;
|
|
1305
1333
|
tokenLoading: boolean;
|
|
@@ -1309,6 +1337,7 @@ declare function useSocialAuth(): {
|
|
|
1309
1337
|
clearError: () => void;
|
|
1310
1338
|
signInWithGoogle: () => Promise<void>;
|
|
1311
1339
|
signInWithKingsChat: () => Promise<void>;
|
|
1340
|
+
signInWithX: () => Promise<void>;
|
|
1312
1341
|
sendEmailCode: (email: string) => Promise<{
|
|
1313
1342
|
codeRequired: true;
|
|
1314
1343
|
}>;
|
package/dist/index.d.ts
CHANGED
|
@@ -92,7 +92,7 @@ interface DecaneConnectConfig {
|
|
|
92
92
|
appId: string;
|
|
93
93
|
apiKey: string;
|
|
94
94
|
chains: Chain[];
|
|
95
|
-
authMethods: Array<'google' | 'email' | 'phone' | 'kingschat'>;
|
|
95
|
+
authMethods: Array<'google' | 'email' | 'phone' | 'kingschat' | 'x'>;
|
|
96
96
|
/**
|
|
97
97
|
* Scopes requested from KingsChat at sign-in. Defaults to
|
|
98
98
|
* `['send_chat_message']`, which is what KingsChat's own SDK asks for and is
|
|
@@ -303,6 +303,23 @@ interface DecaneConnect {
|
|
|
303
303
|
* Decane session; it is never treated as one on its own.
|
|
304
304
|
*/
|
|
305
305
|
connectWithKingsChat(): Promise<ConnectResult>;
|
|
306
|
+
/**
|
|
307
|
+
* Sign in with X (Twitter).
|
|
308
|
+
*
|
|
309
|
+
* A redirect, like Google and unlike KingsChat's popup: calling it navigates
|
|
310
|
+
* away, and the promise never resolves. Call it again on the page X returns
|
|
311
|
+
* to and it finishes the sign-in from the URL instead of starting a new one.
|
|
312
|
+
*
|
|
313
|
+
* X releases no email address, so `result.profile` carries a name and a
|
|
314
|
+
* picture and nothing else. Anything that needs an address must ask the user
|
|
315
|
+
* for one.
|
|
316
|
+
*/
|
|
317
|
+
connectWithX(): Promise<ConnectResult>;
|
|
318
|
+
/**
|
|
319
|
+
* Finish a redirect sign-in already present in the URL, whichever provider
|
|
320
|
+
* started it. Throws when there is nothing to finish — it never starts one.
|
|
321
|
+
*/
|
|
322
|
+
completeRedirectSignIn(): Promise<ConnectResult>;
|
|
306
323
|
/**
|
|
307
324
|
* Sign in with a KingsChat access token the app already holds — from
|
|
308
325
|
* kingschat-web-sdk, a native SDK, or any other flow. Use when you want to
|
|
@@ -548,6 +565,14 @@ declare class ApiClient {
|
|
|
548
565
|
getGoogleInitUrl(): Promise<{
|
|
549
566
|
url: string;
|
|
550
567
|
}>;
|
|
568
|
+
/**
|
|
569
|
+
* The X consent URL. Same contract as Google's: the backend holds the client
|
|
570
|
+
* secret and the PKCE verifier, and answers 503 X_NOT_CONFIGURED when the
|
|
571
|
+
* deployment has no X credentials.
|
|
572
|
+
*/
|
|
573
|
+
getXInitUrl(): Promise<{
|
|
574
|
+
url: string;
|
|
575
|
+
}>;
|
|
551
576
|
/**
|
|
552
577
|
* Exchange a Google ID token the app already holds for a Decane session.
|
|
553
578
|
* Resolves to the SAME identity as the redirect flow, so one Google account
|
|
@@ -755,7 +780,7 @@ interface DecaneProvider {
|
|
|
755
780
|
type ConnectMode = "all" | "social" | "wallets" | "evm" | "solana" | "tron" | "evm+social" | "solana+social" | "tron+social" | "evm+tron" | "evm+tron+social";
|
|
756
781
|
interface SocialConfig {
|
|
757
782
|
apiKey: string;
|
|
758
|
-
authMethods?: ("google" | "email" | "phone" | "kingschat")[];
|
|
783
|
+
authMethods?: ("google" | "email" | "phone" | "kingschat" | "x")[];
|
|
759
784
|
/**
|
|
760
785
|
* Scopes requested from KingsChat. Defaults to `['send_chat_message']`, which
|
|
761
786
|
* is what KingsChat's own SDK asks for and is enough to establish identity.
|
|
@@ -1159,9 +1184,10 @@ interface WalletSelectorProps {
|
|
|
1159
1184
|
theme?: "light" | "dark" | "auto";
|
|
1160
1185
|
networks?: "evm" | "solana" | "tron" | "bitcoin" | "all";
|
|
1161
1186
|
mode?: ConnectMode;
|
|
1162
|
-
socialAuthMethods?: ("google" | "email" | "phone" | "kingschat")[];
|
|
1187
|
+
socialAuthMethods?: ("google" | "email" | "phone" | "kingschat" | "x")[];
|
|
1163
1188
|
onGoogleSignIn?: () => Promise<void>;
|
|
1164
1189
|
onKingsChatSignIn?: () => Promise<void>;
|
|
1190
|
+
onXSignIn?: () => Promise<void>;
|
|
1165
1191
|
onEmailStart?: (email: string) => Promise<{
|
|
1166
1192
|
codeRequired: true;
|
|
1167
1193
|
}>;
|
|
@@ -1179,7 +1205,7 @@ interface WalletSelectorProps {
|
|
|
1179
1205
|
passkeyAddress?: string | null;
|
|
1180
1206
|
onPasskeySignIn?: () => Promise<unknown>;
|
|
1181
1207
|
}
|
|
1182
|
-
declare function WalletSelector({ provider, open, onClose, onConnect, theme, networks, mode, socialAuthMethods, onGoogleSignIn, onKingsChatSignIn, onEmailStart, onEmailVerify, onPhoneStart, onPhoneVerify, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, }: WalletSelectorProps): React.ReactPortal | null;
|
|
1208
|
+
declare function WalletSelector({ provider, open, onClose, onConnect, theme, networks, mode, socialAuthMethods, onGoogleSignIn, onKingsChatSignIn, onXSignIn, onEmailStart, onEmailVerify, onPhoneStart, onPhoneVerify, customAuthLabel, onCustomAuthSignIn, canUsePasskey, passkeyAddress, onPasskeySignIn, }: WalletSelectorProps): React.ReactPortal | null;
|
|
1183
1209
|
|
|
1184
1210
|
type Theme = "light" | "dark" | "auto";
|
|
1185
1211
|
interface SocialAuthState {
|
|
@@ -1243,6 +1269,7 @@ interface SocialWalletModalProps {
|
|
|
1243
1269
|
onDisconnect: () => Promise<void>;
|
|
1244
1270
|
onGoogleSignIn: () => Promise<void>;
|
|
1245
1271
|
onKingsChatSignIn?: () => Promise<void>;
|
|
1272
|
+
onXSignIn?: () => Promise<void>;
|
|
1246
1273
|
onEmailStart: (email: string) => Promise<{
|
|
1247
1274
|
codeRequired: true;
|
|
1248
1275
|
}>;
|
|
@@ -1251,7 +1278,7 @@ interface SocialWalletModalProps {
|
|
|
1251
1278
|
codeRequired: true;
|
|
1252
1279
|
}>;
|
|
1253
1280
|
onPhoneVerify?: (phone: string, code: string) => Promise<void>;
|
|
1254
|
-
authMethods?: Array<"google" | "email" | "phone" | "kingschat">;
|
|
1281
|
+
authMethods?: Array<"google" | "email" | "phone" | "kingschat" | "x">;
|
|
1255
1282
|
customAuthLabel?: string;
|
|
1256
1283
|
onCustomAuthSignIn?: () => Promise<void>;
|
|
1257
1284
|
canUsePasskey?: boolean;
|
|
@@ -1300,6 +1327,7 @@ declare function useSocialAuth(): {
|
|
|
1300
1327
|
needsReconnect: boolean;
|
|
1301
1328
|
googleLoading: boolean;
|
|
1302
1329
|
kingschatLoading: boolean;
|
|
1330
|
+
xLoading: boolean;
|
|
1303
1331
|
emailLoading: boolean;
|
|
1304
1332
|
phoneLoading: boolean;
|
|
1305
1333
|
tokenLoading: boolean;
|
|
@@ -1309,6 +1337,7 @@ declare function useSocialAuth(): {
|
|
|
1309
1337
|
clearError: () => void;
|
|
1310
1338
|
signInWithGoogle: () => Promise<void>;
|
|
1311
1339
|
signInWithKingsChat: () => Promise<void>;
|
|
1340
|
+
signInWithX: () => Promise<void>;
|
|
1312
1341
|
sendEmailCode: (email: string) => Promise<{
|
|
1313
1342
|
codeRequired: true;
|
|
1314
1343
|
}>;
|
package/dist/index.js
CHANGED
|
@@ -1946,6 +1946,37 @@ var EventEmitter = class {
|
|
|
1946
1946
|
}
|
|
1947
1947
|
};
|
|
1948
1948
|
|
|
1949
|
+
// src/social/auth/redirectResult.ts
|
|
1950
|
+
function readRedirectOutcome(search) {
|
|
1951
|
+
const params = new URLSearchParams(search);
|
|
1952
|
+
const error = params.get("decane_error");
|
|
1953
|
+
if (error) return { kind: "error", error };
|
|
1954
|
+
const jwt = params.get("decane_jwt");
|
|
1955
|
+
if (!jwt) return { kind: "none" };
|
|
1956
|
+
const name = params.get("decane_name");
|
|
1957
|
+
const email = params.get("decane_email");
|
|
1958
|
+
const picture = params.get("decane_picture");
|
|
1959
|
+
const profile = {
|
|
1960
|
+
...name ? { name } : {},
|
|
1961
|
+
...email ? { email } : {},
|
|
1962
|
+
...picture ? { picture } : {}
|
|
1963
|
+
};
|
|
1964
|
+
return {
|
|
1965
|
+
kind: "result",
|
|
1966
|
+
result: {
|
|
1967
|
+
jwt,
|
|
1968
|
+
userId: params.get("decane_user_id") ?? "",
|
|
1969
|
+
isNewUser: params.get("decane_is_new_user") === "true",
|
|
1970
|
+
hasShare: params.get("decane_has_share") === "true",
|
|
1971
|
+
// Omitted entirely when the provider released nothing, so callers can
|
|
1972
|
+
// test `result.profile` rather than an object that is always present but
|
|
1973
|
+
// sometimes empty. X never sends an email, so this is the normal case
|
|
1974
|
+
// there rather than an edge one.
|
|
1975
|
+
...Object.keys(profile).length ? { profile } : {}
|
|
1976
|
+
}
|
|
1977
|
+
};
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1949
1980
|
// src/social/api.ts
|
|
1950
1981
|
init_errors();
|
|
1951
1982
|
var ERROR_MAP = {
|
|
@@ -1997,6 +2028,14 @@ var ApiClient = class {
|
|
|
1997
2028
|
async getGoogleInitUrl() {
|
|
1998
2029
|
return this._request("/auth/google/init", { method: "GET" });
|
|
1999
2030
|
}
|
|
2031
|
+
/**
|
|
2032
|
+
* The X consent URL. Same contract as Google's: the backend holds the client
|
|
2033
|
+
* secret and the PKCE verifier, and answers 503 X_NOT_CONFIGURED when the
|
|
2034
|
+
* deployment has no X credentials.
|
|
2035
|
+
*/
|
|
2036
|
+
async getXInitUrl() {
|
|
2037
|
+
return this._request("/auth/x/init", { method: "GET" });
|
|
2038
|
+
}
|
|
2000
2039
|
/**
|
|
2001
2040
|
* Exchange a Google ID token the app already holds for a Decane session.
|
|
2002
2041
|
* Resolves to the SAME identity as the redirect flow, so one Google account
|
|
@@ -4296,6 +4335,21 @@ async function createDecaneConnect(config) {
|
|
|
4296
4335
|
...stored.profile ? { profile: stored.profile } : {}
|
|
4297
4336
|
};
|
|
4298
4337
|
}
|
|
4338
|
+
async function connectViaRedirect(label, getInitUrl) {
|
|
4339
|
+
const outcome = readRedirectOutcome(window.location.search);
|
|
4340
|
+
if (outcome.kind === "error") {
|
|
4341
|
+
window.history.replaceState({}, "", window.location.pathname);
|
|
4342
|
+
throw new CallSequenceError(`${label} sign-in failed: ${outcome.error}`);
|
|
4343
|
+
}
|
|
4344
|
+
if (outcome.kind === "result") {
|
|
4345
|
+
window.history.replaceState({}, "", window.location.pathname);
|
|
4346
|
+
return handleAuthResult(outcome.result);
|
|
4347
|
+
}
|
|
4348
|
+
const { url } = await getInitUrl();
|
|
4349
|
+
window.location.href = url;
|
|
4350
|
+
return new Promise(() => {
|
|
4351
|
+
});
|
|
4352
|
+
}
|
|
4299
4353
|
async function handleAuthResult(result) {
|
|
4300
4354
|
let addresses;
|
|
4301
4355
|
if (!result.hasShare) {
|
|
@@ -4342,39 +4396,33 @@ async function createDecaneConnect(config) {
|
|
|
4342
4396
|
throw new CallSequenceError(`Unknown auth method: ${method}`);
|
|
4343
4397
|
},
|
|
4344
4398
|
async connectWithGoogle() {
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
userId: params.get("decane_user_id") ?? "",
|
|
4364
|
-
isNewUser: params.get("decane_is_new_user") === "true",
|
|
4365
|
-
hasShare: params.get("decane_has_share") === "true",
|
|
4366
|
-
// Omitted entirely when Google released nothing, so callers can test
|
|
4367
|
-
// `result.profile` rather than an object that is always present but
|
|
4368
|
-
// sometimes empty.
|
|
4369
|
-
...Object.keys(profile).length ? { profile } : {}
|
|
4370
|
-
};
|
|
4371
|
-
window.history.replaceState({}, "", window.location.pathname);
|
|
4372
|
-
return handleAuthResult(result);
|
|
4399
|
+
return connectViaRedirect("Google", () => api.getGoogleInitUrl());
|
|
4400
|
+
},
|
|
4401
|
+
/**
|
|
4402
|
+
* Finish a redirect sign-in that is already sitting in the URL, whichever
|
|
4403
|
+
* provider started it.
|
|
4404
|
+
*
|
|
4405
|
+
* Google and X bounce back with the same decane_* params, so the page that
|
|
4406
|
+
* receives them cannot tell which one ran — and should not have to. Calling
|
|
4407
|
+
* connectWithGoogle() here would work by accident and then report an X
|
|
4408
|
+
* failure as "Google sign-in failed".
|
|
4409
|
+
*
|
|
4410
|
+
* Throws if there is nothing to finish: unlike the connectWith* methods,
|
|
4411
|
+
* this never starts a flow.
|
|
4412
|
+
*/
|
|
4413
|
+
async completeRedirectSignIn() {
|
|
4414
|
+
const outcome = readRedirectOutcome(window.location.search);
|
|
4415
|
+
if (outcome.kind === "none") {
|
|
4416
|
+
throw new CallSequenceError("No sign-in result in the URL to complete");
|
|
4373
4417
|
}
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
}
|
|
4418
|
+
window.history.replaceState({}, "", window.location.pathname);
|
|
4419
|
+
if (outcome.kind === "error") {
|
|
4420
|
+
throw new CallSequenceError(`Sign-in failed: ${outcome.error}`);
|
|
4421
|
+
}
|
|
4422
|
+
return handleAuthResult(outcome.result);
|
|
4423
|
+
},
|
|
4424
|
+
async connectWithX() {
|
|
4425
|
+
return connectViaRedirect("X", () => api.getXInitUrl());
|
|
4378
4426
|
},
|
|
4379
4427
|
async connectWithGoogleToken(idToken) {
|
|
4380
4428
|
if (!idToken) throw new CallSequenceError("connectWithGoogleToken requires an ID token");
|
|
@@ -5198,6 +5246,20 @@ function ChainIconStack({ support, size = 16 }) {
|
|
|
5198
5246
|
/* @__PURE__ */ React.createElement(ChainCircleIcon, { chain, size })
|
|
5199
5247
|
)));
|
|
5200
5248
|
}
|
|
5249
|
+
function XLogo({ size = 14 }) {
|
|
5250
|
+
return /* @__PURE__ */ React.createElement(
|
|
5251
|
+
"svg",
|
|
5252
|
+
{
|
|
5253
|
+
width: size,
|
|
5254
|
+
height: size,
|
|
5255
|
+
viewBox: "0 0 24 24",
|
|
5256
|
+
fill: "currentColor",
|
|
5257
|
+
"aria-hidden": "true",
|
|
5258
|
+
focusable: "false"
|
|
5259
|
+
},
|
|
5260
|
+
/* @__PURE__ */ React.createElement("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" })
|
|
5261
|
+
);
|
|
5262
|
+
}
|
|
5201
5263
|
|
|
5202
5264
|
// src/ui/WalletSelector.tsx
|
|
5203
5265
|
var FONT_URL = "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap";
|
|
@@ -5339,6 +5401,7 @@ function WalletSelector({
|
|
|
5339
5401
|
socialAuthMethods = ["google", "email"],
|
|
5340
5402
|
onGoogleSignIn,
|
|
5341
5403
|
onKingsChatSignIn,
|
|
5404
|
+
onXSignIn,
|
|
5342
5405
|
onEmailStart,
|
|
5343
5406
|
onEmailVerify,
|
|
5344
5407
|
onPhoneStart,
|
|
@@ -5433,6 +5496,17 @@ function WalletSelector({
|
|
|
5433
5496
|
setSocialLoad(false);
|
|
5434
5497
|
}
|
|
5435
5498
|
}
|
|
5499
|
+
async function handleXClick() {
|
|
5500
|
+
if (!onXSignIn) return;
|
|
5501
|
+
setSocialLoad(true);
|
|
5502
|
+
setSocialErr("");
|
|
5503
|
+
try {
|
|
5504
|
+
await onXSignIn();
|
|
5505
|
+
} catch (e) {
|
|
5506
|
+
setSocialErr(e.message);
|
|
5507
|
+
setSocialLoad(false);
|
|
5508
|
+
}
|
|
5509
|
+
}
|
|
5436
5510
|
async function handleCustomAuthClick() {
|
|
5437
5511
|
if (!onCustomAuthSignIn) return;
|
|
5438
5512
|
setSocialLoad(true);
|
|
@@ -5914,6 +5988,38 @@ function WalletSelector({
|
|
|
5914
5988
|
},
|
|
5915
5989
|
/* @__PURE__ */ React2.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": "true" }, /* @__PURE__ */ React2.createElement("circle", { cx: "9", cy: "9", r: "9", fill: "var(--dc-accent)" }), /* @__PURE__ */ React2.createElement("path", { d: "M5.5 4.5h1.9v3.6l3.1-3.6h2.3l-3.3 3.8 3.5 5.2h-2.3l-2.5-3.8-.8.9v2.9H5.5V4.5z", fill: "var(--dc-accent-text)" })),
|
|
5916
5990
|
socialLoad ? "Waiting for KingsChat\u2026" : "Continue with KingsChat"
|
|
5991
|
+
), !passkeyFirst && socialAuthMethods.includes("x") && onXSignIn && /* @__PURE__ */ React2.createElement(
|
|
5992
|
+
"button",
|
|
5993
|
+
{
|
|
5994
|
+
onClick: handleXClick,
|
|
5995
|
+
disabled: socialLoad,
|
|
5996
|
+
style: {
|
|
5997
|
+
display: "flex",
|
|
5998
|
+
alignItems: "center",
|
|
5999
|
+
justifyContent: "center",
|
|
6000
|
+
gap: 10,
|
|
6001
|
+
width: "100%",
|
|
6002
|
+
padding: "11px 16px",
|
|
6003
|
+
background: "var(--dc-surface)",
|
|
6004
|
+
border: "1px solid var(--dc-border)",
|
|
6005
|
+
borderRadius: 10,
|
|
6006
|
+
cursor: socialLoad ? "not-allowed" : "pointer",
|
|
6007
|
+
fontSize: 14,
|
|
6008
|
+
fontWeight: 600,
|
|
6009
|
+
color: "var(--dc-text)",
|
|
6010
|
+
fontFamily: "inherit",
|
|
6011
|
+
transition: "border-color 0.12s, background 0.12s",
|
|
6012
|
+
opacity: socialLoad ? 0.6 : 1
|
|
6013
|
+
},
|
|
6014
|
+
onMouseEnter: (e) => {
|
|
6015
|
+
if (!socialLoad) e.currentTarget.style.borderColor = "var(--dc-border-accent)";
|
|
6016
|
+
},
|
|
6017
|
+
onMouseLeave: (e) => {
|
|
6018
|
+
e.currentTarget.style.borderColor = "var(--dc-border)";
|
|
6019
|
+
}
|
|
6020
|
+
},
|
|
6021
|
+
/* @__PURE__ */ React2.createElement(XLogo, { size: 16 }),
|
|
6022
|
+
socialLoad ? "Redirecting\u2026" : "Continue with X"
|
|
5917
6023
|
), !passkeyFirst && socialAuthMethods.includes("google") && socialAuthMethods.includes("email") && /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10 } }, /* @__PURE__ */ React2.createElement("div", { style: { flex: 1, height: 1, background: "var(--dc-border)" } }), /* @__PURE__ */ React2.createElement("span", { style: { fontSize: 11, color: "var(--dc-text-muted)", whiteSpace: "nowrap" } }, "or continue with email"), /* @__PURE__ */ React2.createElement("div", { style: { flex: 1, height: 1, background: "var(--dc-border)" } })), !passkeyFirst && socialAuthMethods.includes("email") && (emailStep === "input" ? /* @__PURE__ */ React2.createElement("form", { onSubmit: handleEmailStart, style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React2.createElement(
|
|
5918
6024
|
"input",
|
|
5919
6025
|
{
|
|
@@ -6281,6 +6387,7 @@ function AddressRow({
|
|
|
6281
6387
|
function SignInView({
|
|
6282
6388
|
onGoogleSignIn,
|
|
6283
6389
|
onKingsChatSignIn,
|
|
6390
|
+
onXSignIn,
|
|
6284
6391
|
onEmailStart,
|
|
6285
6392
|
onEmailVerify,
|
|
6286
6393
|
onPhoneStart,
|
|
@@ -6295,6 +6402,7 @@ function SignInView({
|
|
|
6295
6402
|
}) {
|
|
6296
6403
|
const [googleLoading, setGoogleLoading] = useState2(false);
|
|
6297
6404
|
const [kingsChatLoading, setKingsChatLoading] = useState2(false);
|
|
6405
|
+
const [xLoading, setXLoading] = useState2(false);
|
|
6298
6406
|
const [email, setEmail] = useState2("");
|
|
6299
6407
|
const [code, setCode] = useState2("");
|
|
6300
6408
|
const [emailSent, setEmailSent] = useState2(false);
|
|
@@ -6345,6 +6453,17 @@ function SignInView({
|
|
|
6345
6453
|
setKingsChatLoading(false);
|
|
6346
6454
|
}
|
|
6347
6455
|
}
|
|
6456
|
+
async function handleX() {
|
|
6457
|
+
if (!onXSignIn) return;
|
|
6458
|
+
setError("");
|
|
6459
|
+
setXLoading(true);
|
|
6460
|
+
try {
|
|
6461
|
+
await onXSignIn();
|
|
6462
|
+
} catch (e) {
|
|
6463
|
+
setError(e.message);
|
|
6464
|
+
setXLoading(false);
|
|
6465
|
+
}
|
|
6466
|
+
}
|
|
6348
6467
|
async function handleEmailStart(e) {
|
|
6349
6468
|
e.preventDefault();
|
|
6350
6469
|
setError("");
|
|
@@ -6503,6 +6622,32 @@ function SignInView({
|
|
|
6503
6622
|
}
|
|
6504
6623
|
},
|
|
6505
6624
|
kingsChatLoading ? "Waiting for KingsChat\u2026" : "Continue with KingsChat"
|
|
6625
|
+
), !passkeyFirst && authMethods.includes("x") && onXSignIn && /* @__PURE__ */ React3.createElement(
|
|
6626
|
+
"button",
|
|
6627
|
+
{
|
|
6628
|
+
onClick: handleX,
|
|
6629
|
+
disabled: xLoading,
|
|
6630
|
+
style: {
|
|
6631
|
+
width: "100%",
|
|
6632
|
+
padding: "10px 0",
|
|
6633
|
+
marginBottom: 10,
|
|
6634
|
+
background: "var(--dc-surface)",
|
|
6635
|
+
color: "var(--dc-text)",
|
|
6636
|
+
border: "1px solid var(--dc-border)",
|
|
6637
|
+
borderRadius: 10,
|
|
6638
|
+
fontSize: 13,
|
|
6639
|
+
fontWeight: 700,
|
|
6640
|
+
cursor: xLoading ? "not-allowed" : "pointer",
|
|
6641
|
+
opacity: xLoading ? 0.7 : 1,
|
|
6642
|
+
fontFamily: "inherit",
|
|
6643
|
+
display: "flex",
|
|
6644
|
+
alignItems: "center",
|
|
6645
|
+
justifyContent: "center",
|
|
6646
|
+
gap: 8
|
|
6647
|
+
}
|
|
6648
|
+
},
|
|
6649
|
+
/* @__PURE__ */ React3.createElement(XLogo, null),
|
|
6650
|
+
xLoading ? "Redirecting\u2026" : "Continue with X"
|
|
6506
6651
|
), !passkeyFirst && authMethods.includes("email") && /* @__PURE__ */ React3.createElement(React3.Fragment, null, authMethods.includes("google") && /* @__PURE__ */ React3.createElement("div", { style: { textAlign: "center", color: "var(--dc-text-muted)", fontSize: 12, margin: "10px 0" } }, "\u2014 or \u2014"), !emailSent ? /* @__PURE__ */ React3.createElement("form", { onSubmit: handleEmailStart, style: { display: "flex", gap: 8 } }, /* @__PURE__ */ React3.createElement(
|
|
6507
6652
|
"input",
|
|
6508
6653
|
{
|
|
@@ -7165,7 +7310,7 @@ function DecaneKit({ config, children }) {
|
|
|
7165
7310
|
});
|
|
7166
7311
|
const params = new URLSearchParams(window.location.search);
|
|
7167
7312
|
if (params.has("decane_jwt") || params.has("decane_error")) {
|
|
7168
|
-
sdk.
|
|
7313
|
+
sdk.completeRedirectSignIn().then(applyResult).catch((e) => {
|
|
7169
7314
|
setSocialAuth((p) => p.phase ? { ...p, phase: null } : p);
|
|
7170
7315
|
console.error(e);
|
|
7171
7316
|
});
|
|
@@ -7206,6 +7351,11 @@ function DecaneKit({ config, children }) {
|
|
|
7206
7351
|
if (!sdk) throw new Error("Social sign-in not configured");
|
|
7207
7352
|
await sdk.connectWithGoogle();
|
|
7208
7353
|
}, []);
|
|
7354
|
+
const connectWithX = useCallback3(async () => {
|
|
7355
|
+
const sdk = socialRef.current;
|
|
7356
|
+
if (!sdk) throw new Error("Social sign-in not configured");
|
|
7357
|
+
await sdk.connectWithX();
|
|
7358
|
+
}, []);
|
|
7209
7359
|
const connectWithKingsChat = useCallback3(async () => {
|
|
7210
7360
|
const sdk = socialRef.current;
|
|
7211
7361
|
if (!sdk) throw new Error("Social sign-in not configured");
|
|
@@ -7426,6 +7576,7 @@ function DecaneKit({ config, children }) {
|
|
|
7426
7576
|
signInWithPasskey,
|
|
7427
7577
|
connectWithGoogle,
|
|
7428
7578
|
connectWithKingsChat,
|
|
7579
|
+
connectWithX,
|
|
7429
7580
|
connectWithEmail,
|
|
7430
7581
|
verifyEmailCode: verifyEmailCode2,
|
|
7431
7582
|
connectWithPhone,
|
|
@@ -7477,6 +7628,7 @@ function DecaneKit({ config, children }) {
|
|
|
7477
7628
|
socialAuthMethods: config?.social?.authMethods ?? ["google", "email"],
|
|
7478
7629
|
onGoogleSignIn: connectWithGoogle,
|
|
7479
7630
|
onKingsChatSignIn: connectWithKingsChat,
|
|
7631
|
+
onXSignIn: connectWithX,
|
|
7480
7632
|
onEmailStart: connectWithEmail,
|
|
7481
7633
|
onEmailVerify: verifyEmailCode2,
|
|
7482
7634
|
onPhoneStart: connectWithPhone,
|
|
@@ -7501,6 +7653,7 @@ function DecaneKit({ config, children }) {
|
|
|
7501
7653
|
onCustomAuthSignIn: customAuthConfig ? connectWithCustomAuth : void 0,
|
|
7502
7654
|
onGoogleSignIn: connectWithGoogle,
|
|
7503
7655
|
onKingsChatSignIn: connectWithKingsChat,
|
|
7656
|
+
onXSignIn: connectWithX,
|
|
7504
7657
|
onEmailStart: connectWithEmail,
|
|
7505
7658
|
onEmailVerify: verifyEmailCode2,
|
|
7506
7659
|
onPhoneStart: connectWithPhone,
|
|
@@ -7535,6 +7688,7 @@ function useSocialAuth() {
|
|
|
7535
7688
|
socialAuth,
|
|
7536
7689
|
connectWithGoogle,
|
|
7537
7690
|
connectWithKingsChat,
|
|
7691
|
+
connectWithX,
|
|
7538
7692
|
connectWithEmail,
|
|
7539
7693
|
verifyEmailCode: verifyEmailCode2,
|
|
7540
7694
|
connectWithPhone,
|
|
@@ -7548,6 +7702,7 @@ function useSocialAuth() {
|
|
|
7548
7702
|
} = useDecaneContext();
|
|
7549
7703
|
const [googleLoading, setGoogleLoading] = useState4(false);
|
|
7550
7704
|
const [kingschatLoading, setKingschatLoading] = useState4(false);
|
|
7705
|
+
const [xLoading, setXLoading] = useState4(false);
|
|
7551
7706
|
const [emailLoading, setEmailLoading] = useState4(false);
|
|
7552
7707
|
const [phoneLoading, setPhoneLoading] = useState4(false);
|
|
7553
7708
|
const [tokenLoading, setTokenLoading] = useState4(false);
|
|
@@ -7563,6 +7718,16 @@ function useSocialAuth() {
|
|
|
7563
7718
|
setGoogleLoading(false);
|
|
7564
7719
|
}
|
|
7565
7720
|
}, [connectWithGoogle]);
|
|
7721
|
+
const signInWithX = useCallback4(async () => {
|
|
7722
|
+
setXLoading(true);
|
|
7723
|
+
setError(null);
|
|
7724
|
+
try {
|
|
7725
|
+
await connectWithX();
|
|
7726
|
+
} catch (e) {
|
|
7727
|
+
setError(e.message);
|
|
7728
|
+
setXLoading(false);
|
|
7729
|
+
}
|
|
7730
|
+
}, [connectWithX]);
|
|
7566
7731
|
const signInWithKingsChat = useCallback4(async () => {
|
|
7567
7732
|
setKingschatLoading(true);
|
|
7568
7733
|
setError(null);
|
|
@@ -7700,6 +7865,7 @@ function useSocialAuth() {
|
|
|
7700
7865
|
needsReconnect: socialAuth.needsReconnect,
|
|
7701
7866
|
googleLoading,
|
|
7702
7867
|
kingschatLoading,
|
|
7868
|
+
xLoading,
|
|
7703
7869
|
emailLoading,
|
|
7704
7870
|
phoneLoading,
|
|
7705
7871
|
tokenLoading,
|
|
@@ -7709,6 +7875,7 @@ function useSocialAuth() {
|
|
|
7709
7875
|
clearError: () => setError(null),
|
|
7710
7876
|
signInWithGoogle,
|
|
7711
7877
|
signInWithKingsChat,
|
|
7878
|
+
signInWithX,
|
|
7712
7879
|
sendEmailCode,
|
|
7713
7880
|
confirmEmailCode,
|
|
7714
7881
|
sendPhoneCode,
|