@atproto/bsky 0.0.140 → 0.0.142

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.
Files changed (85) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +2 -2
  3. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
  4. package/dist/data-plane/server/db/database-schema.d.ts +2 -1
  5. package/dist/data-plane/server/db/database-schema.d.ts.map +1 -1
  6. package/dist/data-plane/server/db/migrations/20250404T163421487Z-verifications.d.ts +4 -0
  7. package/dist/data-plane/server/db/migrations/20250404T163421487Z-verifications.d.ts.map +1 -0
  8. package/dist/data-plane/server/db/migrations/20250404T163421487Z-verifications.js +36 -0
  9. package/dist/data-plane/server/db/migrations/20250404T163421487Z-verifications.js.map +1 -0
  10. package/dist/data-plane/server/db/migrations/index.d.ts +1 -0
  11. package/dist/data-plane/server/db/migrations/index.d.ts.map +1 -1
  12. package/dist/data-plane/server/db/migrations/index.js +2 -1
  13. package/dist/data-plane/server/db/migrations/index.js.map +1 -1
  14. package/dist/data-plane/server/db/tables/actor.d.ts +2 -0
  15. package/dist/data-plane/server/db/tables/actor.d.ts.map +1 -1
  16. package/dist/data-plane/server/db/tables/actor.js.map +1 -1
  17. package/dist/data-plane/server/db/tables/verification.d.ts +18 -0
  18. package/dist/data-plane/server/db/tables/verification.d.ts.map +1 -0
  19. package/dist/data-plane/server/db/tables/verification.js +5 -0
  20. package/dist/data-plane/server/db/tables/verification.js.map +1 -0
  21. package/dist/data-plane/server/indexing/index.d.ts +2 -0
  22. package/dist/data-plane/server/indexing/index.d.ts.map +1 -1
  23. package/dist/data-plane/server/indexing/index.js +2 -0
  24. package/dist/data-plane/server/indexing/index.js.map +1 -1
  25. package/dist/data-plane/server/indexing/plugins/verification.d.ts +11 -0
  26. package/dist/data-plane/server/indexing/plugins/verification.d.ts.map +1 -0
  27. package/dist/data-plane/server/indexing/plugins/verification.js +95 -0
  28. package/dist/data-plane/server/indexing/plugins/verification.js.map +1 -0
  29. package/dist/data-plane/server/routes/profile.d.ts.map +1 -1
  30. package/dist/data-plane/server/routes/profile.js +28 -1
  31. package/dist/data-plane/server/routes/profile.js.map +1 -1
  32. package/dist/data-plane/server/util.d.ts +6 -6
  33. package/dist/hydration/actor.d.ts +11 -0
  34. package/dist/hydration/actor.d.ts.map +1 -1
  35. package/dist/hydration/actor.js +19 -0
  36. package/dist/hydration/actor.js.map +1 -1
  37. package/dist/hydration/label.d.ts +1 -0
  38. package/dist/hydration/label.d.ts.map +1 -1
  39. package/dist/hydration/label.js +7 -0
  40. package/dist/hydration/label.js.map +1 -1
  41. package/dist/lexicon/lexicons.d.ts +134 -0
  42. package/dist/lexicon/lexicons.d.ts.map +1 -1
  43. package/dist/lexicon/lexicons.js +67 -0
  44. package/dist/lexicon/lexicons.js.map +1 -1
  45. package/dist/lexicon/types/app/bsky/actor/defs.d.ts +29 -0
  46. package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
  47. package/dist/lexicon/types/app/bsky/actor/defs.js +18 -0
  48. package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
  49. package/dist/lexicon/types/chat/bsky/actor/defs.d.ts +1 -0
  50. package/dist/lexicon/types/chat/bsky/actor/defs.d.ts.map +1 -1
  51. package/dist/lexicon/types/chat/bsky/actor/defs.js.map +1 -1
  52. package/dist/proto/bsky_connect.d.ts +30 -1
  53. package/dist/proto/bsky_connect.d.ts.map +1 -1
  54. package/dist/proto/bsky_connect.js +29 -0
  55. package/dist/proto/bsky_connect.js.map +1 -1
  56. package/dist/proto/bsky_pb.d.ts +243 -0
  57. package/dist/proto/bsky_pb.d.ts.map +1 -1
  58. package/dist/proto/bsky_pb.js +733 -5
  59. package/dist/proto/bsky_pb.js.map +1 -1
  60. package/dist/views/index.d.ts +2 -1
  61. package/dist/views/index.d.ts.map +1 -1
  62. package/dist/views/index.js +42 -0
  63. package/dist/views/index.js.map +1 -1
  64. package/package.json +7 -7
  65. package/proto/bsky.proto +67 -0
  66. package/src/api/app/bsky/graph/getSuggestedFollowsByActor.ts +2 -2
  67. package/src/data-plane/server/db/database-schema.ts +3 -1
  68. package/src/data-plane/server/db/migrations/20250404T163421487Z-verifications.ts +39 -0
  69. package/src/data-plane/server/db/migrations/index.ts +1 -0
  70. package/src/data-plane/server/db/tables/actor.ts +3 -0
  71. package/src/data-plane/server/db/tables/verification.ts +20 -0
  72. package/src/data-plane/server/indexing/index.ts +8 -2
  73. package/src/data-plane/server/indexing/plugins/verification.ts +96 -0
  74. package/src/data-plane/server/routes/profile.ts +63 -19
  75. package/src/hydration/actor.ts +38 -0
  76. package/src/hydration/label.ts +12 -0
  77. package/src/lexicon/lexicons.ts +70 -0
  78. package/src/lexicon/types/app/bsky/actor/defs.ts +47 -0
  79. package/src/lexicon/types/chat/bsky/actor/defs.ts +1 -0
  80. package/src/proto/bsky_connect.ts +35 -0
  81. package/src/proto/bsky_pb.ts +676 -0
  82. package/src/views/index.ts +60 -1
  83. package/tests/views/verification.test.ts +301 -0
  84. package/tsconfig.build.tsbuildinfo +1 -1
  85. package/tsconfig.tests.tsbuildinfo +1 -1
