@vitalpoint/near-phantom-auth 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +250 -0
- package/dist/client/index.cjs +399 -0
- package/dist/client/index.cjs.map +1 -0
- package/dist/client/index.js +391 -0
- package/dist/client/index.js.map +1 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/server/index.cjs +1687 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.js +1676 -0
- package/dist/server/index.js.map +1 -0
- package/package.json +91 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/server/db/adapters/postgres.ts","../../src/server/session.ts","../../src/server/passkey.ts","../../src/server/mpc.ts","../../src/server/recovery/wallet.ts","../../src/server/recovery/ipfs.ts","../../src/server/middleware.ts","../../src/server/codename.ts","../../src/server/router.ts","../../src/server/index.ts"],"names":["randomUUID","createHash","randomBytes"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * PostgreSQL Database Adapter\n */\n\nimport type {\n DatabaseAdapter,\n AnonUser,\n CreateUserInput,\n Session,\n CreateSessionInput,\n Passkey,\n CreatePasskeyInput,\n Challenge,\n RecoveryData,\n RecoveryType,\n AuthenticatorTransport,\n} from '../../../types/index.js';\n\nexport interface PostgresConfig {\n connectionString: string;\n}\n\n/**\n * SQL schema for near-anon-auth tables\n */\nexport const POSTGRES_SCHEMA = `\n-- Anonymous users\nCREATE TABLE IF NOT EXISTS anon_users (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n codename TEXT UNIQUE NOT NULL,\n near_account_id TEXT UNIQUE NOT NULL,\n mpc_public_key TEXT NOT NULL,\n derivation_path TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n last_active_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n);\n\n-- Passkeys (WebAuthn credentials)\nCREATE TABLE IF NOT EXISTS anon_passkeys (\n credential_id TEXT PRIMARY KEY,\n user_id UUID NOT NULL REFERENCES anon_users(id) ON DELETE CASCADE,\n public_key BYTEA NOT NULL,\n counter BIGINT NOT NULL DEFAULT 0,\n device_type TEXT NOT NULL,\n backed_up BOOLEAN NOT NULL DEFAULT false,\n transports TEXT[],\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n);\n\n-- Sessions\nCREATE TABLE IF NOT EXISTS anon_sessions (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n user_id UUID NOT NULL REFERENCES anon_users(id) ON DELETE CASCADE,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n expires_at TIMESTAMPTZ NOT NULL,\n last_activity_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n ip_address TEXT,\n user_agent TEXT\n);\n\n-- WebAuthn challenges (temporary)\nCREATE TABLE IF NOT EXISTS anon_challenges (\n id UUID PRIMARY KEY,\n challenge TEXT NOT NULL,\n type TEXT NOT NULL,\n user_id UUID REFERENCES anon_users(id) ON DELETE CASCADE,\n expires_at TIMESTAMPTZ NOT NULL,\n metadata JSONB\n);\n\n-- Recovery data references\nCREATE TABLE IF NOT EXISTS anon_recovery (\n id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n user_id UUID NOT NULL REFERENCES anon_users(id) ON DELETE CASCADE,\n type TEXT NOT NULL,\n reference TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n UNIQUE(user_id, type)\n);\n\n-- Indexes\nCREATE INDEX IF NOT EXISTS idx_anon_sessions_user ON anon_sessions(user_id);\nCREATE INDEX IF NOT EXISTS idx_anon_sessions_expires ON anon_sessions(expires_at);\nCREATE INDEX IF NOT EXISTS idx_anon_passkeys_user ON anon_passkeys(user_id);\nCREATE INDEX IF NOT EXISTS idx_anon_challenges_expires ON anon_challenges(expires_at);\n`;\n\n/**\n * Create PostgreSQL adapter\n * \n * Note: Requires 'pg' package to be installed by the consuming application\n */\nexport function createPostgresAdapter(config: PostgresConfig): DatabaseAdapter {\n // Dynamic import of pg to make it optional\n let pool: import('pg').Pool | null = null;\n \n async function getPool(): Promise<import('pg').Pool> {\n if (!pool) {\n const { Pool } = await import('pg');\n pool = new Pool({ connectionString: config.connectionString });\n }\n return pool;\n }\n\n return {\n async initialize() {\n const p = await getPool();\n await p.query(POSTGRES_SCHEMA);\n },\n\n async createUser(input: CreateUserInput): Promise<AnonUser> {\n const p = await getPool();\n const result = await p.query(\n `INSERT INTO anon_users (codename, near_account_id, mpc_public_key, derivation_path)\n VALUES ($1, $2, $3, $4)\n RETURNING id, codename, near_account_id, mpc_public_key, derivation_path, created_at, last_active_at`,\n [input.codename, input.nearAccountId, input.mpcPublicKey, input.derivationPath]\n );\n \n const row = result.rows[0];\n return {\n id: row.id,\n codename: row.codename,\n nearAccountId: row.near_account_id,\n mpcPublicKey: row.mpc_public_key,\n derivationPath: row.derivation_path,\n createdAt: row.created_at,\n lastActiveAt: row.last_active_at,\n };\n },\n\n async getUserById(id: string): Promise<AnonUser | null> {\n const p = await getPool();\n const result = await p.query(\n 'SELECT * FROM anon_users WHERE id = $1',\n [id]\n );\n \n if (result.rows.length === 0) return null;\n \n const row = result.rows[0];\n return {\n id: row.id,\n codename: row.codename,\n nearAccountId: row.near_account_id,\n mpcPublicKey: row.mpc_public_key,\n derivationPath: row.derivation_path,\n createdAt: row.created_at,\n lastActiveAt: row.last_active_at,\n };\n },\n\n async getUserByCodename(codename: string): Promise<AnonUser | null> {\n const p = await getPool();\n const result = await p.query(\n 'SELECT * FROM anon_users WHERE codename = $1',\n [codename]\n );\n \n if (result.rows.length === 0) return null;\n \n const row = result.rows[0];\n return {\n id: row.id,\n codename: row.codename,\n nearAccountId: row.near_account_id,\n mpcPublicKey: row.mpc_public_key,\n derivationPath: row.derivation_path,\n createdAt: row.created_at,\n lastActiveAt: row.last_active_at,\n };\n },\n\n async getUserByNearAccount(nearAccountId: string): Promise<AnonUser | null> {\n const p = await getPool();\n const result = await p.query(\n 'SELECT * FROM anon_users WHERE near_account_id = $1',\n [nearAccountId]\n );\n \n if (result.rows.length === 0) return null;\n \n const row = result.rows[0];\n return {\n id: row.id,\n codename: row.codename,\n nearAccountId: row.near_account_id,\n mpcPublicKey: row.mpc_public_key,\n derivationPath: row.derivation_path,\n createdAt: row.created_at,\n lastActiveAt: row.last_active_at,\n };\n },\n\n async createPasskey(input: CreatePasskeyInput): Promise<Passkey> {\n const p = await getPool();\n await p.query(\n `INSERT INTO anon_passkeys (credential_id, user_id, public_key, counter, device_type, backed_up, transports)\n VALUES ($1, $2, $3, $4, $5, $6, $7)`,\n [\n input.credentialId,\n input.userId,\n input.publicKey,\n input.counter,\n input.deviceType,\n input.backedUp,\n input.transports || null,\n ]\n );\n \n return {\n ...input,\n createdAt: new Date(),\n };\n },\n\n async getPasskeyById(credentialId: string): Promise<Passkey | null> {\n const p = await getPool();\n const result = await p.query(\n 'SELECT * FROM anon_passkeys WHERE credential_id = $1',\n [credentialId]\n );\n \n if (result.rows.length === 0) return null;\n \n const row = result.rows[0];\n return {\n credentialId: row.credential_id,\n userId: row.user_id,\n publicKey: row.public_key,\n counter: row.counter,\n deviceType: row.device_type,\n backedUp: row.backed_up,\n transports: row.transports,\n createdAt: row.created_at,\n };\n },\n\n async getPasskeysByUserId(userId: string): Promise<Passkey[]> {\n const p = await getPool();\n const result = await p.query(\n 'SELECT * FROM anon_passkeys WHERE user_id = $1',\n [userId]\n );\n \n return result.rows.map((row: Record<string, unknown>) => ({\n credentialId: row.credential_id as string,\n userId: row.user_id as string,\n publicKey: row.public_key as Uint8Array,\n counter: row.counter as number,\n deviceType: row.device_type as 'singleDevice' | 'multiDevice',\n backedUp: row.backed_up as boolean,\n transports: row.transports as AuthenticatorTransport[] | undefined,\n createdAt: row.created_at as Date,\n }));\n },\n\n async updatePasskeyCounter(credentialId: string, counter: number): Promise<void> {\n const p = await getPool();\n await p.query(\n 'UPDATE anon_passkeys SET counter = $1 WHERE credential_id = $2',\n [counter, credentialId]\n );\n },\n\n async deletePasskey(credentialId: string): Promise<void> {\n const p = await getPool();\n await p.query('DELETE FROM anon_passkeys WHERE credential_id = $1', [credentialId]);\n },\n\n async createSession(input: CreateSessionInput & { id?: string }): Promise<Session> {\n const p = await getPool();\n const result = await p.query(\n `INSERT INTO anon_sessions (id, user_id, expires_at, ip_address, user_agent)\n VALUES (COALESCE($1, gen_random_uuid()), $2, $3, $4, $5)\n RETURNING id, user_id, created_at, expires_at, last_activity_at, ip_address, user_agent`,\n [input.id || null, input.userId, input.expiresAt, input.ipAddress || null, input.userAgent || null]\n );\n \n const row = result.rows[0];\n return {\n id: row.id,\n userId: row.user_id,\n createdAt: row.created_at,\n expiresAt: row.expires_at,\n lastActivityAt: row.last_activity_at,\n ipAddress: row.ip_address,\n userAgent: row.user_agent,\n };\n },\n\n async getSession(sessionId: string): Promise<Session | null> {\n const p = await getPool();\n const result = await p.query(\n 'SELECT * FROM anon_sessions WHERE id = $1 AND expires_at > NOW()',\n [sessionId]\n );\n \n if (result.rows.length === 0) return null;\n \n const row = result.rows[0];\n return {\n id: row.id,\n userId: row.user_id,\n createdAt: row.created_at,\n expiresAt: row.expires_at,\n lastActivityAt: row.last_activity_at,\n ipAddress: row.ip_address,\n userAgent: row.user_agent,\n };\n },\n\n async deleteSession(sessionId: string): Promise<void> {\n const p = await getPool();\n await p.query('DELETE FROM anon_sessions WHERE id = $1', [sessionId]);\n },\n\n async deleteUserSessions(userId: string): Promise<void> {\n const p = await getPool();\n await p.query('DELETE FROM anon_sessions WHERE user_id = $1', [userId]);\n },\n\n async cleanExpiredSessions(): Promise<number> {\n const p = await getPool();\n const result = await p.query('DELETE FROM anon_sessions WHERE expires_at < NOW()');\n return result.rowCount || 0;\n },\n\n async storeChallenge(challenge: Challenge): Promise<void> {\n const p = await getPool();\n await p.query(\n `INSERT INTO anon_challenges (id, challenge, type, user_id, expires_at, metadata)\n VALUES ($1, $2, $3, $4, $5, $6)`,\n [\n challenge.id,\n challenge.challenge,\n challenge.type,\n challenge.userId || null,\n challenge.expiresAt,\n challenge.metadata ? JSON.stringify(challenge.metadata) : null,\n ]\n );\n },\n\n async getChallenge(challengeId: string): Promise<Challenge | null> {\n const p = await getPool();\n const result = await p.query(\n 'SELECT * FROM anon_challenges WHERE id = $1',\n [challengeId]\n );\n \n if (result.rows.length === 0) return null;\n \n const row = result.rows[0];\n return {\n id: row.id,\n challenge: row.challenge,\n type: row.type,\n userId: row.user_id,\n expiresAt: row.expires_at,\n metadata: row.metadata,\n };\n },\n\n async deleteChallenge(challengeId: string): Promise<void> {\n const p = await getPool();\n await p.query('DELETE FROM anon_challenges WHERE id = $1', [challengeId]);\n },\n\n async storeRecoveryData(data: RecoveryData): Promise<void> {\n const p = await getPool();\n await p.query(\n `INSERT INTO anon_recovery (user_id, type, reference)\n VALUES ($1, $2, $3)\n ON CONFLICT (user_id, type) DO UPDATE SET reference = $3, created_at = NOW()`,\n [data.userId, data.type, data.reference]\n );\n },\n\n async getRecoveryData(userId: string, type: RecoveryType): Promise<RecoveryData | null> {\n const p = await getPool();\n const result = await p.query(\n 'SELECT * FROM anon_recovery WHERE user_id = $1 AND type = $2',\n [userId, type]\n );\n \n if (result.rows.length === 0) return null;\n \n const row = result.rows[0];\n return {\n userId: row.user_id,\n type: row.type,\n reference: row.reference,\n createdAt: row.created_at,\n };\n },\n };\n}\n","/**\n * Session Management\n * \n * HttpOnly cookie-based sessions for XSS protection.\n * Sessions are stored server-side (database) with secure cookie reference.\n */\n\nimport { randomUUID, createHmac } from 'crypto';\nimport type { Response, Request } from 'express';\nimport type { Session, CreateSessionInput, DatabaseAdapter } from '../types/index.js';\n\nconst SESSION_COOKIE_NAME = 'anon_session';\nconst DEFAULT_SESSION_DURATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\nexport interface SessionConfig {\n /** Secret for signing session cookies */\n secret: string;\n /** Cookie name (default: anon_session) */\n cookieName?: string;\n /** Session duration in ms (default: 7 days) */\n durationMs?: number;\n /** Cookie domain (optional) */\n domain?: string;\n /** Cookie path (default: /) */\n path?: string;\n /** Secure flag (default: true in production) */\n secure?: boolean;\n /** SameSite setting (default: strict) */\n sameSite?: 'strict' | 'lax' | 'none';\n}\n\nexport interface SessionManager {\n createSession(\n userId: string,\n res: Response,\n options?: { ipAddress?: string; userAgent?: string }\n ): Promise<Session>;\n \n getSession(req: Request): Promise<Session | null>;\n \n destroySession(req: Request, res: Response): Promise<void>;\n \n refreshSession(req: Request, res: Response): Promise<Session | null>;\n}\n\n/**\n * Sign a session ID with HMAC\n */\nfunction signSessionId(sessionId: string, secret: string): string {\n const signature = createHmac('sha256', secret)\n .update(sessionId)\n .digest('base64url');\n return `${sessionId}.${signature}`;\n}\n\n/**\n * Verify and extract session ID from signed value\n */\nfunction verifySessionId(signedValue: string, secret: string): string | null {\n const parts = signedValue.split('.');\n if (parts.length !== 2) return null;\n \n const [sessionId, signature] = parts;\n const expectedSignature = createHmac('sha256', secret)\n .update(sessionId)\n .digest('base64url');\n \n if (signature !== expectedSignature) return null;\n return sessionId;\n}\n\n/**\n * Parse cookies from request\n */\nfunction parseCookies(req: Request): Record<string, string> {\n const cookies: Record<string, string> = {};\n const cookieHeader = req.headers.cookie;\n \n if (!cookieHeader) return cookies;\n \n cookieHeader.split(';').forEach((cookie) => {\n const [name, ...rest] = cookie.trim().split('=');\n if (name && rest.length) {\n cookies[name] = decodeURIComponent(rest.join('='));\n }\n });\n \n return cookies;\n}\n\n/**\n * Create session manager\n */\nexport function createSessionManager(\n db: DatabaseAdapter,\n config: SessionConfig\n): SessionManager {\n const cookieName = config.cookieName || SESSION_COOKIE_NAME;\n const durationMs = config.durationMs || DEFAULT_SESSION_DURATION_MS;\n const isProduction = process.env.NODE_ENV === 'production';\n \n const cookieOptions = {\n httpOnly: true,\n secure: config.secure ?? isProduction,\n sameSite: config.sameSite || 'strict',\n path: config.path || '/',\n domain: config.domain,\n };\n\n return {\n async createSession(userId, res, options = {}) {\n const sessionId = randomUUID();\n const now = new Date();\n const expiresAt = new Date(now.getTime() + durationMs);\n \n const sessionInput: CreateSessionInput = {\n userId,\n expiresAt,\n ipAddress: options.ipAddress,\n userAgent: options.userAgent,\n };\n \n const session = await db.createSession({\n ...sessionInput,\n id: sessionId,\n } as Session);\n \n // Sign and set cookie\n const signedId = signSessionId(sessionId, config.secret);\n \n res.cookie(cookieName, signedId, {\n ...cookieOptions,\n maxAge: durationMs,\n expires: expiresAt,\n });\n \n return session;\n },\n \n async getSession(req) {\n const cookies = parseCookies(req);\n const signedId = cookies[cookieName];\n \n if (!signedId) return null;\n \n const sessionId = verifySessionId(signedId, config.secret);\n if (!sessionId) return null;\n \n const session = await db.getSession(sessionId);\n \n if (!session) return null;\n \n // Check if expired\n if (session.expiresAt < new Date()) {\n await db.deleteSession(sessionId);\n return null;\n }\n \n return session;\n },\n \n async destroySession(req, res) {\n const cookies = parseCookies(req);\n const signedId = cookies[cookieName];\n \n if (signedId) {\n const sessionId = verifySessionId(signedId, config.secret);\n if (sessionId) {\n await db.deleteSession(sessionId);\n }\n }\n \n // Clear cookie\n res.clearCookie(cookieName, {\n ...cookieOptions,\n });\n },\n \n async refreshSession(req, res) {\n const session = await this.getSession(req);\n \n if (!session) return null;\n \n // Check if session is past 50% of its lifetime (sliding window)\n const now = Date.now();\n const created = session.createdAt.getTime();\n const expires = session.expiresAt.getTime();\n const lifetime = expires - created;\n const elapsed = now - created;\n \n if (elapsed > lifetime * 0.5) {\n // Extend session\n const newExpiresAt = new Date(now + durationMs);\n \n // Update in database would happen here\n // For now, just update cookie\n const signedId = signSessionId(session.id, config.secret);\n \n res.cookie(cookieName, signedId, {\n ...cookieOptions,\n maxAge: durationMs,\n expires: newExpiresAt,\n });\n }\n \n return session;\n },\n };\n}\n","/**\n * Passkey (WebAuthn) Authentication\n * \n * Handles passkey registration and authentication using @simplewebauthn/server\n */\n\nimport {\n generateRegistrationOptions,\n verifyRegistrationResponse,\n generateAuthenticationOptions,\n verifyAuthenticationResponse,\n} from '@simplewebauthn/server';\nimport type {\n GenerateRegistrationOptionsOpts,\n GenerateAuthenticationOptionsOpts,\n VerifyRegistrationResponseOpts,\n VerifyAuthenticationResponseOpts,\n VerifiedRegistrationResponse,\n VerifiedAuthenticationResponse,\n} from '@simplewebauthn/server';\nimport { randomUUID } from 'crypto';\nimport type {\n DatabaseAdapter,\n Challenge,\n Passkey,\n CreatePasskeyInput,\n PublicKeyCredentialCreationOptionsJSON,\n PublicKeyCredentialRequestOptionsJSON,\n RegistrationResponseJSON,\n AuthenticationResponseJSON,\n AuthenticatorTransport,\n} from '../types/index.js';\n\nexport interface PasskeyConfig {\n /** Relying Party name (shown to users) */\n rpName: string;\n /** Relying Party ID (your domain, e.g., 'example.com') */\n rpId: string;\n /** Origin for WebAuthn (e.g., 'https://example.com') */\n origin: string;\n /** Challenge timeout in ms (default: 60000) */\n challengeTimeoutMs?: number;\n}\n\nexport interface PasskeyManager {\n startRegistration(\n userId: string,\n userDisplayName: string\n ): Promise<{\n challengeId: string;\n options: PublicKeyCredentialCreationOptionsJSON;\n }>;\n \n finishRegistration(\n challengeId: string,\n response: RegistrationResponseJSON\n ): Promise<{\n verified: boolean;\n passkeyData?: {\n credentialId: string;\n publicKey: Uint8Array;\n counter: number;\n deviceType: 'singleDevice' | 'multiDevice';\n backedUp: boolean;\n transports?: AuthenticatorTransport[];\n };\n tempUserId?: string;\n }>;\n \n startAuthentication(\n userId?: string\n ): Promise<{\n challengeId: string;\n options: PublicKeyCredentialRequestOptionsJSON;\n }>;\n \n finishAuthentication(\n challengeId: string,\n response: AuthenticationResponseJSON\n ): Promise<{\n verified: boolean;\n userId?: string;\n passkey?: Passkey;\n }>;\n}\n\n/**\n * Create passkey manager\n */\nexport function createPasskeyManager(\n db: DatabaseAdapter,\n config: PasskeyConfig\n): PasskeyManager {\n const challengeTimeoutMs = config.challengeTimeoutMs || 60000;\n\n return {\n async startRegistration(userId, userDisplayName) {\n // For registration, userId is a temp ID - user doesn't exist yet\n // We store it in metadata, not as a foreign key\n \n const options = await generateRegistrationOptions({\n rpName: config.rpName,\n rpID: config.rpId,\n userName: userDisplayName,\n userDisplayName: userDisplayName,\n userID: new TextEncoder().encode(userId),\n attestationType: 'none',\n excludeCredentials: [], // No existing passkeys for new user\n authenticatorSelection: {\n residentKey: 'preferred',\n userVerification: 'preferred',\n authenticatorAttachment: 'platform',\n },\n } as GenerateRegistrationOptionsOpts);\n \n // Store challenge - userId goes in metadata since user doesn't exist yet\n const challengeId = randomUUID();\n const challenge: Challenge = {\n id: challengeId,\n challenge: options.challenge,\n type: 'registration',\n userId: undefined, // Don't set foreign key - user doesn't exist\n expiresAt: new Date(Date.now() + challengeTimeoutMs),\n metadata: { tempUserId: userId, userDisplayName }, // Store temp ID here\n };\n \n await db.storeChallenge(challenge);\n \n return {\n challengeId,\n options: options as unknown as PublicKeyCredentialCreationOptionsJSON,\n };\n },\n \n async finishRegistration(challengeId, response) {\n // Get and validate challenge\n const challenge = await db.getChallenge(challengeId);\n \n if (!challenge) {\n throw new Error('Challenge not found or expired');\n }\n \n if (challenge.type !== 'registration') {\n throw new Error('Invalid challenge type');\n }\n \n if (challenge.expiresAt < new Date()) {\n await db.deleteChallenge(challengeId);\n throw new Error('Challenge expired');\n }\n \n // Get temp user ID from metadata (for registration, user doesn't exist yet)\n const tempUserId = challenge.metadata?.tempUserId as string | undefined;\n if (!tempUserId) {\n throw new Error('Challenge missing temp user ID');\n }\n \n // Verify registration\n let verification: VerifiedRegistrationResponse;\n try {\n verification = await verifyRegistrationResponse({\n response: response as unknown as Parameters<typeof verifyRegistrationResponse>[0]['response'],\n expectedChallenge: challenge.challenge,\n expectedOrigin: config.origin,\n expectedRPID: config.rpId,\n } as VerifyRegistrationResponseOpts);\n } catch (error) {\n console.error('[Passkey] Registration verification failed:', error);\n await db.deleteChallenge(challengeId);\n return { verified: false };\n }\n \n if (!verification.verified || !verification.registrationInfo) {\n await db.deleteChallenge(challengeId);\n return { verified: false };\n }\n \n const { registrationInfo } = verification;\n \n // Clean up challenge\n await db.deleteChallenge(challengeId);\n \n // Return verified data - caller must create user first, then passkey\n // We return the passkey data but don't save it yet (user doesn't exist)\n return {\n verified: true,\n passkeyData: {\n credentialId: registrationInfo.credential.id,\n publicKey: registrationInfo.credential.publicKey,\n counter: registrationInfo.credential.counter,\n deviceType: registrationInfo.credentialDeviceType,\n backedUp: registrationInfo.credentialBackedUp,\n transports: response.response.transports,\n },\n tempUserId,\n };\n },\n \n async startAuthentication(userId) {\n // Get user's passkeys if userId provided\n let allowCredentials: Array<{\n id: string;\n type: 'public-key';\n transports?: AuthenticatorTransport[];\n }> | undefined;\n \n if (userId) {\n const passkeys = await db.getPasskeysByUserId(userId);\n allowCredentials = passkeys.map((pk) => ({\n id: pk.credentialId,\n type: 'public-key' as const,\n transports: pk.transports,\n }));\n }\n \n const options = await generateAuthenticationOptions({\n rpID: config.rpId,\n userVerification: 'preferred',\n allowCredentials,\n } as GenerateAuthenticationOptionsOpts);\n \n // Store challenge\n const challengeId = randomUUID();\n const challenge: Challenge = {\n id: challengeId,\n challenge: options.challenge,\n type: 'authentication',\n userId,\n expiresAt: new Date(Date.now() + challengeTimeoutMs),\n };\n \n await db.storeChallenge(challenge);\n \n return {\n challengeId,\n options: options as unknown as PublicKeyCredentialRequestOptionsJSON,\n };\n },\n \n async finishAuthentication(challengeId, response) {\n // Get and validate challenge\n const challenge = await db.getChallenge(challengeId);\n \n if (!challenge) {\n throw new Error('Challenge not found or expired');\n }\n \n if (challenge.type !== 'authentication') {\n throw new Error('Invalid challenge type');\n }\n \n if (challenge.expiresAt < new Date()) {\n await db.deleteChallenge(challengeId);\n throw new Error('Challenge expired');\n }\n \n // Find passkey by credential ID\n const passkey = await db.getPasskeyById(response.id);\n \n if (!passkey) {\n await db.deleteChallenge(challengeId);\n throw new Error('Passkey not found');\n }\n \n // Verify authentication\n let verification: VerifiedAuthenticationResponse;\n try {\n verification = await verifyAuthenticationResponse({\n response: response as unknown as Parameters<typeof verifyAuthenticationResponse>[0]['response'],\n expectedChallenge: challenge.challenge,\n expectedOrigin: config.origin,\n expectedRPID: config.rpId,\n credential: {\n id: passkey.credentialId,\n publicKey: passkey.publicKey,\n counter: passkey.counter,\n transports: passkey.transports,\n },\n } as VerifyAuthenticationResponseOpts);\n } catch (error) {\n console.error('[Passkey] Authentication verification failed:', error);\n await db.deleteChallenge(challengeId);\n return { verified: false };\n }\n \n if (!verification.verified) {\n await db.deleteChallenge(challengeId);\n return { verified: false };\n }\n \n // Update counter\n await db.updatePasskeyCounter(\n passkey.credentialId,\n verification.authenticationInfo.newCounter\n );\n \n // Clean up challenge\n await db.deleteChallenge(challengeId);\n \n return {\n verified: true,\n userId: passkey.userId,\n passkey,\n };\n },\n };\n}\n","/**\n * NEAR MPC Account Manager\n * \n * Creates NEAR accounts using Chain Signatures MPC network.\n * No private keys are stored - all key management is decentralized.\n */\n\nimport { createHash, randomBytes } from 'crypto';\n\nexport interface MPCAccount {\n nearAccountId: string;\n derivationPath: string;\n mpcPublicKey: string;\n onChain: boolean;\n}\n\nexport interface MPCConfig {\n networkId: 'testnet' | 'mainnet';\n accountPrefix?: string;\n}\n\n/**\n * Get the MPC contract ID for a network\n */\nfunction getMPCContractId(networkId: 'testnet' | 'mainnet'): string {\n return networkId === 'mainnet'\n ? 'v1.signer-prod.near'\n : 'v1.signer-prod.testnet';\n}\n\n/**\n * Get the RPC URL for a network\n */\nfunction getRPCUrl(networkId: 'testnet' | 'mainnet'): string {\n return networkId === 'mainnet'\n ? 'https://rpc.mainnet.near.org'\n : 'https://rpc.testnet.near.org';\n}\n\n/**\n * Base58 encode bytes\n */\nfunction base58Encode(bytes: Buffer): string {\n const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n let result = '';\n let num = BigInt('0x' + bytes.toString('hex'));\n\n while (num > 0n) {\n const remainder = Number(num % 58n);\n num = num / 58n;\n result = ALPHABET[remainder] + result;\n }\n\n // Handle leading zeros\n for (const byte of bytes) {\n if (byte === 0) {\n result = '1' + result;\n } else {\n break;\n }\n }\n\n return result || '1';\n}\n\n/**\n * Derive Ed25519 public key from seed (simplified for account creation)\n */\nfunction derivePublicKey(seed: Buffer): Buffer {\n const hash = createHash('sha512').update(seed).digest();\n return hash.subarray(0, 32);\n}\n\n/**\n * Check if NEAR account exists on-chain\n */\nasync function accountExists(\n accountId: string, \n networkId: 'testnet' | 'mainnet'\n): Promise<boolean> {\n try {\n const rpcUrl = getRPCUrl(networkId);\n const response = await fetch(rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 'check-account',\n method: 'query',\n params: {\n request_type: 'view_account',\n finality: 'final',\n account_id: accountId,\n },\n }),\n });\n\n const result = await response.json() as { error?: unknown };\n return !result.error;\n } catch {\n return false;\n }\n}\n\n/**\n * Create NEAR account on testnet using helper API\n */\nasync function createTestnetAccount(accountId: string): Promise<string> {\n // Generate a random keypair for initial account access\n const seed = randomBytes(32);\n const publicKeyBytes = derivePublicKey(seed);\n const publicKey = `ed25519:${base58Encode(publicKeyBytes)}`;\n\n const helperUrl = 'https://helper.testnet.near.org/account';\n\n const response = await fetch(helperUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n newAccountId: accountId,\n newAccountPublicKey: publicKey,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Testnet helper error: ${response.status} - ${errorText}`);\n }\n\n return publicKey;\n}\n\n/**\n * Generate a deterministic account name from user ID\n */\nfunction generateAccountName(userId: string, prefix: string): string {\n const hash = createHash('sha256').update(userId).digest('hex');\n const shortHash = hash.substring(0, 12);\n return `${prefix}-${shortHash}`;\n}\n\n/**\n * MPC Account Manager\n */\nexport class MPCAccountManager {\n private networkId: 'testnet' | 'mainnet';\n private mpcContractId: string;\n private accountPrefix: string;\n\n constructor(config: MPCConfig) {\n this.networkId = config.networkId;\n this.mpcContractId = getMPCContractId(config.networkId);\n this.accountPrefix = config.accountPrefix || 'anon';\n }\n\n /**\n * Create a new NEAR account for an anonymous user\n */\n async createAccount(userId: string): Promise<MPCAccount> {\n const accountName = generateAccountName(userId, this.accountPrefix);\n const suffix = this.networkId === 'mainnet' ? '.near' : '.testnet';\n const nearAccountId = `${accountName}${suffix}`;\n\n // Derivation path for MPC key generation\n const derivationPath = `near-anon-auth,${userId}`;\n\n console.log('[MPC] Creating NEAR account:', {\n nearAccountId,\n derivationPath,\n mpcContractId: this.mpcContractId,\n });\n\n // Check if account already exists\n const exists = await accountExists(nearAccountId, this.networkId);\n if (exists) {\n console.log('[MPC] Account already exists:', nearAccountId);\n return {\n nearAccountId,\n derivationPath,\n mpcPublicKey: 'existing-account',\n onChain: true,\n };\n }\n\n // Create account on testnet\n if (this.networkId === 'testnet') {\n try {\n const publicKey = await createTestnetAccount(nearAccountId);\n console.log('[MPC] Account created:', nearAccountId);\n \n return {\n nearAccountId,\n derivationPath,\n mpcPublicKey: publicKey,\n onChain: true,\n };\n } catch (error) {\n console.error('[MPC] Account creation failed:', error);\n return {\n nearAccountId,\n derivationPath,\n mpcPublicKey: 'creation-failed',\n onChain: false,\n };\n }\n }\n\n // Mainnet requires funded creator account\n // For now, return with onChain: false\n console.warn('[MPC] Mainnet account creation requires funded creator');\n return {\n nearAccountId,\n derivationPath,\n mpcPublicKey: 'mainnet-pending',\n onChain: false,\n };\n }\n\n /**\n * Add a recovery wallet as an access key to the MPC account\n * \n * This creates an on-chain link without storing it in our database.\n * The recovery wallet can be used to prove ownership and create new passkeys.\n */\n async addRecoveryWallet(\n nearAccountId: string,\n recoveryWalletId: string\n ): Promise<{ success: boolean; txHash?: string }> {\n // In production, this would:\n // 1. Create an AddKey transaction\n // 2. Sign it with the MPC key\n // 3. Submit to NEAR\n //\n // The recovery wallet gets a FunctionCall access key that can only:\n // - Call our recovery contract\n // - Not transfer funds or do anything else\n \n console.log('[MPC] Adding recovery wallet:', {\n nearAccountId,\n recoveryWalletId,\n });\n\n // TODO: Implement full MPC signing flow\n // For now, mark as pending\n void nearAccountId;\n void recoveryWalletId;\n \n return {\n success: true,\n txHash: `pending-${Date.now()}`,\n };\n }\n\n /**\n * Verify that a wallet has recovery access to an account\n */\n async verifyRecoveryWallet(\n nearAccountId: string,\n recoveryWalletId: string\n ): Promise<boolean> {\n try {\n const rpcUrl = getRPCUrl(this.networkId);\n\n const response = await fetch(rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 'check-keys',\n method: 'query',\n params: {\n request_type: 'view_access_key_list',\n finality: 'final',\n account_id: nearAccountId,\n },\n }),\n });\n\n const result = await response.json() as {\n result?: { keys: Array<{ public_key: string }> };\n };\n\n // Check if recovery wallet's key is in the access key list\n // This requires knowing the public key of the recovery wallet\n // For now, return true if account exists\n return !!result.result?.keys?.length;\n } catch {\n return false;\n }\n }\n\n /**\n * Get MPC contract ID\n */\n getMPCContractId(): string {\n return this.mpcContractId;\n }\n\n /**\n * Get network ID\n */\n getNetworkId(): string {\n return this.networkId;\n }\n}\n\n/**\n * Create MPC account manager\n */\nexport function createMPCManager(config: MPCConfig): MPCAccountManager {\n return new MPCAccountManager(config);\n}\n","/**\n * Wallet Recovery\n * \n * Allows users to link a NEAR wallet as a recovery method.\n * The wallet is added as an on-chain access key - no mapping stored in our DB.\n */\n\nimport { createHash } from 'crypto';\nimport nacl from 'tweetnacl';\nimport bs58 from 'bs58';\n\nexport interface WalletRecoveryConfig {\n nearNetwork: 'testnet' | 'mainnet';\n}\n\nexport interface WalletSignature {\n signature: string; // Base64 or hex encoded\n publicKey: string; // ed25519:... format\n message: string; // The signed message\n}\n\n/**\n * Generate a challenge message for wallet signing\n */\nexport function generateWalletChallenge(action: string, timestamp: number): string {\n return `near-anon-auth:${action}:${timestamp}`;\n}\n\n/**\n * Verify a NEAR wallet signature\n */\nexport function verifyWalletSignature(\n signature: WalletSignature,\n expectedMessage: string\n): boolean {\n try {\n if (signature.message !== expectedMessage) {\n return false;\n }\n \n // Extract public key bytes\n const pubKeyStr = signature.publicKey.replace('ed25519:', '');\n const publicKeyBytes = bs58.decode(pubKeyStr);\n \n // Decode signature\n const signatureBytes = Buffer.from(signature.signature, 'base64');\n \n // Hash the message (NEAR signs SHA256 hash)\n const messageHash = createHash('sha256')\n .update(signature.message)\n .digest();\n \n // Verify using nacl\n return nacl.sign.detached.verify(\n messageHash,\n signatureBytes,\n publicKeyBytes\n );\n } catch (error) {\n console.error('[WalletRecovery] Signature verification failed:', error);\n return false;\n }\n}\n\n/**\n * Extract account ID from public key (for implicit accounts)\n */\nexport function publicKeyToImplicitAccount(publicKey: string): string {\n const pubKeyStr = publicKey.replace('ed25519:', '');\n const publicKeyBytes = bs58.decode(pubKeyStr);\n return Buffer.from(publicKeyBytes).toString('hex');\n}\n\n/**\n * Check if a wallet has access key on a NEAR account\n */\nexport async function checkWalletAccess(\n nearAccountId: string,\n walletPublicKey: string,\n networkId: 'testnet' | 'mainnet'\n): Promise<boolean> {\n try {\n const rpcUrl = networkId === 'mainnet'\n ? 'https://rpc.mainnet.near.org'\n : 'https://rpc.testnet.near.org';\n\n const response = await fetch(rpcUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 'check-access-key',\n method: 'query',\n params: {\n request_type: 'view_access_key',\n finality: 'final',\n account_id: nearAccountId,\n public_key: walletPublicKey,\n },\n }),\n });\n\n const result = await response.json() as { error?: unknown };\n return !result.error;\n } catch {\n return false;\n }\n}\n\n/**\n * Wallet Recovery Manager\n */\nexport interface WalletRecoveryManager {\n /**\n * Generate challenge for linking a wallet\n */\n generateLinkChallenge(): { challenge: string; expiresAt: Date };\n \n /**\n * Verify wallet signature and prepare for linking\n */\n verifyLinkSignature(\n signature: WalletSignature,\n challenge: string\n ): { verified: boolean; walletId?: string };\n \n /**\n * Generate challenge for recovery\n */\n generateRecoveryChallenge(): { challenge: string; expiresAt: Date };\n \n /**\n * Verify recovery signature\n */\n verifyRecoverySignature(\n signature: WalletSignature,\n challenge: string,\n nearAccountId: string\n ): Promise<{ verified: boolean }>;\n}\n\nexport function createWalletRecoveryManager(\n config: WalletRecoveryConfig\n): WalletRecoveryManager {\n const CHALLENGE_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\n\n return {\n generateLinkChallenge() {\n const timestamp = Date.now();\n const challenge = generateWalletChallenge('link-recovery', timestamp);\n const expiresAt = new Date(Date.now() + CHALLENGE_TIMEOUT_MS);\n return { challenge, expiresAt };\n },\n\n verifyLinkSignature(signature, challenge) {\n const verified = verifyWalletSignature(signature, challenge);\n \n if (!verified) {\n return { verified: false };\n }\n \n // Extract wallet ID from signature's public key\n // For named accounts, we'll need the account ID from the request\n // For implicit accounts, we derive from public key\n const walletId = signature.publicKey;\n \n return { verified: true, walletId };\n },\n\n generateRecoveryChallenge() {\n const timestamp = Date.now();\n const challenge = generateWalletChallenge('recover-account', timestamp);\n const expiresAt = new Date(Date.now() + CHALLENGE_TIMEOUT_MS);\n return { challenge, expiresAt };\n },\n\n async verifyRecoverySignature(signature, challenge, nearAccountId) {\n // First verify the signature itself\n if (!verifyWalletSignature(signature, challenge)) {\n return { verified: false };\n }\n \n // Then verify this wallet has access to the NEAR account\n const hasAccess = await checkWalletAccess(\n nearAccountId,\n signature.publicKey,\n config.nearNetwork\n );\n \n return { verified: hasAccess };\n },\n };\n}\n","/**\n * IPFS + Password Recovery\n * \n * Encrypts recovery data with user's password and stores on IPFS.\n * User needs password + CID to recover.\n * \n * Supported pinning services:\n * - Pinata (https://pinata.cloud)\n * - web3.storage (https://web3.storage)\n * - Infura (https://infura.io)\n */\n\nimport { randomBytes, createCipheriv, createDecipheriv, scrypt } from 'crypto';\nimport { promisify } from 'util';\n\nconst scryptAsync = promisify(scrypt);\n\nexport interface IPFSRecoveryConfig {\n pinningService: 'pinata' | 'web3storage' | 'infura' | 'custom';\n /** API key (required for pinata, web3storage, infura) */\n apiKey?: string;\n /** API secret (required for pinata, infura) */\n apiSecret?: string;\n /** Project ID (required for infura) */\n projectId?: string;\n /** Custom pinning function */\n customPin?: (data: Uint8Array) => Promise<string>;\n /** Custom fetch function */\n customFetch?: (cid: string) => Promise<Uint8Array>;\n}\n\nexport interface EncryptedRecoveryData {\n /** Encrypted payload (base64) */\n ciphertext: string;\n /** Initialization vector (base64) */\n iv: string;\n /** Salt for key derivation (base64) */\n salt: string;\n /** Auth tag for GCM (base64) */\n authTag: string;\n /** Version for future compatibility */\n version: 1;\n}\n\nexport interface RecoveryPayload {\n userId: string;\n nearAccountId: string;\n derivationPath: string;\n createdAt: number;\n}\n\n/**\n * Derive encryption key from password\n */\nasync function deriveKey(password: string, salt: Buffer): Promise<Buffer> {\n return scryptAsync(password, salt, 32) as Promise<Buffer>;\n}\n\n/**\n * Encrypt recovery data\n */\nexport async function encryptRecoveryData(\n payload: RecoveryPayload,\n password: string\n): Promise<EncryptedRecoveryData> {\n const salt = randomBytes(32);\n const iv = randomBytes(16);\n const key = await deriveKey(password, salt);\n \n const cipher = createCipheriv('aes-256-gcm', key, iv);\n \n const payloadJson = JSON.stringify(payload);\n const encrypted = Buffer.concat([\n cipher.update(payloadJson, 'utf8'),\n cipher.final(),\n ]);\n \n const authTag = cipher.getAuthTag();\n \n return {\n ciphertext: encrypted.toString('base64'),\n iv: iv.toString('base64'),\n salt: salt.toString('base64'),\n authTag: authTag.toString('base64'),\n version: 1,\n };\n}\n\n/**\n * Decrypt recovery data\n */\nexport async function decryptRecoveryData(\n encryptedData: EncryptedRecoveryData,\n password: string\n): Promise<RecoveryPayload> {\n const salt = Buffer.from(encryptedData.salt, 'base64');\n const iv = Buffer.from(encryptedData.iv, 'base64');\n const ciphertext = Buffer.from(encryptedData.ciphertext, 'base64');\n const authTag = Buffer.from(encryptedData.authTag, 'base64');\n \n const key = await deriveKey(password, salt);\n \n const decipher = createDecipheriv('aes-256-gcm', key, iv);\n decipher.setAuthTag(authTag);\n \n try {\n const decrypted = Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]);\n \n return JSON.parse(decrypted.toString('utf8'));\n } catch {\n throw new Error('Invalid password or corrupted data');\n }\n}\n\n// ============================================\n// Pinning Services\n// ============================================\n\n/**\n * Pin data to IPFS using Pinata\n * https://docs.pinata.cloud/api-reference/endpoint/pin-file-to-ipfs\n */\nasync function pinToPinata(\n data: Uint8Array,\n apiKey: string,\n apiSecret: string\n): Promise<string> {\n const formData = new FormData();\n const buffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) as ArrayBuffer;\n formData.append('file', new Blob([buffer]), 'recovery.json');\n \n const response = await fetch('https://api.pinata.cloud/pinning/pinFileToIPFS', {\n method: 'POST',\n headers: {\n 'pinata_api_key': apiKey,\n 'pinata_secret_api_key': apiSecret,\n },\n body: formData,\n });\n \n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Pinata error: ${response.status} - ${error}`);\n }\n \n const result = await response.json() as { IpfsHash: string };\n return result.IpfsHash;\n}\n\n/**\n * Pin data to IPFS using web3.storage\n * https://web3.storage/docs/how-to/upload/\n */\nasync function pinToWeb3Storage(\n data: Uint8Array,\n apiToken: string\n): Promise<string> {\n const buffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) as ArrayBuffer;\n \n const response = await fetch('https://api.web3.storage/upload', {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${apiToken}`,\n 'Content-Type': 'application/octet-stream',\n 'X-Name': 'phantom-recovery.json',\n },\n body: buffer,\n });\n \n if (!response.ok) {\n const error = await response.text();\n throw new Error(`web3.storage error: ${response.status} - ${error}`);\n }\n \n const result = await response.json() as { cid: string };\n return result.cid;\n}\n\n/**\n * Pin data to IPFS using Infura\n * https://docs.infura.io/infura/networks/ipfs/http-api-methods/add\n */\nasync function pinToInfura(\n data: Uint8Array,\n projectId: string,\n projectSecret: string\n): Promise<string> {\n const formData = new FormData();\n const buffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) as ArrayBuffer;\n formData.append('file', new Blob([buffer]), 'recovery.json');\n \n const auth = Buffer.from(`${projectId}:${projectSecret}`).toString('base64');\n \n const response = await fetch('https://ipfs.infura.io:5001/api/v0/add', {\n method: 'POST',\n headers: {\n 'Authorization': `Basic ${auth}`,\n },\n body: formData,\n });\n \n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Infura error: ${response.status} - ${error}`);\n }\n \n const result = await response.json() as { Hash: string };\n return result.Hash;\n}\n\n/**\n * Fetch data from IPFS gateway\n */\nasync function fetchFromIPFS(cid: string): Promise<Uint8Array> {\n // Try multiple gateways for reliability\n const gateways = [\n `https://gateway.pinata.cloud/ipfs/${cid}`,\n `https://w3s.link/ipfs/${cid}`,\n `https://ipfs.infura.io/ipfs/${cid}`,\n `https://ipfs.io/ipfs/${cid}`,\n `https://cloudflare-ipfs.com/ipfs/${cid}`,\n `https://dweb.link/ipfs/${cid}`,\n ];\n \n for (const gateway of gateways) {\n try {\n const response = await fetch(gateway, {\n headers: {\n 'Accept': 'application/octet-stream',\n },\n });\n if (response.ok) {\n return new Uint8Array(await response.arrayBuffer());\n }\n } catch {\n continue;\n }\n }\n \n throw new Error('Failed to fetch from IPFS - tried all gateways');\n}\n\n/**\n * IPFS Recovery Manager\n */\nexport interface IPFSRecoveryManager {\n /**\n * Create and pin encrypted recovery data\n */\n createRecoveryBackup(\n payload: RecoveryPayload,\n password: string\n ): Promise<{ cid: string }>;\n \n /**\n * Recover data from IPFS\n */\n recoverFromBackup(\n cid: string,\n password: string\n ): Promise<RecoveryPayload>;\n \n /**\n * Validate password strength\n */\n validatePassword(password: string): {\n valid: boolean;\n errors: string[];\n strength: 'weak' | 'medium' | 'strong';\n };\n}\n\nexport function createIPFSRecoveryManager(\n config: IPFSRecoveryConfig\n): IPFSRecoveryManager {\n const MIN_PASSWORD_LENGTH = 12;\n\n async function pinData(data: Uint8Array): Promise<string> {\n if (config.customPin) {\n return config.customPin(data);\n }\n \n switch (config.pinningService) {\n case 'pinata':\n if (!config.apiKey || !config.apiSecret) {\n throw new Error('Pinata requires apiKey and apiSecret');\n }\n return pinToPinata(data, config.apiKey, config.apiSecret);\n \n case 'web3storage':\n if (!config.apiKey) {\n throw new Error('web3.storage requires apiKey (API token)');\n }\n return pinToWeb3Storage(data, config.apiKey);\n \n case 'infura':\n if (!config.projectId || !config.apiSecret) {\n throw new Error('Infura requires projectId and apiSecret');\n }\n return pinToInfura(data, config.projectId, config.apiSecret);\n \n case 'custom':\n throw new Error('Custom pinning requires customPin function');\n \n default:\n throw new Error(`Unknown pinning service: ${config.pinningService}`);\n }\n }\n\n async function fetchData(cid: string): Promise<Uint8Array> {\n if (config.customFetch) {\n return config.customFetch(cid);\n }\n return fetchFromIPFS(cid);\n }\n\n function calculatePasswordStrength(password: string): 'weak' | 'medium' | 'strong' {\n let score = 0;\n \n if (password.length >= 12) score++;\n if (password.length >= 16) score++;\n if (/[a-z]/.test(password)) score++;\n if (/[A-Z]/.test(password)) score++;\n if (/[0-9]/.test(password)) score++;\n if (/[^a-zA-Z0-9]/.test(password)) score++;\n \n if (score <= 2) return 'weak';\n if (score <= 4) return 'medium';\n return 'strong';\n }\n\n return {\n async createRecoveryBackup(payload, password) {\n // Validate password\n const validation = this.validatePassword(password);\n if (!validation.valid) {\n throw new Error(`Invalid password: ${validation.errors.join(', ')}`);\n }\n \n // Encrypt payload\n const encrypted = await encryptRecoveryData(payload, password);\n \n // Convert to bytes\n const data = new TextEncoder().encode(JSON.stringify(encrypted));\n \n // Pin to IPFS\n const cid = await pinData(data);\n \n console.log(`[IPFS] Recovery backup created: ${cid} (${config.pinningService})`);\n \n return { cid };\n },\n\n async recoverFromBackup(cid, password) {\n // Fetch from IPFS\n const data = await fetchData(cid);\n \n // Parse encrypted data\n const encrypted: EncryptedRecoveryData = JSON.parse(\n new TextDecoder().decode(data)\n );\n \n // Decrypt\n return decryptRecoveryData(encrypted, password);\n },\n\n validatePassword(password) {\n const errors: string[] = [];\n \n if (password.length < MIN_PASSWORD_LENGTH) {\n errors.push(`Password must be at least ${MIN_PASSWORD_LENGTH} characters`);\n }\n \n if (!/[a-z]/.test(password)) {\n errors.push('Password must contain lowercase letters');\n }\n \n if (!/[A-Z]/.test(password)) {\n errors.push('Password must contain uppercase letters');\n }\n \n if (!/[0-9]/.test(password)) {\n errors.push('Password must contain numbers');\n }\n \n const strength = calculatePasswordStrength(password);\n \n return {\n valid: errors.length === 0,\n errors,\n strength,\n };\n },\n };\n}\n","/**\n * Express Middleware\n * \n * Authentication middleware and route protection for Express apps.\n */\n\nimport type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport type { SessionManager } from './session.js';\nimport type { DatabaseAdapter, AnonUser } from '../types/index.js';\n\n/**\n * Create authentication middleware\n * \n * Attaches user and session to request if valid session exists.\n */\nexport function createAuthMiddleware(\n sessionManager: SessionManager,\n db: DatabaseAdapter\n): RequestHandler {\n return async (req: Request, res: Response, next: NextFunction) => {\n try {\n const session = await sessionManager.getSession(req);\n \n if (session) {\n const user = await db.getUserById(session.userId);\n \n if (user) {\n req.anonUser = user;\n req.anonSession = session;\n \n // Refresh session (sliding window)\n await sessionManager.refreshSession(req, res);\n }\n }\n \n next();\n } catch (error) {\n console.error('[AnonAuth] Middleware error:', error);\n next();\n }\n };\n}\n\n/**\n * Create route protection middleware\n * \n * Returns 401 if no valid session.\n */\nexport function createRequireAuth(\n sessionManager: SessionManager,\n db: DatabaseAdapter\n): RequestHandler {\n return async (req: Request, res: Response, next: NextFunction) => {\n try {\n const session = await sessionManager.getSession(req);\n \n if (!session) {\n return res.status(401).json({ error: 'Authentication required' });\n }\n \n const user = await db.getUserById(session.userId);\n \n if (!user) {\n return res.status(401).json({ error: 'User not found' });\n }\n \n req.anonUser = user;\n req.anonSession = session;\n \n // Refresh session\n await sessionManager.refreshSession(req, res);\n \n next();\n } catch (error) {\n console.error('[AnonAuth] Auth check error:', error);\n res.status(500).json({ error: 'Authentication check failed' });\n }\n };\n}\n","/**\n * Codename Generator\n * \n * Generates anonymous codenames for HUMINT sources\n */\n\nimport { randomBytes } from 'crypto';\n\nconst NATO_PHONETIC = [\n 'ALPHA', 'BRAVO', 'CHARLIE', 'DELTA', 'ECHO', 'FOXTROT', 'GOLF', 'HOTEL',\n 'INDIA', 'JULIET', 'KILO', 'LIMA', 'MIKE', 'NOVEMBER', 'OSCAR', 'PAPA',\n 'QUEBEC', 'ROMEO', 'SIERRA', 'TANGO', 'UNIFORM', 'VICTOR', 'WHISKEY',\n 'XRAY', 'YANKEE', 'ZULU'\n];\n\nconst ADJECTIVES = [\n 'SWIFT', 'SILENT', 'SHADOW', 'STEEL', 'STORM', 'FROST', 'CRIMSON', 'GOLDEN',\n 'SILVER', 'IRON', 'DARK', 'BRIGHT', 'RAPID', 'GHOST', 'PHANTOM', 'ARCTIC',\n 'DESERT', 'OCEAN', 'MOUNTAIN', 'FOREST', 'THUNDER', 'LIGHTNING', 'COSMIC'\n];\n\nconst ANIMALS = [\n 'FALCON', 'EAGLE', 'HAWK', 'WOLF', 'BEAR', 'LION', 'TIGER', 'PANTHER',\n 'COBRA', 'VIPER', 'RAVEN', 'OWL', 'SHARK', 'DRAGON', 'PHOENIX', 'GRIFFIN',\n 'LEOPARD', 'JAGUAR', 'LYNX', 'FOX', 'ORCA', 'RAPTOR', 'CONDOR'\n];\n\nexport type CodenameStyle = 'nato-phonetic' | 'animals' | 'custom';\n\n/**\n * Generate a random number suffix (1-99)\n */\nfunction randomSuffix(): number {\n const bytes = randomBytes(1);\n return (bytes[0] % 99) + 1;\n}\n\n/**\n * Pick a random element from an array\n */\nfunction randomPick<T>(array: T[]): T {\n const bytes = randomBytes(1);\n return array[bytes[0] % array.length];\n}\n\n/**\n * Generate NATO phonetic codename (e.g., ALPHA-7, BRAVO-42)\n */\nexport function generateNatoCodename(): string {\n const word = randomPick(NATO_PHONETIC);\n const num = randomSuffix();\n return `${word}-${num}`;\n}\n\n/**\n * Generate animal codename (e.g., SWIFT-FALCON-42)\n */\nexport function generateAnimalCodename(): string {\n const adj = randomPick(ADJECTIVES);\n const animal = randomPick(ANIMALS);\n const num = randomSuffix();\n return `${adj}-${animal}-${num}`;\n}\n\n/**\n * Generate codename based on style\n */\nexport function generateCodename(style: CodenameStyle = 'nato-phonetic'): string {\n switch (style) {\n case 'nato-phonetic':\n return generateNatoCodename();\n case 'animals':\n return generateAnimalCodename();\n default:\n return generateNatoCodename();\n }\n}\n\n/**\n * Check if a codename format is valid\n */\nexport function isValidCodename(codename: string): boolean {\n // NATO: WORD-NN\n const natoPattern = /^[A-Z]+-\\d{1,2}$/;\n // Animal: WORD-WORD-NN\n const animalPattern = /^[A-Z]+-[A-Z]+-\\d{1,2}$/;\n \n return natoPattern.test(codename) || animalPattern.test(codename);\n}\n","/**\n * Express Router\n * \n * API routes for registration, authentication, and recovery.\n */\n\nimport { Router, json } from 'express';\nimport type { Request, Response } from 'express';\nimport type { SessionManager } from './session.js';\nimport type { PasskeyManager } from './passkey.js';\nimport type { MPCAccountManager } from './mpc.js';\nimport type { WalletRecoveryManager } from './recovery/wallet.js';\nimport type { IPFSRecoveryManager } from './recovery/ipfs.js';\nimport type { DatabaseAdapter, CodenameConfig } from '../types/index.js';\nimport { generateCodename, isValidCodename } from './codename.js';\n\nexport interface RouterConfig {\n db: DatabaseAdapter;\n sessionManager: SessionManager;\n passkeyManager: PasskeyManager;\n mpcManager: MPCAccountManager;\n walletRecovery?: WalletRecoveryManager;\n ipfsRecovery?: IPFSRecoveryManager;\n codename?: CodenameConfig;\n}\n\nexport function createRouter(config: RouterConfig): Router {\n const router = Router();\n const {\n db,\n sessionManager,\n passkeyManager,\n mpcManager,\n walletRecovery,\n ipfsRecovery,\n } = config;\n\n // Parse JSON bodies\n router.use(json());\n\n // ============================================\n // Registration\n // ============================================\n\n /**\n * POST /register/start\n * Start passkey registration\n */\n router.post('/register/start', async (req: Request, res: Response) => {\n try {\n // Generate temporary user ID for registration\n const tempUserId = crypto.randomUUID();\n \n // Generate codename\n const style = config.codename?.style || 'nato-phonetic';\n let codename: string;\n \n if (config.codename?.generator) {\n codename = config.codename.generator(tempUserId);\n } else {\n codename = generateCodename(style);\n }\n \n // Ensure codename is unique\n let attempts = 0;\n while (await db.getUserByCodename(codename) && attempts < 10) {\n codename = generateCodename(style);\n attempts++;\n }\n \n if (attempts >= 10) {\n return res.status(500).json({ error: 'Failed to generate unique codename' });\n }\n \n const { challengeId, options } = await passkeyManager.startRegistration(\n tempUserId,\n codename\n );\n \n res.json({\n challengeId,\n options,\n codename,\n tempUserId,\n });\n } catch (error) {\n console.error('[AnonAuth] Registration start error:', error);\n res.status(500).json({ error: 'Registration failed' });\n }\n });\n\n /**\n * POST /register/finish\n * Complete passkey registration\n */\n router.post('/register/finish', async (req: Request, res: Response) => {\n try {\n const { challengeId, response, tempUserId, codename } = req.body;\n \n if (!challengeId || !response || !tempUserId || !codename) {\n return res.status(400).json({ error: 'Missing required fields' });\n }\n \n if (!isValidCodename(codename)) {\n return res.status(400).json({ error: 'Invalid codename format' });\n }\n \n // Verify passkey registration\n const { verified, passkey } = await passkeyManager.finishRegistration(\n challengeId,\n response\n );\n \n if (!verified || !passkey) {\n return res.status(400).json({ error: 'Passkey verification failed' });\n }\n \n // Create NEAR account via MPC\n const mpcAccount = await mpcManager.createAccount(tempUserId);\n \n // Create user\n const user = await db.createUser({\n codename,\n nearAccountId: mpcAccount.nearAccountId,\n mpcPublicKey: mpcAccount.mpcPublicKey,\n derivationPath: mpcAccount.derivationPath,\n });\n \n // Update passkey with real user ID\n // (In a real implementation, we'd update the passkey record)\n \n // Create session\n const session = await sessionManager.createSession(user.id, res, {\n ipAddress: req.ip,\n userAgent: req.headers['user-agent'],\n });\n \n res.json({\n success: true,\n codename: user.codename,\n nearAccountId: user.nearAccountId,\n });\n } catch (error) {\n console.error('[AnonAuth] Registration finish error:', error);\n res.status(500).json({ error: 'Registration failed' });\n }\n });\n\n // ============================================\n // Authentication\n // ============================================\n\n /**\n * POST /login/start\n * Start passkey authentication\n */\n router.post('/login/start', async (req: Request, res: Response) => {\n try {\n const { codename } = req.body;\n \n let userId: string | undefined;\n \n if (codename) {\n const user = await db.getUserByCodename(codename);\n if (!user) {\n return res.status(404).json({ error: 'User not found' });\n }\n userId = user.id;\n }\n \n const { challengeId, options } = await passkeyManager.startAuthentication(userId);\n \n res.json({ challengeId, options });\n } catch (error) {\n console.error('[AnonAuth] Login start error:', error);\n res.status(500).json({ error: 'Login failed' });\n }\n });\n\n /**\n * POST /login/finish\n * Complete passkey authentication\n */\n router.post('/login/finish', async (req: Request, res: Response) => {\n try {\n const { challengeId, response } = req.body;\n \n if (!challengeId || !response) {\n return res.status(400).json({ error: 'Missing required fields' });\n }\n \n const { verified, userId } = await passkeyManager.finishAuthentication(\n challengeId,\n response\n );\n \n if (!verified || !userId) {\n return res.status(401).json({ error: 'Authentication failed' });\n }\n \n const user = await db.getUserById(userId);\n \n if (!user) {\n return res.status(404).json({ error: 'User not found' });\n }\n \n // Create session\n await sessionManager.createSession(user.id, res, {\n ipAddress: req.ip,\n userAgent: req.headers['user-agent'],\n });\n \n res.json({\n success: true,\n codename: user.codename,\n });\n } catch (error) {\n console.error('[AnonAuth] Login finish error:', error);\n res.status(500).json({ error: 'Authentication failed' });\n }\n });\n\n /**\n * POST /logout\n * End session\n */\n router.post('/logout', async (req: Request, res: Response) => {\n try {\n await sessionManager.destroySession(req, res);\n res.json({ success: true });\n } catch (error) {\n console.error('[AnonAuth] Logout error:', error);\n res.status(500).json({ error: 'Logout failed' });\n }\n });\n\n /**\n * GET /session\n * Get current session\n */\n router.get('/session', async (req: Request, res: Response) => {\n try {\n const session = await sessionManager.getSession(req);\n \n if (!session) {\n return res.status(401).json({ authenticated: false });\n }\n \n const user = await db.getUserById(session.userId);\n \n if (!user) {\n return res.status(401).json({ authenticated: false });\n }\n \n res.json({\n authenticated: true,\n codename: user.codename,\n nearAccountId: user.nearAccountId,\n expiresAt: session.expiresAt,\n });\n } catch (error) {\n console.error('[AnonAuth] Session check error:', error);\n res.status(500).json({ error: 'Session check failed' });\n }\n });\n\n // ============================================\n // Wallet Recovery\n // ============================================\n\n if (walletRecovery) {\n /**\n * POST /recovery/wallet/link\n * Link a NEAR wallet for recovery\n */\n router.post('/recovery/wallet/link', async (req: Request, res: Response) => {\n try {\n const session = await sessionManager.getSession(req);\n \n if (!session) {\n return res.status(401).json({ error: 'Authentication required' });\n }\n \n const { challenge: walletChallenge, expiresAt } = walletRecovery.generateLinkChallenge();\n \n // Store challenge for verification\n await db.storeChallenge({\n id: crypto.randomUUID(),\n challenge: walletChallenge,\n type: 'recovery',\n userId: session.userId,\n expiresAt,\n metadata: { action: 'wallet-link' },\n });\n \n res.json({\n challenge: walletChallenge,\n expiresAt: expiresAt.toISOString(),\n });\n } catch (error) {\n console.error('[AnonAuth] Wallet link error:', error);\n res.status(500).json({ error: 'Failed to initiate wallet link' });\n }\n });\n\n /**\n * POST /recovery/wallet/verify\n * Verify wallet signature and complete linking\n */\n router.post('/recovery/wallet/verify', async (req: Request, res: Response) => {\n try {\n const session = await sessionManager.getSession(req);\n \n if (!session) {\n return res.status(401).json({ error: 'Authentication required' });\n }\n \n const { signature, challenge, walletAccountId } = req.body;\n \n if (!signature || !challenge || !walletAccountId) {\n return res.status(400).json({ error: 'Missing required fields' });\n }\n \n const { verified, walletId } = walletRecovery.verifyLinkSignature(\n signature,\n challenge\n );\n \n if (!verified) {\n return res.status(401).json({ error: 'Invalid signature' });\n }\n \n const user = await db.getUserById(session.userId);\n \n if (!user) {\n return res.status(404).json({ error: 'User not found' });\n }\n \n // Add wallet as access key on-chain (no DB storage)\n await mpcManager.addRecoveryWallet(user.nearAccountId, walletAccountId);\n \n // Store reference for our records (just the fact that wallet recovery is enabled)\n await db.storeRecoveryData({\n userId: user.id,\n type: 'wallet',\n reference: 'enabled', // We don't store the wallet ID!\n createdAt: new Date(),\n });\n \n res.json({\n success: true,\n message: 'Wallet linked for recovery. The link is stored on-chain, not in our database.',\n });\n } catch (error) {\n console.error('[AnonAuth] Wallet verify error:', error);\n res.status(500).json({ error: 'Failed to verify wallet' });\n }\n });\n\n /**\n * POST /recovery/wallet/start\n * Start wallet-based recovery\n */\n router.post('/recovery/wallet/start', async (req: Request, res: Response) => {\n try {\n const { challenge, expiresAt } = walletRecovery.generateRecoveryChallenge();\n \n res.json({\n challenge,\n expiresAt: expiresAt.toISOString(),\n });\n } catch (error) {\n console.error('[AnonAuth] Wallet recovery start error:', error);\n res.status(500).json({ error: 'Failed to start recovery' });\n }\n });\n\n /**\n * POST /recovery/wallet/finish\n * Complete wallet-based recovery\n */\n router.post('/recovery/wallet/finish', async (req: Request, res: Response) => {\n try {\n const { signature, challenge, nearAccountId } = req.body;\n \n if (!signature || !challenge || !nearAccountId) {\n return res.status(400).json({ error: 'Missing required fields' });\n }\n \n const { verified } = await walletRecovery.verifyRecoverySignature(\n signature,\n challenge,\n nearAccountId\n );\n \n if (!verified) {\n return res.status(401).json({ error: 'Recovery verification failed' });\n }\n \n // Find user by NEAR account\n const user = await db.getUserByNearAccount(nearAccountId);\n \n if (!user) {\n return res.status(404).json({ error: 'Account not found' });\n }\n \n // Create session for recovered user\n await sessionManager.createSession(user.id, res, {\n ipAddress: req.ip,\n userAgent: req.headers['user-agent'],\n });\n \n res.json({\n success: true,\n codename: user.codename,\n message: 'Recovery successful. You can now register a new passkey.',\n });\n } catch (error) {\n console.error('[AnonAuth] Wallet recovery finish error:', error);\n res.status(500).json({ error: 'Recovery failed' });\n }\n });\n }\n\n // ============================================\n // IPFS Recovery\n // ============================================\n\n if (ipfsRecovery) {\n /**\n * POST /recovery/ipfs/setup\n * Create encrypted backup on IPFS\n */\n router.post('/recovery/ipfs/setup', async (req: Request, res: Response) => {\n try {\n const session = await sessionManager.getSession(req);\n \n if (!session) {\n return res.status(401).json({ error: 'Authentication required' });\n }\n \n const { password } = req.body;\n \n if (!password) {\n return res.status(400).json({ error: 'Password required' });\n }\n \n // Validate password\n const validation = ipfsRecovery.validatePassword(password);\n if (!validation.valid) {\n return res.status(400).json({\n error: 'Password too weak',\n details: validation.errors,\n });\n }\n \n const user = await db.getUserById(session.userId);\n \n if (!user) {\n return res.status(404).json({ error: 'User not found' });\n }\n \n // Create and pin backup\n const { cid } = await ipfsRecovery.createRecoveryBackup(\n {\n userId: user.id,\n nearAccountId: user.nearAccountId,\n derivationPath: user.derivationPath,\n createdAt: Date.now(),\n },\n password\n );\n \n // Store CID reference\n await db.storeRecoveryData({\n userId: user.id,\n type: 'ipfs',\n reference: cid,\n createdAt: new Date(),\n });\n \n res.json({\n success: true,\n cid,\n message: 'Backup created. Save this CID with your password - you need both to recover.',\n });\n } catch (error) {\n console.error('[AnonAuth] IPFS setup error:', error);\n res.status(500).json({ error: 'Failed to create backup' });\n }\n });\n\n /**\n * POST /recovery/ipfs/recover\n * Recover using IPFS backup\n */\n router.post('/recovery/ipfs/recover', async (req: Request, res: Response) => {\n try {\n const { cid, password } = req.body;\n \n if (!cid || !password) {\n return res.status(400).json({ error: 'CID and password required' });\n }\n \n // Decrypt backup\n let payload;\n try {\n payload = await ipfsRecovery.recoverFromBackup(cid, password);\n } catch {\n return res.status(401).json({ error: 'Invalid password or CID' });\n }\n \n // Find user\n const user = await db.getUserById(payload.userId);\n \n if (!user) {\n return res.status(404).json({ error: 'Account not found' });\n }\n \n // Create session\n await sessionManager.createSession(user.id, res, {\n ipAddress: req.ip,\n userAgent: req.headers['user-agent'],\n });\n \n res.json({\n success: true,\n codename: user.codename,\n message: 'Recovery successful. You can now register a new passkey.',\n });\n } catch (error) {\n console.error('[AnonAuth] IPFS recovery error:', error);\n res.status(500).json({ error: 'Recovery failed' });\n }\n });\n }\n\n return router;\n}\n","/**\n * Server SDK Entry Point\n * \n * @example\n * ```typescript\n * import { createAnonAuth } from '@vitalpoint/near-anon-auth/server';\n * \n * const anonAuth = createAnonAuth({\n * nearNetwork: 'testnet',\n * sessionSecret: process.env.SESSION_SECRET,\n * database: {\n * type: 'postgres',\n * connectionString: process.env.DATABASE_URL,\n * },\n * rp: {\n * name: 'My App',\n * id: 'myapp.com',\n * origin: 'https://myapp.com',\n * },\n * });\n * \n * app.use('/auth', anonAuth.router);\n * app.get('/protected', anonAuth.requireAuth, handler);\n * ```\n */\n\nimport type { Router, RequestHandler } from 'express';\nimport type { AnonAuthConfig, DatabaseAdapter } from '../types/index.js';\nimport { createPostgresAdapter } from './db/adapters/postgres.js';\nimport { createSessionManager, type SessionManager } from './session.js';\nimport { createPasskeyManager, type PasskeyManager } from './passkey.js';\nimport { createMPCManager, type MPCAccountManager } from './mpc.js';\nimport { createWalletRecoveryManager, type WalletRecoveryManager } from './recovery/wallet.js';\nimport { createIPFSRecoveryManager, type IPFSRecoveryManager } from './recovery/ipfs.js';\nimport { createAuthMiddleware, createRequireAuth } from './middleware.js';\nimport { createRouter } from './router.js';\n\nexport interface AnonAuthInstance {\n /** Express router with all auth endpoints */\n router: Router;\n \n /** Middleware that attaches user to request if authenticated */\n middleware: RequestHandler;\n \n /** Middleware that requires authentication (401 if not) */\n requireAuth: RequestHandler;\n \n /** Initialize database schema */\n initialize(): Promise<void>;\n \n /** Database adapter */\n db: DatabaseAdapter;\n \n /** Session manager */\n sessionManager: SessionManager;\n \n /** Passkey manager */\n passkeyManager: PasskeyManager;\n \n /** MPC account manager */\n mpcManager: MPCAccountManager;\n \n /** Wallet recovery manager (if enabled) */\n walletRecovery?: WalletRecoveryManager;\n \n /** IPFS recovery manager (if enabled) */\n ipfsRecovery?: IPFSRecoveryManager;\n}\n\n/**\n * Create anonymous authentication instance\n */\nexport function createAnonAuth(config: AnonAuthConfig): AnonAuthInstance {\n // Create database adapter\n let db: DatabaseAdapter;\n \n if (config.database.adapter) {\n db = config.database.adapter;\n } else if (config.database.type === 'postgres') {\n if (!config.database.connectionString) {\n throw new Error('PostgreSQL requires connectionString');\n }\n db = createPostgresAdapter({\n connectionString: config.database.connectionString,\n });\n } else if (config.database.type === 'custom') {\n if (!config.database.adapter) {\n throw new Error('Custom database type requires adapter');\n }\n db = config.database.adapter;\n } else {\n throw new Error(`Unsupported database type: ${config.database.type}`);\n }\n\n // Create session manager\n const sessionManager = createSessionManager(db, {\n secret: config.sessionSecret,\n durationMs: config.sessionDurationMs,\n });\n\n // Create passkey manager\n const rpConfig = config.rp || {\n name: 'Anonymous Auth',\n id: 'localhost',\n origin: 'http://localhost:3000',\n };\n\n const passkeyManager = createPasskeyManager(db, {\n rpName: rpConfig.name,\n rpId: rpConfig.id,\n origin: rpConfig.origin,\n });\n\n // Create MPC manager\n const mpcManager = createMPCManager({\n networkId: config.nearNetwork,\n accountPrefix: 'anon',\n });\n\n // Create recovery managers\n let walletRecovery: WalletRecoveryManager | undefined;\n let ipfsRecovery: IPFSRecoveryManager | undefined;\n\n if (config.recovery?.wallet) {\n walletRecovery = createWalletRecoveryManager({\n nearNetwork: config.nearNetwork,\n });\n }\n\n if (config.recovery?.ipfs) {\n ipfsRecovery = createIPFSRecoveryManager(config.recovery.ipfs);\n }\n\n // Create middleware\n const middleware = createAuthMiddleware(sessionManager, db);\n const requireAuth = createRequireAuth(sessionManager, db);\n\n // Create router\n const router = createRouter({\n db,\n sessionManager,\n passkeyManager,\n mpcManager,\n walletRecovery,\n ipfsRecovery,\n codename: config.codename,\n });\n\n return {\n router,\n middleware,\n requireAuth,\n \n async initialize() {\n await db.initialize();\n },\n \n db,\n sessionManager,\n passkeyManager,\n mpcManager,\n walletRecovery,\n ipfsRecovery,\n };\n}\n\n// Re-export types and utilities\nexport type { AnonAuthConfig, DatabaseAdapter, AnonUser, Session } from '../types/index.js';\nexport type { SessionManager, SessionConfig } from './session.js';\nexport type { PasskeyManager, PasskeyConfig } from './passkey.js';\nexport type { MPCAccountManager, MPCConfig, MPCAccount } from './mpc.js';\nexport type { WalletRecoveryManager } from './recovery/wallet.js';\nexport type { IPFSRecoveryManager, IPFSRecoveryConfig } from './recovery/ipfs.js';\nexport { generateCodename, isValidCodename } from './codename.js';\nexport { createPostgresAdapter, POSTGRES_SCHEMA } from './db/adapters/postgres.js';\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vitalpoint/near-phantom-auth",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Anonymous passkey authentication with NEAR MPC accounts and decentralized recovery",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./server": {
|
|
16
|
+
"import": "./dist/server/index.mjs",
|
|
17
|
+
"require": "./dist/server/index.cjs",
|
|
18
|
+
"types": "./dist/server/index.d.ts"
|
|
19
|
+
},
|
|
20
|
+
"./client": {
|
|
21
|
+
"import": "./dist/client/index.mjs",
|
|
22
|
+
"require": "./dist/client/index.cjs",
|
|
23
|
+
"types": "./dist/client/index.d.ts"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsup",
|
|
32
|
+
"dev": "tsup --watch",
|
|
33
|
+
"test": "vitest",
|
|
34
|
+
"lint": "eslint src/",
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"prepublishOnly": "npm run build",
|
|
37
|
+
"prepare": "npm run build"
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"near",
|
|
41
|
+
"authentication",
|
|
42
|
+
"passkey",
|
|
43
|
+
"webauthn",
|
|
44
|
+
"mpc",
|
|
45
|
+
"anonymous",
|
|
46
|
+
"decentralized",
|
|
47
|
+
"web3"
|
|
48
|
+
],
|
|
49
|
+
"author": "VitalPoint AI",
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "git+https://github.com/jim-agent/near-phantom-auth.git"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@near-js/crypto": "^2.0.1",
|
|
57
|
+
"@near-js/keystores": "^0.2.1",
|
|
58
|
+
"@near-js/providers": "^1.0.1",
|
|
59
|
+
"@near-js/signers": "^0.2.1",
|
|
60
|
+
"@near-js/transactions": "^2.0.1",
|
|
61
|
+
"@simplewebauthn/server": "^11.0.0",
|
|
62
|
+
"bs58": "^6.0.0",
|
|
63
|
+
"cookie": "^1.0.2",
|
|
64
|
+
"tweetnacl": "^1.0.3"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/cookie": "^1.0.0",
|
|
68
|
+
"@types/express": "^5.0.6",
|
|
69
|
+
"@types/node": "^22.0.0",
|
|
70
|
+
"@types/pg": "^8.16.0",
|
|
71
|
+
"@types/react": "^19.2.13",
|
|
72
|
+
"tsup": "^8.3.0",
|
|
73
|
+
"typescript": "^5.7.0",
|
|
74
|
+
"vitest": "^3.0.0"
|
|
75
|
+
},
|
|
76
|
+
"peerDependencies": {
|
|
77
|
+
"express": "^4.18.0 || ^5.0.0",
|
|
78
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
79
|
+
},
|
|
80
|
+
"peerDependenciesMeta": {
|
|
81
|
+
"express": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"react": {
|
|
85
|
+
"optional": true
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"engines": {
|
|
89
|
+
"node": ">=18.0.0"
|
|
90
|
+
}
|
|
91
|
+
}
|