Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add WalletModal component #1610

Merged
merged 10 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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/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 @@ -228,6 +228,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
},
Comment on lines +231 to +235
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we also want to give playground users the ability to see wallet.display.classic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is needed because there is no component to display. In classic mode we just connect directly using the CB wallet connector

}}
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] ?? '',
Copy link
Contributor

@brendan-defi brendan-defi Nov 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add this env var to site/.env.local.example?

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';
cpcramer marked this conversation as resolved.
Show resolved Hide resolved
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
Loading