@@ -0,0 +1,96 @@
1
+ import { Selectable } from 'kysely'
2
+ import { CID } from 'multiformats/cid'
3
+ import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
4
+ import * as lex from '../../../../lexicon/lexicons'
5
+ import * as Verification from '../../../../lexicon/types/app/bsky/graph/verification'
6
+ import { BackgroundQueue } from '../../background'
7
+ import { Database } from '../../db'
8
+ import { DatabaseSchema, DatabaseSchemaType } from '../../db/database-schema'
9
+ import { RecordProcessor } from '../processor'
10
+
11
+ const lexId = lex.ids.AppBskyGraphVerification
12
+ type IndexedVerification = Selectable<DatabaseSchemaType['verification']>
13
+
14
+ const insertFn = async (
15
+ db: DatabaseSchema,
16
+ uri: AtUri,
17
+ cid: CID,
18
+ obj: Verification.Record,
19
+ timestamp: string,
20
+ ): Promise<IndexedVerification | null> => {
21
+ const inserted = await db
22
+ .insertInto('verification')
23
+ .values({
24
+ uri: uri.toString(),
25
+ cid: cid.toString(),
26
+ rkey: uri.rkey,
27
+ creator: uri.host,
28
+ subject: obj.subject,
29
+ handle: obj.handle,
30
+ displayName: obj.displayName,
31
+ createdAt: normalizeDatetimeAlways(obj.createdAt),
32
+ indexedAt: timestamp,
33
+ })
34
+ .onConflict((oc) => oc.doNothing())
35
+ .returningAll()
36
+ .executeTakeFirst()
37
+ return inserted || null
38
+ }
39
+
40
+ const findDuplicate = async (
41
+ db: DatabaseSchema,
42
+ uri: AtUri,
43
+ obj: Verification.Record,
44
+ ): Promise<AtUri | null> => {
45
+ const found = await db
46
+ .selectFrom('verification')
47
+ .where('subject', '=', obj.subject)
48
+ .where('creator', '=', uri.host)
49
+ .selectAll()
50
+ .executeTakeFirst()
51
+ return found ? new AtUri(found.uri) : null
52
+ }
53
+
54
+ const notifsForInsert = (_obj: IndexedVerification) => {
55
+ return []
56
+ }
57
+
58
+ const deleteFn = async (
59
+ db: DatabaseSchema,
60
+ uri: AtUri,
61
+ ): Promise<IndexedVerification | null> => {
62
+ const deleted = await db
63
+ .deleteFrom('verification')
64
+ .where('uri', '=', uri.toString())
65
+ .returningAll()
66
+ .executeTakeFirst()
67
+ return deleted || null
68
+ }
69
+
70
+ const notifsForDelete = (
71
+ _deleted: IndexedVerification,
72
+ _replacedBy: IndexedVerification | null,
73
+ ) => {
74
+ return { notifs: [], toDelete: [] }
75
+ }
76
+
77
+ export type PluginType = RecordProcessor<
78
+ Verification.Record,
79
+ IndexedVerification
80
+ >
81
+
82
+ export const makePlugin = (
83
+ db: Database,
84
+ background: BackgroundQueue,
85
+ ): PluginType => {
86
+ return new RecordProcessor(db, background, {
87
+ lexId,
88
+ insertFn,
89
+ findDuplicate,
90
+ deleteFn,
91
+ notifsForInsert,
92
+ notifsForDelete,
93
+ })
94
+ }
95
+
96
+ export default makePlugin
@@ -1,11 +1,21 @@
1
+ import { Timestamp } from '@bufbuild/protobuf'
1
2
  import { ServiceImpl } from '@connectrpc/connect'
