Skip to content

Commit 14b07bf

Browse files
committed
making progress with sign-in
1 parent c4899f7 commit 14b07bf

File tree

12 files changed

+208
-119
lines changed

12 files changed

+208
-119
lines changed

examples/connect-electron/electron.vite.config.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ export default defineConfig({
5858
},
5959
build: {
6060
outDir: "out/app/dist/renderer",
61+
rollupOptions: {
62+
input: {
63+
launcher: resolve(__dirname, "src/renderer/index.html"),
64+
authComplete: resolve(__dirname, "src/renderer/auth/index.html"),
65+
},
66+
output: {
67+
entryFileNames: (chunkInfo) => {
68+
if (chunkInfo.name === "authComplete") {
69+
return "auth/auth-bundle.js";
70+
}
71+
return "assets/[name].js";
72+
},
73+
assetFileNames: () => "public/[name][extname]",
74+
},
75+
},
6176
},
6277
},
6378
});

examples/connect-electron/out/app/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
"express": "catalog:",
1212
"@electron-toolkit/preload": "catalog:",
1313
"@electron-toolkit/utils": "catalog:",
14-
"@treasure-dev/launcher": "workspace:*",
1514
"thirdweb": "catalog:"
1615
}
1716
}

examples/connect-electron/src/main/app.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import http from "node:http";
2+
import path from "node:path";
23
import type { BrowserWindow } from "electron";
34
import express from "express";
45

@@ -33,6 +34,10 @@ export default class RedirectApp {
3334
next();
3435
});
3536

