Skip to content

Commit

Permalink
feat: Add WalletModal component (#1610)
Browse files Browse the repository at this point in the history
  • Loading branch information
cpcramer authored Nov 25, 2024
1 parent 9426167 commit 02d3aac
Show file tree
Hide file tree
Showing 23 changed files with 1,115 additions and 315 deletions.
5 changes: 5 additions & 0 deletions .changeset/chatty-shirts-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@coinbase/onchainkit': patch
---

-**feat**: Add `WalletModal` component. By @cpcramer #1610
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"react-dom": "^18"
},
"dependencies": {
"@rainbow-me/rainbowkit": "^2.1.3",
"@tanstack/react-query": "^5",
"clsx": "^2.1.1",
"graphql": "^14 || ^15 || ^16",
Expand Down
Binary file modified playground/nextjs-app-router/bun.lockb
Binary file not shown.
5 changes: 5 additions & 0 deletions playground/nextjs-app-router/components/AppProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ export const AppProvider = ({ children }: { children: React.ReactNode }) => {
theme: componentTheme === 'none' ? undefined : componentTheme,
},
paymaster: paymasters?.[chainId || 8453]?.url,
wallet: {
display: 'modal',
termsUrl: 'https://www.coinbase.com/legal/cookie', // URL to the terms of service for the wallet modal
privacyUrl: 'https://www.coinbase.com/legal/privacy', // URL to the privacy policy for the wallet modal
},
}}
projectId={ENVIRONMENT_VARIABLES[ENVIRONMENT.PROJECT_ID]}
schemaId="0xf8b05c79f090979bf4a80270aba232dff11a10d9ca55c4f88de95317970f0de9"
Expand Down
18 changes: 17 additions & 1 deletion playground/nextjs-app-router/components/OnchainProviders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { ReactNode } from 'react';
import { http, createConfig } from 'wagmi';
import { WagmiProvider } from 'wagmi';
import { base, baseSepolia } from 'wagmi/chains';
import { coinbaseWallet } from 'wagmi/connectors';
import { coinbaseWallet, walletConnect } from 'wagmi/connectors';

export const config = createConfig({
chains: [base, baseSepolia],
Expand All @@ -24,6 +24,17 @@ export const config = createConfig({
appName: 'OnchainKit',
preference: 'eoaOnly',
}),
walletConnect({
projectId:
ENVIRONMENT_VARIABLES[ENVIRONMENT.WALLETCONNECT_PROJECT_ID] ?? '',
showQrModal: true,
metadata: {
name: 'OnchainKit',
description: 'build onchain',
url: 'https://onchainkit.xyz/',
icons: [],
},
}),
],
});

Expand All @@ -43,6 +54,11 @@ function OnchainProviders({ children }: { children: ReactNode }) {
mode: 'auto',
theme: 'default',
},
wallet: {
display: 'modal', // 'modal' || 'classic"
termsUrl: 'https://www.coinbase.com/legal/cookie', // URL to the terms of service for the wallet modal
privacyUrl: 'https://www.coinbase.com/legal/privacy', // URL to the privacy policy for the wallet modal
},
}}
projectId={ENVIRONMENT_VARIABLES[ENVIRONMENT.PROJECT_ID]}
schemaId="0xf8b05c79f090979bf4a80270aba232dff11a10d9ca55c4f88de95317970f0de9"
Expand Down
3 changes: 3 additions & 0 deletions playground/nextjs-app-router/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const ENVIRONMENT = {
API_KEY: 'API_KEY',
ENVIRONMENT: 'ENVIRONMENT',
PROJECT_ID: 'PROJECT_ID',
WALLETCONNECT_PROJECT_ID: 'WALLETCONNECT_PROJECT_ID',
RESERVOIR_API_KEY: 'RESERVOIR_API_KEY',
} as const;

