ERC-4337 Account Abstraction is an Ethereum standard that enables gasless transactions by using onchain wallets (smart contracts) instead of externally owned accounts. In this system, users sign 'user operations' (structured data containing sender, init code, and call data) which are bundled by services like StackUp, Candide, or Alchemy Account Kit, and executed through an entry point smart contract. The entry point validates the operation, executes the call data on the onchain wallet, and handles reimbursement to bundlers and paymasters. This architecture allows users to interact with dApps without holding gas tokens in their accounts, as paymasters can cover transaction costs.
ERC-4337 Account Abstraction: Foundry, Next.js, Wagmi, and Account Kit Tutorial
Added:what you see here on the left is a chat application that uses account abstraction and on the right you see a transaction against the entry point smart contract that is debugged fruit tenderly now in this video I want to build this application from scratch using first Foundry for the smart contract development and then build a next CH application using wagi VM and rainbow kit just a normal application that uses a normal external signer and then I want to transform this into an application that uses account abstraction to pay for the transaction cost when I first started with account abstraction I was completely overwhelmed with the amount of onchain wallets different libraries different providers for bundlers and pay masters and so on and so forth and I didn't find a lot of helpful information so in this video I want to use first stackup then I want to use cite and then I want to use Alchemist account abstraction or account kit by the end of this video I hope you have a really good understanding depending of how account abstraction Works how the onchain wallets work what kind of choices are out there and what you should really pay attention to now this video works a little bit different than my other educational videos I have recorded my screen for a lot of hours of pure development and I tried to cut it down to around one and a half or two hours um without sacrificing anything and quality or content but I didn't comment while I was recording so I'm going to comment now after recording and I'm going to pause the video every now and then and just make additional comments where I found out after I did the programming that something is important uh for me it was a huge learning experience and for you I hope you get the learning experience that I had in the past two months now in the next one and a half hours and if you like it well like And subscribe uh or let me know in the comments if I made any mistakes somewhere or you found something better well let's get started if you're watching these videos you're probably wondering how you can get access to the code and there is actually a couple of different places where I have the code for you in a nice way in an interactive way to follow along the first one is an ethereum blockchain DD developer uh if you go to the mini courses and then you go to ERC 437 account abstraction and to end development there is um not only the whole tutorial but there is also an embedded code sand boox death box now what's an a code sand box death box that is a virtual machine that runs on code sand boxes servers and has already the repository the esc4 337 Chet application repository with the nextjs app and the contracts checked out and is running nextjs as a def environment and gives you access to the preview of nextjs so if you open that up you already have a fully featured uh Dev environment that is running remotely you don't need to set up anything you can also Fork this and and run it on your own code sandbox and change the code if you want to now I also deployed the nextjs app to versal on ESC 437- ch- nextjs d.v. apppp link obviously somewhere uh in the description or in the tutorials um there you have the the main branch of the Chatter application built out as an actual app and obviously you get access to the source code in my GitHub if you go to ESC 4337 ch- application repository you can clone that with that command over here and follow along in your own machine if you want to now back to the video the first thing that I'm doing here is setting up a new Foundry project I'm doing a forge in it and then just giving it a name and then it will create a scaffolding project and the scaffolding project comes with a counter example there is a script there is something in the source folder and something in the test folder and I'm basically just removing it to start with a completely empty project now I'm just going to delete that and I personally think Foundry is still at the moment the goto my goto toolkit for St development I like it much better than hardhead personally it's just my personal opinion if you have a different opinion let me know in the comments and the next thing is I'm just creating a little chatter contract so if you think about a chat you really don't need to store anything on chain all I'm doing here is emitting an event called message and this event has uh two different properties that it's going to emit that is the address that sent the message and the message itself and then my idea in the chat application is just to listen for these events and then show them on the front end maybe give it you know little bit of a graphical nice UI so instead of the address give it a like the icon or or something like that but we will see that later so the next thing what I think is really important is a test so I like to unit test everything that I'm doing and Foundry makes it very easy um I put the test in the test folder I name the test file the same as the actual contract file just with a t in between and then you write the test uh you set it up and then you have these little test functions which are Auto uh executed automatically and there I'm right now just sending a message but that's not all uh in The Next Step I'm going to actually listen for that event so I have to copy over the event unfortunately I didn't find the better way and then I am telling the VM that is running the test that it's expecting an event and it is not only expecting an event it's expecting this particular event with this particular payload so I'm saying expect imit then the event and then the payload and now just making the counter example see if it actually works and if I if it doesn't work then I can drill into that with- vvv for more verbos um error messages okay now the next step is to write a script to actually deploy the smart contract now I'm doing that I could do that directly from the command line but I like to do it in a script and I'm using a script in the script folder same with a test same name as the actual contract just with an s in between so chat. s.
Sol and then I am extending uh my contract here from script which is uh a contract from the standard library from Foundry and I'm broadcasting a new chatter smart contract and you will see in a second how that works I'm using Anvil here you could also use ganach or any other blockchain just for testing and I'm running the script with Forge script and then the script name and then I'm giving it an RPC URL in this case it's anvil on the left I say it should broadcast and the sender is the account that I have in enil it gives me 10 accounts with a thousand or 10,000 eth each and I'm telling you it's unlocked the account so doesn't need to ask for any passwords or anything and I give it a chain ID so so now we have sent the transaction and the last thing that I want to do is because I'm working with metamask in my uh Chrome I want to fund it with some eth and I'm doing this with cast that's another one of the tools from the uh Foundry toolkit and what you see here now I did Run cast but I had envil started before I run this uh recording so I had still a number in my metamask account which is really bad because metamask is cashing quite a lot so if you have this issues you just need to wait a little bit it took maybe like 5 minutes which you don't see in this video uh and it updated automatically I also think sometimes it helps if you just restart Chrome well the next thing here is obviously creating the next application NP npx create next app and I'm using 14.04 here standard parameters us using tnd and uh the new app router and all that stuff obviously typescript and now it's installing the dependencies and as soon as that's done we are ready to run our scaffolded or our standard next CHS application and you should get this one over here now it's time to add rainbow kit vagi and weim which we are doing not with the with this preconfigured rainbow kit repository we are doing it with npm install at rainbow kit and vagmi and beam and then we have to add these kind of extra um configurations into our uh own project so instead of just um going by the by the docs I basically cheat a little bit and I copy the stuff from their standard project into my own project so I have the provider uh which I which is necessary to have the context and um the configs because there are a couple of components that with the serverside rendering from nextjs that won't work now we have uh a number of providers we have a number of wallets preconfigured a number of chains that you can select and we don't need all of that because we actually want to have an envil chain which we are over here on the on the bottom left side of the window which is still running and later on we want to connect to girly um and that's it I'm I'm not expecting this chat app to run on polygon or on Main net uh you don't want to pay $30 per chat message so let's keep it simple let's keep it on the goly network but if you want to Fork it and you want to put it onto the main net be my guest just do it so I'm defining here a new chain called envil just giving you the name and I will take all of the parameters in order to connect to my Loc called envil chain so that is the uh network ID give it a name uh call it the network give it a currency which is really just uh anything for the Gest token you can call it anything you want I call it te e for test e uh give it the RPC orals which is Local Host um 8545 uh so first of all the public one and then it also needs a default one so otherwise it would complain and then also give it a test net parameter and set this to true so now we have these two networks Anvil and girly and let's save it and the last part is I just don't need anything of this layout over here delete everything and just put in the connect button from rainbow kit this component so if I reload this well give it a moment it's compiling and then you have the connect button and you can connect with your metamask to your local annual node so that is working and now we need to somehow import our chat application so for this we need a couple of things um we need the AI and we need the address of the application so in this case I am directly importing the Chason file from our Foundry project however that is not always a good idea because with um type inference from V you would actually get um it can actually infer the types of the events and the functions and the arguments and so on um which it cannot do if you just require or import from a Chason file so you would have to actually um import or export somewhere as const um that it works with typescript I'm not doing this here I just want to highlight it um it's maybe not the recommended way to do it the way I it here it's just very convenient and much faster um I don't want to set up any any kind of exporters or converters or anything so the next thing is um we need to write a message and we need to have a button to send the message to the blockchain which we're doing now so I have one input field I have uh State variable message and the function set message which is going to set the message uh on chain on change and then we have uh a button that well does nothing at the moment because we need a function to send the message and for this I want to use vagy and I'm using the use prepare contract right hook which is uh just preparing a contract right um so it's waiting for any changes in the uh arguments and in this case I'm giving it the chat contract address the ABI the function name send message and the argument message and then I'm using the use contract write hook which gives me back a function called right and if the message is you know if the user wrote the message then and click the send button then I'm going to hit the right function and this is going to send the message message now you see that here um it did send the the message off but there is nothing to display the messages yet so what we're doing now is first getting the events and then uh listening to ongoing events from the blockchain in this case our envil note but later girly or wherever you want to it doesn't really matter so the first part is to get the messages when the page loads the first time and we're doing this with the use effect hook uh with an empty array at the end so it only runs uh initially and there we use and there we're doing uh two things first of all we are clearing everything that is in set messages which is not really necessary at the moment um the first of all we are clearing everything and then we are going to go going to get Contract events and over here we are getting all the events from the contract for a specific parameter that is from block and two block so front Block in this case I'm going to set it to zero which only works with Anil um it won't work with the public blockchain as you can see later and you have to set it to a big in zero and then we are going to just simp set the messages everything that comes back there um it's it's a lock array already and then we can just output the logs over here um map the messages onto jsx um items so let's do that really quickly just output the sender address and then the message and you will see that works just fine of course it doesn't look really appealing yet but that is not just to make it work it's it's more than enough so let's save this and you can see here the arguments are underlined because it cannot interfere that the types but you see it's working so let's run another transaction over here yeah if I send another transaction it won't do anything thing I would have to reload the page every time so I want to use another hook called use contract events use contract event not events and there I just give it the same address API the event number want to listen to and then I give it a function called listener and that gets logs and over here I just append the log that I got to the old logs that I already have in my messages so I set messages um gets the old messages and if they are set then it just um spreads the old messages array into a new one and also the locks because this is giving us a locks array or it just sets the locks so every time I send the message now it just pens it to the end fine uh what you cannot see in the video is I always get a popup from metamask it's is on the other screen that you cannot see on this video here but every time I click the button there's a popup well the last thing as I said it doesn't look very appealing um it's like this is a sender and the and and the message so I want to use the chz icon um and you I give you a link in the description below for the library that I used um it just looks nicer as you will see in a second and I think those little tweaks to the UI make or break a make it appealing to use the app uh one way or another so what I'm doing here is I create an extra component called chz icon image um I give it I have it has two parameters uh two properties props um one called address and the other one called class name and then I will just uh add the Jazz icon image component and give it the address of the sender and if I want to some class names um then it just looks like let's hope it's loading like this and obviously it doesn't look good so we have to add a couple of class names for example make it round and make it small and then also make sure that everything is on the same same line so we might want to put everything its own component so we create a new new component called chat message which receives the address and the message which is both the string and then it just uh returns a line of chat messages which in this case is then the the Jazz image in a second and the message all right just a little bit more tidy it looks the same as before no difference and now we need to make that somehow a flex box Flex flex line Flex Flex row sorry Flex column no flex row and give it some Gap in between so that's all Tailwind I just like to play around with this and if you don't don't like to watch me doing that um don't worry everything is time stamped for your convenience you can just skip over to the next chapter and make sure that I have the chapters properly time stamped on the bottom of the video If You hover the the time scale all right now the next thing that I want to do is um if you sent the message it should be right aligned and if somebody else sent a message it should be left aligned and also if you sent a message it has a blue bubble and if somebody else sent a message it has a gray bubble basically like I don't know WhatsApp or iMessage so what do you what you used to from a normal chat application you send a message everything is right and somebody else sent a message everything's on the left and it is a different color it's not not a copy of of any any other jet application it's just the same UI style okay I mean looks already little bit like a Chet application that's too big you have to containerize that put it into a container and make it centered even better all right now we need to add a couple more messages just to make sure that we are not always sending it ourselves so I'm creating a new script and in this case I am not creating a new chat applic ation I'm connecting to the one chat smart contract that we have and I just send a couple of messages over there so I'm using the same Forge script and know wrong directory in Sol you don't need to put the address into quotes and you can see here our messages that we sent from the chat application are right aligned and the ones from somebody else left aligned so from the point of view of the chat application we are connected with a specific account and that account is Right aligned that's what I mean now we need to make a little bit more of a background color and make it make it nicer and more pading put the icons in the center make a like the right bubble make the the border on the top right top left and bottom left and all the left messages make them gray and put the border the Border radius only top left top right and bottom right and leave the bottom left out so it looks like there's a bubble popping up from the bottom left for the left messages and a bubble popping up from the bottom right for the the right messages and I'm doing this with a conditional here so if the address is the connected address then um yeah it will do it like like that and then the last thing is I mean obviously everything is kind of centered right now in the in the center you see here it's it's very Snappy um it immediately reacts well react reacts what a surprise and um everything is kind of centered and for a CH application what you used to is that you start from the bottom and you stay on the bottom for new messages and it will like when you scroll up you will stay stay where you scrolled to but um for when when you are at the bottom and new messages arrive the new message will like it will scroll down if you if you kind of know what I mean you will see this in a second so it it behaves like a normal chat application and that's actually a little bit tricky to do um there's a a couple of tricky elements to that um the one is obviously you need to scroll down when you are like when the when the position of the scroll bar is in the bottom before the message arrived then you add the message to this element and then you scroll back back down to the bottom but if you're not on the bottom then you kind of stay where you are and there is a couple of people already solved that and I'm going to add this um over here as well I'm just going to separate all the different components into like all the different items that we have on the page into different components as it should be so I'm just um making another send message component here and in a second I will show you how the how to do this with the scroll scrollable area so it's it stays on the on the bottom yeah so far so good everything is kind of working we can clear up this part and have a send message thing here and let's just see if that is working yeah looks good great great let's uh format this a little bit differently so it it looks better um the sent message on the bottom it's kind of like a little input field and the and the button next to it but we can do much better so we can make this a flex the surrounding element of flex with the full width and a little bit of a petting maybe we can add a littleit border on the top so it doesn't look like it's just hanging in there it's like a different area of the page that just sticks there and then make this gray make the give the padding for the input field and then make the placeholder uh slightly differently I'm not sure if I'm reallyy happy with this it's just coloring I just let the video run for a moment it's absolutely insane how much how much time goes into such a small little application to make it look like a little bit better than an MVP but it's nothing polished yet it's not something that I would where would say wow this is really polished where a designer was sitting down and and polishing it it's just just to get a a what you would be used to for a decent UI and I have to say that wagi and weam um with the hooks and everything that takes off a lot of work um which I had to do previously manually with um we free JS or even ether JS I mean I never bought into the whole ether CH I kind of got always confused with all the different versions of ether CH so I I kind of was sticking with web free CHS right until version 4.0 which I'm I'm not so fond of no no I was just running into a couple of bugs and then I couldn't find anything in the doc so maybe it's just me uh but wag me and we I kind of like I I tried it and it just worked out of the box and that experience for a developer is is absolutely incredible so what I'm doing here now is I'm going to add uh that when you click control enter or command enter when you type that it sends the message as well so it's not just you don't have to put your mouse onto that little button you can just like write the message and then hit command enter and the message is sent all right then obviously we don't want to have people write messages while the UI is loading so we adding like a weight use weight for a transaction Hook from wag me so it is actually waiting for a transaction to be mined or at least that was my plan um but that's a little bit tricky to do anyway as soon as the message is sent uh it will delete hopefully the message but it doesn't do it because I forgot the value field here so let's try this again yeah but it the problem here is uh unsettled is actually called before it actually settles I don't know I haven't figured out yet exactly when the the transaction is settled so um I was talking before about this uh scroll bar um and there's this component that I I link in the description below as well uh obviously I call it scrollable box and I'm creating this component uh but a little variant from it because I want to not give it the messages itself I actually want to just give it children like message children which are react nodes so I'm adding uh as properties as props children and class name and then we can just add this uh message children or message components um into a scrollable box surrounding those messages yeah and then we are going to make this whole thing scrollable and it's a little bit tricky I was playing around quite a bit and I think I'm just going to speed up the video here and I will let you see the results in the code that is that is anyway um posted on my website ethereum blockchain DD developer.com or I'm going to add um code sandbox and the GitHub repository on the bottom into the description of the video okay now this is finished um it took so long because I had a container in the container and uh the children were WR anyway so what I'm going to do next is actually deploy the smart contracts onto girly and what I'm doing here is I'm using the frame wallet to deploy using my signer and the frame wallet actually Expos an RPC endpoint on 1248 loc close 1248 uh so you can deploy that using the frame wallet which I I previously used the Truffle dashboard but since truffle isn't here anymore and I don't want to export any private keys or any seat phrases I just want to have them in a wallet I can do that with frame wallet now and the problem that I have here is uh it's trying to deploy the smart contract onto the main night I don't want to do that I am going into the menu of the frame wallet and switching it over to gly canceling that and just rest starting the deployment process now you see here it's a gly transaction and I am approving it and I had the verify function in uh as a parameter inside the command line which would verify the smart contract automatically in ether scan but it didn't do it because I did not have the API key of ether Canan exported on my um CLI on my on my terminal so it didn't do this and the same thing is now the problem um it's pending in the queue and you can actually verify smart contracts like this um and now it's verified all right so I have a verified smart con you don't have to do this I I just think it's much easier to have a verified smart contract and now we are going to take out envil completely I don't want to have envil anymore as a as a button inside my wallet connector and normally I would add all these addresses and all these things to environment variables but I'm a little bit lazy here admittedly a little bit too lazy so I just hard code the addresses and everything and you see here that when I'm trying to listen to the event and I'm going from block zero uh it won't work because it's just uh too many blocks and it would need an archive node and it didn't allow me to do that so I'm going to change the from block to the block where the smart contract is actually deployed um which is more than enough but even then later on it won't work so I'm later on just going 500 blocks back and that works so now you see here um well it it works you can just uh interact with that smart contract with your external signer um I'm going to do that here directly via uh ether scan with a different account I believe or it's the same it's the same account uh just sending a transaction to girly um seeing if if that works if that event is uh caught by the by the app and it is so I'm I'm sending it by EA scan and I'm catching it inside my application here all right now we going to transform this with stackup into an account abstraction um enabled chat application where you don't need to have any guess tokens inside your um externally owned account now the problem that I have is account abstraction is a rather complicated topic and every time I was looking into it I found that the official docs are either too complex or incomplete for me so I want to give you a little intro into account abstraction before we getting started okay now before we are getting started with an actual implementation let's just recap how ERC 4337 account extraction actually works if you have a normal transaction like the one we did right now with our chat application you're going to have a signer and that signs a transaction and sends a transaction to the network pays for the gas fees and everything and then it interacts with a smart contract and the message sender of that inside that smart contract is the address of the signer now account abstraction the first step towards account abstraction or even to make something like account abstraction possible are onchain wallets now with onchain wallets you are not directly interacting with the contract that you want to interact with you're making a detour via uh wallet contract so in a wallet contract you're basically having an owner or somebody who is allowed to interact with that wallet contract and tell the wallet contract to do something in the name of the owner so in this case very simple example would be for example I have a wallet contract and that is on the address 0x 567 and and it has an owner 0x123 and that is the the signer over here and when we want to do an interaction with that wallet contract then we are not sending the transaction to the contract we are sending the transaction to the wallet contract that tells the wallet contract to interact with that contract and then we have a message sender inside that contract is the wallet contract not the owner itself and there's a number of wallet contracts out there one that I came across and I'm using very frequently is the safe wallet um previously called gnosis save and you can see here in the little screenshot you are using a safe wallet and that safe wallet is on a specific address and that's basically a a contract or it's a suite of contracts but it's basically a contract that you are controlling with an externally owned account with the signer in this case there's a metamask account attached to it and then you are just telling that's smart contract to do something in your name and when you own any tokens any nfds any kind of um ether then they are attached to the smart contract on this address and you just telling that address to do something now the problem is you still need gas in your externally owned account in order to send the transaction to your onchain wallet to tell it to do something and this is where account exraction comes in now to summarize that I mean an onchain wallet it holds the tokens and it gets the trans instruction from the owner it can do stuff like multi signature or this uh social recovery or any kind of recovery where you have M of end trusted signatures to recover your account and to set the owner to somebody else now let's talk about the actual account abstraction because those are the things that are necessary in order to make account exraction even possible now with account abstraction you are not signing a transaction you are signing a user operation and that is a struct that has a number of fields and when you sign those you you basically just attach a signature from your private key uh to that user operation struct and then you're not sending it off to the blockchain but you hand it over to some other service to package it into an actual transaction and send it off and that is the bundler now let's say you have the address zx1 123 and the bundler has the address 0x ABC and you are interacting with the bundler not via the blockchain you're inter interacting with the bundler Via an RPC method they are just offering hdb RPC methods to send this user operation to the bundler and the bundler itself is going to package that into an actual trans transaction pays for the gas at the moment and sends it to an entry point smart contract now the entry point smart contract is always the same smart contract for all of the user operations because the entry point smart contract will unwrap this whole transaction will look into the user operation and there is a sender field and then it will take this sender field and it will send the call data inside that user operation to that sender field and if the sender is 0x 567 and it contains call data that calls a specific function on that wallet smart contract for example a function that lets the user interact with the other contract then it will unwrap that it will call that function and the wallet smart contract itself is the one who is verifying the signature of that user operation and making sure the owner sent this okay and I'm allowed to call this out contract now you see it is still a wallet contract but it is only one more step in between to sign a transaction which is not a real transaction it is more like a use operation it's more like a message to that wallet contract so that the wallet contract knows yeah I'm allowed to do that great of course then there is also the question how the bundler gets paid and so on which is not something that I want to answer right now but suffice to say the entry point smart contract isal calculating all the gas costs and is trying to refund the bundler for his Services over here and um it either comes out of the wallet contract that is going to pay the entry point which is going to pay the bundler or it comes out of a pay Master smart contract but that's way too much for right now all I'm want to do right now is I want to see how we can get this private key to sign a user operation which then gets send magically to the entry point uh which then unwraps this uh user operation and sends it to the wallet contract or creates the wallet contract if it's not there yet now let's do that with stack up at the beginning and then let's do it with cite and account kit later on okay now having the intro out of the way let's get started with stackup and what I want to do at the beginning is if you go through the docs you find the user opjs which is a JavaScript package which mean they claim it is usable with or without stackup and it's BAS Bally true but I want to show you why I'm actually not opting to use uh stackup it's a good start and it makes it incredibly easy to get started with um account abstraction in general because it has these Builders now if you drill into these Builders then you will see that there is an account Factory and that account Factory is creating an init code and this init code is there to create an onchain wallet in case there is no onchain wallet yet so it will call a function create account on a specific address which is the account Factory address and that account Factory address is a smart contract like any other smart contract and you can even look into that on ether scan so if I open on girly this account Factory I see it's a simple account Factory and it has a function create account and with that function it will either create a new account based on the on the address and the salt of the owner um which is a create to method to create the account or it will just return the simple account later on now internally it's a little bit more complicated because that factory is actually creating a proxy that then points to the implementation of the simple account but more than enough I mean if you interact with that address that is created by the create account function over here you will get a simple account onchain wallet which is simple you cannot do a lot with it you can use this onchain wallet to interact with other smart contracts but as far as I know it does not contain any other functionality like multi signature or any kind of uh things that the safe wallet contains or anything else that you want to add to it um it is as bare metal as it gets with an as a wallet functionality so this is why even though I want to get started with stackup uh later on I want to switch over to another library to actually support the uh safe wallet okay let's talk about the user operation and these free Fields because I think these free fields are the most important part which makes the whole account extraction work there's the other fields like um the gas amount and the gas price and so on that's there to reimburse the bundler or whoever sent the transaction to the blockchain and there's also the pay master and and so on we're talking about these later but those three Fields if you understood these three Fields then you basically understood how the whole EC 4337 works now there's the sender there's the init code and the call data at the beginning when you send your first user operation to the entry point then it somehow needs to deploy that onchain wallet and it's what it's doing is it's actually looking if under the sender address if there is already a code deployed and if there is no code deployed then it would run the init code all right and then later on it will run the call data onto that um sender address which probably is a smart contract hopefully and then it's trying to run that there okay let's talk about the init code the init code if you look inside the entry point smart contract it will call a function and an internal function at some point you can you can open it on ethos scan and you can look at um line 337 the entry point 06 by the way it's not 07 that's currently in the audit um but it will look very very similar so it will call this create sender if needed function with the init code over here and if the init code length is not zero then it will check if there is nothing deployed on the sender address on the on the sender address so if the code length is zero and if the code length is is zero then it will call sender Creator create sender and that one is dysfunction and it's basically just a call with the amount of gas that is available to the factory smart contract which is the first 20 uh bytes of the init code and then the call data it will just attach the call data to that call so it's basically a factory. call with the init call data and then it will try to um get the return data back all right that's that now if you look at that a little bit closer and we were talking about this um simple wallet Factory before then you see that one here is the address that one over here is the call data and that one over here is then calling the factory smart contract.
create account because the call data is AI encoded for a create account and it gets the arguments that we have for the owner that it initializes the wallet through the proxy smart contract this is how the wallet gets gets created all right now we have the wallet now there is a wallet running on the specific address which is the sender address then it the entry point is trying to run the call data now the call data is just it's using this EXA library but it's internally just doing a call on on the on the sender address and it's giving it the call data and it's giving it some guas limit and it's setting the value to zero so the entry point smart contract is not transferring any value to the wallet sender now if you remember if you look at the user opjs um function there to actually do something and execute the function it is actually setting the call data from the proxy of the of the simple wallet to the function execute inside this smart contract and it can uh have two value and data fields now the data field is then the AI encoded data field to send the message to our chatar smart contract and the two field is the address of our chatar smart contract so what it does internally is it will call our wallet it will execute the function execute and inside the execute function it does something else which is uh another call to our chatter smart contract and it's basically just a wrapped wrap in a wrap so that's that's what it is so internally uh what you're actually doing is uh it would just wrap this whole execution of an of a function call to calling a function in a smart contract wallet to calling a function inside the entry point smart contract now there's a lot of validation going on and so forth before that and after that and there is also the gas amount that is calculated and reimbursed but this one is the main part of account abstraction the validation is something I want to talk a little bit later about but right now I really want to focus on how to get this call data right um with the different libraries that we have uh at our disposal and we're going to start with stack up here all right first things first let's get started with a simple page in a new folder so I create a new folder called stackup and I create a new page inside their uh page TSX and I just output something and now I kind of need to bring over this uh account functionality from our normal uh externally owned account method to our stup example um the first thing that I want to do is I want to calculate my address for my onchain wallet based on the address that is connected that uh with my rainbow kit so if now I brought everything over and I want to give the user a choice so I want to put some sort of toggle or checkbox or something in there um to let the user toggle between using the externally owned account to directly interact with the blockchain or using a bundler and account abstraction with an onchain wallet to interact with the blockchain and the reason why I want to do this is I want to really highlight in this example the difference between the account that interacts with this chat application because if you using your externally owned account to interact with the chat application the message sender inside the chat application that will emit the message event will be the account that is connected to the rainbow kit to the connect button over here 0x 5A and so on but if you are using your onchain wallet to connect or send a transaction to the chat application it will be the onchain wallets address that is then used as a message sender so in order to highlight that I want to use this toggle button now if you're having some sort of application that you write yourself you need to consider that in the UI design um if you even want to give the user the option to use the external own account so for example the safe wallet will merely let you connect your externally own account to then interact with the safe wet but you can never I don't think there is any functionality in there to actually send uh transactions from your externally owned account um to the Target at contract that is then connected to the safe wallet anyway so to get started I'm copying over the presets from um the user op uh stackup page and one thing that is necessary there is to get ejs somehow working um with the whole thing um let me just copy copy over the rest of the stuff first and then you will see what I mean I mean it's it's it's it was already there so you need eths CHS and uh wagi actually has an eths CHS adapter to convert wagi to an eths JS instance and what I'm doing here now is I create a lip folder and inside the lip folder I create the eths jsts file and I basically just copy this stuff from you need the wallet client here I copy the stuff from the wallet client the whole thing into this file and then I'm using uh the export from that EAS TS file in the in my page TSX uh in order to get to the to the wallet client all right so now I'm using a couple of State variables um in order to set the connected address if the user has the toggle on it will be the address of the onchain wallet and if the user has to toggle off the connected address will be the address of the externally owned account all right so if the user has toggled if the user has checked that checkbox basically the toggle on then it will just set the state variable to true and if that state variable change then it will calculate either the onchain wallet address or it will use the externally own account address in the connected address State variable okay true false true false now gets gets the interesting part so if we have uh use Smart wallet then we need to calculate the onchain wallet address and if we don't have that toggled on then we just set the connected address to the address of the wallet that is conect connected to rainbow kit okay that one can be either a zerox string or undefined there's a typo over here okay now in our stackup example they actually have a copy more or less copy and pastable code for um getting the address that is connected to the there is the onchain wallet address and since use effect cannot do async functions I'm going to construct here um the promise with then so if the if I have Aigner from use ether signer from this hook that I created earlier that I basically just copied over from Magi um then I can here wait for the promise to resolve I get back a builder and that Builder is then there is a get Sender uh function on it and that get Sender function is trying to calculate the function of the onchain wallet and when we are going to set that to the connected address just have to get the types right here then we should actually be able to Output that connected address over here here okay there is one thing that is that is disturbing me here which is if I toggle it on I have to sign a message with my metamask and I don't think that is actually necessary for that to work because when you can uh calculate the address of a create 2 function without actually sending anything and I don't need to sign a message for that so I don't know exactly what is going on in the background there uh but definitely that is normally not necessary okay the next part uh is we want to send a message to our chat application and in order to do that we need to somehow fix the rest of the fields of our user operation and the rest of the fields here is actually just the call data because we know where this message will be sent to it will be sent to our onchain wallet if the onchain wallet doesn't exist yet it will be created by the entry point and if it exists then it will just be sent to that and then the onchain wallet will have a function that is called and that function will then interact with our chat application and you don't have to take care of anything here it will be the the user op um library that will will take care of um you just have to give it the function that you want to interact with the chat application and the user of smart contract will take care of interacting with your onchain wallet the right way now one thing that I haven't thought through at the beginning when I was writing this application is all of the components that I meticulously extracted before uh that's all useless because I cannot I me I kind of need to always give it a connected address address if I have an address that is connected with an onchain wallet and not my externally owned account in order to then make your messages the blue Bubbles and the other messages the the gray Bubbles and your messages on the right side and the other messages on the left side and so on uh so I need to format a little bit around here but the point is there is an the connected address that you have inside your application is not necessarily the address that is from your externally owned account in in metamask or in in any other Mallet that you have so now I need to make this backwards compatible as well with the uh with the the previous uh externally owned account example that we wrote before and I somehow need to resolve all of that because I just copy and pasted the code in there and it also doesn't like that the block is a specific block um I would just change this to the block that is the current block minus 100 or 200 blocks so let me just see what's going on here that one returns that one actually returns data not a block number just give it a I call it data now I call it block number now the data and what else is the problem it can also be undefined so make no mistake you need to actually make sure that when the block number changes that you also call this use effect hook why it works in this particular recording I'm not exactly sure but it works and I have actually fixed that at the final example when you look into the kite um folder in on the page TSX then you will see it it actually is the fixed version that you will get as code example all right so now if you are going to send that message um it constructs the message correctly but it need to be sent off with the right method because right now if you're hitting send message it would just use metamask to send the message but we actually want to use that one over here um to then not only cons rrct the call data but sent the the the whole user operation to the bundler and I signed up to stack up before uh I got a um an API key for the bundler and I got an API key for the pay Master as well the pay master in this case uh is kind of important because uh if you don't have a pay Master then the wallet smart contract needs to pay for that transaction and the wallet smart contract needs to be funded first if you have no payment master so there is a function inside the entry point that gives the wallet smart contract actually a number of ether it needs to transfer to the entry point so that the entry point will continue to work on on the whole uh transaction and if it doesn't do it it will just stop there but it will not even go that far because the bundler will first um simulate the transaction and we'll find out wait a moment the the wallet smart contract will not send me any funds back so I'm not going to send this transactions because why should I pay for the gas costs because actually the bundler has the the gas costs so you need either fund your address of uh your wallet first or you need to have a pay master in this case I I think I had a pay Master here um already without even exactly knowing how this works but let's let's finish building this and then I will run this transaction through tenderly and we'll show you step by step what's what's happening inside that transaction yeah so in this case I have the builder at the beginning uh from from use effect and then I just want to set the Builder a state variable so I can use that Builder that buil the address of my simple wallet to send the transaction so I have this over here I don't need any of this I have the call to is my chetta address and the data is the and ABI encoded function data that I used a function here from vhm and then I do a client in it uh with the RPC URL the RPC URL is the bundler from uh stackup and then it will ask me to sign that uh transaction uh with metamask and then it will send the transaction and will give me a transaction hash let's just see what happens here I think I wanted to wait for the transaction to be mind but I don't really care okay here's the first sign and then I'm going to send a transaction I have the message hash there's something going on and it says uh it didn't pay the pre fund so the the Bund actually gave me uh an error message that I didn't pay the pref fund so I'm going to fund that wallet now I have a little bit of girly Eve in my um account and I'm going to fund that wallet now now obviously you will say maybe wait a second uh why why would I need girly e in order to fund something I thought account abstraction is the whole point uh that you don't need any have any girly e now I don't have to have it in this account it can also be uh somewhere else and this is also where the pay masters are coming in if you have a pay Master you can actually fund you can actually pay for a user that doesn't have anything in his account because the entry point will ask well look is there a pay Master attached and then it will ask the pay Master do you want to pay for that transaction and if the pay Master pays for the transaction the smart wallet doesn't have to have any eth or any kind of funds in his own um wallet all right what you see here is trfy scan um ether scan cannot deconstruct any uh user operations yet I'm using jfy scan for that and jfy scan will actually give you for a user operation hash which is different than a transaction hash um the contents of the user operation hash and now what I'm also doing here is girly uh what you see here it's basically just a transaction against the entry point and the entry point as I said previously is always the same smart contract always running on the same addresses like this 0 X5 FF and so on um and you will see if you go into that uh transaction the message from our um chatar application is actually emitted and this is what our chat application gets back uh that's the message all right if this was a little bit too fast then I suggest go back to the code sample that I posted and check out the stackup example it's it's all there you just have to go in and and follow the code and see what happens yeah this one is the user operation you see the sender which is my onchain wallet and this one is the entry point smart contract and and it goes directly into the handle user op and calculates then through all of these functions it always calculates how much gas was used um and did the wallet smart contract pay the gas in order to pay back the bundler and then it basically just calls the the sender with the call data um if you leave out all these um gas calculations and so on what it basically does is it takes the user operation it takes the sender it takes the call data and it sends it to the sender and it executes the dysfunction that that's that's basically what it does there's nothing much more behind it and the rest is uh guess calculations now the function that it calls on the simple wallet is the execute function and this execute function or it calls to execute batch function if you have an array of um of two and data values and if you if I go into my my simple wallet uh which in this case is unfortunately a proxy but if you go into the simple wallet itself I need to find where it is because that's what I want to show you yeah here's the simple account and if you look if you scroll down a little bit and then you will find the the execute function here's the simple one and here's the execute function and the execute function really it the call data of the user operation is an ABI encoded execute function with the parameters that's what it does and this is how it gets onto this onchain wallet now I'm going to attach my pay Master here and what you will see is that you don't even need to have any kind of uh money inside your onchain wallet and I'm going to send a transaction from an account that has zero girly eth and I do not fund my um onchain wallet before I going to send this transaction and you will see it still works yeah um it actually did pay for the transaction let me just switch over to a different account that has no girly e zero e in my account it's a different address I'm not going to fund it and I'm just saying hello Zer e account sending this one and it's waiting for the transaction come on send the transaction it sent the transaction I have a transaction hash and if I go back to my dashboard of um of stackup I will see that my so-called pay as you go pay Master paid for the transaction let's just um have a look what was paid here and and so on and so forth so there is um there's the call data sorry there's the pay master and and data that is then called from the entry point smart contract and if I just going to refresh that then you see it actually paid some gas costs so if I would use this pay Master now in in a real life scenario I would um like if I would use this pay master from uh on mainnet or on polygon I would have to have my credit card here and it will directly pay me before we're going to continue with Candide I promised you to look into the transaction with tenderly and before we're doing that I actually want to talk about the rest of the fields of the user op in particular I want to talk about the gas Fields where they're coming from and how they are used so when we are talking about the transaction later that you see where these are used and what happens with them actually now I found it a little bit confusing why I need those fields but they have a very specific reason but let's first have a look where they are coming from now the guas limits they are estimated through the bundler um with stackup you didn't really see that that there is an estimation running in the background before the transaction is actually sent off now with kiet it's a lot more low level and I think it's a lot more understandable what happens behind the scenes then where you have to estimate how much gas will a transaction actually incur the bundler itself gives back a call gas link a verification gas limit and a pre verification gas so the bundler internally will estimate the gas amount that is used up by the transaction and then give it back to you and then you have to add this to the user op yourself before signing the user operation so those are these three Fields the call gas limit the verification gas limit and the pre verification gas that's the um amounts that you get from the bundler but the max fer gas and the max priority Feer gas those are actually uh current block gas fees so when you call any public client and you say like hey what's the max fee per gas and the max priority fee per gas at the moment in the block so those are those values and then you add those and then you check the nons if the nons is zero then uh the init code must be set if the nons is more than zero the init code cannot be set and then you add the signature you sign the whole thing this is where metamask pops up and and the signature happens now let's have a look into an actual transaction what happens this is a random transaction that I just uh took from from tender against the entry point uh it is obviously against um a safe wallet here so you can disregard that because we are mainly talking about the entrypoint functions that are called over here it's running through a number of steps the bundle itself is called with a user operation and a a beneficiary and the beneficiary is actually the one that gets reimbursed at the very end of the whole uh transaction it starts with with uh validating the prepayment that is where the entry point decides um okay based on the guess amounts that the user gave me in his user operation how much money do we need uh to reimburse the bundler or whoever is the beneficiary at the end of this transaction and it will either ask the wallet or it will ask a pay Master if there was a pay master in data attached now there is then a validation phase that is validating the user operation and this is where when we uh open this up here after create sender if needed it will call this uh very strange 0x 3A 871 CDD function signature and that function signature corresponds to validate user operation and that validate user operation is not happening inside the entry point the validate user operation is actually happening inside an an a wallet an onchain wallet now I have this screenshot over here is from the base account from the eth uh infinitism repository it's the current develop branch and inside there you will find validated user op and it takes a user operation and a couple of other fields and then it will if you if you deploy um a wallet with that base account then it will check first wait is the transaction from the entry point is the signature correct is the nons correct then we are going to pay uh our entry point whatever it decided that uh account funds are missing so it will check the signature and it will pay from its own funds and the entry point will set this uh to greater than zero if there was no pay Master attached if there was a pay Master attached then the paymaster will pay for the funds okay now we made sure first of all there is an wallet created and the wallet validated the use operation and the wallet potentially even paid for whatever was the total of all the gas amounts times the block gas fees okay then it continues um after this whole validated account pre prepayment is done and uh the the entry point knows that the signature validated through the wallet the funds are here deposited inside the entry point now we can execute the user operation so it goes la la la la la through the execute execute user op function inside the inner handle user up function inside the call function and over here is exactly what I showed you before there is an a call to the wallet or the address that is given as the the wallet with the call data that was there with the call gas limit that uh the user decided inside the user operation uh that should be the maximum call gas l limit for the call of this call data inside the wallet now when all of this is done and it successfully comes back or maybe even not successfully comes back uh and a payman that was used then it will try to reimburse or actually recalculate how much gas was actually used during that whole transaction uh in case the the pay Master overcharged a little bit to make sure that there is really enough money inside the entry point to uh go through the rest of the transaction and then at the very end it will reimburse the beneficiary that was given to the entry point at the first calling uh the amount that the the guess amounts the sum of the guess amounts times the block gas limit so it will get back what was given inside the user operation there was an interesting question from a user that was like what happens if I set the the the block gas amounts to zero now the sender will not get anything reimbursed this is what happens this is why when you send something through a bundler it will also check the values again inside the user op and make sure that it actually gets reimbursed something and potentially even more than the actual transaction cost so the the there is no real connection or no validation between uh the bundler is sending a a transaction with 20 gay but the user operation says it should be sent with 50 gay and then the bundler gets reimbursed for the the gas amount times 50 gay but it actually just spent 20 Gay so there is a disconnect between that um and the bundler can or cannot send this with whatever Gess amount it deems to be correct all right with that being said let's continue with Candide I think you will like it because it's a lot more low level and you will see the exact steps that are happening uh with the bundler and the pay Master now the problem is I cannot I didn't get with stackup the safe wallet to run and the safe wallet uh that I have here is um I I like it so much because you get a really nice UI to interact with your onchain volet you can you attach your metamask or other signers to your onch wallet and then you interact with your onchain wallet through this UI there's apps that are integrating with iframes for example uh on Rams off Rams uh di apps and so on but you need to create the safe wallet with the account Factory of the safe wallet and the only library that I could find which is doing that correctly is kite now safe wallet also has account abstraction but it's not this account abstraction they are using a service called chilato which then does guest L transactions and you are interacting with your uh onchain wallet through the help of chilato somehow now let's get into kite because uh with kide we can actually use safe accounts to deploy a new new safe gnosis safe account instead of a simple account and I just want to do the same thing I want to create a separate page and I want to use account abstraction with kite in this case um heads up there will be a change to both kite and the entrypoint so there is at at the time of recording this video there was just a new entrypoint version posted or handed over to um to OB zein for audit and at the same time I'm in touch with the kandai team and they are just writing a new version of the kenite npm library so there might be some updates however I do think the basic principles of how to apply account abstraction with candid still apply so follow along and I will try to keep the code updated once a new library comes out all all righty the first thing that I'm doing here as before with stackup I'm going to create a new folder and I basically just copy over the whole page from stackup now a little bit of cleanup and then you will see here on the on the left side that I want to use a specific Branch from abstraction kit and that's the safe Branch now the problem if I just do an npm install and I want to use a specific Branch it doesn't work so I kind of need to install a specific Branch directly from GitHub so npm install abstraction kit at safe doesn't work so I I kind of install try to install that uh with uh the htps version of the repository so mpm install htps github.com klab extraction kit and then at the end uh the safe Branch uh in here now the problem is here that it will download the rest of the note modules inside the abstraction kit but somehow it doesn't have the disc folder or anything else so I'm kind of a little bit lost here um how to do that correctly uh so what I'm trying now is to just make a new library folder and clone the whole repository locally and then try to link it from a local repository into the node modules folder so I have it there and it will I think it would just be a Sim link or something I do not think that you will need to do this when the new version of abstraction kit with safe with the safe module is actually released because they will have it have it in there um Z mpm install doesn't work and I think there is an npm link but and then I opted uh just to add the whole thing to my package Jason file and then just do an npm install and that did work so just give it a minute um yeah again I don't think you will need that try first to just install the abstraction kit and see if you have the the safe wallet or or the the modules for the safe wallet inside there so I'm opening now the package Jason and I'm saying okay uh for this abstraction kit uh just used the foul lip abstraction kit and that actually worked so uh if I go to the modules folder now I have the abstraction keit here there is the source folder and so on and so forth and now I need to check out the safe theosis uh this the safe Branch with theosis safe and I can continue and later on uh you will see that I also needed to run npm run build I think inside the folder to actually get the this uh this folder otherwise uh the IDE vs code will complain that it cannot find abstraction kit all right so it's trying to import this from Source but I just leave it like this um at that point it was yeah over here you see um npm inside the lip folder inside the abstraction key that run npm run build and then we create this disc folder but vs code will still complain and I don't know exactly why uh but it works it it finds it um from nextjs and it can compile the whole next shars app so I think that is fine so I'm going to continue here from now uh and now it's basically what is in the docs um that is uh getting the the safe account and calling this create new account with the address of our externally owned account which is in this case my metamask and what we getting back is the account address address and the init code so the whole Builder and everything and the pay Master middle bear and whatnot from stackup can can go and we are just setting the new account address uh to the one that we getting back from create new account um smart account so if I go to kite and you see here first of all I don't need to sign and second of all it's really blazing fast so this is what I was actually expecting at the beginning when I was was uh using stackup but for some reason it uses the onchain version of the create 2 and then you need to sign the message hash and so on and so forth anyway all right we are continuing we just have a look at this we don't need that we actually want to store the init code somewhere because we are going to need that init code to create call data single transaction which is what we want uh which is then calling on our safe account on our smart account the execute function with the data that we are giving it but if the safe account is not there yet it needs to be created first which means we need to have that init code uh delivered to the bundler right I'm just basically using a a state variable and setting that wallet init code all right getting the operation and now we can do create call data single transaction and we already have a call data there so we don't we don't want that however uh the data here inside the call data single transaction must be the encoded function data to our send message chatar AI uh cheter smart contract with the message so in this case the bundler is going to send a a call to our smart account and that smart account is going to execute a call to our chat application uh send message and this is how it gets in there I'm going to import the the bundler from abstraction kit I don't know why it's doing that but so be it so we have the RPC URL interestingly enough I still using the RPC URL from stackup I'm not using the RPC URL from kite yet uh which is this uh vol. kandid wallet.com um RPC endpoint but it did work at the beginning I'm not sure if we going to change this here now uh either way uh the bundlers are interc compatible so you send stuff with one bundler it also works with the other bundler most likely so if they they're getting um enough money uh reimbursed from the transaction then it will work now we talking about gas estimations so what we want to do here is uh estimate the amount of gas that we going to need in order to send this transaction so first is the bundler gas estimation that weal we talked before and then it is the uh block gas limits that need to be added to the user operation before it can be signed so first of all we need an empty use operation this is this one uh right now we are setting the nons to zero and adding the init code um no matter what because we assume that the first transaction is going to be a non zero transaction uh later on you would need to clear the nons from the entry point you can find it in the final code example that I have uh and then set the entry uh the init code if the nons is zero or set nothing at the init code if the nons is non zero all right we are getting back over here a couple of uh values for the call gu limit the prever verification guess and so on what I'm changing here is the 2B hex from ether JS to two hex from vhm and just outputting this where are they they are currently zero and I'm a little bit confused here but I will find it in a second that we actually have to set these to the user operation all right now we are getting the uh feed data from the public client we getting back max fee per guess and Max priority fee per guess from the public client and for that we either need need to import the public Client First the public client get public use public client Hook from vagi is going to give us the public client and then on this public client we can get the fee data so it's basically just copying this one and then just outputting the feed data and and setting the fee data to hex numbers from Max fee per gas and Max priority fee guas I think there's a typo in the documentation of some sort see mhm I have not set the smart wallet to true and now we get the feed data back so we have fif big number those are big number lits with 15 n and 2 N in case you're wondering and I'm just checking if the user op is having the right values over here and I just saw that there's a typo so fix that one and we are ready to sign the whole thing yeah it's basically sign and submit the transaction uh again we have no pay Master attached here so if there is no pay Mastery attached then the wallet must pay for the transaction that means we need to uh fund that whole the wallet first enough so it can pay for its own transaction and let's just get the uh user operation first over here the user operation hash so it's the hashed version of of the uh user operation and then it is we need to sign that with our metamask account with our externally owned account let's just check if the user operation hash is there it's there and now we need to sign that with uh our signer and for that we are using um VM not wagi uh we are using the V version on the Wallet account the sign message and there you need to have the raw message so getting the wallet client because we are not we not doing any EOS JS things we we don't need that eths JS uh signer hook we need the wallet client from BME and on that wallet client we are going to call sign message and the argument here is the raw the message and the raw message otherwise it will just prepend that um ethereum message prepend thing which we don't we don't need that we can we are doing account hoisting and that is the user operation hash let me just make sure that get the types right okay there we have a signature let's see if we can get that signature and so far you see the only thing that really needs to be signed is the user operation so and actually not the user operation the user operation hash needs to be signed so there is really just one signature that we need to to create which is the one for signing the US operation before sending it to the bundler what it called the connected address format everything and give it a go sign this oh we didn't fund our wallet first of all it's girly uh over here and not aoia but that's a small thing let's fund the wallet so it has enough enough funds to pay for creating the wallet and running the init code and running the call data takes a little bit and as soon as the transaction is mined we can actually then hopefully send this transaction interestingly enough through the bundler from stackup not through the bundler from kenite right well we have a message over here and we can out input the user operation hash inside chiffy scan and we see everything is kind kind of there it's working great yeah we have the sender that's this account we have the target which is our smart contract for um here the the message the chat smart contract and we can see the transfers of eth back to First from our wallet to the uh entry point and then from the entry point to the beneficiary the bundler and we see the user operation over here yeah everything is there now the other thing which we can do is uh we can add our uh safe account to the app. safe. global uh website so it's it's that account over here it's automatically uh recognized by the website and um there's an update to Candide at the moment there is when I was recording this video there was something going wrong there that I couldn't interact with my safe account but it should work and I was assured that it will work again um yeah but basically when you create this safe wallet via kite then you are creating an actual smart contract that conforms to a safe account or should conform to a safe account and you should be able to use that uh wallet inside the the app. safe. global website all right that's it uh with kandai so far um now I want to go on and try the account kit all righty now let's get started with account kit next we just need to install Alchemy uh account kit aa- Alchemy and so on then basically run through that getting started guide and should have pretty much the same as with kandide now there is um a major difference here because account kit is producing a simple account or a light account which they call and that light account uh is optimized for guest usage as far as I understand reading through these documents um you can and bring your signers and so on but you will get a light account and I think they made some sort of effort to give other people the opportunity to add their own wallet Integrations but I could not find a a safe wallet integration which I was personally after so if your use case is to have um an account which is gas optimized then you might want to go with the Alchemy light account if you want something which is more lowlevel um and for me personally easy to understand uh go with Candide if you want something super high level and abstracted may you basically just give it your credit card and uh need a simple account integration you can go with stackup I mean all free services we're working correctly that I have to say um however if you need some specific things from these services like a safe account or something uh or you want to you don't want to use ethos J at all for example you cannot go with a user op Js from stackup uh you might get away with uh Alchemist integration from account kit here but um you definitely get away with the one from from canat because it's very low level you can do on the on the integration side with the wallet whatever you want all right the other thing that I tried to set up in account kit or in alchemy is a guas policy so I wanted to create a pay master and test that over here however I couldn't get it to work um you will see this in a second over here in the in the video uh every time I was trying to create a pay master or create create these uh guess rules for the pay Master it errored out and I didn't want want to go so far to actually create a paid plan maybe that was the issue um but yeah I couldn't I couldn't use a paym with uh account kit so maybe there's something going on maybe alamy will tell me where I made the mistake or maybe it was a UI issue a temporary one it shouldn't stop you from from testing Alchemy as well all right let's get started with Alchemy yeah let's get actually into that app into this dashboard uh log in run through the init setup and create you can use that API key straight away or you'll create your own project so I always recommend putting things in environment files in this case you would put it in a next uh JS public environment file and so on but I just recreate the same thing as before create a new folder uh called Alchemy so it's a route SL Alchemy and then copy the page over from kite and get started from there now if uh my Alchemy integration doesn't work anymore it's probably because I delet needed my Alchemy project uh with the API key um you would have to add your own API key if you want to make it work so the gas manager the gas manager first had an internal error and then I was reading through that whole thing somehow and there's a generous fre here for um the bundler and uh there's a fee logic and so on but it really comes down to creating that that the pay Master rules which didn't work so I'm installing now the Alchemy account kit libraries and run through that getting started page here so importing those things don't need to have the uh abstraction kit things anymore from uh from kenite need to create that provider in order to get that um account address from our wallet it's complaining that the owner needs to be a a wallet client so we need to create a new wallet client signer to import that and then we get the address from our provider and that one is hopefully the connected address that we are getting and now we need an API key so I'm getting this API key over here right let's save everything and see if it's working change the chain to girly yeah and you can see here it is calculating something internally it takes a little bit until this um account is created or the address is calculated I'm not sure exactly what's going on behind the scenes uh but it's definitely not as Snappy as cani but better than stack up in this case so the next thing is to actually send a user operation and again this is abstracted away inside uh send user operation function that most likely internally does everything that we did with cite before um inside our page TSX now it's doing that inside this provider do send user operation probably getting the guess estimates uh the guess fees and creating the hash and setting uh and signing the the hash with our signer that we gave it inside the provider creation so I'm just uh setting the call data to the uh call data for sent message and we don't want to give it any value and then we get this hash that is not the user operation hash that we need to sign that is the user operation hash that is already sent through the bundler all right still complaining about some brackets set wrong there we go so what will happen need to sign this and ah we need to fund our our wallet before we uh we send this okay same as before we are funding our wallet and as soon as the wallet is funded we can retry and we have a use operation hash let's see in Jiffy scan if that was actually sent yeah it was sent so the last thing that we can do is we can wait for uh user operation transaction and what this does internally is it calls the bundler for the status of the user operation and if there comes something back then it resolves that promise and if there's nothing coming back it will just retry with a staggering um timeout so it's not overwhelming the the bundler so the other thing is here um the internal gas estimation failed from from alchemis account kit probably because somehow the the guess amounts changed uh in between one block to the other uh and then it also gave me another error but the transaction worked I don't know something was going on in the background and I didn't know exactly what all right here we are in the gas manager and I'm trying now to add a a gas policy so I'm just creating this policy uh trying to create select an app but I didn't create an app yet so let's create a new app for girly just call this chat app and actually use that one that API key for my bundler I don't need those those addresses anymore right create this new guest policy and next and then I'm trying to just limit this to five operations per address but somehow no what I clicked here didn't work so we reached pretty much the end of this video with that and the last thing that I want to talk about is the pay masters and there's there's two things that I I want to talk about one thing is I did another two hours recording of how I re formatted and better formatted the kite example into an actual chat application so that when you send the message uh it will add the temporary message and you have some nice little status icons to know where in the whole process between estimating the gas fees signing the use operation and getting back the result and and waiting for the transaction to be mined uh you have nice little status icons um and I added a pay master and the pay Master is one thing that is actually quite easy to implement um but there's a huge fuzz around this things so I I just want to give you an example of how how a pay Master could work as promised the last part of this video and I want to go through a couple of things that I changed inside the cite uh example over here um and you see over here the on the left side is the final version of the CH application that I'm going to post into the uh code examples so you see here the little icons um first of all I made the message already appearing inside the messages before it's actually sent um and then when there's a signature or we are waiting for the transaction to be Min uh it will keep it there and then when the actual transaction is mined it will replace this message with the actual lock message that comes from the um from the smart contract now in order to do that inside the send message function that I have inside kite I have a couple of uh things going on there and you see it's not working perfectly but it's good enough for this chat application uh I'm just setting a a pending icon over here every time something changes and I'm using this pending icon inside uh the uh message history um component message history component is over here and then there is there is like um a pending message which is set and if the pending message is set then I would just use this pending icon over here and set a p an extra chat message uh to this pending message that is set as pending when we are writing something over here you see the the icon is changing and we get a nice little UI that's that's working I also had changed a couple of things over here so I have an uh externally owned account method uh which is the pure method with uh the wallet that is connected through rainbow kit and I have this uh button to change it to the um smart contract wallet method or ESC 4337 method um which then uses kite the other examples should still work uh but I found this one the most nice one for me so I started to actually build it out into a little better appc ation now that is the one thing the other thing that I wanted to talk about is the pay master I'm using the pay master from cite over here if you sign up with kite or with Alchemy or with stackup you get a um an API key for a pay master and the way this works is there is a smart contract that gets called from the entry point and that is going to pay for the transaction uh because the pay master and data field will also contain a signature so if you're calling the pay master um the paymaster cide validation pay Master uh get pay Master call data for guest L transaction uh which is a new thing I'm not sure if you can actually get public access to that yet uh join the the kandai Discord if you interested in that you find it on the kendai website the guys are very responsive very nice very nice people and I'm also hanging around there if you have any questions um the point is you will get um a struct that the pay Master smart contract can deconstruct and it will also contain a signature that is signed from the pay Master team from the Candi team so that the paymaster knows okay this is really from the pay master from from from the Kandi team and will pay for the transaction in the the background getting this is an RPC call an HTTP RPC call so there is a normal uh HTTP interaction first but it doesn't have to be so you can also write pay masters which are just smart contracts which are for example converting your C20 tokens to eth or to madic or whatever the guest tokens are on the blockchain you're operating and then just paying for that and and there is a new uh entry point coming uh entry point version 0.7 uh it looks like this looks very similar to the to the previous one the big difference is there is new pay master and if you go to the samples inside the develop directory for the new entry point then you can actually find uh two different pay masters the one is a verifying pay Master when this one gets called from the entry point with validate paym user op which is in the base pay Master uh it will intern generally call the the underscore validated paym user Op with a packed user operation user op and so on and so forth uh it will actually check the the message hash that is given as a signature to the paymaster and data um so that one needs to be generated outside before the user operation is actually sent but it can also be a token pay Master which means that when the validate pay the user opice run it will just take a cached price or some price and do an erc20 safe transfer for the token from the sender from the wallet address to the pay Master address and then just pay for the transaction because the pay Master is just doing that so there is no interaction from an external entity necessary and you could even go so far that you write your own pay master that pays for the transaction no matter what uh you get the whole user operation so you know what's being called you can deconstruct this if you want to and you also know how much funds are required uh and at the end the post op function is called with the context that you give it before over here so you can actually give something uh back to the entry point and then in the entry point it runs through the whole user operation uh calls the wallet and executes whatever call data is there and then goes back to the post op and you get the context back and then you can if something is overcharged under charg you can transfer more or less something back and so on and give the actual price that needs to be paid to the beneficiary most likely the bundler uh then back to the entry point all right that's it I hope you like the video I hope account abstraction is now a lot clearer than at the beginning and I hope I will see you in one of my courses uh you see here that's the app that we wrote um I will make sure that you have all the code samples and everything ready uh if you're looking for something to learn ethereum then one thing that I created is the ethereum blockchain DD developer site with a couple of courses I will also make sure that this particular video is posted there um a lot of the content is for free you I need to pay a couple of things which are really premium content is paid and uh by joining that you will also get access to the Discord you will get an invitation if you want to chat with me join my Discord uh the other Discord that I can recommend is the kandai Discord um the folks are really friendly and I'm also hanging around there if you want to talk about something and if you want well subscribe to my YouTube channel um I'm trying to keep low frequency but high quality content posted there uh you know that by looking at the YouTube channel the last video that I posted is from October and I still have a full-time job next to the videos that I'm creating uh but join me or add me on LinkedIn if uh you're looking for me on other social networks yeah that's it I hope it was helpful and I hope I will see you in the next one
Up Next

Intro to ERC 6551: Token Bound Accounts Explained by Jayden Windle
@ETHGlobal
3.2K views•2023-05-24

Torrent File Format & Bencoding: A Technical Deep Dive
@AsliEngineering
12.5K views•2022-08-08

Operational Security Essentials: A Guide for Hacktivists (OPSEC)
@hitbsecconf
157.4K views•2012-11-26

Understanding Ethereum: A Comprehensive Beginner's Overview
@99Bitcoins
3.1M views•2018-06-26
Related Study Plans & Knowledge Roadmaps
Structured learning paths in Blockchain & Crypto





























![zkSync Airdrop Guide [Full Paymaster guide on zkSync]](https://i.ytimg.com/vi/7iDATf4PrdU/maxresdefault.jpg)









