Skip to main content

Documentation Index

Fetch the complete documentation index at: https://daehan-base.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

이 퀵스타트는 Base Account SDK를 사용하여 Next.js 앱에 Base 로그인(SIWB)과 Base Pay를 추가하는 최소한의 코드를 보여줍니다.

1. 새 Next.js 앱 생성

새로 시작하는 경우, 새 Next.js 앱을 생성합니다:
npx create-next-app@latest base-account-quickstart
cd base-account-quickstart
설정 중 프롬프트가 나타나면 기본 옵션을 선택하거나 필요에 따라 커스터마이즈 하세요. 이 퀵스타트에서는 기본 설정으로 충분합니다.

2. SDK 설치

npm install @base-org/account @base-org/account-ui
피어 의존성 오류가 발생하나요?피어 의존성 오류가 발생하면 --legacy-peer-deps 플래그를 사용하세요.

3. 메인 컴포넌트 생성

app/page.tsx (TypeScript를 사용하지 않는 경우 app/page.js)의 내용을 아래 컴포넌트로 교체하세요:
app/page.tsx
'use client';

import React, { useState } from 'react';
import { createBaseAccountSDK, pay, getPaymentStatus } from '@base-org/account';
import { SignInWithBaseButton, BasePayButton } from '@base-org/account-ui/react';

export default function Home() {
  const [isSignedIn, setIsSignedIn] = useState(false);
  const [paymentStatus, setPaymentStatus] = useState('');
  const [paymentId, setPaymentId] = useState('');
  const [theme, setTheme] = useState('light');

  // Initialize SDK
  const sdk = createBaseAccountSDK(
    {
      appName: 'Base Account Quick-start',
      appLogoUrl: 'https://base.org/logo.png',
    }
  );

  // Optional sign-in step – not required for `pay()`, but useful to get the user address
  const handleSignIn = async () => {
    try {
      await sdk.getProvider().request({ method: 'wallet_connect' });
      setIsSignedIn(true);
    } catch (error) {
      console.error('Sign in failed:', error);
    }
  };

  // One-tap USDC payment using the pay() function
  const handlePayment = async () => {
    try {
      const { id } = await pay({
        amount: '0.01', // USD – SDK quotes equivalent USDC
        to: '0xRecipientAddress', // Replace with your recipient address
        testnet: true // set to false or omit for Mainnet
      });

      setPaymentId(id);
      setPaymentStatus('Payment initiated! Click "Check Status" to see the result.');
    } catch (error) {
      console.error('Payment failed:', error);
      setPaymentStatus('Payment failed');
    }
  };

  // Check payment status using stored payment ID
  const handleCheckStatus = async () => {
    if (!paymentId) {
      setPaymentStatus('No payment ID found. Please make a payment first.');
      return;
    }

    try {
      const { status } = await getPaymentStatus({ id: paymentId });
      setPaymentStatus(`Payment status: ${status}`);
    } catch (error) {
      console.error('Status check failed:', error);
      setPaymentStatus('Status check failed');
    }
  };

  const toggleTheme = () => {
    setTheme(theme === 'light' ? 'dark' : 'light');
  };

  const dark = theme === 'dark';
  const styles = {
    container: { minHeight: '100vh', backgroundColor: dark ? '#111' : '#fff', color: dark ? '#fff' : '#000', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '20px' },
    card: { backgroundColor: dark ? '#222' : '#f9f9f9', borderRadius: '12px', padding: '30px', maxWidth: '400px', textAlign: 'center' },
    title: { fontSize: '24px', fontWeight: 'bold', marginBottom: '10px', color: dark ? '#fff' : '#00f' },
    subtitle: { fontSize: '16px', color: dark ? '#aaa' : '#666', marginBottom: '30px' },
    themeToggle: { position: 'absolute', top: '20px', right: '20px', background: 'none', border: 'none', cursor: 'pointer', fontSize: '18px' },
    buttonGroup: { display: 'flex', flexDirection: 'column', gap: '16px', alignItems: 'center' },
    status: { marginTop: '20px', padding: '12px', backgroundColor: dark ? '#333' : '#f0f0f0', borderRadius: '8px', fontSize: '14px' },
    signInStatus: { marginTop: '8px', fontSize: '14px', color: dark ? '#0f0' : '#060' }
  };

  return (
    <div style={styles.container}>
      <button onClick={toggleTheme} style={styles.themeToggle}>
        {theme === 'light' ? '🌙' : '☀️'}
      </button>
      
      <div style={styles.card}>
        <h1 style={styles.title}>Base Account</h1>
        <p style={styles.subtitle}>Experience seamless crypto payments</p>
        
        <div style={styles.buttonGroup}>
          <SignInWithBaseButton 
            align="center"
            variant="solid"
            colorScheme={theme}
            size="medium"
            onClick={handleSignIn}
          />
          
          {isSignedIn && (
            <div style={styles.signInStatus}>
              ✅ Connected to Base Account
            </div>
          )}
          
          <BasePayButton 
            colorScheme={theme}
            onClick={handlePayment}
          />
          
          {paymentId && (
            <button 
              onClick={handleCheckStatus}
              style={{
                padding: '12px 24px',
                backgroundColor: theme === 'dark' ? '#374151' : '#f3f4f6',
                color: theme === 'dark' ? '#ffffff' : '#1f2937',
                border: `1px solid ${theme === 'dark' ? '#6b7280' : '#d1d5db'}`,
                borderRadius: '8px',
                cursor: 'pointer',
                fontSize: '14px'
              }}
            >
              Check Payment Status
            </button>
          )}
        </div>

        {paymentStatus && (
          <div style={styles.status}>
            {paymentStatus}
          </div>
        )}
      </div>
    </div>
  );
}
참고:0xRecipientAddress를 실제 수신자 주소로 교체해야 합니다.
Base Pay와 SIWB는 독립적입니다Base Pay를 사용하기 위해 SIWB를 반드시 사용할 필요는 없습니다. 추가 설정 없이 pay() 함수만 호출하면 됩니다.

4. 앱 실행

npm run dev
http://localhost:3000을 열고, Sign in with Base (선택 사항)를 클릭한 후 Pay를 클릭하고 트랜잭션을 승인하면 Base Sepolia에서 5 USDC를 전송 완료! 🎉 참고: 기존 Next.js 앱이 있는 경우, SDK(npm install @base-org/account @base-org/account-ui)만 설치하고 위 컴포넌트를 프로젝트에 추가하면 됩니다. 다른 React 프레임워크에서도 이 컴포넌트를 적절히 응용할 수 있습니다.

다음 단계

브랜드 가이드라인을 준수해 주세요SignInWithBaseButton 또는 BasePayButton을 사용하려면 애플리케이션 전반의 일관성을 위해 Base 브랜드 가이드라인을 준수해 주세요.