2
- import { sql } from 'kysely'
3
+ import { Selectable, sql } from 'kysely'
3
4
  import { keyBy } from '@atproto/common'
4
5
  import { parseRecordBytes } from '../../../hydration/util'
5
6
  import { Service } from '../../../proto/bsky_connect'
7
+ import { VerificationMeta } from '../../../proto/bsky_pb'
6
8
  import { Database } from '../db'
9
+ import { Verification } from '../db/tables/verification'
7
10
  import { getRecords } from './records'
8
11
 
12
+ type VerifiedBy = {
13
+ [handle: string]: Pick<
14
+ VerificationMeta,
15
+ 'rkey' | 'handle' | 'displayName' | 'sortedAt'
16
+ >
17
+ }
18
+
9
19
  export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
10
20
  async getActors(req) {
11
21
  const { dids } = req
@@ -19,30 +29,62 @@ export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
19
29
  (did) => `at://${did}/chat.bsky.actor.declaration/self`,
20
30
  )
21
31
  const { ref } = db.db.dynamic
22
- const [handlesRes, profiles, chatDeclarations] = await Promise.all([
23
- db.db
24
- .selectFrom('actor')
25
- .leftJoin('actor_state', 'actor_state.did', 'actor.did')
26
- .where('actor.did', 'in', dids)
27
- .selectAll('actor')
28
- .select('actor_state.priorityNotifs')
29
- .select([
30
- db.db
31
- .selectFrom('labeler')
32
- .whereRef('creator', '=', ref('actor.did'))
33
- .select(sql<true>`${true}`.as('val'))
34
- .as('isLabeler'),
35
- ])
36
- .execute(),
37
- getRecords(db)({ uris: profileUris }),
38
- getRecords(db)({ uris: chatDeclarationUris }),
39
- ])
32
+ const [handlesRes, verificationsReceived, profiles, chatDeclarations] =
33
+ await Promise.all([
34
+ db.db
35
+ .selectFrom('actor')
36
+ .leftJoin('actor_state', 'actor_state.did', 'actor.did')
37
+ .where('actor.did', 'in', dids)
38
+ .selectAll('actor')
39
+ .select('actor_state.priorityNotifs')
40
+ .select([
41
+ db.db
42
+ .selectFrom('labeler')
43
+ .whereRef('creator', '=', ref('actor.did'))
44
+ .select(sql<true>`${true}`.as('val'))
45
+ .as('isLabeler'),
46
+ ])
47
+ .execute(),
48
+ db.db
49
+ .selectFrom('verification')
50
+ .selectAll('verification')
51
+ .innerJoin('actor', 'actor.did', 'verification.creator')
52
+ .where('verification.subject', 'in', dids)
53
+ .where('actor.trustedVerifier', '=', true)
54
+ .orderBy('sortedAt', 'asc')
55
+ .execute(),
56
+ getRecords(db)({ uris: profileUris }),
57
+ getRecords(db)({ uris: chatDeclarationUris }),
58
+ ])
59
+
60
+ const verificationsBySubjectDid = verificationsReceived.reduce(
61
+ (acc, cur) => {
62
+ const list = acc.get(cur.subject) ?? []
63
+ list.push(cur)
64
+ acc.set(cur.subject, list)
65
+ return acc
66
+ },
67
+ new Map<string, Selectable<Verification>[]>(),
68
+ )
69
+
40
70
  const byDid = keyBy(handlesRes, 'did')
