{"id":20974199,"url":"https://github.com/thirdweb-example/thirdweb-siwf","last_synced_at":"2025-06-16T14:08:29.128Z","repository":{"id":236185513,"uuid":"792060517","full_name":"thirdweb-example/thirdweb-siwf","owner":"thirdweb-example","description":"Sign in with Farcaster -\u003e in-app + smart wallet","archived":false,"fork":false,"pushed_at":"2024-05-09T17:19:30.000Z","size":853,"stargazers_count":6,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-14T12:36:44.909Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://thirdweb-siwf.thirdweb-preview.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thirdweb-example.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-25T22:41:01.000Z","updated_at":"2025-04-20T00:16:57.000Z","dependencies_parsed_at":"2024-05-02T00:51:37.539Z","dependency_job_id":null,"html_url":"https://github.com/thirdweb-example/thirdweb-siwf","commit_stats":null,"previous_names":["thirdweb-example/thirdweb-siwf"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thirdweb-example/thirdweb-siwf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fthirdweb-siwf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fthirdweb-siwf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fthirdweb-siwf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fthirdweb-siwf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thirdweb-example","download_url":"https://codeload.github.com/thirdweb-example/thirdweb-siwf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thirdweb-example%2Fthirdweb-siwf/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260173906,"owners_count":22969870,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-19T04:27:12.990Z","updated_at":"2025-06-16T14:08:29.104Z","avatar_url":"https://github.com/thirdweb-example.png","language":"TypeScript","readme":"![banner](https://github.com/thirdweb-example/thirdweb-siwf/assets/17715009/9ec0129f-65ff-4016-a6a0-1e5a4efdad77)\r\n\r\n# thirdweb Sign in with Farcaster Example\r\n\r\n[\u003cimg alt=\"thirdweb SDK\" src=\"https://img.shields.io/npm/v/thirdweb?label=Thirdweb SDK\u0026style=for-the-badge\u0026logo=npm\" height=\"30\"\u003e](https://www.npmjs.com/package/thirdweb)\r\n[\u003cimg alt=\"Discord\" src=\"https://img.shields.io/discord/834227967404146718.svg?color=7289da\u0026label=discord\u0026logo=discord\u0026style=for-the-badge\" height=\"30\"\u003e](https://discord.gg/thirdweb)\r\n\r\nThis example app showcases how to authenticate users via Farcaster (specifically Warpcast) and generate a unique reusable smart wallet from their Farcaster signature.\r\n\r\n## Getting Started\r\n\r\n\u003e This project assumes some basic knowledge of TypeScript, Next.js App Router, and [Connect SDK](https://portal.thirdweb.com/typescript/v5).\r\n\r\n## Environment Variables\r\n\r\n1. Create your `.env` by running `cp .env.example .env` in the project root.\r\n\r\n2. Create a client ID from the [thirdweb dashboard](https://thirdweb.com/dashboard/settings/api-keys) and add it to your `.env` as `NEXT_PUBLIC_THIRDWEB_CLIENT_ID`.\r\n\r\n3. Deploy an [`AccountFactory`](https://thirdweb.com/thirdweb.eth/AccountFactory) on your chain of choice from the thirdweb dashboard and paste the contract address in your `.env` as `NEXT_PUBLIC_FACTORY_ADDRESS`.\r\n\r\n4. Deploy a new [`OpenEditionERC721`](https://thirdweb.com/thirdweb.eth/OpenEditionERC721) contract on your chain of choice from the thirdweb dashboard and add a claim period with no restrictions. Paste the contract's address in your `.env` as `NEXT_PUBLIC_NFT_ADDRESS`.\r\n\r\n5. Set your chain ID, block explorer base url (this should be the base url up until the transaction hash, for etherscan mainnet it would be `https://etherscan.io/tx/`), and an encryption key of your choice in your `.env`\r\n\r\n## Set authentication endpoint\r\n\r\nThis project uses an incredibly powerful thirdweb feature called [Authentication Endpoints](https://portal.thirdweb.com/connect/in-app-wallet/custom-auth/custom-auth-server). It uses your own API endpoint to generate a wallet for users on successful authentication. All the code for this is written for you in this project, you'll just need to set the endpoint in your thirdweb dashboard.\r\n\r\n\u003e To use Custom Authentication Endpoints, you'll need to be on the Growth Plan. If you have questions about the plan options or want to try it out, [reach out to our team](https://thirdweb.com/contact-us).\r\n\r\nNavigate to the [In-App Wallets](https://thirdweb.com/dashboard/connect/in-app-wallets) page on the dashboard and select your project from the dropdown. **This should be the same project your `clientId` is from.** Then click the **\"Configuration\" tab** and scroll down to \"Custom Authentication Endpoint\" and enable the toggle. You'll then see a field to enter your endpoint.\r\n\r\n\u003cimg width=\"1215\" alt=\"Screenshot 2024-04-25 at 10 46 11 PM\" src=\"https://github.com/thirdweb-example/thirdweb-siwf/assets/17715009/b05825c1-96b3-4e58-908e-c47002c4c02f\"\u003e\r\n\r\nWhile testing the project locally, you'll need a publicly exposed endpoint to authenticate through. We recommend using a tool like [ngrok](https://ngrok.com/product/secure-tunnels) to create a public endpoint that forwards traffic to your local server. Forward your traffic to `http://localhost:3000` (where your app will run locally).\r\n\r\nOnce you have your ngrok or similar endpoint, add it to the Authentication Endpoint field as `[YOUR FORWARDING ENDPOINT]/api/authenticate`, the route this app uses to perform authentication.\r\n\r\nYou're now ready to run the project!\r\n\r\n\u003e **When you deploy to production (or any live URL), you'll modify this authentication endpoint to be your actual live URL. You could also create a separate thirdweb project for local development and production.**\r\n\r\n### Run the project\r\n\r\nYou're now ready to test the project! First, install the dependencies:\r\n\r\n```bash\r\npnpm install\r\n```\r\n\r\nThen, run the app locally:\r\n\r\n```bash\r\npnpm run dev\r\n```\r\n\r\nYou should see the app at http://localhost:3000. Try signing in with Warpcast and minting the NFT!\r\n\r\nCheck the users tab in [In-App Wallets](https://thirdweb.com/dashboard/connect/in-app-wallets) dashboard. You should see your created users appear.\r\n\r\n### Going to production\r\n\r\nOnce you've implemented this flow into your own app, there are a few changes you'll need to make to go to production.\r\n\r\n1. Modify the `NEXT_PUBLIC_DOMAIN` in your production `.env` to be your production domain.\r\n    \u003e Don't prepend your domain with https:// when setting it in your `.env`\r\n2. Remember to go to your project in the [In-App Wallets](https://thirdweb.com/dashboard/connect/in-app-wallets) configuration tab and update the auth endpoint to be `[YOUR PRODUCTION URL]/api/authenticate`. In this case, do include `https://` in the URL.\r\n\r\nYou might also want to (but don't have to) use a different account factory, NFT, and chain for production.\r\n\r\nNow, you're ready to deploy your app to Vercel or a similar service.\r\n\r\n## How it works\r\n\r\nAll the logic for this example can be found in `page.tsx`. The most important areas for authentication are `handleSuccess()`, `mint`, and the `useConnect` hook from the thirdweb React SDK.\r\n\r\n### Authenticating the user\r\n\r\nWe use [Farcaster AuthKit](https://docs.farcaster.xyz/auth-kit/introduction) to handle the connection with Warpcast. We use the `useSignIn` hook to trigger the `handleSuccess` as a success callback when the sign in data is available. When the user authenticates with Warpcast, this function will be called with the user's signature.\r\n\r\nIn `handleSuccess`, we optimistically set the fid (it will unset if the signature verification or wallet generation fail), then connect using the `\"auth_endpoint\"` strategy. This strategy needs a `payload` and `encryptionKey` that will be sent to the authentication endpoint we specified in the dashboard. The code below is simplified from the actual project.\r\n\r\n```ts\r\nconst handleSuccess = async (res: StatusAPIResponse) =\u003e {\r\n\tawait wallet.connect({\r\n\t\tclient: thirdwebClient,\r\n\t\tchain: defineChain(Number(process.env.NEXT_PUBLIC_CHAIN_ID)),\r\n\t\tstrategy: \"auth_endpoint\",\r\n\t\tpayload: JSON.stringify({\r\n\t\t\tsignature: res.signature,\r\n\t\t\tmessage: res.message,\r\n\t\t\tnonce: res.nonce,\r\n\t\t}),\r\n\t\tencryptionKey: process.env.NEXT_PUBLIC_ENCRYPTION_KEY!,\r\n\t});\r\n\tawait connect(wallet);\r\n};\r\n```\r\n\r\nThen in the `/api/authenticate/route.ts` file we specify a `POST` handler that accepts the payload and verifies the signature. If this route returns a `userId`, it's considered to be successful and generates and/or connects the user's in-app wallet.\r\n\r\n### Using a smart wallet\r\n\r\nSince this user's wallet is generated the first time they sign into our app, it won't have any funds for gas. Instead, we'll wrap this generated wallet in a smart wallet, which will allow the user to execute gasless transactions.\r\n\r\nWe use the `useConnect` hook from the [React SDK](https://portal.thirdweb.com/typescript/v5/react) to specify the client and account abstraction options (gasless enabled, factory address, and chain). This hook returns a `connect` function that will wrap our in-app wallet and set the app's currently active wallet to this smart wallet.\r\n\r\n```ts\r\nconst { connect } = useConnect({\r\n\tclient: thirdwebClient,\r\n\taccountAbstraction: {\r\n\t\tgasless: true,\r\n\t\tchain: defineChain(Number(process.env.NEXT_PUBLIC_CHAIN_ID)),\r\n\t\tfactoryAddress: process.env.NEXT_PUBLIC_FACTORY_ADDRESS as Address,\r\n\t},\r\n});\r\n```\r\n\r\n\u003e Note; We setup a [ThirdwebProvider](https://portal.thirdweb.com/typescript/v5/react/ThirdwebProvider) in `Providers.tsx` for the `useConnect` and `useActiveAccount` hooks to work.\r\n\r\nOnce our smart wallet is connected, the `useActiveAccount` hook will return it, allowing us to enable minting the NFT.\r\n\r\n### Minting the NFT\r\n\r\nOnce the smart account is ready we enable the minting button. When clicked, it calls `mint`, a simple function that uses the Thirdweb SDK's ERC721 extension to generate a `claimTo` transaction, then we send and await the transaction result in one `sendAndConfirmTransaction` call. With extensions, we don't need to worry about ABIs, argument arrays, calldata, or any other \"low-level\" concepts. All the complicated elements are abstracted away from the frontend code.\r\n\r\n```ts\r\nasync function mint(account: Account, recipient: Address) {\r\n\tconst contract = getContract({\r\n\t\taddress: process.env.NEXT_PUBLIC_NFT_ADDRESS as Address,\r\n\t\tchain: defineChain(Number(process.env.NEXT_PUBLIC_CHAIN_ID)),\r\n\t\tclient: thirdwebClient,\r\n\t});\r\n\r\n\tconst mintTx = claimTo({\r\n\t\tcontract,\r\n\t\tto: recipient,\r\n\t\tquantity: BigInt(1),\r\n\t});\r\n\r\n\tconst res = await sendAndConfirmTransaction({\r\n\t\taccount,\r\n\t\ttransaction: mintTx,\r\n\t});\r\n\r\n\treturn res.transactionHash;\r\n}\r\n```\r\n\r\n## Documentation\r\n\r\n-   [TypeScript SDK](https://portal.thirdweb.com/typescript/v5)\r\n-   [Next.js Docs](https://nextjs.org/docs)\r\n\r\n## Support\r\n\r\nFor help or feedback, please [visit our support site](https://thirdweb.com/support)\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthirdweb-example%2Fthirdweb-siwf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthirdweb-example%2Fthirdweb-siwf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthirdweb-example%2Fthirdweb-siwf/lists"}