demos for spacedust
1// heyyyyyy if you're reading this:
2//
3// it's all copy-pasta from the atproto notifications demo, pasted over from
4// previous experimental stuff.
5//
6// all to say it probably needs some attention and cleanup, in particular with
7// handling failures. i'll get back to it hopefully soon.
8
9import { Client, CredentialManager, ok, simpleFetchHandler } from '@atcute/client';
10import { CompositeDidDocumentResolver, PlcDidDocumentResolver, WebDidDocumentResolver } from '@atcute/identity-resolver';
11
12const docResolver = new CompositeDidDocumentResolver({
13 methods: {
14 plc: new PlcDidDocumentResolver(),
15 web: new WebDidDocumentResolver(),
16 },
17});
18
19async function resolve_did(did) {
20 return await docResolver.resolve(did);
21}
22
23function pds({ service }) {
24 if (!service) {
25 throw new Error('missing service from identity doc');
26 }
27 const { serviceEndpoint } = service[0];
28 if (!serviceEndpoint) {
29 throw new Error('missing serviceEndpoint from identity service array');
30 }
31 return serviceEndpoint;
32}
33
34
35async function get_pds_record(endpoint, did, collection, rkey) {
36 const handler = simpleFetchHandler({ service: endpoint });
37 const rpc = new Client({ handler });
38 const { ok, data } = await rpc.get('com.atproto.repo.getRecord', {
39 params: { repo: did, collection, rkey },
40 });
41 if (!ok) throw new Error('fetching pds record failed');
42 return data;
43}
44
45function parse_at_uri(uri) {
46 let collection, rkey;
47 if (!uri.startsWith('at://')) {
48 throw new Error('invalid at-uri: did not start with "at://"');
49 }
50 let remaining = uri.slice('at://'.length); // remove the at:// prefix
51 remaining = remaining.split('#')[0]; // hash is valid in at-uri but we don't handle them
52 remaining = remaining.split('?')[0]; // query is valid in at-uri but we don't handle it
53 const segments = remaining.split('/');
54 if (segments.length === 0) {
55 throw new Error('invalid at-uri: could not find did after "at://"');
56 }
57 const did = segments[0];
58 if (segments.length > 1) {
59 collection = segments[1];
60 }
61 if (segments.length > 2) {
62 rkey = segments.slice(2).join('/'); // hmm are slashes actually valid in rkey?
63 }
64 return { did, collection, rkey };
65}
66
67export async function getAtUri(atUri) {
68 const { did, collection, rkey } = parse_at_uri(atUri);
69 const doc = await resolve_did(did);
70 const endpoint = pds(doc);
71 const { value } = await get_pds_record(endpoint, did, collection, rkey);
72 return value;
73}