Chad (@chadtmiller.com)
Stoked to spend some time in #ucluelet this week amongst the waves and the whistle buoy.
software engineer, atproto hacking,📍PDX Building @grain.social, a photo sharing platform for Bluesky grain profile: https://grain.social/profile/chadtmiller.com
432 followers 307 following 178 posts
view profile on Bluesky Chad (@chadtmiller.com)
Stoked to spend some time in #ucluelet this week amongst the waves and the whistle buoy.
Chad (@chadtmiller.com) reply parent
Great chatting, @bmann.ca! Excited to share more soon!
Chad (@chadtmiller.com) reply parent
my favorite part of all the proxying stuff is when you eventually find this note in the OAuth docs > Proxying every call through the PDS is not recommended for performance reasons github.com/bluesky-soci...
Chad (@chadtmiller.com) reply parent
The secret sauce. It’s been out for a few months now. I wouldn’t have launched @grain.social without it. Upcoming Slices appview builder uses this for backfill. My BFF library uses it as well but Slices is gonna be better. 🦀
Chad (@chadtmiller.com) reply parent
Stoked for scopes in AIP!
Chad (@chadtmiller.com) reply parent
You can do it without AIP too. Just have your cli spin up a temporary server to catch the callback. Device code flow is better though. Your cli would poll a token endpoint until the code is authorized.
Chad (@chadtmiller.com) reply parent
seeing an issue with the delete record dialog, it's way off to the right. everything else seems good so far!
Chad (@chadtmiller.com) reply parent
So nice! I saw @bad-example.com was using it for slingshot and then went and checked it out!
Chad (@chadtmiller.com)
Another thing I'm playing around with in Slices, auto-generated interactive Open API docs based on your lexicons. All collections get their own xrpc endpoints so you can interact with them via an http client. You can even export the Open API doc.
Chad (@chadtmiller.com) reply parent
Eventually, yes! I haven't tested any of the new scope stuff with the AIP flow. This is very POC getting this all working.
Chad (@chadtmiller.com) reply parent
Hope this works! 🤞 #atprotocol
Chad (@chadtmiller.com) reply parent
tangled.sh/@chadtmiller...
Chad (@chadtmiller.com)
Alright here we go! Statuspere the way it was meant to be statusphere.bigmoves.deno.net running as a fully synced AppView. Uses all new SDKs for running an AppView on Slices (a new appview service coming soon). Deployed with @deno.land deploy, uses Deno KV for session storage, OAuth with AIP ✨
Chad (@chadtmiller.com) reply parent
The statusphere record is a true badge of honor in the atmosphere and should never be deleted
Chad (@chadtmiller.com) reply parent
Could also mean that people delete their statusphere records
Chad (@chadtmiller.com) reply parent
Yeah same. The metric means there are 350 unique repos where the statusphere record exists
Chad (@chadtmiller.com)
I thought there would be more people trying out Statusphere honestly (unless my numbers are wrong). Maybe just confirms we need better appview tooling. Slices is coming to the rescue! #atprotocol
Chad (@chadtmiller.com) reply parent
Yeah it’ll be open source
Chad (@chadtmiller.com) reply parent
Thanks, Boris!
Chad (@chadtmiller.com) reply parent
Yes, would be great to chat! Yeah Slices is not really intended to be IndieSky scale mostly focused on custom lexicons at the moment. I have a ko-fi setup ko-fi.com/bigmoves. Really appreciate the support!
Chad (@chadtmiller.com) reply parent
Working on a new OAuth client library as well to use directly with AIP jsr.io/@slices/oauth. Plugs into the Slices generated client.
Chad (@chadtmiller.com) reply parent
Hopefully launch soon or at least have something self-hostable to start playing around with.
Chad (@chadtmiller.com) reply parent
If anyone is interested in funding/donating to this kinda thing let me know, there is still a lot of work to do. I don't currently work on this stuff full time but would love to. Making appviews more approachable is definitely something this community needs and happy to help. Anyways more soon ✌️
Chad (@chadtmiller.com) reply parent
Slices is a social app so a lot of things to explore!
Chad (@chadtmiller.com) reply parent
I think Slices will be a great way for #atprotocol devs to share lexicons and allow others to build cool stuff on top of their data! Could even have a way to verify slices with their domin so @grain.social for example could have it's own verified index/lexicons to work with.
Chad (@chadtmiller.com) reply parent
Here's some example clients working against a @tangled.sh slice and a Statusphere slice. Slices frontend is also built on top of the same client using the Slices lexicon.
Chad (@chadtmiller.com) reply parent
I'm building all the codegen from the ground up and not connected to any of the existing node sdks for atproto. It also uses @graze.social 's AIP for authentication which unlocks a much better OAuth experience on atproto imo. Also using a lot of @ngerakines.me rust tools tangled.sh/@smokesignal...
Chad (@chadtmiller.com)
Excited to share some new stuff I've been I've been working on. It's an appview for building appviews called Slices. A slice reads your lexicons, indexes your records from the Jetstream, does backfill and provides a typescript client to interact with your lexicon .listRecords, .searchRecords, etc
Chad (@chadtmiller.com) reply parent
@grain.social runs on sqlite as well, single node shared instance lol
Chad (@chadtmiller.com)
new @tangled.sh trending is rad ⚡️
Chad (@chadtmiller.com) reply parent
For now, you could just tag as #ATProto_NYC in the gallery description and they will all show up on the hashtag page if everyone else does the same thing.
Chad (@chadtmiller.com) reply parent
Yes, it's something I want to support in the future! I was playing around with some ideas for that exact use case a while ago but got distracted by other stuff. I'll try to get back to it soon!
Chad (@chadtmiller.com) reply parent
Haha I thought that looked familiar!
Chad (@chadtmiller.com)
Some pics off the 101 in Southern Oregon. Cape Blanco, Brookings, Boardman Corridor. Shot on the #ricohgrII grain.social/profile/chad...
Chad (@chadtmiller.com)
#ATProto_NYC talks were awesome! I was on the live stream in spirit 🙌
Chad (@chadtmiller.com) reply parent
Atproto on Rails??
Chad (@chadtmiller.com) reply parent
They are better than I expected! I fixed some bugs before launching that I thought for sure would show up again but it’s working great!
Chad (@chadtmiller.com) reply parent
updated my pds and we're all good
Chad (@chadtmiller.com) reply parent
login doesn't seem to be working a self-hosted pds
Chad (@chadtmiller.com) reply parent
Yeah for sure, if possible or other people are interested that would be great!
Chad (@chadtmiller.com) reply parent
Grain could sync all of the @smokesignal.events events you've attended and show a dropdown on gallery create/edit.
Chad (@chadtmiller.com) reply parent
Wish I could make it! Anyone want to take some pics from the event and post to @grain.social? I've got some ideas for a @smokesignal.events collab where we could link a photo gallery to an event and render the embed!
Chad (@chadtmiller.com) reply parent
looks great!
Chad (@chadtmiller.com)
Ok did some hacking and I think I got it working. Here's a POC of the full OAuth 2.0 Device Authorization Grant (RFC 8628) flow in AIP! Authorize with #atproto using device codes. Opens up all kinds of things authorizing with #atproto like CLIs, TVs, IoT stuff, etc. github.com/graze-social....
Chad (@chadtmiller.com) reply parent
Goal is to have the @grain.social web, flutter, and cli apps all talking to AIP to resolve atproto session data for the user/validate tokens. More on this soon and some reference implementations! Excited to finally get the auth piece out of the way and keep building new stuff for @grain.social 📸
Chad (@chadtmiller.com) reply parent
I've got a working nix flake for the AIP sqlite build (excluding some env vars you need to set at runtime) deployed to auth.grainsocial.network. tangled.sh/strings/chad...
Chad (@chadtmiller.com) reply parent
@ngerakines.me explains issues/solutions around this here: blog.smokesignal.events/posts/3lvtim.... AIP doesn't fully support DCR yet (some of the client metadata in the blog post isn't supported and needs device code handlers) but it's trivial to add the missing pieces based on the spec.
Chad (@chadtmiller.com)
Working on a quite a large rewrite of @grain.social to work with AIP github.com/graze-social.... If you are looking to build an #atproto app for web, native, and cli definitely check it out. I was hitting a dead end with the official node atproto oauth library, as it doesn't currently support DCR.
Chad (@chadtmiller.com) reply parent
www.goatcounter.com
Chad (@chadtmiller.com) reply parent
Something like calagator.org would be cool. Not overly flashy and gets the job done. Claude could probably do it.
Chad (@chadtmiller.com) reply parent
Rad, gonna look into moving all our stuff over. Really appreciate all your content and work on atproto things!
Chad (@chadtmiller.com) reply parent
Yes! I'm running into this issue with @grain.social having recently spun up a native mobile app and working on a cli in addition to the web experience. Currently working around around it by managing sessions per client type using the bff to delegate the redirect. Does AIP support multiple clients?
Chad (@chadtmiller.com) reply parent
These are generated via a rust service tangled.sh/@grain.socia.... It renders the gallery in a headless browser and takes a snapshot. Thinking about using the same templates for embeds as well.
Chad (@chadtmiller.com) reply parent
grain.social/profile/chad...
Chad (@chadtmiller.com) reply parent
grain.social/profile/chad...
Chad (@chadtmiller.com) reply parent
grain.social/profile/chad...
Chad (@chadtmiller.com)
Giving @grain.social some flare ✨. The og:image by default will now display a preview of your gallery in a collage format. Probably have a way to customize this in the future. Still playing around with different ideas. Here's a few examples: grain.social/profile/chad...
Chad (@chadtmiller.com)
Went down a rabbit hole getting a minimal nix flake setup with rust and a headless browser but now @grain.social can create these gallery composites for sharing. Inspired by retro.app. Hopefully have more on this soon!
Chad (@chadtmiller.com) reply parent
Also caligator calagator.org
Chad (@chadtmiller.com) reply parent
Some inspiration, I frequent these a lot in Portland everout.com/portland/eve... and www.wweek.com/calendar/cal.... Also something like songkick could be cool www.songkick.com/artists/1335...
Chad (@chadtmiller.com) reply parent
Yeah! I just a need a burner android device to get it setup in the play store. I only have an iOS device. I’ll try to get it sorted out soon!
Chad (@chadtmiller.com)
Excited to finally make this available. Started learning @flutter.dev only a few weeks so be gentle! Honestly flutter has been great so far.
Chad (@chadtmiller.com)
Just published the code for the @grain.social iOS/android app to tangled.sh/@grain.socia... and github.com/grainsocial/.... Still working through a few things before releasing more widely but here’s a quick video of what it’s looking like so far.
Chad (@chadtmiller.com)
Photos from an adventure this past weekend to escape all the noise. #adventure #photography #mountains Check out this gallery on @grain.social grain.social/profile/chad...
Chad (@chadtmiller.com)
It's been an insane amount of work but hoping have a beta ready soon for @grain.social on iOS/Android. The goal is to have feature parity with the web app. Building with @flutter.dev. Will be open source. ✌️ #photography #atprotocol
Chad (@chadtmiller.com) reply parent
for inspiration swag.htmx.org/en-usd
Chad (@chadtmiller.com) reply parent
This is rad!
Chad (@chadtmiller.com) reply parent
love that place
Chad (@chadtmiller.com) reply parent
It would be cool though if bsky posts supported various record embeds or there was a more robust api for that. Then you could view a grain gallery fully in app.
Chad (@chadtmiller.com) reply parent
You could definitely have a separate appview just for that experience. Photos on the #atprotocol. Blob refs have a mime type so could detect various image formats on the firehose.
Chad (@chadtmiller.com) reply parent
Grain galleries aren’t the same as posts so I’m not really sure how a cross integration work but maybe you could convert a flashes post for example into a grain gallery.
Chad (@chadtmiller.com) reply parent
The intent of the integration of other networks on grain was just to show grain galleries of people of you follow on other atproto platforms or potentially bridged users from other networks.
Chad (@chadtmiller.com)
Really stoked for this! @grain.social is built from the ground up (not a Bluesky client) rethinking what it means to share photos on the #atprotocol.
Chad (@chadtmiller.com) reply parent
where do all the chads go?
Chad (@chadtmiller.com) reply parent
This is awesome! Gonna have to checkout disco
Chad (@chadtmiller.com) reply parent
*There is no React.js involved in this operation.
Chad (@chadtmiller.com)
If you were like me, pulled down the statusphere repo when you first started getting into #atproto, and thought there's no way this barebones stack is going to make anything cool...it can and it has! @grain.social is essentially built on the same concepts: ssr + sqlite + some js sprinkled on top.
Chad (@chadtmiller.com) reply parent
Good news is that I updated BFF to support this and you can continue to use the index service queries as normal. There's also a new countRecords method with the same signature as getRecords. @grain.social timeline loads pretty fast now.
Chad (@chadtmiller.com)
jk def need indexes. I added gallery favorites to the @grain.social timeline and query performance dropped significantly. Maybe this is a right of passage for building a social app. Index monster is waiting for you...
Teen Vogue (@teenvogue.com) reposted
A wave of legislation and executive actions have targeted transgender people, particularly teens, by stripping away gender-affirming care and other essential rights, but intersex people and anyone who doesn’t conform to strict sex binaries also stand to lose something as a result.
Chad (@chadtmiller.com) reply parent
Awesome list! Would be cool to see @grain.social on the next update! Flickr style photo sharing on the #atprotocol totally separate from Bluesky.
Chad (@chadtmiller.com)
Really stoked for this. Bringing flickr style photo sharing to the #atprotocol but more hip and open source.
Chad (@chadtmiller.com) reply parent
Maybe there can be a way to get the diff and you could apply the changes back to your repo.
Chad (@chadtmiller.com) reply parent
Right now I'm thinking of simple apps where maybe you initially started out with deploy and want to make tweaks on the fly without having to jump back to your editor.
Chad (@chadtmiller.com) reply parent
Awesome! Enjoying the new deploy so far! Is there going to be a way to create a playground from an existing application?
Chad (@chadtmiller.com) reply parent
It appears the new @deno.land deploy shuts down your app after a short period of inactivity so no live sync for now. But when your app boots back up it will sync all your records again. You could deploy to a different cloud provider to keep the jetstream connected.
Chad (@chadtmiller.com) reply parent
Working on getting BFF github.com/bigmoves/bff out of the current beta cycle. Hopefully have some more updates on that soon. Documentation is fairly light at the moment but the portfolio site and @grain.social are both open source as references.
Chad (@chadtmiller.com) reply parent
Not having proper indexes could bite in the long run, but at that point hopefully your app has some traction and funding and you can spend more time on performance. At least that's the idea I'm running with right now.
Chad (@chadtmiller.com) reply parent
All of the records are stored in a simple "records" table so you don't have to worry about creating separate indexes. This honestly caused me a lot of headache when starting to build an appview. I don't want to think about indexes right now, I just wanna build something.
Chad (@chadtmiller.com) reply parent
The idea with BFF is that you get all the data you need via an initial sync and then listen to the jetstream for updates. BFF has a built in query builder with support for various where and orderBy clauses so you don't have to write any custom sql queries.
Chad (@chadtmiller.com) reply parent
This is cool because you don't have to wait for an #atprotocol app to build out xrpc apis to get at it's indexed data, you can just create a slice for what you need. You could also integrate other apps on the protocol. For example, you might want to show your @tangled.sh repos!
Chad (@chadtmiller.com) reply parent
Code is here github.com/bigmoves/bff.... This is a functioning appview! It will watch for updates to your grain records on the firehose and update it's index with any changes. For example, you add some new photos to a gallery or change the sort order on grain, your portfolio stays in sync.
Chad (@chadtmiller.com)
Created a tiny BFF app (an #atprotocol framework I'm working on that also runs @grain.social) you can use to display all your grain galleries on your own portfolio site. I deployed it with @deno.land's new deploy and it was pretty easy. bff-grain-portfolio-example.bigmoves.deno.net
Chad (@chadtmiller.com)
Weekend adventure to Bainbridge shot on the Ricoh GRii. Check out this gallery on @grain.social grain.social/profile/chad...
zeu (@zeu.dev) reposted reply parent
we love oobs, all the homies love oobs
Chad (@chadtmiller.com)
@htmx.org oobs in the wild 📸🕵️ @grain.social #htmx #oob