41
71
  const actors = dids.map((did, i) => {
42
72
  const row = byDid.get(did)
43
73
  const chatDeclaration = parseRecordBytes(
44
74
  chatDeclarations.records[i].record,
45
75
  )
76
+
77
+ const verifications = verificationsBySubjectDid.get(did) ?? []
78
+ const verifiedBy: VerifiedBy = verifications.reduce((acc, cur) => {
79
+ acc[cur.creator] = {
80
+ rkey: cur.rkey,
81
+ handle: cur.handle,
82
+ displayName: cur.displayName,
83
+ sortedAt: Timestamp.fromDate(new Date(cur.sortedAt)),
84
+ }
85
+ return acc
86
+ }, {} as VerifiedBy)
87
+
46
88
  return {
47
89
  exists: !!row,
48
90
  handle: row?.handle ?? undefined,
@@ -58,6 +100,8 @@ export default (db: Database): Partial<ServiceImpl<typeof Service>> => ({
58
100
  upstreamStatus: row?.upstreamStatus ?? '',
59
101
  createdAt: profiles.records[i].createdAt, // @NOTE profile creation date not trusted in production
60
102
  priorityNotifications: row?.priorityNotifs ?? false,
103
+ trustedVerifier: row?.trustedVerifier ?? false,
104
+ verifiedBy,
61
105
  }
62
106
  })
63
107
  return { actors }
@@ -1,6 +1,8 @@
1
+ import { mapDefined } from '@atproto/common'
1
2
  import { DataPlaneClient } from '../data-plane/client'
2
3
  import { Record as ProfileRecord } from '../lexicon/types/app/bsky/actor/profile'
3
4
  import { Record as ChatDeclarationRecord } from '../lexicon/types/chat/bsky/actor/declaration'
5
+ import { VerificationMeta } from '../proto/bsky_pb'
4
6
  import {
5
7
  HydrationMap,
6
8
  RecordInfo,
@@ -23,8 +25,20 @@ export type Actor = {
23
25
  upstreamStatus?: string
24
26
  createdAt?: Date
25
27
  priorityNotifications: boolean
28
+ trustedVerifier?: boolean
29
+ verifications: VerificationHydrationState[]
26
30
  }
27
31
 
32
+ export type VerificationHydrationState = {
33
+ issuer: string
34
+ uri: string
35
+ handle: string
36
+ displayName: string
37
+ createdAt: string
38
+ }
39
+
40
+ export type VerificationMetaRequired = Required<VerificationMeta>
41
+
28
42
  export type Actors = HydrationMap<Actor>
29
43
 
30
44
  export type ChatDeclaration = RecordInfo<ChatDeclarationRecord>
@@ -127,6 +141,28 @@ export class ActorHydrator {
127
141
  ? parseRecord<ProfileRecord>(actor.profile, includeTakedowns)
128
142
  : undefined
129
143
 
144
+ const verifications = mapDefined(
145
+ Object.entries(actor.verifiedBy),
146
+ ([actorDid, verificationMeta]) => {
147
+ if (
148
+ verificationMeta.displayName &&
149
+ verificationMeta.handle &&
150
+ verificationMeta.rkey &&
151
+ verificationMeta.sortedAt
152
+ ) {
153
+ return {
154
+ issuer: actorDid,
155
+ uri: `at://${actorDid}/app.bsky.graph.verification/${verificationMeta.rkey}`,
156
+ handle: verificationMeta.handle,
157
+ displayName: verificationMeta.displayName,
158
+ createdAt: verificationMeta.sortedAt.toDate().toISOString(),
159
+ }
160
+ }
161
+ // Filter out the verification meta that doesn't contain all info.
162
+ return undefined
163
+ },
164
+ )
165
+
130
166
  return acc.set(did, {
131
167
  did,
132
168
  handle: parseString(actor.handle),
@@ -141,6 +177,8 @@ export class ActorHydrator {
141
177
  upstreamStatus: actor.upstreamStatus || undefined,
142
178
  createdAt: actor.createdAt?.toDate(),
143
179
  priorityNotifications: actor.priorityNotifications,
180
+ trustedVerifier: actor.trustedVerifier,
181
+ verifications,
144
182
  })
145
183
  }, new HydrationMap<Actor>())
146
184
  }
@@ -16,6 +16,7 @@ import {
16
16
  export type { Label } from '../lexicon/types/com/atproto/label/defs'
17
17
 
18
18
  export type SubjectLabels = {
19
+ isImpersonation: boolean
19
20
  isTakendown: boolean
20
21
  needsReview: boolean
21
22
  labels: HydrationMap<Label> // src + val -> label
@@ -84,12 +85,14 @@ export class LabelHydrator {
84
85
  let entry = acc.get(label.uri)
85
86
  if (!entry) {
86
87
  entry = {
88
+ isImpersonation: false,
87
89
  isTakendown: false,
88
90
  needsReview: false,
89
91
  labels: new HydrationMap(),
90
92
  }
91
93
  acc.set(label.uri, entry)
92
94
  }
95
+
93
96
  const isActionableNeedsReview =
94
97
  label.val === NEEDS_REVIEW_LABEL &&
95
98
  !label.neg &&
@@ -110,6 +113,14 @@ export class LabelHydrator {
110
113
  if (isActionableNeedsReview) {
111
114
  entry.needsReview = true
112
115
  }
116
+ if (
117
+ label.val === IMPERSONATION_LABEL &&
118
+ !label.neg &&
119
+ labelers.redact.has(label.src)
120
+ ) {
121
+ entry.isImpersonation = true
122
+ }
123
+
113
124
  return acc
114
125
  }, new Labels())
115
126
  }
@@ -160,5 +171,6 @@ const labelerDidToUri = (did: string): string => {
160
171
  return AtUri.make(did, ids.AppBskyLabelerService, 'self').toString()
161
172
  }
162
173
 
174
+ const IMPERSONATION_LABEL = 'impersonation'
163
175
  const TAKEDOWN_LABELS = ['!takedown', '!suspend']
164
176
  const NEEDS_REVIEW_LABEL = 'needs-review'
@@ -4564,6 +4564,10 @@ export const schemaDict = {
4564
4564
  type: 'string',
4565
4565
  format: 'datetime',
4566
4566
  },
4567
+ verification: {
4568
+ type: 'ref',
4569
+ ref: 'lex:app.bsky.actor.defs#verificationState',
4570
+ },
4567
4571
  },
4568
4572
  },
4569
4573
  profileView: {
@@ -4615,6 +4619,10 @@ export const schemaDict = {
4615
4619
  ref: 'lex:com.atproto.label.defs#label',
4616
4620
  },
4617
4621
  },
4622
+ verification: {
4623
+ type: 'ref',
4624
+ ref: 'lex:app.bsky.actor.defs#verificationState',
4625
+ },
4618
4626
  },
