AgentSkillsCN

Clerk-Crossmint-Supabase Integration Flow

当用户询问“BlockDrive 身份验证流程”、“钱包同步至数据库”、“Clerk 与 Crossmint、Supabase 的集成”、“嵌入式钱包同步”、“带钱包的用户资料”、“sync-crossmint-wallet”、“钱包数据库存储”、“多链钱包流程”,或需要理解并实现 BlockDrive 中所采用的完整身份验证与钱包同步流程时,应使用此技能。这是将用户身份与多链区块链钱包相连接的核心集成模式。

SKILL.md
--- frontmatter
name: Clerk-Crossmint-Supabase Integration Flow
description: This skill should be used when the user asks about "BlockDrive auth flow", "wallet sync to database", "Clerk Crossmint Supabase integration", "embedded wallet sync", "user profile with wallet", "sync-crossmint-wallet", "wallet database storage", "multichain wallet flow", or needs to understand or implement the complete authentication and wallet synchronization flow used in BlockDrive. This is the core integration pattern connecting user identity to multichain blockchain wallets.
version: 0.2.0

Clerk-Crossmint-Supabase Integration Flow

Overview

BlockDrive uses a three-service integration pattern: Clerk for identity, Crossmint for embedded wallets, and Supabase for data persistence. This creates a seamless experience where users authenticate once and automatically receive multichain blockchain wallets (Solana + EVM chains) linked to their account.

When to Use

Activate this skill when:

  • Understanding the complete BlockDrive auth architecture
  • Implementing wallet-to-user linking
  • Syncing multichain wallet addresses to the database
  • Troubleshooting the auth/wallet flow
  • Extending the integration pattern for new chains

Complete Architecture

code
┌─────────────────────────────────────────────────────────────────┐
│                 BLOCKDRIVE AUTH ARCHITECTURE                     │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌──────────┐     ┌──────────────┐     ┌──────────┐            │
│  │  CLERK   │────▶│  CROSSMINT   │────▶│ SUPABASE │            │
│  │ Identity │     │ Multi-Wallet │     │ Database │            │
│  └──────────┘     └──────────────┘     └──────────┘            │
│       │                  │                  │                   │
│       │                  │                  │                   │
│  1. User signs in   2. Creates wallets  3. Multi-chain         │
│     via Clerk          on ALL chains       addresses stored    │
│                                                                  │
│  ────────────────────────────────────────────────────────────  │
│                                                                  │
│  User Experience: Sign in once → Wallets automatically created │
│  No seed phrases, no wallet extensions, gas-sponsored txns     │
│  Supported Chains: Solana + Ethereum + Base + Polygon + more  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Key Benefits

  • Multichain from Day 1: Single auth creates wallets on Solana + 50+ EVM chains
  • Automatic: Users get wallets without manual setup
  • Gas Sponsored: Crossmint pays for transaction fees
  • Non-Custodial: MPC wallets, no seed phrases
  • Built-in Compliance: AML/KYC for enterprise users

Step-by-Step Flow

Step 1: User Authentication (Clerk)

typescript
// User signs in via Clerk UI component
// Clerk manages the entire auth flow

import { useAuth, useUser } from '@clerk/clerk-react';

const { isSignedIn, getToken } = useAuth();
const { user } = useUser();

// Wait for successful sign-in
if (isSignedIn && user) {
  // Proceed to wallet initialization
  const email = user.primaryEmailAddress?.emailAddress;
}

Step 2: Wallet Initialization (Crossmint)

typescript
import { CrossmintWalletProvider } from '@crossmint/client-sdk-react-ui';

// Crossmint automatically creates wallets on login
// No manual initialization required
<CrossmintWalletProvider createOnLogin={{
  chain: 'solana:devnet',  // Primary chain
  signer: { type: 'email', email: user.email },
}}>
  {children}
</CrossmintWalletProvider>

// Wallets created on ALL chains:
// - Solana (devnet/mainnet)
// - Ethereum, Base, Polygon, Arbitrum, Optimism

Step 3: Wallet Address Retrieval

typescript
import { useWallet } from '@crossmint/client-sdk-react-ui';

const { wallet } = useWallet();

// Get addresses for all chains
const addresses = {
  solana: wallet.address,  // Primary Solana address
  ethereum: await wallet.getAddress('ethereum'),
  base: await wallet.getAddress('base'),
  polygon: await wallet.getAddress('polygon'),
};

Step 4: Database Sync (Supabase)

