 Hello everyone, I'm Eric Marks. I am the lead engineer of MetaMask Snaps. This workshop is called Getting Started with MetaMask Snaps. I realize we have some Wi-Fi issue masks since 2018. Snaps was first announced as a concept three years ago at DevCon in Osaka. So I know we have we have some returning guests with us today in the room and you know since then lots of things happened, COVID happened, 2020 happened, but since at 2021 we've been working on Snaps full-time at MetaMask and since the beginning of this year we have been in a developer release via our Canary version of the MetaMask extension called MetaMask Flask. And this workshop is basically like the sort of Snaps 101. How do you get started like developing a snap using one of the newer APIs that we developed? If you read the instructions, there's a custom build of MetaMask to download because we haven't shipped this API in production yet. It's coming in the next few weeks. But before continuing, we need to talk a little bit about what is MetaMask Snaps? And we're gonna start from the very ground level and build up from there. And so MetaMask, as all of you probably know, is a non-custodial cryptocurrency wallet for Ethereum. You enter your secret recovery phrase into MetaMask. You can derive your keys and your externally owned accounts and it will manage those keys for you and encrypt them with a password. MetaMask allows you to interact with Ethereum via an RPC endpoint. By default, we use our friends at Infura, but you can add whichever ones that you want. And that allows you to do stuff like, you know, send transactions from account one to account two. The really powerful thing about MetaMask is that it enables you to interact with Ethereum DApps. And so that is through our window.Ethereum provider object that we inject into the web page. And that is what all DApps use in order to submit JSON RPC requests that are either handled directly by MetaMask or smart contract accounts. What about, you know, zero-knowledge applications and non-Ethereum cryptography select things that use curves other than SecP256k1. And that's just like a sample of the things that's being built in Ethereum that we don't support out of the box. And that, you know, doesn't even get into Cosmos, Polkadot, Avalanche, Solana, whatever, in addition to those things. And so it is, we believe, basically impossible, and I think, you know, practically like I observed this, I don't predict it. It is impossible for any single organization to add support, to develop the domain expertise to understand all of these different protocols and primitives. And then also to develop the code and maintain the, you know, unimaginably large code base that it would take to actually create user experience for all of the things that are being built in Web 3. And MetaMask Snaps is our answer to this problem. And Snaps are simply sandbox programs that are run by MetaMask, and their purpose is to create new user experiences in the wallet. And that is to say, the purpose is for them to modify the wallet in some useful way. And the user adds Snaps to the wallet at runtime, and they have access to special permissions that are not available to dApps, including things like key management. And that makes them uniquely powerful building blocks for Web 3 developers. And so using this simple model, just in the past week over the course of ETH Bogota and some, and a hacker house that we co-sponsored with BitDow and Game7, hackers have developed a CK nullifier snap, a transaction security snap, and account activity notifications, and a smart contract account wallet, or a smart contract account support, all in MetaMask, all using Snaps. And Snaps currently in developer releases include StarkNet, Filecoin, Bitcoin, Arweave, and many more. And here I'll just briefly stop to say that this isn't a developer release, so the reason we keep it in the channel is because it's not quite ready to be pushed to the tens of millions of people that use MetaMask on a daily basis. But that is our goal in the upcoming year, and we'll get to that in a bit. And so we believe that this illustrates that Snaps is the gateway to all of Web 3. By turning the wallet itself into an application platform, only then can we invite the entire community in in order to bring their domain expertise and their passion for the specific features and functionality that they're interested in in order to add that functionality to the wallet and make it available to all of their users. And with that, we're going to get started. So again, there's the HackMD link, for those of you who are able to access that. And we're going to start here. And we're actually going to, I was too busy trying to get my Wi-Fi to work to clear out all of this stuff, but we'll get started here in a second. And so as I mentioned, the first thing that we need to do is add a custom build of MetaMask Flask to the browser. And my visibility is the size of the editor and the text and everything good so far. Okay, yeah, please holler at me if not. And the way you add a custom build to Chrome is you simply get your build from wherever that lives and you just drag and drop it in. Your browser needs to be in developer mode in order for that to work. And be advised that developer mode exposes your extensions to certain kinds of malware, so don't put main in developer mode. And we're just going to go through onboarding here super quickly. I'm going to go ahead and snag my throwaway seed phrase for that. And Wi-Fi permitting, we should be good to go. Okay, yes. All right, so now I've set up a version of Flask. And so the only thing you'll notice that's like immediately different with Flask is that the onboarding is slightly different. And we have a purple fox to distinguish it from the regular orange fox. And the next thing we're going to do is I've already done this, but the next step is to create a new GitHub repository using the template snap monorepo. So this monorepo is a template that contains two things, a two or two sub repositories or packages, a website and the actual snap itself. And things are they're kind of loading. But once you've pulled that down and run yarn install, we can see here. That should still be good that we have in our packages. We have the website and the snap. And I'm just going to make sure that we've installed and everything with that is good. And then we're going to kick things off by running yarn start, which should hopefully not need too much network access great. And so this is the template snap interface. And so you see we have it we have everything hosted on local host. And the first thing we need to do is connect to our snap. And so first, when you install a snap, you get a permission request from the website that that made the request and it's basically saying, hey, I the website at this URL wants to talk to this particular snap. And during local development snaps are just identified by the local host URL where they're hosted, just out of convenience. And once we've accepted that permission request, then MetaMask will go and fetch the snap source code and its manifest and then ask for its permissions. And so here we see that this snap again identified by its local host URL that wants to display confirmations inside of MetaMask. And we're going to say okay to that. And to try out this functionality. Oops. Excellent. Right. That's it. That's it folks, a snap a snap everyone get a look get a look. It's showing a confirmation. Oh goodness. Yes, yes, yes. Okay, it's real. Yeah, yeah. So what happened here is I was going to do a little I was going to mess around with this notification a little bit but or confirmation rather, but we're not going to do that. So this is just a dummy notification for display purposes. And we're going to skip right to the source code and look at like what is going on and what is the anatomy of these things. And we're going to reject that and that's totally fine. And so if we go in back here. And if we look at see we have packages. Snap we have you see we have like in the snap package. There's like some regular like npm stuff going JavaScript stuff going on. But you also see that we have a snap config and a snap manifest, and then a source file, and then the source file is just index dot ts. And so, looking at the manifest here. You're going to see that there's a version, which you may have noticed matched what we saw in the application. And then we have some information about the source so a shot some of the bundle and some other like metadata if we were to publish the snap to npm, which is our currently supported like distribution mechanism. We have plans for others. And then finally, you have the permissions here and snap confirm is the actual RPC method that gets called by the snap in order to display a confirmation inside of metamask. And if we actually look at the snap source code, you see here that it exports a this on RPC request handler function. And basically the way that looks the way that looks from inside of the website so this is a file from inside of the website. You will call this it's an RPC method inside of an RPC method. So you have wallet invoke snap, and then you pass it the ID of the snap and then the request that you want to pass to it. And you see that the method is hello. If we go back to the snap, that is the only method that we support, and that just causes this confirmation to be displayed. Now, if things like continue working a little bit better than they were doing some minutes ago, we're going to take this snap and turn it into a transaction insight snap. And if we briefly return here, so we basically we've demonstrated like we've gotten a snap running and now it's time to like replace its confirmation permission with this transaction insight permission. And all that this permission does is it tells MetaMask that like, oh, this snap wants to provide transaction insights. And in order to do so, we're just going to nuke the contents of this file. And then we're going to go ahead and import some other stuff, namely on transaction handler. We are going to add a package called utils. And we're going to import some stuff from that. And then we have this handler that we need to specify on transaction. And that is going to be a function that looks something like this. And right now it's a sad function because it's not returning what it needs to return to satisfy its type. And we're just going to return some like dummy, a dummy trend, a dummy insight for now. And I think we also need it to be async. Yes. Okay. And we're also just going to add a little bit of validation to make sure that the transaction is of a type that we can understand because like, you know, we're writing a specific insight snap that uses our particular domain knowledge. And so we need the transaction to look at a particular way. So if it's not an object, or if it doesn't have the property data, or if the data is not a string, then we're going to say, oh, actually we're going to do this first. Oh, wait, no. Let's call it an unknown transaction for now. I'm going to say import this, import this little warning for sanity in case I make any typos here, this down here, hide that. And then we need to make some modifications on the front end as well. And on the front end, so the front end is just a react application written in TypeScript, nothing fancy going on there. Although it certainly looks fancy. And I'm going to snag a little snippet here with some useful constants that we are going to use because right now, our problem is that let's see where do we have send hello. When we click on the on this button here, it is going to call this handler, which is going to call send hello, which calls this hello method and we don't even have an RPC handler anymore so that's not going to work. So we need to delete that. And then rather than doing that, we're first going to grab some accounts because we need access to the user's accounts in order to send a transaction. I do need in a way. Thank you, sir. And then if there's no, if there's no account, we're just going to throw an error failed to get accounts. Actually, that should even request if it rejects, but you know, never hurts to be defensive. And then, once we have done that, we are going to then we have an account and then we're going to just send a transaction. And we're going to do again method, send transaction. We're going to have some programs that should be recognizable to many of the fine folks in this room. So we have a from address. The to address is going to be the address of a contract that is in fact deployed to mainnet, but that will reject any transaction that we accidentally sent to it. I just happened to know this to be the case. We are not sending it anything in terms of value. And then the data that we're going to send it to start with is just going to be some dummy, like 0x1. And that is basically outright. And now we're going to have, now I'm going to have a little fight with prettier. For some reason, the ESLint prettier plugin does not work as advertised. We're not going to let that stop us. Excellent. Okay, now I'm going to try to reconnect and it's not going to fail to install. And so we can see that like the permissions that we're requesting have changed because we're now fetching and displaying transaction insights. That's the purpose of the snap now. We're going to improve and install and I'm going to anxiously look at the background console. I think it worked. Yes, it did. So now it's asking for accounts. That should be familiar and here where Mademask is trying to estimate some stuff and look foobar. Okay, we're using the API correctly. We're slowly inching towards our goal. You're too kind. You're too kind. All right. And so we rejected that and there's an error here. That's totally fine. That's expected. We love our expected errors. Okay, so the next thing, so the front end now for like this demonstration is basically is basically done. And we're going to go back and look at our snap because the next thing is, okay, so we managed to like interact with the API. We've demonstrated that we can do transaction insights, but now let's actually go get some like useful information and see if we can like decode more of this transaction. Then we're currently doing and in order to do that. We're going to add a second permission because we are going to call the four byte registry API and snaps do not get network access by default. So they cannot just like call out to the network unless they are granted the permission to do so explicitly. And that permission is simply called endowment network access. And we are going to call, as I said, the four byte API. And we have some and we have some useful snippets here in order to do that. And so here the this API endpoint that simply just like the the four byte API endpoint that we're going to call it has a single query parameter which is the hexadecimal like four byte signature of the of the contract call call data. And then we have just a useful type that we will use when we parse the results once once we get them this network permitting. And so actually before I forget to do this, I'm going to swap out this dummy value into something real. Let's see transaction constants dot update withdrawal account. So these are just some these are just like some encoded contract calls that we to save time we encoded before this workshop. And so next we want to fetch data from four bytes. And that is going to start with a fetch call await fetch. Are we done? No, we're not done because we need to parse the transaction data first. And we are going to do let's see function signature is going to be equal to. All right, first we're going to do transaction data actually equals remove zero X. So we're going to it's zero X prefixed and we're going to strip that. And then the function signature is going to be the first eight bytes of the transaction data or sorry the first four bytes, which will. Let's see transaction data slice. There we go. And now we have the function signature as well. And in order to fetch from four byte, we need to do the API endpoint, followed by the function signature with a zero X prefix. And then we have some parameters to give this, which is going to be get. And we have just basic headers. I would already knew what I was going to do. Oh, sweet. And then if we fail to do that, we are going to throw. And we're going to say, failed to fetch from four bytes registry. But otherwise, we should be good to start working with this data. And the result is going to look something like this, where we get the JSON. And that's going to be a four bytes signature an array of four bytes signature results. And then once we have that result. So the thing there's one thing we have to deal with we're going to extract the actual text signature of the of the function call. And because four bytes is not a very big space. There are a lot of collisions so it might return multiple results. Anyone who's dealt with this with four byte in practice is probably familiar with this problem. And we're just going to pick the oldest one, because we need to pick something. And so we're going to see function text signature is going to be. Let's see result. And then we're going to sort created at locale compare e dot create it. And then we're just going to map that to you dot text signature. And so, and if there is no function text signature, then there is no signature for this. And so we're going to say, no function signature or no function. No results in registry for function signature. And then we're going to do an early return. But in the happy case, we are going to have our insights dot type. And we are going to give that a try next. And we're actually going to link as well just to ensure we have no problems with that. Okay, so going back, we're going to need to reconnect because we modified the snap. The library load unfortunately doesn't go all the way into the extension. Someday we're going to be able to do that. But now we see that the permissions are different. We have access to the internet as one of the permissions now. And we're going to go ahead and approve and install so far so good. And then let's see what happens now. This may be a lot to ask of the network at the moment. Yeah, the console does get very, the console there is, we probably have a bug where there is too much looping happening in the background. But if we were actually, if I reject this, I might get a useful. Okay, yeah, so I messed it up. And let's see what I messed up. No, the thing that was result is the thing that was undefined. And that hasn't happened before. I shouldn't know. All right, I'm going to cheat. Let's see. Thank you. Thank you eagle eyed stranger. Yeah, if I were, if I had, if I had done my types better, this wouldn't have been a problem, but that'd be a lesson to everyone. Okay, now we're going to try that again. There it is, there it is, the function signature, the function signature. And for our final trick, we're going to get a little bit fancier. We're also going to decode the actual parameters that are encoded in the call data as well, just because we can. And in order to do that, we are going to add a another package called ABI utils to our snap. Ooh, spooky workshop. And that's too much. Yeah, well, we'll let someone, someone will no doubt figure out the right level. And we have another snippet. If we increase the frequency there a little bit, like we can really create magic in here. And so this, and so this, this ABI utils package has an encode in a decode function, which allows you to decode an encode call data. And it has, it returns values that are not JSON serializable. And that doesn't work because the transaction insights need to be JSON serializable. So this is just a function that handles that. And we're not going to worry about what it does in detail. Decode parameters. And so we are going to import encode from Minimask, ABI utils, stupendous. And for this one, we need to, now we need to do some slicing because first we need to extract the actual parameter types from the function text signature. And we're going to do that by some good old fashioned string parsing. And so we are going to do function text signature. And it's going to be a slice and it's going to be an index of the first parenthesis plus one. My ID is leaking that I've already done this earlier today. And then we are going to split. Right, because if you, you'll recall that this looks something like a function name type one, type two, dot, dot, dot. So we're just going to extract this substring, split on the commas, and then we're going to have the parameter types. And the reason we need that is because that is an input to the decode function. So then we are going to decode the, let's see, parameter types. Let's see const decoded equals, and let's see, the next thing I want is, yes, now I want the transaction data without the function signature. And why wouldn't that work? Okay. And so that's going to give us the decoded stuff. And the, we're going to decode the parameter types out of the transaction call data. And just to make sure I'm going to cheat again really quickly. Normally I would have my notes off to the side. So you wouldn't know that I'm cheating. But but life is not fair sometimes. So we're going to set insights.params to decoded. We're going to map that with our value normalizer. And then we should be, now we should be in good shape. I don't want encode, I just want decode. Connect again. So that metamask loads our changes. We're going to send a message, open this up. Hey parameters. Address and Boolean, just as we would expect from the function type. And so now, and so this is, so obviously like we're not going super deep. And like just seeing the parameters here is not super useful. But the, but the point that that we're illustrating here is that like, you know, this snap is pretty much. Aside from it in forebite, like it's itself contained. It uses like very basic like utilities in order to like tell useful information. And obviously we could dig deeper into the call data. But like if we wanted to, or like fetch, you know, the compiled contract code and try to like say something about that. And so I mentioned one of the, one of the snaps that got built at the hackathon recently, and we've had a couple of these built so far by the community, which is just like snaps that do, they know something about contract security or have like a list of accounts that are unsafe and will display some information to the user when they're like, hey, like this isn't going to work. And you could just as easily imagine like you could even run ganache inside of a snap in order to simulate the transaction or like hit a tenderly endpoint or whatever like service that you imagine in order to add like useful data that you know about. And then MetaMask does not know about for any given contract interaction. And that is a wrap for the workshop and I am happy to take questions for the remaining time that we have. You were, you were fast. Oh, I really like it. And I definitely see a lot of use cases where I would use it. My only concern is that I often have to support other wallets. One base wallet, which to be honest, I don't like as much because it's out of source. So would it be possible for do you see other wallets implementing anything like this for do you see any support from like other tooling. The community users like either or support this or maybe in a way that if I'm in MetaMask, I have a snap but other places that's not from you. Right, right. And so the, so we are trying to create specifications for like the manifest and the apis that we ship and so on. We have a lot of work that I won't have time in progress that I won't have time to talk about. But like using something like wallet connect me to to like, you know, just like the, the dapple just ask for the network that it wants and then MetaMask will go and find the snap that supports it and add it as part of like the connection flow. So you don't have to like, call a specific snap in order to interact with it. And so we're trying to create specifications for those things. And I can't talk it like really about concrete plans at this point but personally like my, I would love to see snaps become like an open standard and like for there to be like an open source like wallet kernel or something that like others can build on in the future. Yeah, sure. And I think I saw you next. Yes, yes, correct. So there is so there is no marketplace as yet if anyone wants to build a marketplace we would love to see that being built because we don't want to be we don't want to have an app store. We want it to be like a full and open open permission less ecosystem. And so when right now, the way it works is like when a snap is published to npm, like if you have MetaMask flask you can install and run that snap and any website that like knows how to talk to it can just can talk to it. So, and once we get to stable, they're like, they're, you know, we're going to we're going to have like a essentially like a block list. If like there are no malicious snaps and things of that nature, but really in order for this to scale, there is going to need to be like a Yelp for snaps in order for people to like it be able to establish trust in them, because we do not want to be in the business of running an app store, because it's antithetical to the values of web three, and also it sucks as a job. Does that answer your question. Splendid. And I think you were next also. Yes. Yes, so, so that's like. So, recently, if you follow like news about app stores and stuff. There was an instance where like there are essentially two philosophy philosophies that you can use to approach it like the sort of walled garden app store approach that exists right now. And what we want to do which is a permissionless web of trust model. And so in the after model, it basically relies on like executive oversight and like review of the tenders of the walled garden, like for scams to not be presented, but like just the other week. I think Facebook reported to Google a list of like hundreds of malicious Android apps whose only purpose was to steal Facebook credentials. And so, even like with executive and oversight like it's impossible to fully prevent scams. And I think the best way that even in an app store model that you actually establish trust in something is you look who recommends this how many reviews does it have how many how long has it existed. And so, we, so that's like why we want a need a marketplace to exist in order for it to scale to users without them getting scammed. And until we get to that point. Our first release is probably going to have like a finite set of snaps that like, at least, you know, we can. We're confident, you know, our, you know, we're implemented rigorously. If they're managing keys, they, they were perhaps audited and like we know they're not like outright trying to steal your stuff. But like, but preventing scams in a like permissionless application ecosystem is not a fully solvable problem. But we think by building but but by investing in the community and in like a marketplace. We can get there. Next question. So mobile. So we've, mobile is a TBD. It's it's going we're we're working on it at no timelines to announce as of yet. No, they so so they are like the execution environment is the same the goal is for a snap to be unable to tell if it's executing in the browser in the server on a mobile device on an abacus like shouldn't matter. That's the that's the guarantee. Yes. Yeah, so so there are publicly released right now in a developer channel. So like you can download metamask flask and just like get started with the ones that exist in terms of release to stable we're targeting early next year. Yes. That is a great question kind stranger. And so we have like in the in the hack md. There are some links at the top that lead you probably. Yeah, no, yeah, it's locked whatever now it's on the hack md which is on the slides which are accessible through the schedule like on on dev con, but that metamask has a repository called snaps monitor. Repo that snaps dash monitor repo and the discussions in there are great place to get started. We also have a landing page on our website called metamask.io slash snaps that will also get you to a lot of the resources, but the get up discussions is a great place to get started. Yes. Yes, we are we are in touch with Google and are working with them to ensure that everybody is happy and we and we don't get banned from the Chrome store. How much. All right, I'm being asked to stop so I'm going to stop but thank you. Thank you everyone so much for attending.