Files
pwap/shared/utils/auth.ts
T
Claude 7b95b8a409 Centralize common code in shared folder
This commit reorganizes the codebase to eliminate duplication between web and mobile frontends by moving all commonly used files to the shared folder.

Changes:
- Moved lib files to shared/lib/:
  * wallet.ts, staking.ts, tiki.ts, identity.ts
  * multisig.ts, usdt.ts, scores.ts, citizenship-workflow.ts

- Moved utils to shared/utils/:
  * auth.ts, dex.ts
  * Created format.ts (extracted formatNumber from web utils)

- Created shared/theme/:
  * colors.ts (Kurdistan and App color definitions)

- Updated web configuration:
  * Added @pezkuwi/* path aliases in tsconfig.json and vite.config.ts
  * Updated all imports to use @pezkuwi/lib/*, @pezkuwi/utils/*, @pezkuwi/theme/*
  * Removed duplicate files from web/src/lib and web/src/utils

- Updated mobile configuration:
  * Added @pezkuwi/* path aliases in tsconfig.json
  * Updated theme/colors.ts to re-export from shared
  * Mobile already uses relative imports to shared (no changes needed)

Architecture Benefits:
- Single source of truth for common code
- No duplication between frontends
- Easier maintenance and consistency
- Clear separation of shared vs platform-specific code

Web-specific files kept:
- web/src/lib/supabase.ts
- web/src/lib/utils.ts (cn function for Tailwind, re-exports formatNumber from shared)

All imports updated and tested. Both web and mobile now use the centralized shared folder.
2025-11-14 22:46:39 +00:00

87 lines
2.3 KiB
TypeScript

/**
* Authentication and Authorization Utilities
* Security-critical: Founder wallet detection and permissions
*/
// SECURITY: Founder wallet address for beta testnet
// This address has sudo rights and can perform privileged operations
export const FOUNDER_ADDRESS = '5GgTgG9sRmPQAYU1RsTejZYnZRjwzKZKWD3awtuqjHioki45';
/**
* Check if given address is the founder wallet
* @param address - Substrate address to check
* @returns true if address matches founder, false otherwise
*/
export const isFounderWallet = (address: string | null | undefined): boolean => {
if (!address) return false;
return address === FOUNDER_ADDRESS;
};
/**
* Validate substrate address format
* @param address - Address to validate
* @returns true if address is valid format
*/
export const isValidSubstrateAddress = (address: string): boolean => {
// Substrate addresses start with 5 and are 47-48 characters
return /^5[a-zA-Z0-9]{46,47}$/.test(address);
};
/**
* Permission levels for DEX operations
*/
export enum DexPermission {
// Anyone can perform these
VIEW_POOLS = 'view_pools',
ADD_LIQUIDITY = 'add_liquidity',
REMOVE_LIQUIDITY = 'remove_liquidity',
SWAP = 'swap',
// Only founder can perform these
CREATE_POOL = 'create_pool',
SET_FEE_RATE = 'set_fee_rate',
PAUSE_POOL = 'pause_pool',
WHITELIST_TOKEN = 'whitelist_token',
}
/**
* Check if user has permission for a specific DEX operation
* @param address - User's wallet address
* @param permission - Required permission level
* @returns true if user has permission
*/
export const hasPermission = (
address: string | null | undefined,
permission: DexPermission
): boolean => {
if (!address || !isValidSubstrateAddress(address)) {
return false;
}
const founderOnly = [
DexPermission.CREATE_POOL,
DexPermission.SET_FEE_RATE,
DexPermission.PAUSE_POOL,
DexPermission.WHITELIST_TOKEN,
];
// Founder-only operations
if (founderOnly.includes(permission)) {
return isFounderWallet(address);
}
// Everyone can view and trade
return true;
};
/**
* Get user role string for display
* @param address - User's wallet address
* @returns Human-readable role
*/
export const getUserRole = (address: string | null | undefined): string => {
if (!address) return 'Guest';
if (isFounderWallet(address)) return 'Founder (Admin)';
return 'User';
};