typescript
// Call Supabase edge function to sync wallet addresses
const response = await fetch(
  `${SUPABASE_URL}/functions/v1/sync-crossmint-wallet`,
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${clerkToken}`,
    },
    body: JSON.stringify({
      clerkUserId: user.id,
      walletId: wallet.id,
      addresses: addresses,
    }),
  }
);

// Edge function stores addresses in crossmint_wallets table

Database Schema

sql
CREATE TABLE crossmint_wallets (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES profiles(id),
  clerk_user_id TEXT NOT NULL,

  -- Crossmint wallet identifier
  crossmint_wallet_id TEXT UNIQUE NOT NULL,

  -- Multi-chain addresses
  solana_address TEXT,
  ethereum_address TEXT,
  base_address TEXT,
  polygon_address TEXT,
  arbitrum_address TEXT,
  optimism_address TEXT,

  -- Metadata
  wallet_type TEXT DEFAULT 'crossmint_embedded',
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW(),
  is_active BOOLEAN DEFAULT TRUE,

  CONSTRAINT unique_user_crossmint UNIQUE (user_id, clerk_user_id)
);

-- Indexes for fast lookups
CREATE INDEX idx_crossmint_wallets_clerk_user ON crossmint_wallets(clerk_user_id);
CREATE INDEX idx_crossmint_wallets_solana ON crossmint_wallets(solana_address);
CREATE INDEX idx_crossmint_wallets_ethereum ON crossmint_wallets(ethereum_address);

Supabase Edge Function

typescript
// supabase/functions/sync-crossmint-wallet/index.ts

import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

serve(async (req) => {
  const { clerkUserId, walletId, addresses } = await req.json();

  // Initialize Supabase
  const supabase = createClient(
    Deno.env.get('SUPABASE_URL')!,
    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
  );

  // Get user profile
  const { data: profile } = await supabase
    .from('profiles')
    .select('id')
    .eq('clerk_user_id', clerkUserId)
    .single();

  // Upsert wallet addresses
  await supabase
    .from('crossmint_wallets')
    .upsert({
      user_id: profile.id,
      clerk_user_id: clerkUserId,
      crossmint_wallet_id: walletId,
      solana_address: addresses.solana,
      ethereum_address: addresses.ethereum,
      base_address: addresses.base,
      polygon_address: addresses.polygon,
      updated_at: new Date().toISOString(),
    }, {
      onConflict: 'clerk_user_id',
    });

  return new Response(JSON.stringify({ success: true }));
});

React Provider Setup

typescript
// src/providers/CrossmintProvider.tsx

import { CrossmintProvider, CrossmintAuthProvider, CrossmintWalletProvider } from '@crossmint/client-sdk-react-ui';
import { useAuth, useUser } from '@clerk/clerk-react';

export function AppCrossmintProvider({ children }) {
  const { isSignedIn } = useAuth();
  const { user } = useUser();

  if (!isSignedIn || !user) {
    return <>{children}</>;
  }

  return (
    <CrossmintProvider apiKey={CROSSMINT_API_KEY}>
      <CrossmintAuthProvider>
        <CrossmintWalletProvider createOnLogin={{
          chain: 'solana:devnet',
          signer: { type: 'email', email: user.primaryEmailAddress.emailAddress },
        }}>
          {children}
        </CrossmintWalletProvider>
      </CrossmintAuthProvider>
    </CrossmintProvider>
  );
}

Complete Integration Guide

For comprehensive implementation details, see:

  • Plugin: plugins/crossmint-fullstack/
  • Setup Command: /crossmint:setup
  • Wallet Flow Command: /crossmint:create-wallet-flow
  • Documentation: docs/CROSSMINT_INTEGRATION_PLAN.md

Comparison to Previous Architecture

FeaturePrevious (Alchemy)Current (Crossmint)
Chains SupportedSolana onlySolana + 50+ EVM chains
Wallet CreationManual per chainAutomatic multichain
Setup ComplexityModerateSimple (createOnLogin)
NFT MintingExternal toolsBuilt-in API
Gas SponsorshipPolicy-basedBuilt-in
Enterprise FeaturesLimitedAML/KYC built-in

Troubleshooting

Issue: Wallet not created after sign-in

  • Check Crossmint API key is valid
  • Verify createOnLogin config is set
  • Check browser console for errors
  • Ensure Clerk authentication completed

Issue: Addresses not syncing to database

  • Verify edge function deployed
  • Check edge function logs in Supabase dashboard
  • Ensure RLS policies allow wallet insertion
  • Validate Clerk token in edge function

Issue: Wrong chain addresses

  • Use wallet.getAddress(chain) for specific chains
  • Primary wallet.address is always Solana
  • Chain identifiers: 'ethereum', 'base', 'polygon', etc.

Next Steps

  1. Install Crossmint SDK: npm install @crossmint/client-sdk-react-ui
  2. Run setup wizard: /crossmint:setup
  3. Generate wallet flow: /crossmint:create-wallet-flow
  4. Deploy edge function: supabase functions deploy sync-crossmint-wallet
  5. Test multichain wallet creation

References