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
2 changes: 1 addition & 1 deletion MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ ie.
- `SequenceWalletProvider` (previously KitWalletProvider)
- `SequenceHooksProvider`

Also for builder integration KitPreviewProvider was renamed `SequenceConnectPreviewProvider`
Also for builder integration KitPreviewProvider was renamed `SequenceConnectInlineProvider`

### Hooks

Expand Down
2 changes: 2 additions & 0 deletions examples/react/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { BrowserRouter, Route, Routes } from 'react-router-dom'

import { Homepage } from './components/Homepage'
import { ImmutableCallback } from './components/ImmutableCallback'
import { InlineDemo } from './components/InlineDemo'
import { XAuthCallback } from './components/XAuthCallback'
import { checkoutConfig, config } from './config'

Expand All @@ -16,6 +17,7 @@ export const App = () => {
<BrowserRouter>
<Routes>
<Route path="/" element={<Homepage />} />
<Route path="/inline" element={<InlineDemo />} />
<Route path="/auth-callback" element={<ImmutableCallback />} />
<Route path="/auth-callback-X" element={<XAuthCallback />} />
</Routes>
Expand Down
4 changes: 4 additions & 0 deletions examples/react/src/components/Homepage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useOpenConnectModal, useWallets, WalletType } from '@0xsequence/connect
import { Button, Card, CheckmarkIcon, Image, Text } from '@0xsequence/design-system'
import { clsx } from 'clsx'
import { Footer } from 'example-shared-components'
import { Link } from 'react-router-dom'

import { Connected } from './Connected'

