forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {type AppBskyActorGetProfile} from '@atproto/api'
2import {useMutation, useQueryClient} from '@tanstack/react-query'
3
4import {until} from '#/lib/async/until'
5import {useConstellationInstance} from '#/state/preferences/constellation-instance'
6import {
7 useDeerVerificationEnabled,
8 useDeerVerificationTrusted,
9} from '#/state/preferences/deer-verification'
10import {useUpdateProfileVerificationCache} from '#/state/queries/verification/useUpdateProfileVerificationCache'
11import {useAgent, useSession} from '#/state/session'
12import {useAnalytics} from '#/analytics'
13import type * as bsky from '#/types/bsky'
14import {asUri, asyncGenFind, type ConstellationLink} from '../constellation'
15import {
16 getTrustedConstellationVerifications,
17 RQKEY as DEER_VERIFICATION_RQKEY,
18} from '../deer-verification'
19
20export function useVerificationCreateMutation() {
21 const ax = useAnalytics()
22 const agent = useAgent()
23 const {currentAccount} = useSession()
24 const updateProfileVerificationCache = useUpdateProfileVerificationCache()
25
26 const qc = useQueryClient()
27 const deerVerificationEnabled = useDeerVerificationEnabled()
28 const deerVerificationTrusted = useDeerVerificationTrusted(
29 currentAccount?.did,
30 )
31 const constellationInstance = useConstellationInstance()
32
33 return useMutation({
34 async mutationFn({profile}: {profile: bsky.profile.AnyProfileView}) {
35 if (!currentAccount) {
36 throw new Error('User not logged in')
37 }
38
39 const {uri} = await agent.app.bsky.graph.verification.create(
40 {repo: currentAccount.did},
41 {
42 subject: profile.did,
43 createdAt: new Date().toISOString(),
44 handle: profile.handle,
45 displayName: profile.displayName || '',
46 },
47 )
48
49 if (deerVerificationEnabled) {
50 await until(
51 10,
52 2e3,
53 (link: ConstellationLink | undefined) => {
54 return link !== undefined
55 },
56 () => {
57 return asyncGenFind(
58 getTrustedConstellationVerifications(
59 constellationInstance,
60 profile.did,
61 deerVerificationTrusted,
62 ),
63 link => asUri(link) === uri,
64 )
65 },
66 )
67 } else {
68 await until(
69 5,
70 1e3,
71 ({data: profile}: AppBskyActorGetProfile.Response) => {
72 if (
73 profile.verification &&
74 profile.verification.verifications.find(v => v.uri === uri)
75 ) {
76 return true
77 }
78 return false
79 },
80 () => {
81 return agent.getProfile({actor: profile.did ?? ''})
82 },
83 )
84 }
85 },
86 async onSuccess(_, {profile}) {
87 ax.metric('verification:create', {})
88 await updateProfileVerificationCache({profile})
89 qc.invalidateQueries({
90 queryKey: DEER_VERIFICATION_RQKEY(profile.did, deerVerificationTrusted),
91 })
92 },
93 })
94}