> ## Documentation Index
> Fetch the complete documentation index at: https://daehan-base.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Base로 로그인

> Wagmi에서 올바른 SIWE 플로우를 사용하여 Base Account 인증 구현하기

Wagmi를 사용하여 Base Account 프로바이더에 접근하고 올바른 SIWE(Sign-In With Ethereum) 인증 플로우를 따름으로써 Base로 로그인을 구현하는 방법을 알아보세요.

## 사전 요구 사항

이 가이드를 따르기 전에 [Wagmi와 Base Account를 설정](/base-account/framework-integrations/wagmi/setup)했는지 확인하세요.

## 개요

Wagmi에서 Base로 로그인을 구현하려면 다음이 필요합니다:

1. Wagmi에서 Base Account 커넥터 가져오기
2. 커넥터에서 내부 프로바이더 접근
3. `signInWithEthereum` 기능으로 `wallet_connect` 사용
4. 백엔드에서 서명 검증

이는 [사용자 인증 가이드](/base-account/guides/authenticate-users)에 표시된 것과 동일한 플로우를 따르되 Wagmi의 커넥터 시스템과 통합됩니다.

<Tip>
  Wagmi 내에서 최신 버전의 Base Account SDK에 접근하려면 다음 명령어를 사용하여 오버라이드할 수 있습니다:

  ```bash theme={null}
  npm pkg set overrides.@base-org/account="latest"
  ```

  또는 특정 버전을 사용하려면:

  ```bash theme={null}
  npm pkg set overrides.@base-org/account="2.2.0"
  ```

  오버라이드가 적용되도록 `node_modules`와 `package-lock.json`을 삭제하고 새로 설치해야 합니다.
</Tip>

## 구현

### 코드 스니펫

<CodeGroup>
  ```ts 브라우저 (Wagmi + SDK) theme={null}
  import { useState } from 'react'
  import { useConnect, useAccount, useDisconnect } from 'wagmi'
  import { baseAccount } from 'wagmi/connectors'

  export function SignInWithBase() {
    const [isLoading, setIsLoading] = useState(false)
    const [error, setError] = useState<string | null>(null)
    const { isConnected, address } = useAccount()
    const { connectAsync, connectors } = useConnect()
    const { disconnect } = useDisconnect()

    // Base Account 커넥터 찾기
    const baseAccountConnector = connectors.find(
      connector => connector.id === 'baseAccount'
    )

    const handleSignIn = async () => {
      if (!baseAccountConnector) {
        setError('Base Account 커넥터를 찾을 수 없습니다')
        return
      }

      setIsLoading(true)
      setError(null)

      try {
        // 1 — 새로운 nonce 가져오기 (로컬에서 생성하거나 백엔드에서 미리 가져오기)
        const nonce = window.crypto.randomUUID().replace(/-/g, '')
        // 또는 서버에서 미리 가져오기
        // const nonce = await fetch('/auth/nonce').then(r => r.text())

        // 2 — 연결하고 프로바이더 가져오기
        await connectAsync({ connector: baseAccountConnector })
        const provider = baseAccountConnector.provider

        // 3 — wallet_connect로 인증
        const authResult = await provider.request({
          method: 'wallet_connect',
          params: [{
            version: '1',
            capabilities: {
              signInWithEthereum: { 
                nonce, 
                chainId: '0x2105' // Base 메인넷 - 8453
              }
            }
          }]
        })

        const { accounts } = authResult
        const { address, capabilities } = accounts[0]
        const { message, signature } = capabilities.signInWithEthereum

        // 4 — 백엔드에서 검증
        await fetch('/auth/verify', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ address, message, signature })
        })
      } catch (err: any) {
        console.error(`err ${err}`)
        setError(err.message || '로그인 실패')
      } finally {
        setIsLoading(false)
      }
    }

    if (isConnected) {
      return (
        <div className="flex items-center gap-4">
          <span className="font-mono text-sm">{address}</span>
          <button onClick={() => disconnect()}>로그아웃</button>
        </div>
      )
    }

    return (
      <button onClick={handleSignIn} disabled={isLoading}>
        {isLoading ? '로그인 중...' : 'Base로 로그인'}
      </button>
    )
  }
  ```

  ```ts 백엔드 (Viem) theme={null}
  import { createPublicClient, http } from 'viem';
  import { base } from 'viem/chains';

  const client = createPublicClient({ chain: base, transport: http() });

  export async function verifySig(req, res) {
    const { address, message, signature } = req.body;
    const valid = await client.verifyMessage({ address, message, signature });
    if (!valid) return res.status(401).json({ error: 'Invalid signature' });
    // 세션 / JWT 생성
    res.json({ ok: true });
  }
  ```
</CodeGroup>

### 3. 미리 구축된 버튼 컴포넌트 사용

공식 `SignInWithBaseButton` 버튼 컴포넌트를 사용할 수도 있습니다:

```tsx theme={null}
// components/SignInButton.tsx
import { SignInWithBaseButton } from '@base-org/account-ui/react'
import { useConnect } from 'wagmi'

export function SignInButton() {
  const { connectAsync, connectors } = useConnect()

  const handleSignIn = async () => {
    const baseAccountConnector = connectors.find(
      connector => connector.id === 'baseAccount'
    )

    if (!baseAccountConnector) return

    try {
      // Nonce 생성
      const nonce = window.crypto.randomUUID().replace(/-/g, '')

      // 연결하고 프로바이더 가져오기
      await connectAsync({ connector: baseAccountConnector })
      const provider = baseAccountConnector.provider

      // SIWE 인증 수행
      const authResult = await provider.request({
        method: 'wallet_connect',
        params: [{
          version: '1',
          capabilities: {
            signInWithEthereum: { 
              nonce, 
              chainId: '0x2105'
            }
          }
        }]
      })

      // 서명 추출 및 검증
      const { accounts } = authResult
      const { address, capabilities } = accounts[0]
      const { message, signature } = capabilities.signInWithEthereum

      // 백엔드로 전송하여 검증
      await fetch('/auth/verify', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ address, message, signature })
      })
    } catch (error) {
      console.error('Authentication failed:', error)
    }
  }

  return (
    <SignInWithBaseButton
      colorScheme="light"
      onClick={handleSignIn}
    />
  )
}
```

<Warning>
  **브랜드 가이드라인을 준수해 주세요**

  `SignInWithBaseButton`을 사용할 경우 애플리케이션 전체의 일관성을 위해 Base 브랜드 가이드라인을 준수해 주세요.
</Warning>