4619
4627
  },
4620
4628
  profileViewDetailed: {
@@ -4687,6 +4695,10 @@ export const schemaDict = {
4687
4695
  type: 'ref',
4688
4696
  ref: 'lex:com.atproto.repo.strongRef',
4689
4697
  },
4698
+ verification: {
4699
+ type: 'ref',
4700
+ ref: 'lex:app.bsky.actor.defs#verificationState',
4701
+ },
4690
4702
  },
4691
4703
  },
4692
4704
  profileAssociated: {
@@ -4776,6 +4788,60 @@ export const schemaDict = {
4776
4788
  },
4777
4789
  },
4778
4790
  },
4791
+ verificationState: {
4792
+ type: 'object',
4793
+ description:
4794
+ 'Represents the verification information about the user this object is attached to.',
4795
+ required: ['verifications', 'verifiedStatus', 'trustedVerifierStatus'],
4796
+ properties: {
4797
+ verifications: {
4798
+ type: 'array',
4799
+ description:
4800
+ 'All verifications issued by trusted verifiers on behalf of this user. Verifications by untrusted verifiers are not included.',
4801
+ items: {
4802
+ type: 'ref',
4803
+ ref: 'lex:app.bsky.actor.defs#verificationView',
4804
+ },
4805
+ },
4806
+ verifiedStatus: {
4807
+ type: 'string',
4808
+ description: "The user's status as a verified account.",
4809
+ knownValues: ['valid', 'invalid', 'none'],
4810
+ },
4811
+ trustedVerifierStatus: {
4812
+ type: 'string',
4813
+ description: "The user's status as a trusted verifier.",
4814
+ knownValues: ['valid', 'invalid', 'none'],
4815
+ },
4816
+ },
4817
+ },
4818
+ verificationView: {
4819
+ type: 'object',
4820
+ description: 'An individual verification for an associated subject.',
4821
+ required: ['issuer', 'uri', 'isValid', 'createdAt'],
4822
+ properties: {
4823
+ issuer: {
4824
+ type: 'string',
4825
+ description: 'The user who issued this verification.',
4826
+ format: 'did',
4827
+ },
4828
+ uri: {
4829
+ type: 'string',
4830
+ description: 'The AT-URI of the verification record.',
4831
+ format: 'at-uri',
4832
+ },
4833
+ isValid: {
4834
+ type: 'boolean',
4835
+ description:
4836
+ 'True if the verification passes validation, otherwise false.',
4837
+ },
4838
+ createdAt: {
4839
+ type: 'string',
4840
+ description: 'Timestamp when the verification was created.',
4841
+ format: 'datetime',
4842
+ },
4843
+ },
4844
+ },
4779
4845
  preferences: {
4780
4846
  type: 'array',
4781
4847
  items: {
@@ -11014,6 +11080,10 @@ export const schemaDict = {
11014
11080
  description:
11015
11081
  'Set to true when the actor cannot actively participate in converations',
11016
11082
  },
11083
+ verification: {
11084
+ type: 'ref',
11085
+ ref: 'lex:app.bsky.actor.defs#verificationState',
11086
+ },
11017
11087
  },
11018
11088
  },
