> ## 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 Account가 제공하는 가장 큰 UX 향상 중 하나는 앱 개발자가 사용자의 트랜잭션을 스폰서할 수 있는 기능입니다.
앱이 Base Account를 지원한다면 [표준화된 페이마스터 서비스 통신](https://erc7677.xyz)과 [새로운 지갑 RPC 메서드](https://eip5792.xyz)를 사용하여 사용자의 트랜잭션을 스폰서할 수 있습니다.

이 가이드는 Base Account 사용에 특화되어 있습니다. Base에서 페이마스터를 사용하는 방법에 대해 자세히 알아보려면 [Coinbase Developer Platform 문서](https://docs.cdp.coinbase.com/paymaster/introduction/welcome)를 참조하세요.

## 구현 가이드

<Steps>
  <Step title="페이마스터 서비스 설정">
    먼저 페이마스터 서비스 제공업체에서 페이마스터 서비스 URL을 획득해야 합니다.

    [Coinbase Developer Platform](https://www.coinbase.com/developer-platform)을 페이마스터 서비스 제공업체로 사용하겠습니다.
    현재 [Base 가스리스 캠페인](/base-account/more/base-gasless-campaign)의 일환으로 최대 \$15,000의 가스 크레딧을 제공합니다.

    <Warning>
      **ERC-7677 호환 페이마스터 제공업체**

      다른 페이마스터 서비스 제공업체를 사용하는 경우 [ERC-7677 호환](https://www.erc7677.xyz/ecosystem/paymasters) 여부를 확인하세요.
    </Warning>

    [Coinbase Developer Platform](https://www.coinbase.com/developer-platform)에 가입한 후 아래와 같이 **온체인 도구 > 페이마스터**로 이동하여 페이마스터 서비스 URL을 얻을 수 있습니다:

    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
      <Frame>
        <img alt="페이마스터 CDP" src="https://mintcdn.com/daehan-base/AjQ7x4Yn-uFfYw2D/images/smart-wallet/PaymasterCDP.png?fit=max&auto=format&n=AjQ7x4Yn-uFfYw2D&q=85&s=1d2b04f2d6e822fd60b961e1a7455ae4" width="1000" loading="lazy" data-path="images/smart-wallet/PaymasterCDP.png" />
      </Frame>

      <em>페이마스터 서비스 URL을 얻는 방법</em>
    </div>

    <Warning>
      **페이마스터 서비스를 위한 프록시를 생성해야 할까요?**

      프런트엔드 클라이언트에서 노출/유출되는 것을 방지하기 위해 페이마스터 서비스 URL을 보호하는 프록시를 사용하는 것을 권장합니다.

      로컬 개발의 경우 페이마스터 서비스와 프록시에 동일한 URL을 사용할 수 있습니다.
    </Warning>

    페이마스터 서비스 URL을 얻은 후 컨트랙트 허용 목록을 설정할 수 있습니다.
    이것은 페이마스터가 스폰서할 컨트랙트와 함수 호출의 목록입니다.

    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
      <Frame>
        <img alt="페이마스터 CDP 허용 목록" src="https://mintcdn.com/daehan-base/AjQ7x4Yn-uFfYw2D/images/smart-wallet/PaymasterAllowlist.png?fit=max&auto=format&n=AjQ7x4Yn-uFfYw2D&q=85&s=cd9f1175cad967328f4d509f536b8922" width="1000" loading="lazy" data-path="images/smart-wallet/PaymasterAllowlist.png" />
      </Frame>

      <em>페이마스터 컨트랙트 허용 목록을 설정하는 방법</em>
    </div>

    페이마스터 서비스와 컨트랙트 허용 목록 설정이 완료되었습니다.
    이제 Base Account SDK를 설정할 차례입니다.

    <Check>
      **커스텀 고급 정책을 생성할 수도 있습니다!**

      정책 시행에 더 많은 제어가 필요한 경우 추가 검증을 위한 `willSponsor` 함수를 생성할 수 있습니다.

      `willSponsor`는 [Coinbase Developer Platform](https://www.coinbase.com/developer-platform)에 내장 정책 시행 기능이 있으므로 사용하지 않아도 될 가능성이 높지만, 필요한 경우 여전히 가능합니다.
    </Check>
  </Step>

  <Step title="Base Account SDK 설정">
    Base Account와 상호작용하기 위해 Base Account SDK를 설치하고 초기화합니다:

    ### 설치

    <CodeGroup>
      ```bash npm theme={null}
      npm install @base-org/account
      ```

      ```bash pnpm theme={null}
      pnpm add @base-org/account
      ```

      ```bash yarn theme={null}
      yarn add @base-org/account
      ```

      ```bash bun theme={null}
      bun add @base-org/account
      ```
    </CodeGroup>

    ### SDK 초기화

    ```tsx theme={null}
    import { createBaseAccountSDK, base } from '@base-org/account';

    const sdk = createBaseAccountSDK({
      appName: '페이마스터 데모',
      appLogoUrl: 'https://base.org/logo.png',
      appChainIds: [base.constants.CHAIN_IDS.baseSepolia], // 메인넷은 base.constants.CHAIN_IDS.base 사용
    });

    const provider = sdk.getProvider();
    ```
  </Step>

  <Step title="페이마스터 서비스 기능으로 트랜잭션 전송">
    페이마스터 서비스를 설정했다면 이제 트랜잭션을 스폰서하기 위해 페이마스터 기능과 함께 `wallet_sendCalls`를 사용할 수 있습니다.

    <Note>
      **프록시 URL 전달**

      위의 (1)단계에서 권장한 대로 앱의 백엔드에 프록시를 설정한 경우 생성한 프록시 URL을 전달합니다.
    </Note>

    ### 기본 스폰서 트랜잭션

    `wallet_sendCalls` RPC 메서드를 사용하여 스폰서 트랜잭션을 전송하는 방법:

    ```tsx theme={null}
    import { createBaseAccountSDK, getCryptoKeyAccount, base } from '@base-org/account';
    import { numberToHex, encodeFunctionData, parseEther } from 'viem';

    // 예제 NFT 컨트랙트 ABI
    const nftABI = [
      {
        name: 'safeMint',
        type: 'function',
        stateMutability: 'nonpayable',
        inputs: [{ name: 'to', type: 'address' }],
        outputs: []
      }
    ] as const;

    async function sendSponsoredTransaction() {
      const sdk = createBaseAccountSDK({
        appName: '페이마스터 데모',
        appLogoUrl: 'https://base.org/logo.png',
        appChainIds: [base.constants.CHAIN_IDS.baseSepolia],
      });

      const provider = sdk.getProvider();
      
      try {
        // 사용자 계정 가져오기
        const cryptoAccount = await getCryptoKeyAccount();
        const fromAddress = cryptoAccount?.account?.address;
        
        if (!fromAddress) {
          throw new Error('계정을 찾을 수 없습니다');
        }

        // 페이마스터 서비스 URL (프록시 URL 사용)
        const paymasterServiceUrl = process.env.NEXT_PUBLIC_PAYMASTER_PROXY_SERVER_URL;
        
        // 트랜잭션 콜 준비
        const nftAddress = '0x119Ea671030FBf79AB93b436D2E20af6ea469a19';
        const calls = [
          {
            to: nftAddress,
            value: '0x0',
            data: encodeFunctionData({
              abi: nftABI,
              functionName: 'safeMint',
              args: [fromAddress]
            })
          }
        ];

        // 페이마스터 기능과 함께 트랜잭션 전송
        const result = await provider.request({
          method: 'wallet_sendCalls',
          params: [{
            version: '1.0',
            chainId: numberToHex(base.constants.CHAIN_IDS.baseSepolia),
            from: fromAddress,
            calls: calls,
            capabilities: {
              paymasterService: {
                url: paymasterServiceUrl
              }
            }
          }]
        });

        console.log('Sponsored transaction sent:', result);
        return result;
      } catch (error) {
        console.error('Sponsored transaction failed:', error);
        throw error;
      }
    }
    ```

    ### 다중 스폰서 트랜잭션

    여러 트랜잭션을 배치로 묶어 모두 스폰서할 수도 있습니다:

    ```tsx theme={null}
    async function sendMultipleSponsoredTransactions() {
      const sdk = createBaseAccountSDK({
        appName: '페이마스터 데모',
        appLogoUrl: 'https://base.org/logo.png',
        appChainIds: [base.constants.CHAIN_IDS.baseSepolia],
      });

      const provider = sdk.getProvider();
      const cryptoAccount = await getCryptoKeyAccount();
      const fromAddress = cryptoAccount?.account?.address;

      const paymasterServiceUrl = process.env.NEXT_PUBLIC_PAYMASTER_PROXY_SERVER_URL;

      // 단일 스폰서 트랜잭션에서 여러 콜
      const calls = [
        {
          to: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
          value: numberToHex(parseEther('0.001')),
          data: '0x' // 간단한 ETH 전송
        },
        {
          to: '0x742d35Cc6634C0532925a3b844Bc9e7595f6E456',
          value: numberToHex(parseEther('0.001')),
          data: '0x' // 다른 ETH 전송
        }
      ];

      const result = await provider.request({
        method: 'wallet_sendCalls',
        params: [{
          version: '1.0',
          chainId: numberToHex(base.constants.CHAIN_IDS.baseSepolia),
          from: fromAddress,
          calls: calls,
          capabilities: {
            paymasterService: {
              url: paymasterServiceUrl
            }
          }
        }]
      });

      return result;
    }
    ```

    ### 페이마스터 기능 확인

    스폰서 트랜잭션을 전송하기 전에 지갑이 페이마스터 서비스를 지원하는지 확인할 수 있습니다:

    ```tsx theme={null}
    async function checkPaymasterSupport() {
      const sdk = createBaseAccountSDK({
        appName: '페이마스터 데모',
        appLogoUrl: 'https://base.org/logo.png',
        appChainIds: [base.constants.CHAIN_IDS.baseSepolia],
      });

      const provider = sdk.getProvider();
      const cryptoAccount = await getCryptoKeyAccount();
      const address = cryptoAccount?.account?.address;

      try {
        const capabilities = await provider.request({
          method: 'wallet_getCapabilities',
          params: [address]
        });

        const baseCapabilities = capabilities[base.constants.CHAIN_IDS.baseSepolia];
        
        if (baseCapabilities?.paymasterService?.supported) {
          console.log('페이마스터 서비스가 지원됩니다');
          return true;
        } else {
          console.log('페이마스터 서비스가 지원되지 않습니다');
          return false;
        }
      } catch (error) {
        console.error('Failed to check paymaster capabilities:', error);
        return false;
      }
    }
    ```

    이것으로 완료됩니다! Base Account가 나머지를 처리합니다. 페이마스터 서비스가 트랜잭션을 스폰서할 수 있다면 Base Account UI에서 사용자에게 트랜잭션이 스폰서됨을 표시합니다.
  </Step>
</Steps>
