feat: replace supabase auth with citizen/visa identity system for P2P

Replace all supabase.auth.getUser() calls with P2PIdentityContext that
resolves identity from on-chain citizen NFT or off-chain visa system.

- Add identityToUUID() in shared/lib/identity.ts (UUID v5 from citizen/visa number)
- Add P2PIdentityContext with citizen NFT detection and visa fallback
- Add p2p_visa migration for off-chain visa issuance
- Refactor p2p-fiat.ts: all functions now accept userId parameter
- Fix all P2P components to use useP2PIdentity() instead of useAuth()
- Update verify-deposit edge function: walletToUUID -> identityToUUID
- Add P2PLayout with identity gate (wallet/citizen/visa checks)
- Wrap all P2P routes with P2PLayout in App.tsx
This commit is contained in:
2026-02-23 19:54:57 +03:00
parent 350b65dec3
commit bb772668ba
25 changed files with 594 additions and 237 deletions
@@ -35,10 +35,10 @@ const RPC_WS = 'wss://rpc.pezkuwichain.io'
// Token decimals
const DECIMALS = 12
// Generate deterministic UUID v5 from wallet address
async function walletToUUID(walletAddress: string): Promise<string> {
// Generate deterministic UUID v5 from identity ID (citizen number or visa number)
async function identityToUUID(identityId: string): Promise<string> {
const NAMESPACE = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'
const data = new TextEncoder().encode(walletAddress)
const data = new TextEncoder().encode(identityId)
const namespaceBytes = new Uint8Array(16)
const hex = NAMESPACE.replace(/-/g, '')
for (let i = 0; i < 16; i++) {
@@ -66,6 +66,7 @@ interface DepositRequest {
token: 'HEZ' | 'PEZ'
expectedAmount: number
walletAddress: string
identityId: string
blockNumber?: number
}
@@ -371,11 +372,11 @@ serve(async (req) => {
const serviceClient = createClient(supabaseUrl, supabaseServiceKey)
const body: DepositRequest = await req.json()
const { txHash, token, expectedAmount, walletAddress, blockNumber } = body
const { txHash, token, expectedAmount, walletAddress, identityId, blockNumber } = body
if (!txHash || !token || !expectedAmount || !walletAddress) {
if (!txHash || !token || !expectedAmount || !walletAddress || !identityId) {
return new Response(
JSON.stringify({ success: false, error: 'Missing required fields: txHash, token, expectedAmount, walletAddress' }),
JSON.stringify({ success: false, error: 'Missing required fields: txHash, token, expectedAmount, walletAddress, identityId' }),
{ status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
)
}
@@ -414,8 +415,8 @@ serve(async (req) => {
}
}
// Map wallet address to deterministic UUID
const userId = await walletToUUID(walletAddress)
// Map identity (citizen/visa number) to deterministic UUID
const userId = await identityToUUID(identityId)
// Create or update deposit request
const { data: depositRequest, error: requestError } = await serviceClient