11019
11089
  },
@@ -29,6 +29,7 @@ export interface ProfileViewBasic {
29
29
  viewer?: ViewerState
30
30
  labels?: ComAtprotoLabelDefs.Label[]
31
31
  createdAt?: string
32
+ verification?: VerificationState
32
33
  }
33
34
 
34
35
  const hashProfileViewBasic = 'profileViewBasic'
@@ -53,6 +54,7 @@ export interface ProfileView {
53
54
  createdAt?: string
54
55
  viewer?: ViewerState
55
56
  labels?: ComAtprotoLabelDefs.Label[]
57
+ verification?: VerificationState
56
58
  }
57
59
 
58
60
  const hashProfileView = 'profileView'
@@ -83,6 +85,7 @@ export interface ProfileViewDetailed {
83
85
  viewer?: ViewerState
84
86
  labels?: ComAtprotoLabelDefs.Label[]
85
87
  pinnedPost?: ComAtprotoRepoStrongRef.Main
88
+ verification?: VerificationState
86
89
  }
87
90
 
88
91
  const hashProfileViewDetailed = 'profileViewDetailed'
@@ -169,6 +172,50 @@ export function validateKnownFollowers<V>(v: V) {
169
172
  return validate<KnownFollowers & V>(v, id, hashKnownFollowers)
170
173
  }
171
174
 