Expand All @@ -23,5 +24,7 @@ export const ENVIRONMENT_VARIABLES: Record<EnvironmentKey, string | undefined> =
[ENVIRONMENT.API_KEY]: process.env.NEXT_PUBLIC_OCK_API_KEY,
[ENVIRONMENT.ENVIRONMENT]: process.env.NEXT_PUBLIC_VERCEL_ENV,
[ENVIRONMENT.PROJECT_ID]: process.env.NEXT_PUBLIC_PROJECT_ID,
[ENVIRONMENT.WALLETCONNECT_PROJECT_ID]:
process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID,
[ENVIRONMENT.RESERVOIR_API_KEY]: process.env.NEXT_PUBLIC_RESERVOIR_API_KEY,
};
1 change: 0 additions & 1 deletion playground/nextjs-app-router/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-switch": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
"@rainbow-me/rainbowkit": "^2.1.3",
"@reservoir0x/reservoir-sdk": "^2.4.25",
"@tanstack/react-query": "^5.51.11",
"class-variance-authority": "^0.7.0",
Expand Down
5 changes: 5 additions & 0 deletions src/OnchainKitConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ export const ONCHAIN_KIT_CONFIG: OnchainKitConfig = {
theme: null,
},
paymaster: null,
wallet: {
display: null,
termsUrl: null,
privacyUrl: null,
},
},
rpcUrl: null,
schemaId: null,
Expand Down
64 changes: 37 additions & 27 deletions src/OnchainKitProvider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { useConfig } from 'wagmi';
import { mock } from 'wagmi/connectors';
import { setOnchainKitConfig } from './OnchainKitConfig';
import { OnchainKitProvider } from './OnchainKitProvider';
import { COINBASE_VERIFIED_ACCOUNT_SCHEMA_ID } from './identity/constants';
import type { EASSchemaUid } from './identity/types';
import { useOnchainKit } from './useOnchainKit';
import { useProviderDependencies } from './useProviderDependencies';
Expand Down Expand Up @@ -184,6 +183,11 @@ describe('OnchainKitProvider', () => {
theme: 'default',
},
paymaster: paymasterUrl,
wallet: {
display: 'classic',
termsUrl: 'https://base.org/terms-of-service',
privacyUrl: 'https://base.org/privacy-policy',
},
},
chain: base,
rpcUrl: null,
Expand Down Expand Up @@ -214,22 +218,32 @@ describe('OnchainKitProvider', () => {
theme: 'default',
},
paymaster: null,
wallet: {
display: 'classic',
termsUrl: 'https://base.org/terms-of-service',
privacyUrl: 'https://base.org/privacy-policy',
},
},
}),
);
});
});

it('should use default values for appearance when config is provided', async () => {
it('should use custom values when override in config is provided', async () => {
const customConfig = {
appearance: {},
appearance: {
name: 'custom name',
logo: 'https://example.com/logo.png',
},
paymaster: 'https://example.com',
};

render(
<WagmiProvider config={mockConfig}>
<QueryClientProvider client={queryClient}>
<OnchainKitProvider
chain={base}
schemaId={schemaId}
apiKey={apiKey}
config={customConfig}
>
Expand All @@ -247,28 +261,33 @@ describe('OnchainKitProvider', () => {
chain: base,
config: {
appearance: {
logo: appLogo,
name: appName,
name: 'custom name',
logo: 'https://example.com/logo.png',
mode: 'auto',
theme: 'default',
},
paymaster: paymasterUrl,
paymaster: 'https://example.com',
wallet: {
display: 'classic',
termsUrl: 'https://base.org/terms-of-service',
privacyUrl: 'https://base.org/privacy-policy',
},
},
projectId: null,
rpcUrl: null,
schemaId: COINBASE_VERIFIED_ACCOUNT_SCHEMA_ID,
schemaId: schemaId,
}),
);
});
});

