Can social media exist without being owned by big companies? The community behind ATProto believes social media should be about people, not specific apps. Zeu Capua gives us an intro to building apps for the atmosphere.
Can social media exist without being owned by big companies? The community behind ATProto believes social media should be about people, not specific apps.
Zeu Capua gives us an intro to building apps for the atmosphere.
Resources & Links
Read the transcript
Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.
JASON: Hello, everyone, and welcome to another episode of Learn With Jason. Today on the show, we are going to be building with one of the things I'm most excited about on the web right now, which is the AT Proto. This is a way to do kind of distributed social or a connected social across a whole bunch of kinds of sites. It's really exciting, a little confusing at first, and that's why we've brought in an expert. Please welcome Zeu to the stage, who's going to teach us about AT Proto today. How you doing?
ZEU: I'm doing pretty good. How about you?
JASON: I'm doing so good. I'm so excited to dive in. So I just want to maybe kick off with a few words about who you are and what you do. Then let's get coding.
ZEU: Yeah, quick intro. I'm Zeu, a software engineer focused on website stuff. I yell a lot about AT Proto online.
JASON: Amazing. Let's dive right into it. And here we go. I'm looking at your website. This is zeu.dev. If I want to start building something with AT Proto, what should I do first?
ZEU: Yeah, so we're going to go to your hometown framework Astro. Let's make a new project. Then we're going to install a few packages.
JASON: Okay, great. Let me pull up ‐‐ I'm going to get a new window going here. Actually, why don't we start in a terminal because that's going to make more sense to my brain. And we're going to go into the GitHub folder. Then we'll go into CodeTV. Wait. Probably want this one to be in Learn With Jason because that's what we're doing right now. I can pnpx Astro ‐‐ wait, that's not right. Pnpm create Astro @ latest. This is going to be called AT Proto Astro. So this is going to help us create a brand new site. We'll make this a little bigger so we can see what's going on. Do you want me to use a template or go empty?
ZEU: Let's go empty.
JASON: Okay. Get the dependencies, install that new git repository. I'm actually going to close this window. Instead, we'll do one of these. So here we are. I do trust these authors, in fact.
ZEU: You trust yourself.
JASON: Words to live by. Trust yourself. So I'm here. I'm ready. Where do we want to start? We've got our basic Astro site sitting there. Nothing up our sleeve in terms of dependencies. We've just got Astro. What's step one?
ZEU: Yeah, so let's install ‐‐ we only have a few dependencies we need to get. So we are going to use the Astro CLI. So pnpx Astro add. We're going to install a plugin called at fujocoded, slash auth proto. No dash.
JASON: Got it. Okay. So we got that one coming. To run this command without prompts... what does that mean?
ZEU: I think you can pass the yes flag, and it'll say yes the entire time.
JASON: Oh, I see. This is showing me what it's going to do. It's going to add the thing. I do love Astro for this. Okay. So we got that one.
ZEU: Perfect. We are ‐‐ then we're going to normal install ‐‐ oh, actually, we're going to ‐‐ this is a server app. I don't know if you ‐‐ I mean, we're just doing this locally. I don't think ‐‐ you just need a Node or Netlify integration. Whatever your preferred one is.
JASON: Let's do it. Probably should have added the yes flag. But that's fine. Okay. So now we got ‐‐ there's our Netlify adapter. I'm going to clean that up just a tad.
ZEU: Yep. Then just two more normal packages. We're going to get unstorage and at sign. AT Proto slash common web. Perfect. Then we're done.
JASON: Great. So by default, Astro is running in hybrid mode. So we can just tell it not to pre‐render. Anything else before I start the dev server?
ZEU: Umm... other than output being server, no. We're pretty good.
JASON: Yeah, I'll put it right in. That's going to be server. There we go. Then we'll pnpm run dev. Okay. So that is running at local host 4321. I'm going to close that up and head over here. This is now our little Astro site. As you can see, nothing to it right now. Real simple stuff. But just you wait.
ZEU: So I normally put the default Astro page, like with the HTML stuff, I normally put that as a layout. Do you do that as well? It'll make life easy.
JASON: Yeah, so let's do new file. We're going to do layouts default dot Astro. I'm going to grab everything that was in here. Put it in here. Then do you want me to do anything with this or just kind of for now put it in a slot?
ZEU: Yeah, we're going to put in a slot and add in O‐auth. The cool thing about fujo coded integration is we don't have to mess through a billion steps to do O‐auth. It'll give us more time to do everything else.
JASON: Excellent.
ZEU: Yeah, so right now, under layout ‐‐
JASON: So here now we're just ‐‐ for anybody who's not familiar with Astro, we just moved all of this boilerplate out, and the only thing we have to put in the index is the content we actually want. Then whatever is inside the layout goes into the slot here.
ZEU: Perfect. Cool. So at the top there in the front matter, we're going to import login. Sorry, curly brace. It's a component. Perfect. We're also going to get a variable. Not an import. We're going to do const logged in user equals Astro dot locals dot logged in user.
JASON: Oh, right. And that's not a function, right?
ZEU: No, that's a global variable.
JASON: Okay. I have an Astro plugin for VS Code that should get all this stuff to work properly. It's like 60% of the time it works every time. It's that kind of thing. Today seems to be a good day. My camera is on the fritz, but ‐‐
ZEU: Don't jinx it. This is not the time. Cool. All we need to do is add in the login component. Yep, perfect. Then to just show off we are logged in, we could do a conditional that's like logged in user double ampersand and then a P tag. Then we could just do logged in user dot handle or DID, whichever one looks cooler.
JASON: Let's to handle. Maybe here we can do a did. I think that is useful to have. Also to understand what it is we're getting at. So out here, we have our login. Then do I just do one of these?
ZEU: No at sign, but yes.
JASON: There we go. So I'm logging in. This is taking me to Bluesky. So we'll do one of those. I think it's that one.
ZEU: Perfect.
JASON: And we're authorizing.
ZEU: Yep.
JASON: Back we go. Oh, no, are you being bad? No, there it is. It just didn't catch it on the first thing, which is all stuff we can
figure out later. But this ‐‐ now, let me make the font bigger. You can see this is my handle. This is the DID, which has a structure. DID to identify what it is, PLC, which I'm not going to try to remember right now, and my actual unique ID. So this is ‐‐ honestly, I've heard people talking about AT Proto O‐auth, and I was really worried that's where we would spend all our time.
ZEU: Literally, when I was making this project, just demo to make sure everything worked, I was also dreading that because I have spent like 30 minutes to an hour, depending on the stream ‐‐ mainly because people talk in chat. But it takes a minute. There's a few steps. But thanks to the community for making this integration. Then we don't got to deal with that anymore.
JASON: Yeah, that is definitely really, really nice that just worked. Very, very cool. Awesome. So we're logged in. We got AT Proto rolling on an Astro site. Already.
ZEU: Perfect, perfect. All right. So our goal for today ‐‐ doing the O‐auth bit, honestly, making templates like that, very straightforward. But that's like the hard part, kind of. Our goal for today is to make basically an opinion aggregator. There's a site online called poll.is. Basically, the idea is somebody can put forward a topic. People can submit statements. Then you as a user can agree or disagree. Or have no opinion. So we're going to see how far we get into implementing all of that. So... yeah, I mean, first things first. I guess let's make sure we make a topic. Now, I do have a lexicon ready to go. But for this example, you don't need to know it, other than a few type definitions. So let's go ahead and make a utils library file. Then we can throw all of our type definitions in there.
JASON: Okay.
ZEU: Exactly, yeah. I normally put in lib or library, but I don't think Astro cares about that.
JASON: No, we're doing it right. We're not taking half measures here.
ZEU: You're right, you're right. Okay. So we're going to get ‐‐ let's see here ‐‐ four type definitions. First is ref. This is just a general reference to a record. So this would be URI and CID. Both are string.
JASON: Okay.
ZEU: Then the actual data that we're going to work with is ‐‐ first one is topic. This will have a title and description. The description is optional.
JASON: I'm getting quizzed on TypeScript right now. (Laughter)
ZEU: Sorry, my bad. Same vibe with statement. Title, description, same thing. We're also going to have a topic property that is a ref or a reference.
JASON: Okay. And the topic is a ref.
ZEU: Okay. Then last one is vote. This is going to have a statement, which is a ref. I call it say. Then I put agree or disagree, but you could go aye or nay if you want to be fancy about it. I don't know. Let's do agree, disagree.
JASON: Like a union. Okay.
ZEU: Perfect. Let's see here. Then we are actually ‐‐ while we're here, I'm going to throw you ‐‐ not throw you ‐‐ but we are going to make a bunch of utilities because we're going to be using ‐‐ we're going to be using a are two services made by microcosm dot blue. We're going to use constellation and slingshot to get back links and resolve records and stuff. That way we don't have to go to a PDS.
JASON: Are these packages or like APIs that I'm hitting?
ZEU: These are just APIs.
JASON: So the first one you said was constellation.
ZEU: Yeah, so constellation basically lets you index back links. For example, we want to see every single vote on a specific statement or every single statement that's attached to a topic. We're going to use constellation. So, that's that one.
JASON: Okay. Then slingshot was the other one.
ZEU: Yeah, slingshot specifically gets specific records. So we're going to use their resolve handle to get a person's DID based on the handle we give them, as well as getting a literal record based on a URI. So we're going to be using these two services to make life much easier without making our own app view.
JASON: Excellent. Okay. So you said we're going to need a handful of utils. Should we, like, scaffold them out and go fill them in?
ZEU: Yeah, so let's do ‐‐ sorry, brain. Let's do three async functions. We got get back links, which will take a subject and a source, both are strings.
JASON: And do you want these to be, like, separate arguments like this or destructured objects?
ZEU: Either one. Doesn't matter.
JASON: Okay.
ZEU: We're going to have one called get record. Let's do like a type argument. No, no, no. On get record, angle bracket T. Yep. And then we're just going to pass in a URI. Which is a string.
JASON: And third one.
ZEU: Resolve handle. It's going to have a handle property.
JASON: Perfect.
ZEU: All right. Woo. Okay. So, back links. We're going to do a normal fetch, so like const response equals await fetch. Then we could do a string literal here. It's going to be a long one. HTTPS, double backslash, constellation dot microcosm dot blue, slash XRPC slash blue dot microcosm ‐‐ I ran out of space on my page. Hold on. Let's see. Dot links dot get back links.
JASON: Is it capitalized like that?
ZEU: Yes. Perfect. Then we're going to do question mark subject equals the subject and then and source equals the source.
JASON: Spell that right. And source equals the source. Okay. Then any headers? Is it a get method?
ZEU: Yes. Just one header. We just need to accept application slash JSON.
JASON: Okay. Then we can do the standard basic check. Then we're going to get data back. So can I assume that it's called back links once we await the res JSON. Is that right?
ZEU: I destructure at this point. I destructure to total cursor and records. You don't really need cursor. This is going to be a low amount of records.
JASON: And cursor would be like for handling pagination. But we're not going to be using enough to need pagination today.
ZEU: Yes, we're using a whole new lexicon. So nobody has used it other than me. So just await res to JSON. I feel like at this point, just return both of those. Records is going to be ‐‐ records are going to be ‐‐ we'll deal with it later. Okay. Get record. Cool. We are going to use slingshot this time.
JASON: Same general idea?
ZEU: Yes. Then the URL is going to be slingshot dot microcosm dot blue slash KRPC slash blue dot microcosm dot repo dot get record by
URI.
JASON: Is URI capitalized or camel case?
ZEU: That's perfect. Then question mark at underscore URI.
JASON: Oh, because it's an AT Proto URI. Okay. Geez. Trying to talk and type at the same time is not working out. So we got that. Then same thing with the header?
ZEU: You don't need that.
JASON: And these are both get requests?
ZEU: Yes.
JASON: Okay. Then I'm going to copy paste this part. We'll change what comes out down here.
ZEU: Then this would just be ‐‐ like, you could structure it to just be JSON or something.
JASON: Got it.
ZEU: Then you could do at the end there like a type deaf anything. So as ref ampersand and then an object that has value T. Perfect. Then just return JSON.
JASON: Okay. So that's our get record.
ZEU: Cool. Then resolve handle. This is the easiest out of all of them. Same thing as the slingshot bit here. Literally just copy everything. We're just going to change that XRPC there to com dot AT Proto identify resolve handle. It's just handle as the parameter.
JASON: Handle. Then that one is ‐‐ whoops. I got a new mouse, and it's real squirrely. Okay. Then down here, we're getting ‐‐
ZEU: Destructured and it's just DID.
JASON: But we're not getting an as. Okay.
ZEU: Yeah, just DID. Just return the DID.
JASON: What did you do? Okay. So we've got our ability to resolve a handle. We've got the ability to get a record. And we've gotten a ability to get our back links. And we've got some types. Okay. I feel like we just laid a lot of foundational work here.
ZEU: Yes. This should make the rest of our time way easier. So, let's hope. So our goal right now on the homepage is to make a form. We're going to have the user make a topic. In this case, let me just double check some things here. Yeah, we just need a form. Then an action, we're going to make an Astro action in a moment. So method post action.
JASON: And we can replace that in a second.
ZEU: Yes, then we just need title description, inputs, and a button to submit.
JASON: So this is going to be create topic, right.
ZEU: Yes.
JASON: So that's our title. Here's our description. And it's okay to leave them as text fields. We don't need long descriptions or anything. Okay. Any other details in here? Oh, I need to give this a name.
ZEU: Yeah, just names.
JASON: Okay. So now on the homepage, when we look at our site, we have our title, our description, and then we can create our topic. That's going to post, but right now it doesn't post anywhere because our action is empty. So we need to create an action.
ZEU: Yes.
JASON: And we do that ‐‐ remind me, is it an actions folder?
ZEU: Yes, under source.
JASON: Okay. And this one is going to be called what?
ZEU: So we do export const server equals an object. Then in here, we're going to call it create topic. It'll auto import. Define action. Then an object inside. Then we're going to add a lot of things.
So accept is equal to form. Input, we need some validation here. We need to do Z dot object.
JASON: Gonna let me auto import that? You're not. I'll get it later. Okay. So I think ‐‐
ZEU: It's under Astro slash zod. You need to turn that into a curly brace.
JASON: What else are you unhappy about? You want the handler. I assume that's an async function, right?
ZEU: Yes. Perfect.
JASON: So now that it's not yelling at me, we have our input is going to be title. That's a Z string. And our description. Because they need to match what we did in our form.
ZEU: We're going to make description optional. Just wrap everything ‐‐ oh, or you could do that.
JASON: I think that works. Is it supposed to be Z optional around it?
ZEU: Yeah, it's Z optional. I mean, that's the way I did it.
JASON: You know, let's not rock the boat here. I feel like if you've got working code, I don't want to ‐‐ this is not the thing that I want to waste time on.
ZEU: Fair, fair. Yeah, we have ‐‐ we're speed running this. All right. Inside the parameters is input comma context. No object.
JASON: Oh, right, right. I forget. Context.
ZEU: We're going to lay more groundwork, but we're going to be copy pasting all of this later on. So let's get the logged in user by doing context dot locals logged in user, kind of like before. Then we could throw in some validation. If not logged in user, throw a new action error. I believe it's an object.
JASON: That's right, that's right.
ZEU: And it's like message. Yeah.
JASON: What is the code? Is it a 401? That's not right. What is the code?
ZEU: It's the whole string, yeah. Unauthorized.
JASON: Ahh.
ZEU: You know, it's kind of nice that Astro makes you write it all out.
JASON: It is nice.
ZEU: Cool. We're going to do something similar. We're going to get the agent. So const agent equals await. Then we're going to import get PDS agent. That's going to be a ‐‐ okay. It does not show up. I'll get you the import in a moment. Lower case ds agent. PDS agent is going to be imported from fujo coded auth proto helpers.
JASON: Oh, helpers. Okay.
ZEU: Perfect. Then similar error tracking.
JASON: Is this also unauthorized?
ZEU: I threw an internal server error. Up to you. Cool. Now let's actually make a topic. So we're going to do a try catch. If you do a catch first, you literally copy paste from the agent error. Just throw that and it's perfect.
JASON: Okay.
ZEU: Cool. So what we could do is make a record from the input. We're going to do const record ‐‐ or I call it topic record ‐‐ equals input as topic. Perfect. Now we're actually going to make the thing. We're going to do const result equals await agent dot com dot AT Proto dot repo dot create record. Okay. We're going to make an object as a parameter here. Then we're going to do repo is equal to the logged in user's DID.
JASON: Okay.
ZEU: Collection ‐‐ oh, we should make some const here. If you go back to the utilities real quick, we're going to make some constant variables here. At the very top, or there ‐‐ okay. Here's the question. Would you rather have this eventual app that I will be adding on to later be called et tu dot app or Pedro dot vote.
JASON: Obviously Pedro dot vote.
ZEU: Okay, cool. So let's call it Pedro topic. We're literally going to have this be equal to a string that's vote dot Pedro dot topic.
JASON: And this is us giving a name space for our lexicon.
ZEU: Exactly.
JASON: Did you want this to be all caps?
ZEU: Yeah, yeah.
JASON: I'm here to do it the right way. We're not cutting corners today.
ZEU: Then do the same thing for statement and vote.
JASON: Statement. And do you want it to be Pedro statement?
ZEU: Yes. Be very specific.
JASON: Okay. So vote Pedro statement. Then we'll duplicate and vote.
ZEU: Yes. We're about to use those name spaces a lot. I forgot to do that.
JASON: Got it, got it, got it. And this is going to be Pedro topic.
ZEU: Yes. Our key is going to be TID all caps. Dot next STR.
JASON: Like that?
ZEU: It's a function. Sorry. Then record is going to be the topic record.
JASON: Look at us go. Okay. So we've created a record. And so this action that we're taking right now is we're using, which comes out of the AT Proto library. Then we are creating a record. This is what will put it into the jetstream.
ZEU: This will put it into the user's PDS.
JASON: Right. Sorry. I'm skipping some steps. I'm saving it into the PDS, which means that once this happens, other apps will now be able to pick up this record if they're listening for this lexicon.
ZEU: Exactly.
JASON: Okay, cool. So this is ‐‐ for anybody who's wondering how does AT Proto work, this is the magic sauce. Once we create this thing, it's out in the world. It's out there now.
ZEU: Yes, perfect. Okay. We're going to add two more utilities. My bad.
JASON: Okay. I'm ready. We're still good.
ZEU: So we are ‐‐ oh, nope. That's not where that goes. So we are going to make two things about the at URI. They're all normal functions. One is going to be called the build at URI. The other is called parse at URI. Perfect. So build URI, here we could make this an object. It'll be DID collection and ‐‐
JASON: Oh, wait. I'm doing this wrong. Did collection, R key. Then we need to copy this. Now they all get to be strings. None of these are optional, right?
ZEU: No. Then we're just going to return a string literal that is at. Yep. Then just DID slash collection slash R key. The cool bit about this is it looks like HTTP, like just a normal URI. It's modeled after that. It's pretty cool.
JASON: I do really like that about this protocol. It just makes ‐‐ it doesn't force you to build a whole new mental model. You're kind of doing this already. It just has different semantics.
ZEU: Exactly.
JASON: Or same semantics but different outcomes.
ZEU: Yeah.
JASON: Okay, so here.
ZEU: Ready for some regex?
JASON: Oh, yeah, all right. Let's do it.
ZEU: Const regex equals slash at ‐‐ yeah. Then we're going to do group. Parentheses, question mark, angle bracket. Then DID dot star. Perfect. Slash collection. So name it collection. It's just going to be dot star here. Then same thing for R key from the collection.
JASON: For anybody who is confused by what's happening right now, don't worry about it. Regex sucks.
ZEU: When I first made this, like a year and a half ago, it took me a solid 30 minutes. I was like regex sucks.
JASON: It's one of those things that, like, for some reason I spent a long time getting really good at it. Now every time ‐‐ like, it doesn't matter how good you get at it. You still regret it every time you have to use it.
ZEU: So true. So true. Cool. So we're going to do const groups equals regex dot exec. That's a function URI question mark dot groups. Perfect. We're just going to return an object with the DID equals groups question mark dot DID and the rest are the same.
JASON: So we got our collection and our R key. Okay.
ZEU: Cool, great. Perfect. So back to the ‐‐ back at the action. That should be the last time we touch utilities. Cool. Here we're going to get the R key. So const R key. I feel like I could have made this easier.
JASON: You know, it's fine.
ZEU: It is what it is. Optimization later. Then result dot data dot URI. Perfect. Then we're going to go ahead and return an object. We're going to use it to redirect once we create it. So redirect is equal to a string literal. We're going to do slash opinion slash the logged in user dot handle. Then the R key as a string.
JASON: Okay. Like that?
ZEU: Yes, perfect. My news the semicolon.
JASON: Oh, right, right. Because we're in an object.
ZEU: Yeah, so we're good on that. Now we can just go back to the main page.
JASON: Here. Now we're going to use our actions. Ta‐da.
ZEU: Perfect. Then in the front matter, we're going to do const result equals Astro dot get action result.
JASON: That's right. That's right.
ZEU: Actions dot create topic. Then an if statement. If result dot data dot redirect. Then return Astro dot redirect result dot data dot redirect.
JASON: Okay. So that will put us over on the page. Do we want to create the page, or do we want to try to submit this and show that it's working?
ZEU: Yeah, yeah. Let's make the thing real quick.
JASON: Okay. So that was opinions. Then we have the handle. Then we have R key dot Astro. Okay
ZEU: Then we can do params to show the params exist.
JASON: Import layout from layouts. Am I doing that wrong? Come on, bud. Layouts default. And the result is ‐‐ where does that live? Same thing?
ZEU: We need to get the handle and R key from Astro.
JASON: I absolutely knew that. We're getting the handle and R key equals Astro params. Okay. Then down here. Okay. So that's our guy. Theoretically speaking, if we ‐‐ don't you do that to me. We're going to stop and restart because we created an action. I think that
sometimes causes ‐‐ wait, did I just forget ‐‐ oh, it's down here. No! Actions can't be loaded?
ZEU: I've never seen that.
JASON: Oh, good. That means I did something wrong. Actions from Astro actions. That's exactly what we want it to be. There's our create target. Why can't you load our actions? Oh, my god. I just have a completely invalid file because I forgot how freaking TypeScript works. Which would explain why nothing is loading. Now does it work? What a doofus. Okay. Now I got to log in one more time. Hopefully it does a quick redirect for us this time. Nope.
ZEU: Remember this account on this device.
JASON: Okay. We're going to copy the password. We're going to do this. Yeah, I know. I'm not going to do that, but I am going to authorize it. Okay. So now we're logged back in. We can say test topic. Description is optional. I'm going to let it rip, right?
ZEU: Yeah, go for it.
JASON: Action create topic.
ZEU: It didn't redirect. That was interesting.
JASON: It didn't redirect, and it ‐‐ did it do the thing?
ZEU: Oh, it errored.
JASON: An error is Astro action error. And what is the ‐‐ you got to give me better errors than that. What's going on?
ZEU: We literally gave it descriptions on the errors.
JASON: Yeah, where you at? Payload, headers, response headers. So it just sent back a 500, which means what? Let's look at our index here.
ZEU: We could console log the error.
JASON: Yeah, let's throw a bunch of console logs in here and see which thing is failing. Then we'll do the same thing down here. All right. Let's try that one more time. That gave us just a straight‐up failed for some reason. But it did give us our object here. This is what's failing. And it's failing for what purpose?
ZEU: Why is R key highlighted?
JASON: That's a different plugin. It's like a spell check thing.
ZEU: Trying to see what's different. Const result equals await agent. Parameter repo is logged in user dot DID. Pedro topic. R key is TID dot next string. Record is topic record.
JASON: And we know the topic record is right. Because here's our topic. So that's fine. Where am I getting the TID from? That's correct, right?
ZEU: Yes. That'll automatically generate the TID. Then const R key.
JASON: We're not getting here, which means this actual call is failing.
ZEU: Interesting. The agent is failing.
JASON: Let me try ‐‐
ZEU: Because the agent exists. It didn't throw there.
JASON: Let's just see what happens if we stringify this error and see what comes out. Scope missing.
ZEU: Okay. So the cool thing about AT Proto that I completely forgot about, we need to go to the Astro config file and add an object to the auth proto integration there. The cool thing about AT Proto is that you can, as a developer, scope your app so that your app only has access to specific name spaces.
JASON: Oh, got it. Okay.
ZEU: Right. Okay. So this is going to be a long one, but we're going to copy it. We're going to do repo colon ‐‐
JASON: Wait, wait, wait. Hold on. Is this in scopes, or am I somewhere else?
ZEU: We're inside scopes in the array. We're going to make three of them for each one, but we'll make one and just copy paste. Repo colon vote dot Pedro dot topic question mark action equals create and action equals update and action equals delete.
JASON: Like that?
ZEU: Yep, then the same thing for the rest of them.
JASON: And that was ‐‐
ZEU: Statement and vote.
JASON: Statement and vote. Then do we need to allow any of the other stuff? Why are you so mad?
ZEU: We need to add two more things that are needed. Application name. Just call it Pedro. Then application domain. Just throw Pedro dot vote. I will be stealing it, but that's okay. There we go. Perfect.
JASON: So now let's see if it'll just let us do what we want here.
ZEU: You need to re‐auth. So just log in again.
JASON: Oh, got it. Okay. Are you dead? You look dead. Let's try again. Okay. Cancel. Let's go back here. There we go. Logging in. Nope.
ZEU: Cool. Then before you move on here ‐‐ oh, no.
JASON: Shoot. Let me try it again.
ZEU: The cool thing, apps can be scoped down so you only have access to specific lexicons. So for this one, you don't need Bluesky posts. So it is detailed on the O‐auth screen that this app will only have access to these records, which is really cool.
JASON: Cool, and that's nice if you're trying to tell somebody I want you to log into this, but I'm not trying to get full access to your entire data.
ZEU: Exactly.
JASON: Okay. So now ‐‐ so much closer, but we screwed something up. The thing I screwed up is I think I ‐‐ yes. I did that wrong. Opinion. Look at us go.
ZEU: You did it. Look at us go.
JASON: So, we are basically out of time, but the cool thing about this is ‐‐ is there a place we can go to, like, find this in the firehose somewhere really quickly? Just to show it is, in fact, on the chain or on the AT Proto?
ZEU: Yes. So there is a site. I put it on the chat here. It's called atproto dot at. This is an explorer where you can look at anybody's public PDS. Then we could look up yours real quick.
JASON: Okay. So we can look at my DID for this, yes?
ZEU: You can put in your handle.
JASON: Oh, nice. Okay. There's my handle. And that's here.
ZEU: So now you can see ‐‐
JASON: Hey, hey. Look at that. This is sick. Okay. I mean, obviously we didn't have time to get in and actually start pulling this and displaying it, but the hard part is getting things to exist out in the world for other people to consume. So now that this exists and we have the ability to create data, put it on the AT Proto, and you can go to a different site. We don't have anything to do with AT Proto. That means anybody, anywhere who's using AT Proto can pull this lexicon, and they can do stuff with it. That's freaking cool. Like, I have so many ideas for different ways that this could be used. There's so many interesting things happening out in the atmosphere, so to speak, that are just ‐‐ like, it truly ‐‐ I talked about this earlier. This is one of the things that I find so exciting
in the web dev space, especially right now in this time where it kind of seems like cynicism is running rampant. This does not feel cynical to me. This feels so unapologetically hopeful and excited for what's possible on the web. Thank you so much for teaching us. Anywhere that people should go if they want to take this further? What resources do you love?
ZEU: Yeah, so if you want a quick introduction to AT Protocol in general, go to the official docs at atproto.com. There are lovely writing by Dan Abramov, the React guy, at overreacted.io. He has a few blogs there called Open Social, Where It's At, and a Social File System, that will really radicalize you into believing AT Proto is the future. Yeah, those are where you should start.
JASON: Okay. And then if you want to learn more about lexicons, I found the standard site is just good for sort of seeing things that aren't Bluesky as lexicons. So you can start to get your head around what's possible. Then of course, we're going to throw back to Zeu's website. Zeu, any additional words for everybody before we wrap up?
ZEU: Quick shill. I will probably be livestreaming later today, continuing to make Pedro dot vote a real thing. So, go to Twitch.TV/zeu_ dev. I will be there in some indeterminant future today, making what we were just doing here with JSON ‐‐ Jason. I called you JSON.
JASON: Yeah, let's do it. I'm full of data.
ZEU: Exactly. I will be there. And yeah, I'm also on Bluesky. I'm in conversations with a lot of AT Proto developers. If you want to be in the conversation and shape the future of this protocol and shape the future of the decentralized social web, come join us on Bluesky.
JASON: Love it. Zeu, thank you so much for being here. Thank you all so much for hanging out with us today and watching. We are doing Learn With Jason. There's a companion episode to this where we talked more abstract about what AT Proto is, why it's exciting. You can find that on your podcaster of choice or codeTV.dev. If you've enjoyed this, like the show, share it, leave a comment, subscribe to the channel. Do whatever it is you do that lets other people know you enjoyed something. Thank you all for being here. Head to codeTV.dev. Zeu, thanks again. Thank you all for watching. We'll see you all next time.