Farcaster frames: building embeddable Ethereum apps
Devcon·Thu, Oct 9, 2025, 12:00 AM
Frames are an open standard for creating embeddable, interactive apps in social media feeds and on the web. They help solve one of the hardest problems for Ethereum dapp developers: distribution. Although frames originated on Farcaster, it's now possible to build cross-platform frames that work on Farcaster, Lens, XMTP, and the open web. In this hands on workshop we'll introduce the core concepts behind frames and build a simple frame app that interacts with a smart contract.
Transcript
[Music] [Music] all right hey everyone uh my name is horx and I work on farcaster I'm here today to talk about building embeddable ethereum apps using forecaster frames so forecaster is a decentralized programmable social network built on top of ethereum and this is what it looks like right now it's basically a feed focused short text social network uh you can create a profile you can follow people and topics you're interested in post things like text images links and video uh it looks a lot like Twitter but it's purple and if you squint it might look a little bit like Instagram or Facebook or Reddit too because it's built on most of the same social Primitives things like your identity your social graph and text and media content uh just curious like how many folks here are on farcaster okay how many are like daily active users of forecaster cool and how many of you have built a a frame already okay cool uh so yeah at farcaster we're building social networking as an open protocol that means that your account and identity live on chain as something that you actually meaningfully own it means that your data and social graph are stored and replicated on an open peer-to-peer Network that can't be shut down like a private API uh and it means that forecaster clients are something we design and build with programmability in mind so that you can build and distribute apps permissionless so David actually already gave us a really great intro to frames and what they are um but I'll I'll give you another frames are a way to build interactive apps that are embedded directly in the forecaster social feed uh so here's an example uh and this is kind of the demo we'll be using today which is a little game called yoink if you're building an ethereum app it can be pretty difficult to get that app in front of users they have to find your app on the web or on social media they have to click through to the app open a new page connect their wallets sign in and only then can they do something interesting uh I think most builders in the space of had this experience it's like can be really hard if you've built something just to get it in front in front of users who have a connected ethereum wallet so frames helped solve this problem by helping your opet distribution they enable you to embed interactive calls to action and ethereum transactions Direct ly in the forecaster social feed so you can reach users where they are we have right now around 50,000 daily active users on forecaster and creating a frame is a great way to reach them we wrote the first frame spec back in January and since then developers have built thousands of frames for all kinds of interesting applications so apps like rodo Zora and Moshi cam have built frames that enable you to Mint and collect and feed on farcaster every poly Market link is a frame where you can make a prediction in just a few Taps every mirror and paragraph article is a frame where you can subscribe in one click or even launch a mini app to read articles right in the app yeah let's let that that one play for a sec so yeah you can uh click through to open this mini app and actually browse an article directly in in warcast uh there are frame apps for organizing and managing events that take place in the real world and events that are online things like meetups and audio spaces developers have built frames that facilitate payments subscriptions and commerce and that's just the surface there's a lot more things like polls media games crowdfunding tipping swapping and much more so if you want to explore frames for yourself a really good place to find some is this explore tab in warcast if you tap this globe right in the center of the nav bar and scroll down in webcast you'll find sort of an interactive uh screen here where you can browse through uh not just frames but apps uh and and other things that are built on top of the forecaster protocol so frames are cool on their own just as like an embed that appears in the feed but they get even more interesting when you combine them with other programmable surfaces in farcaster uh so sort of throughout farcaster we've tried to build in places where you can uh program forecaster right you can build through using apis and using Open Standards the ability to uh build your app into the farcaster social feed so for example developers can build mini apps that interactively add frame from the cast composer so you can create a poll with Ponder and insert it into a cast on wecast you could search for a gift to insert from a GI keyboard or you could share media like books songs and movies with Nook uh you can also launch a frame by clicking on a cast to take actions like translating bookmarking and tipping that exist in kind of the the context of a cast so you can think of this almost like a browser extension for a social network or a programmable like button that's built into the app uh a final way you can use frames is sending them in direct messages so like this event reminder on the left was sent through a direct message so sort of closing this feedback loop where you can communicate back to the user uh and send them a frame in in a direct message so we think about frames actions mini apps direct messages all of these things as developer Legos that we're building uh on top of forecaster and into forecaster clients uh and building Legos that enable you to kind of snap them together to extend clients in new and interesting ways and embed your app throughout the social feed frames are not just on forecaster uh they originated on forecaster But ultimately they're based on a pretty simple open spec that anyone can Implement uh in fact David and open frames have extended farcaster frames to be usable in in a bunch of different applications throughout the ecosystem so thanks to projects like open frames you can build frames that now work across foraster lens xmt uh the open web and even like he demoed using their extension on X uh we think there are now at least 24 apps that display frames across the ethereum ecosystem you can see some of them here uh on the left here as well you can see a frame that's embedded in lens so a math quiz frame that works across the forecaster and lens ecosystem uh okay so we're going to build a frame in today's talk let's talk a little bit about kind of the theory behind frames and how they work uh ultimately they're based on a few Old Reliable web standards the three big ones are open graph HTML and HTTP uh so one thing I think is great about frames is that if you can build a web app you can build a frame in particular I think they're cool because they're permissionless meaning anyone can build one they're simple which also means anyone can build one and we've seen lots of developers come to forecaster and kind of build a frame as as their first app right or their introduction to to web programming or ethereum programming uh and in fact they're so simple you might call them extremely constrained but I think that encourages creativity so if you've ever copy pasted a link from the web and seen it unfurl into a preview image this was probably thanks to open craft uh and here's a great example right if you copy a GitHub repo URL uh and paste it into Twitter you get an image that looks like this it's this nice Dynamic image that shows the repo name icon number of stars and forks so it's possible for Twitter clients and you know uh applications on the web to render this because GitHub includes special metadata tags in the HTML head elements of this page uh and in fact here's what they look like uh yeah these meta tags describe the image here the type of the content here this is a website the title description of the site and a URL so when you post your tweet twitter makes an HTTP request to fetch this page loads the HTML looks for the the head element parses these metadata tags out of it and then ultimately renders this really nice image instead of the plain URL so open graph is actually kind of an oldish standard at this point it was created way back in 20110 by Facebook uh but it's still very widely used around the web uh and in fact you might have seen more of these Dynamic images around the web lately if you use versel they have really good tools like Satori which are used for rendering HTML into a nice Dynamic image and in fact one of our Inspirations for frames was the fact that we were already rendering these share images for farcaster casts you can like click within warcast and share out an image and will'll render this uh um sheare image that you can can post around the web um we realized kind of by building this that there were pretty good tooling out there for rendering jsx rendering HTML to images and so it's kind of becoming possible to turn open graph previews into these simple if constrained uis okay so the big idea behind frames is that we're going to take the sort of static open graph metadata and extend it with the ability to Define interactive actions and simple UI elements along with static components that you're used to from open graph like an image But ultimately it's all the same basic idea uh forecaster client will fetch the URL it will load the HTML parse out the metat tags and render an interactive embed it's just that if it's a frame we've happened to added we've happened to add these uh these buttons and actions that Define some interactive things you can do with it so here's what frame metadata looks like you can see it looks a lot like open graph you can define an image think of this as your UI right this is kind of your browser canvas in which you're going to build and render your application you can Define simple UI elements so buttons you have up to four buttons and you can add a very simple text input um that's it and then finally you can define a web server which is how your frame handles interactive actions over HTTP so it's kind of like if open graph was created by cool Mark Zuckerberg that did not land all right uh cool okay so here's how a frame interacts with the server like kind of the whole the whole life cycle more concretely um we've got the cast composer up here this is where you're typing in your your cast your post uh so yeah when you first post a link your forecaster client will get the URL the frame server then returns an HTML page right this defines those images buttons and actions in the markup client parses that frame metadata and renders it in feed so it looks like this Frame server returns frame metadata uh the client parses that and renders it so clients will typically cache this initial frame uh in fact in warcast they're like cach quite heavily so we can build feeds and render them quickly uh which is kind of a common frame gotcha so be careful about this in in that your layout and your initial image will typically be cached okay so now when the user comes and clicks a button the client makes a post request to the server and this post request includes some information about which button was clicked and the user's identity from there the server can return HTML that defines another frame and if there's a button to click in that frame the client posts back to the server it can return another frame so on and so forth sort of just back and forth HTTP request response cycle so this means you can chain frames together to create workflows that have multiple steps uh you can Branch based on user input you know return frame a if this return frame B if that uh and you can even compose frames kind of like you might compose functions you can have one frame make a request to another okay action types so you can Define this image you can Define these buttons that make particular requests that uh represent different types of actions what are those typ types of actions so there are a few different ones uh by default clicking a button will make a post request to your frame server sort of standard HTTP post um there are some other types as well so you may want to link out right send the user to an external link uh you can do that using either a post redirect button or a link button so which is one of those is a sort of a dynamic link where your server will receive a post request uh you can respond with a with a URL that will redirect the user to so you can use that to kind of figure out if you want a dynamic link based on some state of the request or or the user or whatever uh versus a link if you just want to add a static link which is like a pretty pretty common typical use case you can simply add that as a link button uh and then the most interesting one and the one that we're going to talk about a lot today are transactions uh which make a request to fetch an ethereum transaction uh they get the call data for that ethereum transaction and then they forward that to the user's connected wallet so you can use that to basically embed direct ethereum transactions calls to action uh Direct into a button on a frame okay so images and buttons in HTML metadata you can think of these as defining your frame UI uh we have HTTP requests made to your frame server that Define the actions you can take the Behavior Uh there's one more really important frames concept to cover which is the signed frame message so this is the like data payload that the client posts whenever you click a frame button and this is a Json object that looks like this uh it's compact but it actually communicates a bunch of useful information to your frame server so up here you get the forecaster user ID of who interacted with the frame uh in this case it was me that's my FID 361 it tells you what frame they interacted with and when they did it you get in here in this cast ID components information about the cast The Post where the frame was embedded and that includes who posted that cast which is very useful and then of course you get which button the user pressed so you can use this to figure out what they did and then respond to it on your server so in addition to all this since farcaster data is open and public you can further enhance this with data from the user's social graph or onchain history so for example you could look up whether the user who interacted with the frame is following you uh or you could look up their linked ethereum addresses and you know figure out whether they own a token things like that this last component of the message is probably the most important so this trusted data field is a hex encoded cryptographic signature that you can use to verify the data in the rest of the message so every post follow and like on forecaster is a cryptographically signed message which is stor stor on farcaster hubs uh when you publish a cast basically you're signing a message with an ed25519 key uh hubs will store that message as long as the key exists in an onchain registry so your ethereum account controls your identity that account can delegate to uh an ed25519 key which signs your messages on the protocol those go onto hubs this peer-to-peer Network which stores stores all the data uh yeah this is kind of a diagram of the uh The Hub system and how how hubs work so a hub will accept a message if the the cryptographic signature is valid and if the key is in the onchain registry so frame messages use this same format which we use for signing uh signing posts signing reactions signing all the other types of messaging data on foraster you can verify them in exactly the same way but they're ephemeral so they're not stored on the network but you can still verify them in the same way so this means it's possible to build authenticated experiences that rely on the user's identity uh and you can do this permissionless without needing an API key or asking the user to log in and so concretely the way you can do this is uh to interact with an HTTP API that's Exposed on the hubs you can basically grab that uh cryptographic that grab that hex encoded signature out of the uh the message data make a request to a hub API which will verify it for you uh if you want to do that you know trustless as well you could um verify the signature yourself check the onchain uh the onchain signature ET ET and that's it so frames our HTML markup that describes an image and buttons there are HTTP requests back and forth to a web server and they're assigned data payload those are the three most important principles okay so some design principles for building good frames uh I think we've seen thousands of frames built over the past year and after seeing lots of experiments in the wild there are a few a few principles that i' encourage for building good frames uh the most important is to just keep them simple fast and focused the very best frames have a clear call to action and a linear workflow with only one or two steps so if you're trying to build like a complex multi-step app that has a lot of branching and error handling and callbacks a frame might not be the best way to build your app uh they're really good for you know simple call to action linear workflows without too much wrenching uh I like to think of a frame kind of as a Game Boy right it's this very simple constrained user interface you have a couple buttons um and you want to fit like yeah you want to fit sort of a simple uh fun fast experience into a very limited UI uh or even better think of like the Wii U if you remember this uh think of it as the little gamepad screen that was built into the Wii U basically there's a whole game your application that's going on outside your frame but your frame is a way that you can highlight a specific action in context in the feed and encourage somebody to take an action in context now uh you can definitely build your app frame first if you want and you know frames are permissionless Open Standards so you can do whatever you want with them but I think it's almost always best to to keep them simple here are a couple examples I grabbed that I think are are good frames uh this one is from hypers sub which is subscription service and what I really like about this one is that it has a very clear CTA just as a single button and it has really good default settings so you can see well yeah you can see by default it will subscribe you to a single a single month um so you can ask the user for kind of complex input um but by default it is doing something with with a good default uh so yeah this frame has a a really simple straightforward single-click workflow you send the transaction and it shows you the receipt right away that's it uh so I think this is this is a great way to you know bring a really simple call Action directly into the feed here's another one this one's from Zora uh I like this because it has one very clear in feed action mint and it includes a link out to the main app if you want to do more so you know don't think of the frame as your entire app kind of crammed into the social feed into this very constrained UI that we provide with frames think of how you can bring the most important actions from your app that exists outside of farcaster into the frame and kind of put those put those in front of people so Zora also really makes nice use of the image uh they're showing the number of mints and comments dynamically this can be kind of tricky to get right because of the way frames are cached uh but we will like respect cach headers and you can build Dynamic frames that kind of regularly update and show things like the number of people who have minted the number of people who have interacted um yeah I described this as kind of an advanced technique so uh you'll practice a bit with frames before you do this but it's a great technique um if you're careful about how to do it uh so Paradigm put together a great uh resource called the frame interface guidelines which has a bunch of principles for building good frames if you're interested in uh yeah interested in expanding on this I would encourage folks to go go check that out so there's a a figma guide and a bunch of guidelines here for how to think about building UI uh and how to think about building really good user interactions in frames okay a few common gas uh frames in general are really simple I think there are a few a few common difficulties and gas that we see with lots of people who buil them and the three big ones are performance large images and caching so first Up Performance frames need to respond in less than 5 seconds or they'll time out uh and especially if you're using like a serverless tool that might have a cold start this can be kind of difficult to sometimes to to fit your app within this timeout so ideally you should cache and index as much data as you can you should add loading frames like interstial States if necessary if you're loading a transaction and um uh waiting you know to load the hash or looking at the the status of a transaction on chain uh and yeah if you're using something like for sale a serverless deployment uh where you might have a cold start uh be careful to try to keep that warm and keep that as responsive as possible uh the second common gcha is large images so we do enforce a 10 megabyte limit on image size if you're not careful you can exceed that easily the other sort of more subtle but common Goa here is uh building very complex user interfaces using some of the main frame uh frame Frameworks so frog and Frames JS which are the two main frame libraries can have trouble rendering very complicated uh jsx that has a lot of components third Pretty common gcha is caching so your initial frame will always be cached by clients and that initial image will be cached according to whatever cach header you send down to the client so it's possible to build frames with Dynamic images but it can be tricky to get right fortunately there are good tools for testing this out so warcast provides a a frame validator tool that can show you your cach shutters we're going to look at the frames JS debugger as well when we build out this Frame shortly so those are good ways to kind of experiment with and and watch these gachas above all though with all three of these I think like just keep it simple um keep your images simple keep your applications simple try to think about like what is the the one action that you want to bring in the feed if you're building a frame okay so that's theory of frames uh we're going to try and build something here move over to doing some live coding uh frames are simple enough that you can use any web framework to build them if You' like but today we're going to use frames JS which is a library and tool for building frames in JavaScript and typescript that works on top of a bunch of different web Frameworks in this example we're going to use typescript nextjs and react today but uh it plugs into a bunch of a bunch of different Frameworks and so you can sort of use it with your your tools of choice uh we're also going to use a few ecosystem tools so we'll use VM to read and interact with a smart contract we're going to use Nar which is a forecaster API service to enhance our app with uh foraster social data and we're going to use Ponder which is an indexing tool for ethereum contracts okay yeah and the goal today is to build a really simple game that interacts with the smart contract uh it's a capture the flag game called yoink here's what it looks like so in yink you can see who currently has the flag uh you can yink the flag from them and when you y it you will get a token in your wallet so it we'll track a number of Ys that have happened to build a leaderboard and then then we will enhance the context of the game with forecaster data uh all right hopefully this goes well I'm going to switch over to life coding from here um but if you want to follow along you can clone this repo from GitHub to get up and running and yeah let's give it maybe uh five minutes for folks to grab this repo and get set up if they want uh in the meantime maybe we can take questions for all right we'll give it like 30 more seconds I'm going to switch over uh here I'll put it back up for a sec yeah github.com horack yink Devcon I can maybe uh cast it out I'm farcaster too if you're following me let's do that for cool all right praying that the uh the network holds up here okay so yeah here's our yink repo this is our frames JS repo um this has been created with uh just like the frames JS starter kit uh you can we'll give a quick walk through the repo here okay so if you pulled it you'll want to just run yarn to install uh install dependencies and you can run yarn Dev to spin up the frames JS uh debug Earth and test server we'll look at this frames jsd buger in a sec but let's take a quick look at how this is all laid out first uh okay so if you've used next you'll see like this is the structure of a pretty typical next app we have stuff here in app which will Define routes within our application and we have some components a frames folder here which will create a slf frames route and then we have this Global stuff like our uh Global layout and our homepage uh We've basis on the frames JS starter kit which has this really really useful set of examples out of the box so so if you look in this folder here examples you'll see sort of worked examples for lots of interesting and and different things you might want to do with frames so here's like the most basic frame caching building composer actions Dynamic routes error handling uh so if you're poking around in this repo sort of as as we go this is a really good resource to go look at at how to do different different things with frames so basic structure of our app here we have uh the homepage and then nested inside this frames directory we'll have uh our actual frames code and we can go look at this home page over http cool so you can see here if we look in our page markup we're serving these uh these meta tags right that we looked at FC frame FC frame image open graph image and our frame buttons from this entry point of of our app unfortunately frames JS takes care of like you know injecting this into our our homepage and everything for us we can just work on uh on building the frames using the tools that it's uh tools that was provided here in this frames directory okay so let's look at yink from the top and then we'll kind of roll back and build it uh build it out step by step uh here in this frames. TS file we're kind of defining the configuration for our uh our frames application so a base path which is like where we're going to mount the frames we can Define sort of all the configuration for the app here uh go check out the frames JS docs for all all the details on how this works we can def find things like middle Wares so if we wanted this to be compatible with other frame ecosystems you know like lens or x& MTP we could add middle Wares here that uh that extend it to be uh compatible with other ecosystems and then here's our entry point frame route so frames route. TSS uh and you can see we're kind of mirroring that structure that we looked at in the uh in the frame metatags we can define an image and some buttons uh and the cool thing about Fram JS is that we can Define this image dynamically using jsx so if you're familiar with writing react you can build up a dynamic image here just by using jsx components uh we can also use Tailwind Styles in here so you can see we have like Flex Flex column font buold text adxl all of these Tailwind uh identifiers you can use these to uh to style your frames as you're developing them so here's our simple entry point image uh it says yink click to yink the flag we have a button uh and this button points to another frame it's pointing to this path at SL start so you can see we're going to build out a few different uh components here a few different routes within the frames you can think of sort of each of these subd directories uh as a separate frame so here's the start frame when you click this button it's going to post to the start frame and we're going to want to define a a route Handler to handle that here's this Frame Okay so let's just step through this in the frames debugger so when you run yarn Dev uh this will spin up this local frames JS debugger uh which you can use to browse and uh and view your frame uh this provides a bunch of you know really useful information about your frame you can see some Diagnostics around the tags you can browse your console uh you can see the metatags and then you can sort of Step through your frame step by step here so we'll click Start okay network connection is working it's going to show us who currently has the flag we'll do a transaction here I've yed the flag I can click an external link here to go view that transaction on Bas scan and then we've got a simple leaderboard here that shows uh who has yanked the flag their addresses and and how many times okay so that's the idea let's uh let's go through and build this up step by step okay so we're back to the frames JS starter here we have kind of a simple demo app where we can increment and decrement a counter let's start by just building like the start page for our frame so we'll come in here to our entry point route let's just Define some simple text in here yoink we'll remove this text input remove these buttons and for now I'll just put a simple button here that um thank you you yep okay so this just a simple button that points to back to the initial frame so to start this is not going to do anything cool okay so there's our image yoink click to yank the flag we have a button we can click to start this is just like posting back to our same initial frame so it's not yet doing anything so if we wanted to we could access the Contex text from this request so that information that's in that signed frame message in this context object so we could show for example which button was pressed or the ID of the user who pressed it so we'll just put those here in this initial frame cool so you can see right there's no value here in this initial request because that's just the the G request that loads the initial frame once I press the button it re receives that signed payload including information about who's interacting with it uh and we can embed that information into the frame so you could build an entire app with like a single frame route if you want you know doing your switching and branching within a single route just like posting back to uh to one route if you want I think there are a couple examples like the simple examples in in frames JS do this but if you're building an app with like you know more than one workflow for me at least it makes sense to kind of um separate these out into individual routes for for every single frame so we'll kind of Define one API route or one frame API route for each frame uh so in this case let's create a start route and we're going to when we push this button we will send the request to the start frame all right so we'll create a directory in here with a route. TSX I'm just going to copy paste our our start frame and let's just change the text on this Frame ah okay we need to update this one to point to this new route cool let's remove this kind text Data cool so we've got our initial frame right our entry point uh we're posting and sort of you can think of it as returning a new frame or kind of redirecting to to the next frame that's going to handle the next step in the workflow uh so with yink it would be really cool to use like a dynamic image that shows the number of yinks on the first uh the first image and shows a bunch of contextual information that's kind of difficult to do in our demo and difficult to do with caching so we're going to adopt this pattern where there's always a start button we're going to load some data dynamically into that that second step and uh um and display it in that second step so if you're building frames and want to avoid some of these issues with caching it's not a bad idea to sort of always start with this start step this initial interaction and you can start loading dynamically data from there uh it's a lot easier to avoid issues that you might bump into with caching so we'll follow that approach here uh okay so in the second frame ideally we'd like to uh show some onchain State about the game uh right we're going to want to show the current user who has the flag like the number of Ys that have happened in the game and to do that we're going to need to read some of that onchain state from the contract we can do a super quick tour of the yink contract this is not a solidity uh Workshop but we can take a quick look at it so here's how the game of yink Works uh it is a ERC 1155 token with some special logic in here for managing the game uh and we're going to transfer some different tokens to people when different actions happen in the game so we're tracking the total number of yinks in the game the time it was last y Y at the uh current record for most yinks the address of the top Yer and the address of the person who last yank the flag everyone has a score stored in this mapping and then here are the rules of yink so you can't yink the flag from yourself if you already have it we also will enforce a cool down where you can only yank the flag once every 10 minutes when you y the flag we will transfer you this special flag token also the first time you participate we will mint you a score token this will like show your score in your wallet and then if you happen to be the top Yer at any given time we'll send you this trophy token so it we'll do some calculation on chain to calculate how long you've held the token or how long you've held on the the flag uh we'll build a leaderboard right so track how long you've held it how many times you've yanked it who is the current top yanker and how many times the flag has been yed uh we have some you know helper functions in here for generating onchain svgs so these tokens have a nice little onchain image okay we have a lot of helper code for generating the uh the unchain spgs uh and then the flag and trophy are special tokens so they're uh soulbound they're non-transferable right so if you you've been issued these tokens we're going to revert if you try to transfer them to somebody else so only the game can transfer these tokens you'll get the flag sent to you basically by the the game contract when you yink it okay so that's the game of yink uh this contract is deployed on chain on base okay we'll give up on that but yeah it's played on on chain on base and we can you know you could interact on ether scan right you could go to Bas scan uh and call the yink function to to play the game okay so let's set up to actually read some data from this contract in our frame and to do this we'll use VM I'm going to add some helpers in here no here we are we're back all right let's no okay so we'll grab the contract ABI let's add it here and let's get the contract address all right and in order to interact with it using VM we're going to create a public client here connect it to base and we'll use the HTTP transport by default okay so yeah let's start by showing how many times the flag has been yed we'll just create a function here get y count and we'll read our contract and we'll call this function I think it's total yoinks I need to crib for my nuts here hold on function name all right cool so that should be what we need to go read data from the contract on chain let's go back to our frame Handler here and before we render the image right we can call that function to read some some data okay so that's going to return total yinks as a big in we'll want to convert that let's do that in the function oh yeah we need to wait it and return it God love like cting so we'll just convert it to number there and return it all right let's put it all together cool ugly but there we go flag has been yanked seven times so we're reading that state out of uh out of the onchain contract so next we'd like to show Who currently is holding the flag we can add a a similar function here got to go look at what this is okay this is the last y by address so this will show us who is currently holding on to it and we can just return this directly because it's going to return an address yeah cool cool okay so we're showing the address of the user who is currently yanked the flag and the number of times it's been yed so yeah our UI kind of ends here right we're not doing anything after this point um let's do two things let's add a back button so you can go back to the initial state cool so now we can kind of go back and forth between the launch frame and this data frame this start frame that's pretty boring though uh what we actually want to do is be able to trigger a transaction here right to yink the flag so so far we've been using post actions right um sort of the standard standard action is just a post now we're going to use a new type of action which is a transaction action so change this here to TX and post actions are very simple it's just a request response transaction actions are a little bit more complicated because they do two things they need to load your transaction data they forward that to the user wallet uh then they get back a transaction hash and then they push that back to your frame so there's sort of more of a of a back and forth there two steps in a transaction so we actually need two um two routes when we build a transaction one that Returns the transaction call data and one that kind of handles the next step in the framework flow so the target of this transaction action is going to return the call data and then the post URL is going to be the uh the action that handles the the response uh let's call this receipt all right so two new routes let's go create those we'll just put a simple placeholder in here for the receipt okay and then this TX data Handler is going to look a little bit different because it's returning Json about an encoded transaction and in fact I'm going to crib from the examples here to look up how to do this so there's a good one in here transactions you can see it has a similar structure TX data so this particular example is reading from the forecaster storage registry it's doing some encoding of the transaction and construction of the transaction we'll just crib from that so our y contract is very simple though we're just making one uh one simple call to a function that has no arguments so we can avoid doing some of this uh set up okay and here's the basic structure of a a transaction route Handler so you're going to return Json that looks pretty much like an ethereum RPC request uh includes the chain ID the method so you can do signatures through frames as well this is going to be just a transaction but you could do a eth type signature V4 and then parameters that are I think pretty much identical to the uh the Json RPC call okay so in our case we're going to use the yink [Music] ABI so yeah we'll just pull in these constants that we defined in there oh got export it we're going to call that contract address let's skip data for now uh and no value with this transaction so we're just going to need to construct the encoded call data to call the contract e e all right cool so we can just use this VM helper in code function data we can pass it the ABI of our contract the function name that we want to encode uh and get back the the encoded call data to call a particular function on that contract oh okay and we need to change the change ID to base 8453 okay so that's our transaction Handler uh our receipt Handler is empty right now but I think this will just work as it is let's give it a try Famous Last Words reorder these buttons cool so yeah you can see the little lightning bolt here indicates that this is a a transaction button and hopefully if we're configured right we can click this and something will happen sick there we go so yeah this is prompting me in my connected wallet uh you can connect up here in the frame JS debugger connect up to uh to your own wallet here and Trigger transactions and yeah you can see um it simulated the transaction we're transferring those tokens when I interact with it let's sign it cool okay and then we've hit that uh that second route right that we defined you can see we see the transaction receipt Handler route so that's returning the the receipt Handler frame so we're not doing anything here yet but this is received basically the uh the transaction hash of that transaction and we can we can use it to either watch the transaction and show like a loading state or show the user some feedback on what has happened so let's build that out so inside our context uh when we're handling a transaction call back we can access the transaction ID uh which is just a generic name for like the transaction hash we sort of designed this because we may do Salon transactions or other types of transactions in the future so this is just in the evm context this is just the transaction hash of the the transaction that was triggered and while we're at it why don't we add like a base scan Link in here as well so we'll Define Explorer URL so this time we'll use a new action a link this is just a static uh static link out to any URL and we'll put that Explorer you all in here okay ugly but there it is the transaction hash and we can click out here and view the transaction on Bas scan great cool so somebody's already playing yink on chain that's great uh I've yed it from someone else so that's very useful because we have some uh we have some roles in the game right that you can't yink from yourself and you are you have a timeout right so um that's good we haven't implemented handling those yet so it might have reverted otherwise cool uh okay yeah so at this point we kind of have a fully functional yink game you can uh see who's currently holding the flag you can yank it you can trigger the transaction um it's a little bit ugly in that we are only showing uh ethereum addresses right in our frames you know transaction hash ethereum address uh rather than uh enhancing this with the data we can get from forecaster right so we have this long ugly ethereum address has the flag we'd like that to be uh if possible Right a forecaster username or some sort of more meaningful notion of of user identity uh so we can do let's do that yeah we'll add some enhancements here to show the user's identity so to do this I'm going to use Nar which is an API for accessing forecaster data uh our example here like is sort of focused on building directly interacting on chains we haven't like made great use necessarily of forecaster social contexts right like we're not really reading the users forecaster ID uh in any of these frames here we're sort of working in the other direction right we're going to go look because this game is on chain and figure out uh what working back from their ethereum identity to what their forecaster identity is so since we're running a little short on time I'm going to grab these from the example repo okay so we built out a few functions here let's just copy paste this all right we're pulling in the Nar API client this is going to give us uh access to this this SDK that can give us information about forecaster identity and sort of interactions with a bunch of different forast related apis we'll set up a client and have built out some utility functions here right so one of these lets us fetch uh forecaster users by their Associated ethereum address so we can use that basically to say when we have an address let's convert it to a user let's not worry about this one for now uh and then just a helper in here for truncating addresses which are a little bit uh a little bit ugly okay I think we have a special API key if anyone else is building here too you can use Nar Devcon 2024 okay and yeah going back to our start route here let's enhance this with the user's actual identity rather than their uh their blockchain address for for for cool okay so yeah we grabbed that ethereum address we used the NR API to look up uh batch lookup users who are associated with that address and their forecaster identity and got back a username here rather than showing uh showing their onchain address uh you can see that was pretty slow right I think it's not just the network here right we're making like multiple uh multiple async requests here to go make an RPC call to read onchain data and to go out to the the Nar API and um make an API call there so we're probably like kind of at the limit of what this Frame can handle in terms of the the timeout um if we want to keep it it responsive uh one thing we can do is um at the very least is do do that action concurrently right so we can use promis all or something to uh to make that a little bit more performant okay so yeah final thing I think we may want to do in here is handle error cases from the contract uh which I think maybe What's Happening Here uh I've been timed out right so I recently uh called called yink with this address uh but right now I've been rate limited right uh I can't yink for another 10 minutes so we're not handling that well right now right this is just crashing so let's catch that custom error from the contract and display a nice message back to the user okay so to do this we're going to simulate the transaction first we're going to see if it reverts and if we catch an error from that revert we're going to display it back to the user all right so we can use this helpful simulate contract function from VM to to uh simulate the contract call we'll just create a helper here import address all right and then here in our uh transaction call data generation Handler we will simulate the call uh if we catch any errors from this this is like pretty gnarly VM code for for catching a uh custom error um um but yeah basically we walk these errors anything that comes back um we'll catch the errors from convert them from their onchain representation right we have unauthorized which is the error you'll get back if you already have the flag and slow down which is the uh custom error that you'll get if you're uh rate limited and just convert these to uh nicer more human readable errors okay let's grabb our functions here for cool so yeah within a frame context you have the ability to return an error to the user um which will sort of show up in a toast in most clients um so this is sort of useful for simple error handling cases you can do this from transaction frames uh you can do it from other types of frames as well which will just show a quick human readable error uh rather than returning a whole frame for an error all right let's give this a try cool all right I was able to call it that time I think I uh my timeout has passed let's try it again cool there it is so yeah you can see it's a little difficult to catch sometimes in the frames debugger but yeah here here we've converted that error right from the onchain sort of difficult to read custom error um concise custom error into something that a user can read you have the flag you can't yink from yourself and let's try out that rate limiting error as well so I'll change addresses let's change back cool and there's our second custom error you're yanking too fast try again in 520 seconds so we could convert that to you know a nice human readable uh date would be nice to do but yeah that's sort of the principle there we're converting those onchain uh difficult to read on chain errors into a nice human readable error message here okay final step in here um I'm not going to implement it since we're running out of time but let's just uh take a quick look at the code so the last thing in here is to build out a leaderboard and if you want to go yeah look at this separately the idea here is that uh it's very difficult to build a leader board uh in a performant way right we could load all the log data like Cal at how how many people have yed and kind of do all those calculations within the context of the route that's very difficult though right so uh it's a good example of where you should use an indexer or sort of caching to keep your frames performance so there is an example in here of a really simple Ponder indexer which I built so Ponder is a great uh open source tool for building indexers for ethereum applications you can sort of spin it up point it at your contracts and you get a really nice uh simple syntax for writing indexers so I've set this up um as sort of a separate API service here that we can use to read the leaderboard uh and read recent activity and so if you're doing anything that kind of needs uh real- time data right or performant data it's a good idea to use uh use something like an indexer to load that so go check that out in the repo you can sort of see how to interact with that API load the data from that API and build out a leaderboard route okay last step here let's uh let's look at the actual Live app so if you go to the repo and look at the code this is the one that's deployed and we'll put it all together and post this game cool so this is the warcast B this is kind of the final uh yep all right here we go new y just dropped cool and there's the final game so go find that on webcast uh check it out uh yeah happy Ying everyone thank you [Applause] thank you so much uh Horsea for the wonderful session on farcaster frames so we have a few questions here uh so can I integrate frames to my existing site as a component or is it uh or it must be inside farcaster yeah so I would look within frames JS uh is a good example of this there are a couple tools for like embedding frames on the web in fact frame JS you have a renderer right David yeah so frame JS has a renderer tool like a library that you can use to render frames outside of forecaster context in like a general web context or other context so the answer is probably yes you can embed them in other applications thank you thank you yep so uh let's thank the speaker
Automatic transcript — names and jargon may be misspelled.