it('should use custom values when override in config is provided', async () => {
it('should use custom wallet config when provided', async () => {
const customConfig = {
appearance: {
name: 'custom name',
logo: 'https://example.com/logo.png',
wallet: {
display: 'modal',
termsUrl: 'https://example.com/terms',
privacyUrl: 'https://example.com/privacy',
},
paymaster: 'https://example.com',
};

render(
Expand All @@ -277,7 +296,6 @@ describe('OnchainKitProvider', () => {
<OnchainKitProvider
chain={base}
schemaId={schemaId}
apiKey={apiKey}
config={customConfig}
>
<TestComponent />
Expand All @@ -289,21 +307,13 @@ describe('OnchainKitProvider', () => {
await waitFor(() => {
expect(setOnchainKitConfig).toHaveBeenCalledWith(
expect.objectContaining({
address: null,
apiKey: apiKey,
chain: base,
config: {
appearance: {
name: 'custom name',
logo: 'https://example.com/logo.png',
mode: 'auto',
theme: 'default',
config: expect.objectContaining({
wallet: {
display: 'modal',
termsUrl: 'https://example.com/terms',
privacyUrl: 'https://example.com/privacy',
},
paymaster: 'https://example.com',
},
projectId: null,
rpcUrl: null,
schemaId: schemaId,
}),
}),
);
});
Expand Down
6 changes: 6 additions & 0 deletions src/OnchainKitProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createContext, useMemo } from 'react';
import { WagmiProvider } from 'wagmi';
import { ONCHAIN_KIT_CONFIG, setOnchainKitConfig } from './OnchainKitConfig';
import { DEFAULT_PRIVACY_URL, DEFAULT_TERMS_URL } from './constants';
import { createWagmiConfig } from './createWagmiConfig';
import { COINBASE_VERIFIED_ACCOUNT_SCHEMA_ID } from './identity/constants';
import { checkHashLength } from './internal/utils/checkHashLength';
Expand Down Expand Up @@ -47,6 +48,11 @@ export function OnchainKitProvider({
theme: config?.appearance?.theme ?? 'default',
},
paymaster: config?.paymaster || defaultPaymasterUrl,
wallet: {
display: config?.wallet?.display ?? 'classic',
termsUrl: config?.wallet?.termsUrl || DEFAULT_TERMS_URL,
privacyUrl: config?.wallet?.privacyUrl || DEFAULT_PRIVACY_URL,
},
},
projectId: projectId ?? null,
rpcUrl: rpcUrl ?? null,
Expand Down
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export enum Capabilities {
AuxiliaryFunds = 'auxiliaryFunds',
PaymasterService = 'paymasterService',
}
export const DEFAULT_PRIVACY_URL = 'https://base.org/privacy-policy';
export const DEFAULT_TERMS_URL = 'https://base.org/terms-of-service';
4 changes: 2 additions & 2 deletions src/internal/svg/closeSvg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { icon } from '../../styles/theme';
export const closeSvg = (
<svg
aria-label="ock-closeSvg"
width="16"
height="16"
width="12"
height="12"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
Expand Down
20 changes: 20 additions & 0 deletions src/internal/svg/coinbaseWalletSvg.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const coinbaseWalletSvg = (
<svg
width="100%"
height="100%"
viewBox="0 0 146 146"
fill="none"
xmlns="http://www.w3.org/2000/svg"
role="img"
aria-label="Coinbase Wallet Logo"
>
<title>Coinbase Wallet Logo</title>
<rect width="146" height="146" fill="#0052FF" />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M21.9 73C21.9 102.053 45.1466 125.3 74.2 125.3C103.253 125.3 126.5 102.053 126.5 73C126.5 43.9466 103.253 20.7 74.2 20.7C45.1466 20.7 21.9 43.9466 21.9 73ZM60.5 54.75C58.5673 54.75 57 56.3173 57 58.25V87.75C57 89.6827 58.5673 91.25 60.5 91.25H87.9C89.8327 91.25 91.4 89.6827 91.4 87.75V58.25C91.4 56.3173 89.8327 54.75 87.9 54.75H60.5Z"
fill="white"
/>
</svg>
);
35 changes: 35 additions & 0 deletions src/internal/svg/walletConnectSvg.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export const walletConnectSvg = (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
role="img"
aria-label="WalletConnect Logo"
>
<title>WalletConnect Logo</title>
<mask
id="mask0_1630_9125"
style={{ maskType: 'luminance' }}
maskUnits="userSpaceOnUse"
x="0"
y="0"
width="16"
height="16"
>
<path d="M0 0H16V16H0V0Z" fill="white" />
</mask>
<g mask="url(#mask0_1630_9125)">
<path
d="M15.5195 8.02002C15.5195 12.1622 12.1617 15.52 8.01953 15.52C3.8774 15.52 0.519531 12.1622 0.519531 8.02002C0.519531 3.87788 3.8774 0.52002 8.01953 0.52002C12.1617 0.52002 15.5195 3.87788 15.5195 8.02002Z"
fill="#3396FF"
stroke="#66B1FF"
/>
<path
d="M4.91197 5.97351C6.6279 4.30017 9.41005 4.30017 11.126 5.97351L11.3325 6.1749C11.4183 6.25855 11.4183 6.39421 11.3325 6.47785L10.6261 7.16678C10.5831 7.2086 10.5136 7.2086 10.4707 7.16678L10.1865 6.88964C8.9894 5.72229 7.04855 5.72229 5.85143 6.88964L5.54707 7.18643C5.50417 7.22825 5.43463 7.22825 5.39173 7.18643L4.68528 6.4975C4.59946 6.41385 4.59946 6.2782 4.68528 6.19455L4.91197 5.97351ZM12.587 7.39824L13.2158 8.01137C13.3016 8.09502 13.3016 8.23068 13.2158 8.31433L10.3807 11.079C10.2949 11.1627 10.1558 11.1627 10.07 11.079L8.05783 9.11685C8.03638 9.09592 8.00161 9.09592 7.98016 9.11685L5.96801 11.079C5.88223 11.1627 5.74312 11.1627 5.65731 11.079L2.82216 8.31429C2.73636 8.23064 2.73636 8.09498 2.82216 8.01133L3.45091 7.3982C3.53671 7.31455 3.67582 7.31455 3.76161 7.3982L5.7738 9.36038C5.79525 9.38131 5.83002 9.38131 5.85147 9.36038L7.86358 7.3982C7.94936 7.31451 8.08847 7.31451 8.17428 7.3982L10.1865 9.36038C10.2079 9.38131 10.2427 9.38131 10.2641 9.36038L12.2763 7.39824C12.3621 7.31455 12.5012 7.31455 12.587 7.39824Z"
fill="white"
/>
</g>
</svg>
);
2 changes: 1 addition & 1 deletion src/styles/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const pressable = {
default:
'cursor-pointer ock-bg-default active:bg-[var(--ock-bg-default-active)] hover:bg-[var(--ock-bg-default-hover)]',
alternate:
'cursor-pointer ock-bg-alternate active:bg-[var(--ock-bg-alternate-active)] hover:[var(--ock-bg-alternate-hover)]',
'cursor-pointer ock-bg-alternate active:bg-[var(--ock-bg-alternate-active)] hover:bg-[var(--ock-bg-alternate-hover)]',
inverse:
'cursor-pointer ock-bg-inverse active:bg-[var(--ock-bg-inverse-active)] hover:bg-[var(--ock-bg-inverse-hover)]',
primary:
Expand Down
7 changes: 7 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export type AppConfig = {
theme?: ComponentTheme | null; // Optionally sets the visual style for components
};
paymaster?: string | null; // Paymaster URL for gas sponsorship
wallet?: {
display?: ConnectWalletDisplay | null; // Determines the display style of the wallet modal
termsUrl?: string | null; // URL to the terms of service for the wallet modal
privacyUrl?: string | null; // URL to the privacy policy for the wallet modal
};
};

export type CreateWagmiConfigParams = {
Expand Down Expand Up @@ -94,3 +99,5 @@ export type OnchainKitProviderReact = {
export type UseCapabilitiesSafeParams = {
chainId: number;
};

export type ConnectWalletDisplay = 'modal' | 'classic';
Loading

0 comments on commit 02d3aac

Please sign in to comment.