Skip to content

Commit

Permalink
react: fix active wallet missing from TDK API client
Browse files Browse the repository at this point in the history
  • Loading branch information
alecananian committed Dec 18, 2024
1 parent 11b3c25 commit b5b9265
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 56 deletions.
5 changes: 5 additions & 0 deletions .changeset/tender-guests-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@treasure-dev/tdk-react": patch
---

Fixed active wallet missing from TDK API client
16 changes: 0 additions & 16 deletions examples/connect-react/src/constants.ts

This file was deleted.

13 changes: 10 additions & 3 deletions examples/connect-react/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import "@treasure-dev/tdk-react/dist/index.css";
import "@treasure-dev/tailwind-config/fonts.css";

import { treasureTopaz } from "@treasure-dev/tdk-core";
import { getContractAddress, treasureTopaz } from "@treasure-dev/tdk-core";
import { TreasureProvider } from "@treasure-dev/tdk-react";
import ReactDOM from "react-dom/client";
import { toWei } from "thirdweb";
import { arbitrumSepolia } from "thirdweb/chains";
import { ThirdwebProvider } from "thirdweb/react";

import { App } from "./App.tsx";
import { SESSION_OPTIONS_BY_CHAIN_ID } from "./constants";
import "./index.css";

const root = document.getElementById("root");
Expand All @@ -27,7 +27,14 @@ if (root) {
clientId={import.meta.env.VITE_TDK_CLIENT_ID}
ecosystemId={import.meta.env.VITE_TDK_ECOSYSTEM_ID}
ecosystemPartnerId={import.meta.env.VITE_TDK_ECOSYSTEM_PARTNER_ID}
sessionOptions={SESSION_OPTIONS_BY_CHAIN_ID[defaultChainId]}
sessionOptions={{
backendWallet: import.meta.env.VITE_TDK_BACKEND_WALLET,
approvedTargets: [
getContractAddress(arbitrumSepolia.id, "MAGIC"),
"0xE647b2c46365741e85268ceD243113d08F7E00B8", // Treasury
],
nativeTokenLimitPerTransaction: toWei("1"),
}}
analyticsOptions={{
apiKey: import.meta.env.VITE_TDK_ANALYTICS_API_KEY,
appInfo: {
Expand Down
99 changes: 62 additions & 37 deletions packages/react/src/contexts/treasure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
useIsAutoConnecting,
useSwitchActiveWalletChain,
} from "thirdweb/react";
import { isZkSyncChain } from "thirdweb/utils";
import { type Wallet, ecosystemWallet } from "thirdweb/wallets";

import { useLauncher } from "../hooks/useLauncher";
Expand Down Expand Up @@ -85,6 +86,7 @@ const TreasureProviderInner = ({
}: Props) => {
const [isAuthenticating, setIsAuthenticating] = useState(false);
const [user, setUser] = useState<User | undefined>();
const [authToken, setAuthToken] = useState<string | undefined>();
const [el, setEl] = useState<ReactNode>(null);
const client = useMemo(
() => createTreasureConnectClient({ clientId }),
Expand All @@ -102,9 +104,18 @@ const TreasureProviderInner = ({
baseUri: apiUri,
chainId: chain.id,
backendWallet: sessionOptions?.backendWallet,
authToken,
client,
activeWallet,
}),
[apiUri, chain.id, sessionOptions?.backendWallet, client],
[
apiUri,
chain.id,
sessionOptions?.backendWallet,
authToken,
client,
activeWallet,
],
);

const contractAddresses = useMemo(
Expand Down Expand Up @@ -171,12 +182,12 @@ const TreasureProviderInner = ({
(authToken: string) => {
tdk.user.me({ overrideAuthToken: authToken }).then((user) => {
setUser(user);
setAuthToken(authToken);
setStoredAuthToken(authToken);
tdk.setAuthToken(authToken);
onConnect?.(user);
});
},
[tdk.user.me, tdk.setAuthToken, onConnect],
[tdk.user.me, onConnect],
);

const { isUsingTreasureLauncher, openLauncherAccountModal } = useLauncher({
Expand All @@ -201,8 +212,7 @@ const TreasureProviderInner = ({
});
}
setUser(undefined);
tdk.clearAuthToken();
tdk.clearActiveWallet();
setAuthToken(undefined);
clearStoredAuthToken();
activeWallet?.disconnect();
};
Expand All @@ -219,33 +229,40 @@ const TreasureProviderInner = ({
return { user: undefined, legacyProfiles: [] };
}

let user: User | undefined;
if (chainId) {
tdk.chainId = chainId;
}

let nextUser: User | undefined;
let nextAuthToken: string | undefined;
let legacyProfiles: LegacyProfile[] = [];
let authToken = getStoredAuthToken();

// Check for existing stored auth token
if (authToken && !skipCurrentUser) {
// Validate if it's expired before attempting to use it
try {
const { exp: authTokenExpirationDate } = decodeAuthToken(authToken);
if (authTokenExpirationDate > Date.now() / 1000) {
setIsAuthenticating(true);
user = await tdk.user.me({ overrideAuthToken: authToken });
if (!skipCurrentUser) {
const storedAuthToken = getStoredAuthToken();
if (storedAuthToken) {
// Validate if it's expired before attempting to use it
try {
const { exp: authTokenExpirationDate } =
decodeAuthToken(storedAuthToken);
if (authTokenExpirationDate > Date.now() / 1000) {
setIsAuthenticating(true);
nextUser = await tdk.user.me({
overrideAuthToken: storedAuthToken,
});
nextAuthToken = storedAuthToken;
}
} catch (err) {
console.debug(
"[TreasureProvider] Error fetching user with stored auth token:",
err,
);
// Ignore errors and proceed with login
}
} catch (err) {
console.debug(
"[TreasureProvider] Error fetching user with stored auth token:",
err,
);
// Ignore errors and proceed with login
}
}

if (chainId) {
tdk.chainId = chainId;
}

if (!user) {
if (!nextUser) {
setIsAuthenticating(true);
try {
const result = await authenticateWallet({
Expand All @@ -255,29 +272,35 @@ const TreasureProviderInner = ({
authOptions?.authTokenDurationSec ??
sessionOptions?.sessionDurationSec,
});
authToken = result.token;
user = result.user;
nextAuthToken = result.token;
nextUser = result.user;
legacyProfiles = result.legacyProfiles;
} catch (err) {
setIsAuthenticating(false);
throw err;
}
}

// Set auth token and wallet on TDK so they can be used in future requests
tdk.setAuthToken(authToken as string);
tdk.setActiveWallet(wallet);
if (!nextUser || !nextAuthToken) {
throw new Error("An unknown error occurred during login");
}

// Set auth token on this instance of the TDK for the next request
tdk.setAuthToken(nextAuthToken);

// Start user session if configured
if (sessionOptions) {
// Start user session if configured and not on ZKsync chain
if (
sessionOptions &&
!(await isZkSyncChain(chainId ? defineChain(chainId) : chain))
) {
setIsAuthenticating(true);
try {
await startUserSession({
client,
wallet,
chainId: chainId ?? chain.id,
tdk,
sessions: user.sessions,
sessions: nextUser.sessions,
options: sessionOptions,
});
} catch (err) {
Expand All @@ -287,8 +310,9 @@ const TreasureProviderInner = ({
}

// Update user state
setUser(user);
setStoredAuthToken(authToken as string);
setUser(nextUser);
setAuthToken(nextAuthToken);
setStoredAuthToken(nextAuthToken);

if (analyticsOptions?.automaticTrackLogin !== false) {
trackCustomEvent({
Expand All @@ -306,10 +330,10 @@ const TreasureProviderInner = ({
}

// Trigger completion callback
onConnect?.(user);
onConnect?.(nextUser);

setIsAuthenticating(false);
return { user, legacyProfiles };
return { user: nextUser, legacyProfiles };
};

const switchChain = async (chainId: number) => {
Expand All @@ -322,6 +346,7 @@ const TreasureProviderInner = ({
// Attempt an automatic background connection
useAutoConnect({
client,
chain,
wallets: [
ecosystemWallet(ecosystemId, {
partnerId: ecosystemPartnerId,
Expand Down

0 comments on commit b5b9265

Please sign in to comment.