Skip to content

Commit

Permalink
Verify record badge
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-sherman committed Aug 6, 2024
1 parent 33b3aad commit e7fdc56
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 1 deletion.
70 changes: 69 additions & 1 deletion packages/atproto-browser/app/at/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
DidResolver,
getHandle,
getKey,
getPds,
HandleResolver,
} from "@atproto/identity";
Expand All @@ -12,6 +13,7 @@ import { AtBlob } from "./_lib/at-blob";
import { CollectionItems } from "./_lib/collection";
import { SWRConfig } from "swr";
import { listRecords } from "@/lib/atproto";
import { verifyRecords } from "@atproto/repo";

const didResolver = new DidResolver({});
const resolveDid = cache((did: string) => didResolver.resolve(did));
Expand Down Expand Up @@ -122,12 +124,78 @@ export default async function AtPage({
<Author did={didStr} />
</Suspense>
</details>
<h2>Record</h2>
<h2>
Record
<Suspense
fallback={
<span title="Verifying record..." aria-busy>
🤔
</span>
}
>
<RecordVerificationBadge
did={didStr}
collection={uri.collection}
rkey={uri.rkey}
/>
</Suspense>
</h2>
<JSONValue data={record} repo={didDocument.id} />
</div>
);
}

async function RecordVerificationBadge({
did,
collection,
rkey,
}: {
did: string;
collection: string;
rkey: string;
}) {
const didDoc = (await resolveDid(did))!;
const pds = getPds(didDoc);
if (!pds) {
return <span title="Invalid record (no pds)"></span>;
}

const verifyRecordsUrl = new URL(`${pds}/xrpc/com.atproto.sync.getRecord`);
verifyRecordsUrl.searchParams.set("did", did);
verifyRecordsUrl.searchParams.set("collection", collection);
verifyRecordsUrl.searchParams.set("rkey", rkey);

const response = await fetch(verifyRecordsUrl, {
headers: {
accept: "application/vnd.ipld.car",
},
});

if (!response.ok) {
return (
<span title={`Invalid record (failed to fetch ${await response.text()})`}>
</span>
);
}
const car = new Uint8Array(await response.arrayBuffer());
const key = getKey(didDoc);
if (!key) {
return <span title="Invalid record (no key)"></span>;
}

try {
await verifyRecords(car, did, key);
return <span title="Valid record"></span>;
} catch (e) {
if (e instanceof Error) {
return <span title={`Invalid record (${e.message})`}></span>;
} else {
return <span title="Invalid record (unknown)"></span>;
}
}
}

async function Author({ did }: { did: string }) {
const didDocument = await resolveDid(did);
if (!didDocument) {
Expand Down
2 changes: 2 additions & 0 deletions packages/atproto-browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"dependencies": {
"@atproto/did": "^0.1.0",
"@atproto/identity": "^0.4.0",
"@atproto/repo": "^0.4.1",
"@atproto/syntax": "^0.3.0",
"next": "15.0.0-rc.0",
"react": "19.0.0-rc-f994737d14-20240522",
Expand All @@ -26,6 +27,7 @@
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "15.0.0-rc.0",
"tsx": "^4.16.5",
"typescript": "^5"
}
}
45 changes: 45 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e7fdc56

Please sign in to comment.