Encrypted, ephemeral, private memos on atproto

feat(producer): list public keys from PDS

graham.systems 0c575e72 ebcc4349

verified
Changed files
+44 -2
packages
producer
+38 -2
packages/producer/mod.ts
··· 4 LocalPublicKey, 5 ProducerOptions, 6 ProducerParams, 7 } from "./types.ts"; 8 import { type Did, parse, type ResourceUri } from "@atcute/lexicons"; 9 import type { Client, CredentialManager } from "@atcute/client"; ··· 106 107 /** 108 * Lists public keys registered in the user's PDS 109 - * @todo List public keys 110 */ 111 - async listPublicKeys() {} 112 113 /** 114 * Sets a public key as the main encryption key
··· 4 LocalPublicKey, 5 ProducerOptions, 6 ProducerParams, 7 + PublicKeyOption, 8 } from "./types.ts"; 9 import { type Did, parse, type ResourceUri } from "@atcute/lexicons"; 10 import type { Client, CredentialManager } from "@atcute/client"; ··· 107 108 /** 109 * Lists public keys registered in the user's PDS 110 */ 111 + async *listPublicKeys(): AsyncIterator< 112 + PublicKeyOption, 113 + void, 114 + void 115 + > { 116 + let cursor: string | undefined; 117 + 118 + while (true) { 119 + const res = await this.rpc.get("com.atproto.repo.listRecords", { 120 + params: { 121 + collection: "app.cistern.lexicon.item", 122 + repo: this.did, 123 + cursor, 124 + }, 125 + }); 126 + 127 + if (!res.ok) { 128 + throw new Error( 129 + `failed to list public keys: ${res.status} ${res.data.error}`, 130 + ); 131 + } 132 + 133 + cursor = res.data.cursor; 134 + 135 + for (const record of res.data.records) { 136 + const item = parse(AppCisternLexiconPubkey.mainSchema, record.value); 137 + 138 + yield { 139 + uri: record.uri, 140 + content: item.content, 141 + name: item.name, 142 + }; 143 + } 144 + 145 + if (!cursor) return; 146 + } 147 + } 148 149 /** 150 * Sets a public key as the main encryption key
+6
packages/producer/types.ts
··· 14 uri: ResourceUri; 15 record: AppCisternLexiconPubkey.Main; 16 }
··· 14 uri: ResourceUri; 15 record: AppCisternLexiconPubkey.Main; 16 } 17 + 18 + export interface PublicKeyOption { 19 + uri: ResourceUri; 20 + name: string; 21 + content: string; 22 + }