-
Notifications
You must be signed in to change notification settings - Fork 13
feat: Add Farcaster miniapp support for identity verification flow #10 #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 39 commits
25ee077
42fc37e
9557dce
42e08a9
64d56a8
3323d82
8bff2fe
f3940b2
53564da
60eb1cb
c105e1b
e10b584
8edaca1
c34de25
f6889fd
8616d89
36dfa32
5ed0e06
5bdab21
cd6d40f
f1e9b8d
b7de6cb
304c15a
9841794
d19d211
158465a
4060809
e6ba4d0
8cf55a7
c1486dc
04ff59c
3dd1832
59484bc
f620a1c
c38476f
20d0905
9a9dbbc
7a7a921
994b4f3
75a9b45
6377bf0
359e2c2
4ad2886
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,4 +10,4 @@ | |
| <div id="app"></div> | ||
| <script type="module" src="/src/main.tsx"></script> | ||
| </body> | ||
| </html> | ||
| </html> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,4 +31,4 @@ export default defineConfig({ | |
| "process.browser": true, | ||
| "process.env": process.env, | ||
| }, | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,4 +25,4 @@ export default defineConfig({ | |
| "process.browser": true, | ||
| "process.env": process.env, | ||
| }, | ||
| }) | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,6 +35,7 @@ | |
| "wagmi": "*" | ||
| }, | ||
| "dependencies": { | ||
| "@farcaster/miniapp-sdk": "^0.1.8", | ||
|
||
| "lz-string": "^1.5.0", | ||
| "tsup": "^8.4.0" | ||
| }, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,29 @@ export const Envs: Record<string, Record<string, string>> = { | |
| }, | ||
| } | ||
|
|
||
| /** | ||
|
||
| * Farcaster Mini App configurations for different environments | ||
| * @notice THESE ARE EXAMPLE / PLACEHOLDER VALUES ONLY. | ||
| * Developers integrating the SDK SHOULD: | ||
| * 1. Pass a custom `farcasterConfig` when initializing IdentitySDK / ClaimSDK | ||
| * | ||
| * The SDK will default to these values if no config is provided, which will likely fail in production. | ||
| */ | ||
| export const FarcasterAppConfigs: Record<string, { appId: string; appSlug: string }> = { | ||
|
||
| production: { | ||
| appId: "", // REQUIRED: Replace with actual app ID from Farcaster Developer Portal | ||
| appSlug: "", // REQUIRED: Replace with actual app slug | ||
| }, | ||
| staging: { | ||
| appId: "", // REQUIRED: Replace with actual app ID from Farcaster Developer Portal | ||
| appSlug: "", // REQUIRED: Replace with actual app slug | ||
| }, | ||
| development: { | ||
| appId: "", // REQUIRED: Replace with actual app ID from Farcaster Developer Portal | ||
| appSlug: "", // REQUIRED: Replace with actual app slug | ||
| }, | ||
| } | ||
|
|
||
| export interface ContractAddresses { | ||
| identityContract: `0x${string}` | ||
| ubiContract: `0x${string}` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,4 @@ | ||
| export * from "./sdks" | ||
| export * from "./constants" | ||
| export * from "./utils/auth" | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,3 @@ | ||
| export * from "./viem-identity-sdk" | ||
| export * from "./viem-claim-sdk" | ||
| export * from "./viem-custodial-claim-sdk" | ||
| export * from "./viem-custodial-identity-sdk" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ import { | |
| type WalletClient, | ||
| ContractFunctionExecutionError, | ||
| TransactionReceipt, | ||
| zeroAddress, | ||
| } from "viem" | ||
|
|
||
| import { waitForTransactionReceipt } from "viem/actions" | ||
|
|
@@ -20,9 +21,16 @@ import { | |
| faucetABI, | ||
| isSupportedChain, | ||
| ubiSchemeV2ABI, | ||
| FarcasterAppConfigs, | ||
| } from "../constants" | ||
| import type { ContractAddresses } from "../constants" | ||
| import { resolveChainAndContract } from "../utils/chains" | ||
| import { | ||
| createVerificationCallbackUrl, | ||
| createFarcasterCallbackUniversalLink, | ||
| isInFarcasterMiniApp, | ||
| navigateToUrl | ||
| } from "../utils/auth" | ||
|
||
| import { triggerFaucet as triggerFaucetUtil } from "../utils/triggerFaucet" | ||
| import { | ||
| createRpcIteratorRegistry, | ||
|
|
@@ -82,7 +90,7 @@ export class ClaimSDK { | |
| private readonly faucetAddress: Address | ||
| private readonly account: Address | ||
| private readonly env: contractEnv | ||
| public readonly rdu: string | ||
| public rdu: string | ||
|
|
||
| constructor({ | ||
| account, | ||
|
|
@@ -99,9 +107,11 @@ export class ClaimSDK { | |
| this.walletClient = walletClient | ||
| this.identitySDK = identitySDK | ||
| this.account = account ?? walletClient.account.address | ||
| this.env = env | ||
|
|
||
| // Initialize callback URL - will be set properly in initializeCallbackUrl | ||
| this.rdu = rdu | ||
| this.env = env | ||
| this.initializeCallbackUrl(rdu); | ||
|
|
||
| const { chainId, contractEnvAddresses } = resolveChainAndContract( | ||
| walletClient, | ||
|
|
@@ -142,6 +152,37 @@ export class ClaimSDK { | |
| this.faucetAddress = contractEnvAddresses.faucetContract as Address | ||
| } | ||
|
|
||
| /** | ||
| * Initialize the callback URL with proper Farcaster Universal Link support | ||
| * @param rdu - The redirect URL after claim | ||
| */ | ||
| private async initializeCallbackUrl(rdu?: string): Promise<void> { | ||
|
||
| if (!rdu) return; | ||
|
|
||
| try { | ||
| // Check if we're in a Farcaster context and should use Universal Links | ||
| const isFarcaster = await isInFarcasterMiniApp(); | ||
|
|
||
| if (isFarcaster && FarcasterAppConfigs[this.env]) { | ||
| // Create proper Farcaster Universal Link | ||
| const farcasterConfig = FarcasterAppConfigs[this.env]; | ||
| this.rdu = createFarcasterCallbackUniversalLink( | ||
| farcasterConfig, | ||
| 'claim', | ||
| { source: "gooddollar_claim_verification" } | ||
| ); | ||
| } else { | ||
| // Fallback to direct callback URL for non-Farcaster environments | ||
| this.rdu = await createVerificationCallbackUrl(rdu, { | ||
| source: "gooddollar_claim_verification" | ||
| }); | ||
| } | ||
| } catch (error) { | ||
| // Fallback to original URL on error | ||
| this.rdu = rdu; | ||
| } | ||
| } | ||
|
|
||
| private getContractsForChain(chainId: SupportedChains): ContractAddresses { | ||
| const contracts = this.chainContracts.get(chainId) | ||
|
|
||
|
|
@@ -454,19 +495,21 @@ export class ClaimSDK { | |
| * @throws If face verification redirect fails. | ||
| */ | ||
| private async fvRedirect(): Promise<void> { | ||
| const fvChainId = this.fvDefaultChain ?? this.chainId | ||
| // Generate link with current chain ID as default, respecting identity-contract logic | ||
| const fvLink = await this.identitySDK.generateFVLink( | ||
| false, | ||
| this.rdu, | ||
| fvChainId, | ||
| this.chainId | ||
| ) | ||
| if (typeof window !== "undefined") { | ||
| window.location.href = fvLink | ||
| } else { | ||
| throw new Error( | ||
| "Face verification redirect is only supported in browser environments.", | ||
| ) | ||
|
|
||
| // Handle Farcaster Context | ||
| if (await isInFarcasterMiniApp()) { | ||
| await navigateToUrl(fvLink, false) | ||
| return | ||
| } | ||
|
|
||
| // Default legacy behavior | ||
| window.location.href = fvLink | ||
| } | ||
|
|
||
| /** | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why was this removed