Skip to main content
애플리케이션에 직접 임베드된 앱별 지갑 계정을 제공하는 서브 어카운트를 생성하고 관리하는 방법을 알아보세요.

개요

서브 어카운트를 통해 애플리케이션 내에서 사용자를 위한 전용 지갑 계정을 프로비저닝할 수 있습니다. 이 계정들은 사용자의 메인 Base Account에 의해 제어되며, 사용자의 상호작용 시 패스키 프롬프트나 팝업이 없어 향상된 사용자 경험을 제공합니다. 사용자는 account.base.app에서 모든 서브 어카운트를 관리할 수 있습니다.
서브 어카운트의 라이브 데모를 보려면 서브 어카운트 데모를 확인하세요.

달성할 내용

이 가이드를 마치면 다음을 할 수 있습니다:
  • Base Account와 서브 어카운트의 작동 방식 이해
  • 사용자를 위한 새 서브 어카운트 생성
  • 기존 서브 어카운트 조회 및 관리
  • Privy 프로젝트에 서브 어카운트 구현
이 가이드의 코드 스니펫은 다음 예제 프로젝트를 기반으로 합니다:

설정

설정 가이드를 따라 Base Account와 함께 Privy를 설정하세요.

구현

컴포넌트 설정

"use client";

import { useState, useMemo } from "react";
import { useWallets } from "@privy-io/react-auth";

const SubAccounts = () => {
  const { wallets } = useWallets();
  const [subAccounts, setSubAccounts] = useState<
    {
      address: string;
      factory: string;
      factoryData: string;
    }[]
  >([]);
  const [isLoading, setIsLoading] = useState(false);

  // Base Account 지갑 찾기
  const baseAccount = useMemo(() => {
    return wallets.find((wallet) => wallet.walletClientType === 'base_account');
  }, [wallets]);

  const handleGetSubAccounts = async () => {
    if (!baseAccount) return;

    setIsLoading(true);
    try {
      // Base Sepolia로 전환 (또는 메인넷의 경우 8453 사용)
      await baseAccount.switchChain(84532);
      const provider = await baseAccount.getEthereumProvider();

      // 기존 서브 어카운트 조회
      const response = await provider.request({
        method: 'wallet_getSubAccounts',
        params: [{
          account: baseAccount.address,
          domain: window.location.origin
        }]
      });

      const { subAccounts: existingSubAccounts } = response;
      setSubAccounts(existingSubAccounts || []);
    } catch (error) {
      console.error("Error getting Sub Accounts:", error);
    } finally {
      setIsLoading(false);
    }
  };

  const handleAddSubAccount = async () => {
    if (!baseAccount) return;

    setIsLoading(true);
    try {
      // Base Sepolia로 전환 (또는 메인넷의 경우 8453 사용)
      await baseAccount.switchChain(84532);
      const provider = await baseAccount.getEthereumProvider();

      // 새 서브 어카운트 생성
      await provider.request({
        method: 'wallet_addSubAccount',
        params: [{
          version: '1',
          account: {
            type: 'create',
            keys: [{
              type: 'address',
              publicKey: baseAccount.address
            }]
          }
        }]
      });

      // 서브 어카운트 목록 새로고침
      await handleGetSubAccounts();
    } catch (error) {
      console.error("Error creating Sub Account:", error);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <div className="space-y-4">
      <div className="flex gap-4">
        <button 
          onClick={handleGetSubAccounts}
          disabled={!baseAccount || isLoading}
          className="px-4 py-2 bg-blue-600 text-white rounded disabled:opacity-50"
        >
          서브 어카운트 조회
        </button>
        <button 
          onClick={handleAddSubAccount}
          disabled={!baseAccount || isLoading}
          className="px-4 py-2 bg-green-600 text-white rounded disabled:opacity-50"
        >
          서브 어카운트 생성
        </button>
      </div>

      {subAccounts.length > 0 && (
        <div>
          <h4 className="font-medium mb-2">기존 서브 어카운트:</h4>
          <div className="space-y-2">
            {subAccounts.map((subAccount, index) => (
              <div key={index} className="p-3 border rounded-md">
                <p><strong>주소:</strong> {subAccount.address}</p>
                <p><strong>팩토리:</strong> {subAccount.factory}</p>
                <p><strong>팩토리 데이터:</strong> {subAccount.factoryData}</p>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

주요 메서드

서브 어카운트 조회

wallet_getSubAccounts를 사용하여 도메인의 기존 서브 어카운트를 조회합니다:
서브 어카운트 조회 (components/sections/sub-accounts.tsx)
const response = await provider.request({
  method: 'wallet_getSubAccounts',
  params: [{
    account: baseAccount.address,
    domain: window.location.origin
  }]
});

서브 어카운트 생성

wallet_addSubAccount를 사용하여 새 서브 어카운트를 생성합니다:
서브 어카운트 생성 (components/sections/sub-accounts.tsx)
await provider.request({
  method: 'wallet_addSubAccount',
  params: [{
    version: '1',
    account: {
      type: 'create',
      keys: [{
        type: 'address',
        publicKey: baseAccount.address
      }]
    }
  }]
});

네트워크 설정

서브 어카운트는 Base 메인넷과 Base Sepolia 모두에서 작동합니다:
  • Base 메인넷: 체인 ID 8453
  • Base Sepolia: 체인 ID 84532

더 알아보기