Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fair-mails-divide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"thirdweb": minor
---

Add all connected wallets in all onConnect callbacks
14 changes: 13 additions & 1 deletion apps/playground-web/src/components/in-app-wallet/ecosystem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,17 @@ const getEcosystemWallet = () => {
export function EcosystemConnectEmbed(
props?: Omit<ConnectButtonProps, "client" | "theme">,
) {
return <StyledConnectEmbed {...props} wallets={[getEcosystemWallet()]} />;
return (
<StyledConnectEmbed
{...props}
wallets={[getEcosystemWallet()]}
onConnect={(activeWallet, allConnectedWallets) => {
console.log("active wallet", activeWallet.id);
console.log(
"all connected wallets",
allConnectedWallets.map((wallet) => wallet.id),
);
}}
/>
);
}
7 changes: 7 additions & 0 deletions packages/thirdweb/src/exports/react.native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ export type {
ConnectButton_detailsButtonOptions,
ConnectButton_detailsModalOptions,
ConnectButtonProps,
DirectPaymentOptions,
FundWalletOptions,
PaymentInfo,
PayUIOptions,
TransactionOptions,
} from "../react/core/hooks/connection/ConnectButtonProps.js";
export type { ConnectEmbedProps } from "../react/core/hooks/connection/ConnectEmbedProps.js";
export type { OnConnectCallback } from "../react/core/hooks/connection/types.js";
export { useContractEvents } from "../react/core/hooks/contract/useContractEvents.js";
// contract
export { useReadContract } from "../react/core/hooks/contract/useReadContract.js";
Expand Down
1 change: 1 addition & 0 deletions packages/thirdweb/src/exports/react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type {
TransactionOptions,
} from "../react/core/hooks/connection/ConnectButtonProps.js";
export type { ConnectEmbedProps } from "../react/core/hooks/connection/ConnectEmbedProps.js";
export type { OnConnectCallback } from "../react/core/hooks/connection/types.js";
export { useContractEvents } from "../react/core/hooks/contract/useContractEvents.js";
// contract
export { useReadContract } from "../react/core/hooks/contract/useReadContract.js";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import type {
TokenInfo,
} from "../../utils/defaultTokens.js";
import type { SiweAuthOptions } from "../auth/useSiweAuth.js";
import type { OnConnectCallback } from "./types.js";

export type PaymentInfo = Prettify<
{
Expand Down Expand Up @@ -937,13 +938,14 @@ export type ConnectButtonProps = {
*
* ```tsx
* <ConnectButton
* onConnect={(wallet) => {
* console.log("connected to", wallet)
* onConnect={(activeWallet, allConnectedWallets) => {
* console.log("connected to", activeWallet)
* console.log("all connected wallets", allConnectedWallets)
* }}
* />
* ```
*/
onConnect?: (wallet: Wallet) => void;
onConnect?: OnConnectCallback;

/**
* Called when the user disconnects the wallet by clicking on the "Disconnect Wallet" button in the `ConnectButton`'s Details Modal.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { WelcomeScreen } from "../../../web/ui/ConnectWallet/screens/types.
import type { LocaleId } from "../../../web/ui/types.js";
import type { Theme } from "../../design-system/index.js";
import type { SiweAuthOptions } from "../auth/useSiweAuth.js";
import type { OnConnectCallback } from "./types.js";

export type ConnectEmbedProps = {
/**
Expand Down Expand Up @@ -213,14 +214,15 @@ export type ConnectEmbedProps = {
*
* ```tsx
* <ConnectEmbed
* onConnect={(wallet) => {
* console.log("connected to", wallet)
* onConnect={(activeWallet, allConnectedWallets) => {
* console.log("connected to", activeWallet)
* console.log("all connected wallets", allConnectedWallets)
* }}
* />
* ```
* ```
*/
onConnect?: (wallet: Wallet) => void;
onConnect?: OnConnectCallback;

/**
* By default, A "Powered by Thirdweb" branding is shown at the bottom of the embed.
Expand Down
6 changes: 6 additions & 0 deletions packages/thirdweb/src/react/core/hooks/connection/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { Wallet } from "../../../../wallets/interfaces/wallet.js";

export type OnConnectCallback = (
activeWallet: Wallet,
allConnectedWallets: Wallet[],
) => void;
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
useSiweAuth,
} from "../../../../core/hooks/auth/useSiweAuth.js";
import type { ConnectEmbedProps } from "../../../../core/hooks/connection/ConnectEmbedProps.js";
import type { OnConnectCallback } from "../../../../core/hooks/connection/types.js";
import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js";
import { useActiveWallet } from "../../../../core/hooks/wallets/useActiveWallet.js";
import { useIsAutoConnecting } from "../../../../core/hooks/wallets/useIsAutoConnecting.js";
Expand Down Expand Up @@ -354,7 +355,7 @@ const ConnectEmbedContent = (props: {
| true
| undefined;
localeId: LocaleId;
onConnect: ((wallet: Wallet) => void) | undefined;
onConnect: OnConnectCallback | undefined;
recommendedWallets: Wallet[] | undefined;
showAllWallets: boolean | undefined;
hiddenWallets: WalletId[] | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { Wallet } from "../../../../../wallets/interfaces/wallet.js";
import type { SmartWalletOptions } from "../../../../../wallets/smart/types.js";
import type { WalletId } from "../../../../../wallets/wallet-types.js";
import type { SiweAuthOptions } from "../../../../core/hooks/auth/useSiweAuth.js";
import type { OnConnectCallback } from "../../../../core/hooks/connection/types.js";
import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js";
import {
useIsWalletModalOpen,
Expand All @@ -26,7 +27,7 @@ type ConnectModalOptions = {
wallets: Wallet[];
accountAbstraction: SmartWalletOptions | undefined;
auth: SiweAuthOptions | undefined;
onConnect: ((wallet: Wallet) => void) | undefined;
onConnect: OnConnectCallback | undefined;
size: "compact" | "wide";
welcomeScreen: WelcomeScreen | undefined;
meta: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
type SiweAuthOptions,
useSiweAuth,
} from "../../../../core/hooks/auth/useSiweAuth.js";
import type { OnConnectCallback } from "../../../../core/hooks/connection/types.js";
import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js";
import { useActiveWallet } from "../../../../core/hooks/wallets/useActiveWallet.js";
import { useSetActiveWallet } from "../../../../core/hooks/wallets/useSetActiveWallet.js";
Expand Down Expand Up @@ -43,7 +44,7 @@
wallets: Wallet[];
accountAbstraction: SmartWalletOptions | undefined;
auth: SiweAuthOptions | undefined;
onConnect: ((wallet: Wallet) => void) | undefined;
onConnect: OnConnectCallback | undefined;
size: "compact" | "wide";
meta: {
title?: string;
Expand Down Expand Up @@ -93,7 +94,7 @@
}

if (props.onConnect) {
props.onConnect(wallet);
props.onConnect(wallet, connectionManager.connectedWallets.getValue());

Check warning on line 97 in packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectModalContent.tsx

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectModalContent.tsx#L97

Added line #L97 was not covered by tests
}

onModalUnmount(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { AppMetadata } from "../../../../wallets/types.js";
import type { WalletId } from "../../../../wallets/wallet-types.js";
import type { Theme } from "../../../core/design-system/index.js";
import type { SiweAuthOptions } from "../../../core/hooks/auth/useSiweAuth.js";
import type { OnConnectCallback } from "../../../core/hooks/connection/types.js";
import { SetRootElementContext } from "../../../core/providers/RootElementContext.js";
import { WalletUIStatesProvider } from "../../providers/wallet-ui-states-provider.js";
import { canFitWideModal } from "../../utils/canFitWideModal.js";
Expand Down Expand Up @@ -90,7 +91,7 @@ export function useConnectModal() {

function Modal(
props: UseConnectModalOptions & {
onConnect: (wallet: Wallet) => void;
onConnect: OnConnectCallback;
onClose: () => void;
connectLocale: ConnectLocale;
},
Expand Down
5 changes: 3 additions & 2 deletions packages/thirdweb/src/wallets/connection/autoConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ import type { AutoConnectProps } from "./types.js";
*
* const autoConnected = await autoConnect({
* client,
* onConnect: (wallet) => {
* console.log("wallet", wallet);
* onConnect: (activeWallet, allConnectedWallets) => {
* console.log("active wallet", activeWallet);
* console.log("all connected wallets", allConnectedWallets);
* },
* });
* ```
Expand Down
45 changes: 26 additions & 19 deletions packages/thirdweb/src/wallets/connection/autoConnectCore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ describe("useAutoConnectCore", () => {
const mockStorage = new MockStorage();
const manager = createConnectionManager(mockStorage);

const wallet1 = createWalletAdapter({
adaptedAccount: TEST_ACCOUNT_A,
chain: ethereum,
client: TEST_CLIENT,
onDisconnect: () => {},
switchChain: () => {},
});

const wallet2 = createWalletAdapter({
adaptedAccount: { ...TEST_ACCOUNT_A, address: "0x123" },
chain: ethereum,
client: TEST_CLIENT,
onDisconnect: () => {},
switchChain: () => {},
});
wallet2.id = "io.metamask" as unknown as "adapter";

afterEach(() => {
vi.restoreAllMocks();
});
Expand Down Expand Up @@ -161,23 +178,6 @@ describe("useAutoConnectCore", () => {
});

it("should connect multiple wallets correctly", async () => {
const wallet1 = createWalletAdapter({
adaptedAccount: TEST_ACCOUNT_A,
chain: ethereum,
client: TEST_CLIENT,
onDisconnect: () => {},
switchChain: () => {},
});

const wallet2 = createWalletAdapter({
adaptedAccount: { ...TEST_ACCOUNT_A, address: "0x123" },
chain: ethereum,
client: TEST_CLIENT,
onDisconnect: () => {},
switchChain: () => {},
});
wallet2.id = "io.metamask" as unknown as "adapter";

mockStorage.setItem("thirdweb:active-wallet-id", wallet1.id);
mockStorage.setItem(
"thirdweb:connected-wallet-ids",
Expand Down Expand Up @@ -228,7 +228,10 @@ describe("useAutoConnectCore", () => {
storage: mockStorage,
});

expect(mockOnConnect).toHaveBeenCalledWith(wallet);
expect(mockOnConnect).toHaveBeenCalledWith(
wallet,
manager.connectedWallets.getValue(),
);
});

it("should continue even if onConnect callback throws", async () => {
Expand Down Expand Up @@ -262,7 +265,10 @@ describe("useAutoConnectCore", () => {
storage: mockStorage,
});

expect(mockOnConnect).toHaveBeenCalledWith(wallet);
expect(mockOnConnect).toHaveBeenCalledWith(
wallet,
manager.connectedWallets.getValue(),
);
});

it("should call setLastAuthProvider if authProvider is present", async () => {
Expand Down Expand Up @@ -300,6 +306,7 @@ describe("useAutoConnectCore", () => {
});

it("should set connection status to disconnect if no connectedWallet is returned", async () => {
manager.activeWalletStore.setValue(undefined);
const wallet = createWalletAdapter({
adaptedAccount: TEST_ACCOUNT_A,
chain: ethereum,
Expand Down
26 changes: 15 additions & 11 deletions packages/thirdweb/src/wallets/connection/autoConnectCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,22 +152,12 @@ const _autoConnectCore = async ({

try {
// connected wallet could be activeWallet or smart wallet
const connectedWallet = await (connectOverride
await (connectOverride
? connectOverride(activeWallet)
: manager.connect(activeWallet, {
accountAbstraction: props.accountAbstraction,
client: props.client,
}));
if (connectedWallet) {
autoConnected = true;
try {
onConnect?.(connectedWallet);
} catch {
// ignore
}
} else {
manager.activeWalletConnectionStatusStore.setValue("disconnected");
}
} catch (e) {
if (e instanceof Error) {
console.warn("Error auto connecting wallet:", e.message);
Expand Down Expand Up @@ -216,6 +206,20 @@ const _autoConnectCore = async ({
});
}
manager.isAutoConnecting.setValue(false);

const connectedActiveWallet = manager.activeWalletStore.getValue();
const allConnectedWallets = manager.connectedWallets.getValue();
if (connectedActiveWallet) {
autoConnected = true;
try {
onConnect?.(connectedActiveWallet, allConnectedWallets);
} catch (e) {
console.error("Error calling onConnect callback:", e);
}
} else {
manager.activeWalletConnectionStatusStore.setValue("disconnected");
}

return autoConnected; // useQuery needs a return value
};

Expand Down
7 changes: 4 additions & 3 deletions packages/thirdweb/src/wallets/connection/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,14 @@ export type AutoConnectProps = {
*
* ```tsx
* <AutoConnect
* onConnect={(wallet) => {
* console.log("auto connected to", wallet)
* onConnect={(activeWallet, otherWallets) => {
* console.log("auto connected to", activeWallet)
* console.log("other wallets that were also connected", otherWallets)
* }}
* />
* ```
*/
onConnect?: (wallet: Wallet) => void;
onConnect?: (activeWallet: Wallet, otherWallets: Wallet[]) => void;

/**
* Optional chain to autoconnect to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe.runIf(process.env.TW_SECRET_KEY)("Connection Manager", () => {

await manager.connect(wallet, { client, onConnect });

expect(onConnect).toHaveBeenCalledWith(wallet);
expect(onConnect).toHaveBeenCalledWith(wallet, [wallet]);
expect(storage.setItem).toHaveBeenCalled();
});

Expand Down
7 changes: 4 additions & 3 deletions packages/thirdweb/src/wallets/manager/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Chain } from "../../chains/types.js";
import { cacheChains } from "../../chains/utils.js";
import type { ThirdwebClient } from "../../client/client.js";
import type { OnConnectCallback } from "../../react/core/hooks/connection/types.js";
import { computedStore } from "../../reactive/computedStore.js";
import { effect } from "../../reactive/effect.js";
import { createStore } from "../../reactive/store.js";
Expand Down Expand Up @@ -29,7 +30,7 @@
client: ThirdwebClient;
accountAbstraction?: SmartWalletOptions;
setWalletAsActive?: boolean;
onConnect?: (wallet: Wallet) => void;
onConnect?: OnConnectCallback;
};

/**
Expand Down Expand Up @@ -158,7 +159,7 @@
wallet.subscribe("accountChanged", async () => {
// We reimplement connect here to prevent memory leaks
const newWallet = await handleConnection(wallet, options);
options?.onConnect?.(newWallet);
options?.onConnect?.(newWallet, connectedWallets.getValue());

Check warning on line 162 in packages/thirdweb/src/wallets/manager/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/wallets/manager/index.ts#L162

Added line #L162 was not covered by tests
});

return activeWallet;
Expand All @@ -167,7 +168,7 @@
const connect = async (wallet: Wallet, options?: ConnectManagerOptions) => {
// connectedWallet can be either wallet or smartWallet
const connectedWallet = await handleConnection(wallet, options);
options?.onConnect?.(connectedWallet);
options?.onConnect?.(connectedWallet, connectedWallets.getValue());
return connectedWallet;
};

Expand Down
Loading