diff --git a/.changeset/green-coins-add.md b/.changeset/green-coins-add.md
new file mode 100644
index 0000000000..42dd3a651c
--- /dev/null
+++ b/.changeset/green-coins-add.md
@@ -0,0 +1,5 @@
+---
+'@coinbase/onchainkit': patch
+---
+
+- **feat**: Add Phantom Wallet connection support in `WalletModal`. By @cpcramer #1770
diff --git a/site/docs/public/assets/wallet-modal.png b/site/docs/public/assets/wallet-modal.png
index 3b4c7657cf..d249aff53c 100644
Binary files a/site/docs/public/assets/wallet-modal.png and b/site/docs/public/assets/wallet-modal.png differ
diff --git a/src/internal/svg/phantomSvg.tsx b/src/internal/svg/phantomSvg.tsx
new file mode 100644
index 0000000000..c097b9d9f2
--- /dev/null
+++ b/src/internal/svg/phantomSvg.tsx
@@ -0,0 +1,26 @@
+export const phantomSvg = (
+
+);
diff --git a/src/wallet/components/WalletModal.test.tsx b/src/wallet/components/WalletModal.test.tsx
index ea3e2a78e3..f6408e1380 100644
--- a/src/wallet/components/WalletModal.test.tsx
+++ b/src/wallet/components/WalletModal.test.tsx
@@ -27,6 +27,9 @@ vi.mock('../../core-react/useOnchainKit', () => ({
vi.mock('wagmi/connectors', () => ({
coinbaseWallet: () => ({ preference: 'all' }),
metaMask: ({ dappMetadata }: MetaMaskParameters) => ({ dappMetadata }),
+ injected: ({ target }: { target: string }) => ({
+ target,
+ }),
}));
describe('WalletModal', () => {
@@ -493,4 +496,62 @@ describe('WalletModal', () => {
'Some string error',
);
});
+
+ it('connects with Phantom when clicking Phantom button', () => {
+ render();
+
+ fireEvent.click(screen.getByText('Phantom'));
+
+ expect(mockConnect).toHaveBeenCalledWith({
+ connector: {
+ target: 'phantom',
+ },
+ });
+ expect(mockOnClose).toHaveBeenCalled();
+ });
+
+ it('handles Phantom connection errors', () => {
+ const mockError = new Error('Phantom connection failed');
+ const mockOnError = vi.fn();
+ (useConnect as Mock).mockReturnValue({
+ connect: vi.fn(() => {
+ throw mockError;
+ }),
+ });
+
+ render(
+ ,
+ );
+
+ fireEvent.click(screen.getByText('Phantom'));
+
+ expect(mockOnError).toHaveBeenCalledWith(mockError);
+ expect(console.error).toHaveBeenCalledWith(
+ 'Phantom connection error:',
+ mockError,
+ );
+ });
+
+ it('handles non-Error objects in Phantom connection errors', () => {
+ const mockOnError = vi.fn();
+ (useConnect as Mock).mockReturnValue({
+ connect: vi.fn(() => {
+ throw 'Some string error';
+ }),
+ });
+
+ render(
+ ,
+ );
+
+ fireEvent.click(screen.getByText('Phantom'));
+
+ expect(mockOnError).toHaveBeenCalledWith(
+ new Error('Failed to connect wallet'),
+ );
+ expect(console.error).toHaveBeenCalledWith(
+ 'Phantom connection error:',
+ 'Some string error',
+ );
+ });
});
diff --git a/src/wallet/components/WalletModal.tsx b/src/wallet/components/WalletModal.tsx
index 2127bb586e..d7fc1b6b19 100644
--- a/src/wallet/components/WalletModal.tsx
+++ b/src/wallet/components/WalletModal.tsx
@@ -1,11 +1,12 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import { useConnect } from 'wagmi';
-import { coinbaseWallet, metaMask } from 'wagmi/connectors';
+import { coinbaseWallet, injected, metaMask } from 'wagmi/connectors';
import { useOnchainKit } from '../../core-react/useOnchainKit';
import { closeSvg } from '../../internal/svg/closeSvg';
import { coinbaseWalletSvg } from '../../internal/svg/coinbaseWalletSvg';
import { defaultAvatarSVG } from '../../internal/svg/defaultAvatarSVG';
import { metamaskSvg } from '../../internal/svg/metamaskSvg';
+import { phantomSvg } from '../../internal/svg/phantomSvg';
import {
background,
border,
@@ -125,6 +126,22 @@ export function WalletModal({
}
}, [connect, onClose, onError, appName, appLogo]);
+ const handlePhantomConnection = useCallback(() => {
+ try {
+ const phantomConnector = injected({
+ target: 'phantom',
+ });
+
+ connect({ connector: phantomConnector });
+ onClose();
+ } catch (error) {
+ console.error('Phantom connection error:', error);
+ onError?.(
+ error instanceof Error ? error : new Error('Failed to connect wallet'),
+ );
+ }
+ }, [connect, onClose, onError]);
+
const handleLinkKeyDown = (
event: React.KeyboardEvent,
url: string,
@@ -278,6 +295,24 @@ export function WalletModal({
{metamaskSvg}
+
+