Expand Down Expand Up @@ -34,6 +35,9 @@ export const Homepage = () => {

<div className="flex gap-2 flex-row items-center">
<Button onClick={onClickConnect} variant="feature" label="Connect" />
<Link to="/inline">
<Button variant="primary" label="Inline Demo" />
</Link>
</div>

<div className="flex gap-2 flex-col px-4 mt-10 w-full max-w-[480px]">
Expand Down
60 changes: 60 additions & 0 deletions examples/react/src/components/InlineDemo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { SequenceConnectInline, type SequenceConnectConfig } from '@0xsequence/connect'
import { Text } from '@0xsequence/design-system'
import { Footer } from 'example-shared-components'
import { useMemo } from 'react'
import { useNavigate } from 'react-router-dom'

import { config } from '../config'

export const InlineDemo = () => {
const navigate = useNavigate()

const inlineConfig: SequenceConnectConfig = useMemo(
() => ({
...config,
connectConfig: {
...config.connectConfig,
onConnectSuccess: (address: string) => {
console.log('Connected successfully with address:', address)
// Redirect to homepage after successful connection
navigate('/')
}
}
}),
[navigate]
)

return (
<main className="flex flex-col h-screen">
<div className="flex-1 flex items-center justify-center p-8">
<div className="flex flex-row gap-8 max-w-6xl w-full">
{/* Left side - Description */}
<div className="flex-1 flex flex-col justify-center gap-4">
<Text variant="xlarge" fontWeight="bold" color="primary">
Inline Connect Demo
</Text>
<Text variant="large" color="secondary">
This demonstrates the SequenceConnectInline component, which renders the connect UI inline within your layout
instead of in a modal.
</Text>
<Text variant="normal" color="muted">
Perfect for custom layouts, embedded wallet experiences, or when you want the connect UI to be part of your page
flow.
</Text>
<Text variant="small" color="muted" className="mt-4">
Connect with your wallet and you'll be redirected to the homepage automatically.
</Text>
</div>

{/* Right side - Inline Connect UI */}
<div className="flex-1 flex items-center justify-center">
<div className="w-full max-w-[390px]">
<SequenceConnectInline config={inlineConfig} />
</div>
</div>
</div>
</div>
<Footer />
</main>
)
}
77 changes: 77 additions & 0 deletions packages/connect/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Sequence Web SDK 🧰 is a library enabling developers to easily integrate web3
- Connect to popular web3 wallets eg: walletConnect, metamask ! 🦊 ⛓️
- Full-fledged embedded wallet for coins and collectibles 👛 🖼️ 🪙
- Fiat onramp 💵 💶 💴 💷
- Inline connect UI for custom layouts and embedded experiences 🎨

View the [demo](https://0xsequence.github.io/web-sdk)! 👀

Expand Down Expand Up @@ -52,6 +53,7 @@ interface CreateConfigOptions {
chainId: number
}>
ethAuth?: EthAuthSettings
onConnectSuccess?: (address: string) => void // callback fired when wallet connects

wagmiConfig?: WagmiConfig // optional wagmiConfig overrides

Expand Down Expand Up @@ -243,6 +245,76 @@ const MyReactComponent = () => {
}
```

### Inline Connect UI

<div align="center">
<img src="public/docs/inline-connect.png" alt="Inline Connect UI">
</div>

Instead of using a modal, you can render the connect UI inline within your layout using the `SequenceConnectInline` component. This is perfect for custom layouts, embedded wallet experiences, or when you want the connect UI to be part of your page flow.

```js
import { SequenceConnectInline, createConfig } from '@0xsequence/connect'
import { useNavigate } from 'react-router-dom'

const config = createConfig('waas', {
projectAccessKey: '<your-project-access-key>',
chainIds: [1, 137],
defaultChainId: 1,
appName: 'Demo Dapp',
waasConfigKey: '<your-waas-config-key>',

// Optional: callback fired when wallet connects successfully
onConnectSuccess: (address) => {
console.log('Connected wallet:', address)
// Redirect or perform other actions
},

google: { clientId: '<your-google-client-id>' },
email: true
})

function InlinePage() {
return (
<div className="my-custom-layout">
<h1>Connect Your Wallet</h1>
<SequenceConnectInline config={config} />
</div>
)
}
```

#### Key Differences from Modal UI:

- **No padding/margins**: The inline UI removes the default padding designed for modal display
- **Full width**: The component fills its container width
- **No modal backdrop**: Renders directly in your layout
- **Custom positioning**: You control the placement with your own CSS/layout

#### Advanced: Using SequenceConnectInlineProvider

For more control, you can use the lower-level `SequenceConnectInlineProvider`:

```js
import { SequenceConnectInlineProvider } from '@0xsequence/connect'
import { WagmiProvider } from 'wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

const queryClient = new QueryClient()

function App() {
return (
<WagmiProvider config={wagmiConfig}>
<QueryClientProvider client={queryClient}>
<SequenceConnectInlineProvider config={connectConfig}>
<YourContent />
</SequenceConnectInlineProvider>
</QueryClientProvider>
</WagmiProvider>
)
}
```

## Hooks

### useOpenConnectModal
Expand Down Expand Up @@ -294,6 +366,11 @@ The settings are described in more detailed in the Sequence Web SDK documentatio
}
],
readOnlyNetworks: [10],
// callback fired when wallet connects successfully
onConnectSuccess: (address) => {
console.log('Wallet connected:', address)
// Perform actions like redirecting, analytics tracking, etc.
},
}

<SequenceConnectProvider config={connectConfig}>
Expand Down
25 changes: 15 additions & 10 deletions packages/connect/src/components/Connect/Connect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const SEQUENCE_UNIVERSAL_CONNECTOR_NAME = 'Sequence'
interface ConnectProps extends SequenceConnectProviderProps {
emailConflictInfo?: FormattedEmailConflictInfo | null
onClose: () => void
isPreview?: boolean
isInline?: boolean
}

export const Connect = (props: ConnectProps) => {
Expand All @@ -52,7 +52,7 @@ export const Connect = (props: ConnectProps) => {
const { analytics } = useAnalyticsContext()
const { hideExternalConnectOptions, hideConnectedWallets, hideSocialConnectOptions } = useWalletSettings()

const { onClose, emailConflictInfo, config = {} as ConnectConfig, isPreview = false } = props
const { onClose, emailConflictInfo, config = {} as ConnectConfig, isInline = false } = props
const { signIn = {} } = config
const storage = useStorage()

Expand Down Expand Up @@ -256,6 +256,11 @@ export const Connect = (props: ConnectProps) => {
connect(
{ connector },
{
onSuccess: result => {
if (result?.accounts[0]) {
config.onConnectSuccess?.(result.accounts[0])
}
},
onSettled: result => {
setLastConnectedWallet(result?.accounts[0])
}
Expand Down Expand Up @@ -377,14 +382,14 @@ export const Connect = (props: ConnectProps) => {
: `Something went wrong. (${waasStatusData.errorResponse.msg})`

return (
<div className="p-4">
<div className={isInline ? 'p-0' : 'p-4'}>
<div
className="flex flex-col justify-center text-primary items-center font-medium"
style={{
marginTop: '2px'
marginTop: isInline ? '0' : '2px'
}}
>
<TitleWrapper isPreview={isPreview}>
<TitleWrapper isInline={isInline}>
<Text color="secondary">
{isLoading
? `Connecting...`
Expand All @@ -406,14 +411,14 @@ export const Connect = (props: ConnectProps) => {
}

return (
<div className="p-4">
<div className={isInline ? 'p-0' : 'p-4'}>
<div
className="flex flex-col justify-center text-primary items-center font-medium"
style={{
marginTop: '2px'
marginTop: isInline ? '0' : '2px'
}}
>
<TitleWrapper isPreview={isPreview}>
<TitleWrapper isInline={isInline}>
<Text color="secondary">
{isLoading
? `Connecting...`
Expand Down Expand Up @@ -595,8 +600,8 @@ export const Connect = (props: ConnectProps) => {
)
}

const TitleWrapper = ({ children, isPreview }: { children: ReactNode; isPreview: boolean }) => {
if (isPreview) {
const TitleWrapper = ({ children, isInline }: { children: ReactNode; isInline: boolean }) => {
if (isInline) {
return <>{children}</>
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,30 @@ import type { ReactNode } from 'react'
import { WagmiProvider, type State } from 'wagmi'

import type { SequenceConnectConfig } from '../../config/createConfig.js'
import { SequenceConnectPreviewProvider } from '../SequenceConnectPreviewProvider/SequenceConnectPreviewProvider.js'
import { SequenceConnectInlineProvider } from '../SequenceConnectInlineProvider/SequenceConnectInlineProvider.js'

const defaultQueryClient = new QueryClient()

interface SequenceConnectPreviewProps {
export interface SequenceConnectInlineProps {
config: SequenceConnectConfig
queryClient?: QueryClient
initialState?: State | undefined
children: ReactNode
children?: ReactNode
}

/**
* @internal
* Preview version of SequenceConnect component.
* This component should only be used for testing purposes.
* It provides the same functionality as SequenceConnect but only for preview purposes.
* Inline version of SequenceConnect component.
* This component renders the connect UI inline within your layout instead of in a modal.
* Ideal for embedded wallet experiences or custom layouts.
*/
export const SequenceConnectPreview = (props: SequenceConnectPreviewProps) => {
export const SequenceConnectInline = (props: SequenceConnectInlineProps) => {
const { config, queryClient, initialState, children } = props
const { connectConfig, wagmiConfig } = config

return (
<WagmiProvider config={wagmiConfig} initialState={initialState}>
<QueryClientProvider client={queryClient || defaultQueryClient}>
<SequenceConnectPreviewProvider
config={{
...connectConfig,
hideConnectedWallets: true
}}
>
{children}
</SequenceConnectPreviewProvider>
<SequenceConnectInlineProvider config={connectConfig}>{children}</SequenceConnectInlineProvider>
</QueryClientProvider>
</WagmiProvider>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './SequenceConnectInline.js'
Loading