37+
this.app.use("/auth", [
38+
express.static(path.resolve(__dirname, "../renderer/auth/")),
39+
]);
40+
3641
this.app.post("/auth", (req, res) => {
3742
const { searchParams }: { searchParams: string } = req.body;
3843

examples/connect-electron/src/main/index.ts

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,93 @@
11
import { join } from "node:path";
22
import { electronApp, is, optimizer } from "@electron-toolkit/utils";
3-
import {
4-
getTreasureLauncherAuthToken,
5-
getTreasureLauncherWalletComponents,
6-
} from "@treasure-dev/launcher";
7-
import { BrowserWindow, app, ipcMain, shell } from "electron";
3+
import { BrowserWindow, app, ipcMain, session, shell } from "electron";
84
import icon from "../../resources/icon.png?asset";
95
import { startRedirectApp } from "./app";
106

117
let mainWindow: BrowserWindow;
128

9+
export function getTreasureLauncherAuthToken(): string | undefined {
10+
let args: string[] | undefined;
11+
12+
if (typeof process !== "undefined" && Array.isArray(process.argv)) {
13+
args = process.argv;
14+
} else if (
15+
typeof window !== "undefined" &&
16+
window.process &&
17+
Array.isArray(window.process.argv)
18+
) {
19+
args = window.process.argv;
20+
} else {
21+
return undefined;
22+
}
23+
24+
const arg = args.find((arg) => arg.startsWith("--tdk-auth-token="));
25+
return arg ? arg.split("=")[1] : undefined;
26+
}
27+
28+
export function getTreasureLauncherWalletComponents():
29+
| { walletId: string; authProvider: string; authCookie: string }
30+
| undefined {
31+
let args: string[] | undefined;
32+
33+
if (typeof process !== "undefined" && Array.isArray(process.argv)) {
34+
args = process.argv;
35+
} else if (
36+
typeof window !== "undefined" &&
37+
window.process &&
38+
Array.isArray(window.process.argv)
39+
) {
40+
args = window.process.argv;
41+
} else {
42+
return undefined;
43+
}
44+
45+
let walletId: string | undefined = args.find((arg) =>
46+
arg.startsWith("--tdk-wallet-id="),
47+
);
48+
if (walletId) {
49+
walletId = walletId.split("=")[1];
50+
}
51+
52+
let authProvider: string | undefined = args.find((arg) =>
53+
arg.startsWith("--tdk-auth-provider="),
54+
);
55+
if (authProvider) {
56+
authProvider = authProvider.split("=")[1];
57+
}
58+
59+
let authCookie: string | undefined = args.find((arg) =>
60+
arg.startsWith("--tdk-auth-cookie="),
61+
);
62+
if (authCookie) {
63+
authCookie = authCookie.split("=")[1];
64+
}
65+
66+
if (!walletId || !authProvider || !authCookie) {
67+
return undefined;
68+
}
69+
70+
return {
71+
walletId,
72+
authProvider,
73+
authCookie,
74+
};
75+
}
76+
77+
function initThirdwebBundleHeader() {
78+
session.defaultSession.webRequest.onBeforeSendHeaders(
79+
{
80+
urls: ["https://*.thirdweb.com/*"],
81+
},
82+
(details, callback) => {
83+
// TODO: should be updated to actual bundle id once signing is done
84+
details.requestHeaders["x-bundle-id"] =
85+
"lol.treasure.tdk-examples-connect-electron";
86+
callback({ cancel: false, requestHeaders: details.requestHeaders });
87+
},
88+
);
89+
}
90+
1391
function createWindow(): void {
1492
// Create the browser window.
1593
mainWindow = new BrowserWindow({
@@ -59,6 +137,8 @@ app.whenReady().then(() => {
59137
// IPC test
60138
ipcMain.on("ping", () => console.log("pong"));
61139

140+
initThirdwebBundleHeader();
141+
62142
createWindow();
63143

64144
app.on("activate", () => {

examples/connect-electron/src/renderer/src/App.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import Versions from "./components/Versions";
55

66
let started = false;
77

8+
const isPackaged = import.meta.env.MODE !== "development";
9+
810
function App(): JSX.Element {
911
useEffect(() => {
1012
if (!started) {
@@ -16,7 +18,9 @@ function App(): JSX.Element {
1618
return (
1719
<>
1820
<p>
19-
<ConnectButton redirectUrl={`${window.location.origin}/auth/`} />
21+
<ConnectButton
22+
redirectUrl={`${!isPackaged && typeof window !== "undefined" ? window.location.origin : "http://localhost:5180"}/auth/`}
23+
/>
2024
</p>
2125
<Versions />
2226
</>

packages/react/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"i18next": "catalog:",
5050
"i18next-browser-languagedetector": "catalog:",
5151
"input-otp": "catalog:",
52+
"jwt-decode": "catalog:",
5253
"react-i18next": "catalog:",
5354
"tailwind-merge": "catalog:"
5455
},

packages/react/src/contexts/treasure.tsx

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import {
2-
type WalletComponents,
3-
startUserSessionViaLauncher,
4-
} from "@treasure-dev/launcher";
1+
import { startUserSessionViaLauncher } from "@treasure-dev/launcher";
52
import {
63
AnalyticsManager,
74
DEFAULT_TDK_API_BASE_URI,
@@ -42,6 +39,7 @@ import {
4239
import { isZkSyncChain } from "thirdweb/utils";
4340
import { type Wallet, ecosystemWallet } from "thirdweb/wallets";
4441

42+
import type { AuthStoredTokenWithCookieReturnType } from "thirdweb/dist/types/wallets/in-app/core/authentication/types";
4543
import { useLauncher } from "../hooks/useLauncher";
4644
import { i18n } from "../i18n";
4745
import type { AnalyticsEvent, Config, ContextValues } from "../types";
@@ -71,6 +69,8 @@ export const useTreasure = () => {
7169

7270
type Props = PropsWithChildren<Config>;
7371

72+
let hasSetUrlParams = false;
73+
7474
const TreasureProviderInner = ({
7575
children,
7676
appName,
@@ -195,26 +195,43 @@ const TreasureProviderInner = ({
195195
);
196196

197197
const onWalletComponentsUpdated = useCallback(
198-
(walletComponents: WalletComponents) => {
198+
async (
199+
authResult: AuthStoredTokenWithCookieReturnType,
200+
authProvider: string,
201+
walletId: string,
202+
authCookie: string,
203+
) => {
199204
if (activeWallet) {
200205
console.debug(
201206
"[TreasureProvider] There is already an active wallet, skipping updating with launcher wallet components",
202207
);
203208
return;
204209
}
210+
if (hasSetUrlParams) {
211+
return;
212+
}
213+
hasSetUrlParams = true;
205214
console.debug(
206215
"[TreasureProvider] Updating wallet with launcher wallet components",
207216
);
217+
218+
authResult.storedToken.cookieString = authCookie;
219+
const encoded = encodeURIComponent(JSON.stringify(authResult));
208220
const url = new URL(window.location.href);
209-
url.searchParams.set("walletId", walletComponents.walletId);
210-
url.searchParams.set("authProvider", walletComponents.authProvider);
211-
url.searchParams.set("authCookie", walletComponents.authCookie);
212-
window.history.pushState({}, "", url);
221+
url.searchParams.set("authResult", encoded);
222+
url.searchParams.set("authProvider", authProvider);
223+
url.searchParams.set("walletId", walletId);
224+
url.searchParams.set("authCookie", authCookie);
225+
window.history.pushState({}, "", url.toString());
213226
},
214227
[activeWallet],
215228
);
216229

217-
const { isUsingTreasureLauncher, openLauncherAccountModal } = useLauncher({
230+
const {
231+
isUsingTreasureLauncher,
232+
isUsingLauncherAuthToken,
233+
openLauncherAccountModal,
234+
} = useLauncher({
218235
getAuthTokenOverride: launcherOptions?.getAuthTokenOverride,
219236
getWalletComponentsOverride: launcherOptions?.getWalletComponentsOverride,
220237
setRootElement: setEl,
@@ -228,6 +245,7 @@ const TreasureProviderInner = ({
228245
name: EVT_TREASURECONNECT_DISCONNECTED,
229246
properties: {
230247
isUsingTreasureLauncher,
248+
isUsingLauncherAuthToken,
231249
},
232250
})
233251
.then((eventId) => {
@@ -248,7 +266,7 @@ const TreasureProviderInner = ({
248266
chainId?: number,
249267
skipCurrentUser = false,
250268
): Promise<{ user: User | undefined; legacyProfiles: LegacyProfile[] }> => {
251-
if (isUsingTreasureLauncher) {
269+
if (isUsingLauncherAuthToken) {
252270
console.debug(
253271
"[TreasureProvider] Skipping login because launcher is being used",
254272
);
@@ -345,6 +363,7 @@ const TreasureProviderInner = ({
345363
name: EVT_TREASURECONNECT_CONNECTED,
346364
properties: {
347365
isUsingTreasureLauncher,
366+
isUsingLauncherAuthToken,
348367
},
349368
})
350369
.then((eventId) => {
@@ -409,6 +428,7 @@ const TreasureProviderInner = ({
409428
userAddress: undefined,
410429
}),
411430
isUsingTreasureLauncher,
431+
isUsingLauncherAuthToken,
412432
logIn,
413433
logOut,
414434
updateUser: (partialUser) =>

packages/react/src/hooks/useConnect.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export const useConnect = (options?: Options) => {
4242
logOut,
4343
setRootElement,
4444
isUsingTreasureLauncher,
45+
isUsingLauncherAuthToken,
4546
openLauncherAccountModal,
4647
trackCustomEvent,
4748
} = useTreasure();
@@ -60,13 +61,6 @@ export const useConnect = (options?: Options) => {
6061
: [chain];
6162

6263
const openConnectModal = () => {
63-
if (isUsingTreasureLauncher) {
64-
console.debug(
65-
"[useConnect] openConnectModal cannot be used when Treasure Launcher is being used",
66-
);
67-
return;
68-
}
69-
7064
trackCustomEvent({
7165
name: EVT_TREASURECONNECT_UI_LOGIN,
7266
});
@@ -89,7 +83,7 @@ export const useConnect = (options?: Options) => {
8983
},
9084
});
9185

92-
if (isUsingTreasureLauncher) {
86+
if (isUsingLauncherAuthToken) {
9387
openLauncherAccountModal(connectModalSize);
9488
return;
9589
}

packages/react/src/hooks/useLauncher.tsx

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,22 @@ import {
33
getTreasureLauncherAuthToken,
44
getTreasureLauncherWalletComponents,
55
} from "@treasure-dev/launcher";
6-
import { type ReactNode, useEffect } from "react";
6+
import { jwtDecode } from "jwt-decode";
7+
import { type ReactNode, useEffect, useState } from "react";
8+
import type { AuthStoredTokenWithCookieReturnType } from "thirdweb/dist/types/wallets/in-app/core/authentication/types";
79
import { AccountModal } from "../components/launcher/AccountModal";
810

911
type Props = {
1012
getAuthTokenOverride?: () => string | undefined;
1113
getWalletComponentsOverride?: () => WalletComponents | undefined;
1214
setRootElement: (el: ReactNode) => void;
1315
onAuthTokenUpdated: (authToken: string) => void;
14-
onWalletComponentsUpdated: (walletComponents: WalletComponents) => void;
16+
onWalletComponentsUpdated: (
17+
authResult: AuthStoredTokenWithCookieReturnType,
18+
authProvider: string,
19+
walletId: string,
20+
authCookie: string,
21+
) => Promise<void>;
1522
};
1623

1724
export const useLauncher = ({
@@ -22,11 +29,13 @@ export const useLauncher = ({
2229
onWalletComponentsUpdated,
2330
}: Props) => {
2431
const authToken = getAuthTokenOverride?.() ?? getTreasureLauncherAuthToken();
25-
const isUsingTreasureLauncher =
26-
authToken !== undefined && authToken.length > 0;
2732
const walletComponents: WalletComponents | undefined =
2833
getWalletComponentsOverride?.() ?? getTreasureLauncherWalletComponents();
2934

35+
const [isUsingTreasureLauncher, setIsUsingTreasureLauncher] = useState(false);
36+
const [isUsingLauncherAuthToken, setIsUserLauncherAuthToken] =
37+
useState(false);
38+
3039
const openLauncherAccountModal = (size?: "lg" | "xl" | "2xl" | "3xl") => {
3140
if (!isUsingTreasureLauncher) {
3241
console.debug(
@@ -47,13 +56,26 @@ export const useLauncher = ({
4756
useEffect(() => {
4857
if (walletComponents) {
4958
console.debug("[useLauncher] Using launcher wallet components");
50-
onWalletComponentsUpdated(walletComponents);
59+
const authResult: AuthStoredTokenWithCookieReturnType = jwtDecode(
60+
walletComponents.authCookie,
61+
);
62+
onWalletComponentsUpdated(
63+
authResult,
64+
walletComponents.authProvider,
65+
walletComponents.walletId,
66+
walletComponents.authCookie,
67+
);
68+
setIsUsingTreasureLauncher(true);
5169
return;
5270
}
5371
if (authToken) {
5472
console.debug("[useLauncher] Using launcher auth token");
73+
setIsUsingTreasureLauncher(true);
74+
setIsUserLauncherAuthToken(true);
5575
onAuthTokenUpdated(authToken);
76+
return;
5677
}
78+
setIsUsingTreasureLauncher(false);
5779
}, [
5880
authToken,
5981
onAuthTokenUpdated,
@@ -63,6 +85,7 @@ export const useLauncher = ({
6385

6486
return {
6587
isUsingTreasureLauncher,
88+
isUsingLauncherAuthToken,
6689
openLauncherAccountModal,
6790
};
6891
};

0 commit comments

Comments
 (0)