import { getHumanitySdk } from './humanity-sdk'
export class AuthService {
private readonly sdk = getHumanitySdk()
async extractUserData(accessToken: string): Promise<ExtractedUserData> {
const tokenPayload = this.decodeJwt(accessToken)
// 1. Fetch email preset for user email
const userProfile = await this.fetchEmailPreset(accessToken)
// 2. Verify social account presets in batch
const linkedSocials = await this.verifySocialAccounts(accessToken)
// 3. Check travel profile using query engine
const travelProfile = await this.checkTravelProfile(accessToken)
// 4. Build presets list from social connections and travel
const presets = this.buildPresetsList(linkedSocials, travelProfile)
return {
humanityUserId:
(tokenPayload?.sub as string) || userProfile.humanityId || '',
appScopedUserId:
(tokenPayload?.app_scoped_user_id as string) ||
(tokenPayload?.sub as string) ||
'',
email: userProfile.email || (tokenPayload?.email as string | undefined),
evmAddress: userProfile.evmAddress,
linkedSocials,
presets,
travelProfile,
rawEvidence: { ...tokenPayload, ...userProfile.evidence },
}
}
// 1. Fetch email preset for user email
private async fetchEmailPreset(accessToken: string): Promise<{
email?: string
evmAddress?: string
humanityId?: string
evidence: Record<string, unknown>
}> {
try {
const result = await this.sdk.verifyPreset({
preset: 'email',
accessToken,
})
const email =
typeof result.value === 'string' ? result.value : result.evidence?.email
const evidence = result.evidence || {}
const evmAddress = result.evidence?.wallet_address
const humanityId = result.evidence?.humanity_id
return {
email: email || undefined,
evmAddress: evmAddress || undefined,
humanityId: humanityId || undefined,
evidence: evidence as Record<string, unknown>,
}
} catch {
return { evidence: {} }
}
}
// 2. Verify social connection presets in batch
private async verifySocialAccounts(
accessToken: string,
): Promise<SocialAccount[]> {
const socials: SocialAccount[] = []
const now = new Date()
try {
const batchResult = await this.sdk.verifyPresets({
accessToken,
presets: [
'google_connected',
'linkedin_connected',
'twitter_connected',
'discord_connected',
'github_connected',
'telegram_connected',
],
})
for (const preset of SOCIAL_PRESETS) {
const result = batchResult.results?.find(
(r: any) => r.presetName === preset || r.preset === preset,
)
const isConnected = result?.value === true
const provider = SOCIAL_PRESET_TO_PROVIDER[preset]
socials.push({
provider: provider as SocialAccount['provider'],
connected: isConnected,
username: undefined,
connectedAt: isConnected ? now : undefined,
})
}
} catch {
// Return empty socials on error
for (const preset of SOCIAL_PRESETS) {
const provider = SOCIAL_PRESET_TO_PROVIDER[preset]
socials.push({
provider: provider as SocialAccount['provider'],
connected: false,
username: undefined,
connectedAt: undefined,
})
}
}
return socials
}
}