2025-03-28 13:56:27 -07:00
|
|
|
import { CredentialManager, XRPC } from '@atcute/client';
|
|
|
|
|
import { getPdsEndpoint } from '@atcute/identity';
|
|
|
|
|
import {
|
|
|
|
|
AtprotoWebDidDocumentResolver,
|
|
|
|
|
CompositeDidDocumentResolver,
|
|
|
|
|
PlcDidDocumentResolver,
|
|
|
|
|
XrpcHandleResolver
|
|
|
|
|
} from '@atcute/identity-resolver';
|
|
|
|
|
|
2025-03-28 15:56:30 -07:00
|
|
|
import type { At } from '@atcute/client/lexicons';
|
|
|
|
|
|
2025-03-28 13:56:27 -07:00
|
|
|
const didDocumentResolver = new CompositeDidDocumentResolver({
|
|
|
|
|
methods: {
|
|
|
|
|
plc: new PlcDidDocumentResolver(),
|
|
|
|
|
web: new AtprotoWebDidDocumentResolver()
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const handleResolver = new XrpcHandleResolver({
|
|
|
|
|
serviceUrl: 'https://public.api.bsky.app'
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
async function resolvePDS(did: string) {
|
|
|
|
|
const doc = await didDocumentResolver.resolve(did as `did:plc:${string}` | `did:web:${string}`);
|
|
|
|
|
const pds = getPdsEndpoint(doc);
|
|
|
|
|
return pds;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function resolveHandle(handle: string) {
|
|
|
|
|
if (!handle.includes('.')) {
|
|
|
|
|
throw new Error(`Invalid DID: ${handle}`);
|
|
|
|
|
}
|
|
|
|
|
return await handleResolver.resolve(handle as `${string}.${string}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function createRPC(did: string) {
|
|
|
|
|
if (!did.startsWith('did:')) did = await resolveHandle(did);
|
|
|
|
|
|
|
|
|
|
const pds = await resolvePDS(did);
|
|
|
|
|
if (!pds) {
|
|
|
|
|
throw new Error(`Failed to resolve PDS for DID: ${did}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const manager = new CredentialManager({ service: pds });
|
|
|
|
|
const rpc = new XRPC({ handler: manager });
|
|
|
|
|
|
|
|
|
|
return rpc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function getSessions(rpc: XRPC, did: string) {
|
|
|
|
|
const {
|
|
|
|
|
data: { records }
|
|
|
|
|
} = await rpc.get('com.atproto.repo.listRecords', {
|
|
|
|
|
params: {
|
|
|
|
|
repo: did,
|
|
|
|
|
collection: 'me.woach.feed.session'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return records;
|
|
|
|
|
}
|
2025-03-28 14:04:56 -07:00
|
|
|
|
|
|
|
|
export async function getActivity(rpc: XRPC, did: string) {
|
|
|
|
|
const {
|
|
|
|
|
data: { records }
|
|
|
|
|
} = await rpc.get('com.atproto.repo.listRecords', {
|
|
|
|
|
params: {
|
|
|
|
|
repo: did,
|
|
|
|
|
collection: 'me.woach.feed.activity'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return records;
|
|
|
|
|
}
|
2025-03-28 15:56:30 -07:00
|
|
|
|
|
|
|
|
export async function resolveSession(rpc: XRPC, uri: At.Uri) {
|
|
|
|
|
const repo = uri.split('at://')[1].split('/')[0];
|
|
|
|
|
const rkey = uri.split('/')[4];
|
|
|
|
|
const {
|
|
|
|
|
data: { value }
|
|
|
|
|
} = await rpc.get('com.atproto.repo.getRecord', {
|
|
|
|
|
params: {
|
|
|
|
|
repo,
|
|
|
|
|
rkey,
|
|
|
|
|
collection: 'me.woach.feed.session'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function resolveMedia(rpc: XRPC, uri: At.Uri) {
|
|
|
|
|
const repo = uri.split('at://')[1].split('/')[0];
|
|
|
|
|
const rkey = uri.split('/')[4];
|
|
|
|
|
const {
|
|
|
|
|
data: { value }
|
|
|
|
|
} = await rpc.get('com.atproto.repo.getRecord', {
|
|
|
|
|
params: {
|
|
|
|
|
repo,
|
|
|
|
|
rkey,
|
|
|
|
|
collection: 'me.woach.content.anilist'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return value;
|
|
|
|
|
}
|