여러분이 이 튜토리얼을 읽고 있는 이유는 아마도 다음 중 하나 또는 둘 다를 하고 싶어서일 것입니다:
지갑이 없는 사용자가 이메일로 앱에 로그인할 수 있게 하기 (“임베디드 지갑”)
사용자가 가스비를 지불하지 않도록 트랜잭션을 스폰서하기 (“스마트 지갑”)
Privy가 이 두 가지를 설명하는 방식은 다음과 같습니다:
임베디드 지갑은 Privy가 직접 제공하는 자체 보관 지갑으로, 애플리케이션에 직접 내장된 지갑 경험을 제공합니다. 임베디드 지갑은 브라우저 확장 프로그램이나 모바일 앱과 같은 별도의 지갑 클라이언트가 필요 없으며, 제품에서 직접 접근할 수 있습니다. 이는 주로 외부 지갑이 없거나 외부 지갑을 연결하고 싶지 않은 앱 사용자를 위해 설계되었습니다.
스마트 지갑은 계정 추상화의 기능을 통합한 프로그래밍 가능한 온체인 계정입니다. 몇 줄의 코드만으로 사용자를 위한 스마트 지갑을 만들어 가스 결제를 스폰서하고, 일괄 트랜잭션을 보내는 등의 작업을 할 수 있습니다.
&#xNAN;“App ID”를 “App settings > API keys” 아래에서 복사합니다. 로컬 프로젝트에서 .env.env.local 파일을 만들고 App ID를 추가합니다:
.env
NEXT_PUBLIC_PRIVY_APP_ID=
프로젝트 대시보드에서 “Wallet Configuration > Smart wallets” 아래의 스마트 지갑을 활성화하고 “Kernel (ZeroDev)“를 선택합니다. 아래와 같이:
스마트 지갑을 활성화하면 바로 아래에 다음 값으로 “Custom chain”을 설정해야 합니다:
Name: Story Aeneid Testnet
ID 번호: 1315
RPC URL: https://aeneid.storyrpc.io
Bundler URL과 Paymaster URL의 경우, Pimlico의 대시보드로 가서 새 앱을 만듭니다. 그런 다음 “API Keys”를 클릭하고 새 API 키를 만든 후, 아래와 같이 “RPC URLs”를 클릭하고 네트워크로 “Story Aeneid Testnet”을 선택합니다:
이는 테스트용입니다. 실제 시나리오에서는 앱을 대신하여 트랜잭션을 자동으로 스폰서하기 위해 Pimlico에서 적절한 스폰서십 정책과 결제 정보를 설정해야 합니다. 테스트넷에서는 이 작업을 할 필요가 없습니다.
Privy의 튜토리얼을 여기서 읽을 수 있습니다. 이 튜토리얼은 임베디드 지갑 설정에 대해 설명하는데, 이는 사용자를 위한 이메일 로그인을 멋지게 표현한 것입니다. 아래 예제에서는 단순히 모든 사용자를 위해 임베디드 지갑을 만들지만, 그들의 튜토리얼을 읽어 더 많은 사용자 정의를 원할 수 있습니다.
임베디드/스마트 지갑을 사용할 모든 컴포넌트를 PrivyProvider와 SmartWalletsProvider로 감싸야 합니다. providers.tsxproviders.tsx (또는 원하는 이름) 파일에 다음 코드를 추가하세요:
providers.tsx
"use client";import { PrivyProvider } from "@privy-io/react-auth";import { SmartWalletsProvider } from "@privy-io/react-auth/smart-wallets";import { aeneid } from "@story-protocol/core-sdk";export default function Providers({ children }: { children: React.ReactNode }) { return ( <PrivyProvider appId={process.env.NEXT_PUBLIC_PRIVY_APP_ID as string} config={{ // Customize Privy's appearance in your app appearance: { theme: "light", accentColor: "#676FFF", logo: "/story-logo.jpg", }, // Create embedded wallets for users who don't have a wallet // when they sign in with email embeddedWallets: { createOnLogin: "all-users", }, defaultChain: aeneid, supportedChains: [aeneid], }} > <SmartWalletsProvider>{children}</SmartWalletsProvider> </PrivyProvider> );}
그런 다음 layout.tsx_app.tsx에 다음과 같이 추가할 수 있습니다:
layout.tsx
import Providers from "@/providers/providers";/* other code here... */export default function RootLayout({ children,}: Readonly<{ children: React.ReactNode,}>) { return ( <html lang="en"> <body className={`${geistSans.variable} ${geistMono.variable} antialiased`} > <Providers>{children}</Providers> </body> </html> );}
또한 생성된 스마트 지갑을 사용하여 🛠️ TypeScript SDK에서 트랜잭션을 보낼 수 있습니다. 일부 함수는 encodedTxData를 반환하는 옵션이 있어, 이를 Privy의 스마트 지갑에 전달할 수 있습니다. SDK 레퍼런스에서 어떤 함수가 이를 지원하는지 확인할 수 있습니다.
page.tsx
import { useSmartWallets } from "@privy-io/react-auth/smart-wallets";import { EncodedTxData, StoryClient, StoryConfig,} from "@story-protocol/core-sdk";import { http } from "viem";export default function Home() { const { client: smartWalletClient } = useSmartWallets(); /* previous code here */ async function setupStoryClient() { const config: StoryConfig = { account: smartWalletClient!.account, transport: http("https://aeneid.storyrpc.io"), chainId: "aeneid", }; const client = StoryClient.newClient(config); return client; } async function registerIp() { const storyClient = await setupStoryClient(); const response = await storyClient.ipAsset.mintAndRegisterIp({ spgNftContract: "0xc32A8a0FF3beDDDa58393d022aF433e78739FAbc", // public spg contract for testing txOptions: { encodedTxDataOnly: true }, }); const uiOptions = { title: "Register IP", description: "This is an example transaction that registers an IP.", buttonText: "Register", }; const txHash = await smartWalletClient?.sendTransaction( response.encodedTxData as EncodedTxData, { uiOptions } ); console.log(`View Tx: https://aeneid.storyscan.io/tx/${txHash}`); } return ( <div> {/* previous code here */} <button onClick={registerIp}>Register IP</button> </div> );}