175
+ /** Represents the verification information about the user this object is attached to. */
176
+ export interface VerificationState {
177
+ $type?: 'app.bsky.actor.defs#verificationState'
178
+ /** All verifications issued by trusted verifiers on behalf of this user. Verifications by untrusted verifiers are not included. */
179
+ verifications: VerificationView[]
180
+ /** The user's status as a verified account. */
181
+ verifiedStatus: 'valid' | 'invalid' | 'none' | (string & {})
182
+ /** The user's status as a trusted verifier. */
183
+ trustedVerifierStatus: 'valid' | 'invalid' | 'none' | (string & {})
184
+ }
185
+
186
+ const hashVerificationState = 'verificationState'
187
+
188
+ export function isVerificationState<V>(v: V) {
189
+ return is$typed(v, id, hashVerificationState)
190
+ }
191
+
192
+ export function validateVerificationState<V>(v: V) {
193
+ return validate<VerificationState & V>(v, id, hashVerificationState)
194
+ }
195
+
196
+ /** An individual verification for an associated subject. */
197
+ export interface VerificationView {
198
+ $type?: 'app.bsky.actor.defs#verificationView'
199
+ /** The user who issued this verification. */
200
+ issuer: string
201
+ /** The AT-URI of the verification record. */
202
+ uri: string
203
+ /** True if the verification passes validation, otherwise false. */
204
+ isValid: boolean
205
+ /** Timestamp when the verification was created. */
206
+ createdAt: string
207
+ }
208
+
209
+ const hashVerificationView = 'verificationView'
210
+
211
+ export function isVerificationView<V>(v: V) {
212
+ return is$typed(v, id, hashVerificationView)
213
+ }
214
+
215
+ export function validateVerificationView<V>(v: V) {
216
+ return validate<VerificationView & V>(v, id, hashVerificationView)
217
+ }
218
+
172
219
  export type Preferences = (
173
220
  | $Typed<AdultContentPref>
174
221
  | $Typed<ContentLabelPref>
@@ -27,6 +27,7 @@ export interface ProfileViewBasic {
27
27
  labels?: ComAtprotoLabelDefs.Label[]
28
28
  /** Set to true when the actor cannot actively participate in converations */
29
29
  chatDisabled?: boolean
30
+ verification?: AppBskyActorDefs.VerificationState
30
31
  }
31
32
 
32
33
  const hashProfileViewBasic = 'profileViewBasic'
@@ -168,6 +168,12 @@ import {
168
168
  GetTimelineResponse,
169
169
  GetUnreadNotificationCountRequest,
170
170
  GetUnreadNotificationCountResponse,
171
+ GetVerificationRecordsRequest,
172
+ GetVerificationRecordsResponse,
173
+ GetVerificationsIssuedRequest,
174
+ GetVerificationsIssuedResponse,
175
+ GetVerificationsReceivedRequest,
176
+ GetVerificationsReceivedResponse,
171
177
  PingRequest,
172
178
  PingResponse,
173
179
  SearchActorsRequest,
@@ -373,6 +379,35 @@ export const Service = {
373
379
  O: GetFollowsResponse,
374
380
  kind: MethodKind.Unary,
375
381
  },
382
+ /**
383
+ * Verifications
384
+ *
385
+ * @generated from rpc bsky.Service.GetVerificationRecords
386
+ */
387
+ getVerificationRecords: {
388
+ name: 'GetVerificationRecords',
389
+ I: GetVerificationRecordsRequest,
390
+ O: GetVerificationRecordsResponse,
391
+ kind: MethodKind.Unary,
392
+ },
393
+ /**
394
+ * @generated from rpc bsky.Service.GetVerificationsIssued
395
+ */
396
+ getVerificationsIssued: {
397
+ name: 'GetVerificationsIssued',
398
+ I: GetVerificationsIssuedRequest,
399
+ O: GetVerificationsIssuedResponse,
400
+ kind: MethodKind.Unary,
401
+ },
402
+ /**
403
+ * @generated from rpc bsky.Service.GetVerificationsReceived
404
+ */
405
+ getVerificationsReceived: {
406
+ name: 'GetVerificationsReceived',
407
+ I: GetVerificationsReceivedRequest,
408
+ O: GetVerificationsReceivedResponse,
409
+ kind: MethodKind.Unary,
410
+ },
376
411
  /**
377
412
  * Likes
378
413
  *