Atproto AMA app
1#!/usr/bin/env tsx
2
3/**
4 * Boots a local AT Protocol network (PDS + PLC) using @atproto/dev-env
5 * and creates test accounts for alice and bob.
6 *
7 * The PDS includes a built-in OAuth Authorization Server, so the full
8 * browser-based OAuth flow works against it.
9 *
10 * Usage:
11 * pnpm run dev:network
12 */
13
14import { TestNetworkNoAppView } from "@atproto/dev-env";
15
16const APP_URL = process.env.APP_URL || "http://[::1]:3000";
17
18const ACCOUNTS = [
19 {
20 shortName: "alice",
21 handle: "alice.test",
22 email: "alice@test.com",
23 password: "alice-pass-123",
24 displayName: "Alice Test",
25 },
26 {
27 shortName: "bob",
28 handle: "bob.test",
29 email: "bob@test.com",
30 password: "bob-pass-123",
31 displayName: "Bob Test",
32 },
33];
34
35async function main() {
36 console.log("Starting local AT Protocol network...\n");
37
38 const network = await TestNetworkNoAppView.create({
39 plc: { port: 2583 },
40 pds: { port: 2584 },
41 });
42
43 const pdsUrl = network.pds.url;
44 const plcUrl = network.plc.url;
45
46 console.log(`PDS running at: ${pdsUrl}`);
47 console.log(`PLC running at: ${plcUrl}\n`);
48
49 const sc = network.getSeedClient();
50
51 for (const account of ACCOUNTS) {
52 const { shortName, handle, email, password, displayName } = account;
53 await sc.createAccount(shortName, { handle, email, password });
54 const did = sc.dids[shortName];
55 await sc.createProfile(did, displayName, `Hi, I'm ${displayName}`);
56 console.log(`Account created: ${handle} (DID: ${did})`);
57 }
58
59 await network.processAll();
60
61 const bar = "═".repeat(60);
62 console.log(`\n${bar}`);
63 console.log(` Open the app at: ${APP_URL}`);
64 console.log(`${bar}`);
65 console.log(
66 " IMPORTANT: use exactly this URL (IPv6 loopback). Opening\n" +
67 " http://localhost:3000 or http://127.0.0.1:3000 will break the\n" +
68 " OAuth flow — the PDS rejects same-site authorize requests.\n",
69 );
70
71 console.log("--- Test accounts ---\n");
72 for (const account of ACCOUNTS) {
73 const did = sc.dids[account.shortName];
74 console.log(` ${account.handle}`);
75 console.log(` DID: ${did}`);
76 console.log(` Email: ${account.email}`);
77 console.log(` Password: ${account.password}`);
78 console.log("");
79 }
80
81 console.log("Network is running. Press Ctrl+C to stop.\n");
82
83 await new Promise(() => {});
84}
85
86main().catch((err) => {
87 console.error("Fatal error:", err);
88 process.exit(1);
89});