# Connext 🛠 Build xApps with xcall - Eddie Ye

- Channel: [ETHGlobal](https://streameth.org/ethglobal)
- Date: 2022-10-09
- Duration: 57:49
- Topics: Science & Technology
- Watch: https://streameth.org/watch/yt-a5vKOVCozqY
- YouTube: https://www.youtube.com/watch?v=a5vKOVCozqY

## Description

Welcome Eddie Ye from Connext for a workshop titled "Build xApps with xcall". Start building cross chain applications with Connext's xcall primitive. 

ETHOnline is our biggest event of the year! Collaborate with thousands of developers and creatives from around the world and win over $300k+ in prizes! We're bringing in 30+ of the biggest teams in web3 to give you access like never before. Learn from ecosystem leaders and build your biggest ideas as the merge nears reality. The future of Ethereum is being written right now, and it's time to make your mark.

---------------------------------------------------
Follow us: https://twitter.com/ETHGlobal​
Check us out: https://ethglobal.co​m
Email us at: hello@ethglobal.com

#ethereum #web3 #blockchain #eth

## Transcript

[Applause] [Music] all right thanks for tuning into this workshop everybody i'm eddie an integration engineer at connext and i'll be running us through some context around connects and also jumping into some code to show you some examples and get you on your way to building your own crosstraining application so uh first of all i just want to make it clear that this workshop is relevant to the amarok network upgrade which is like connects v2 of our protocol and some of you may have already been aware of the v1 you may have already used the the bridge here which was originally called x pollinate this is a bridge ui that's built on top of the v1 protocol that allows users to transfer funds from one chain to another this v1 was built on the system of of the locally verified mechanism where there are two counterparties involved that kind of verify each other so there's no third party validators that are introduced into the system and so no additional trust assumptions so this kind of mechanism is very secure but there are some drawbacks and one of the major ones is that local verification doesn't support fully generalized data passing between chains and in a nutshell that means that you can't conduct authenticated cross-chain calls but you can do unauthenticated cross-chain calls like swaps on uni-swap since that function is not protected and anybody is allowed to call that function so what we really wanted to do for the last couple of months was to solve for this generalizability issue with our system and solve for other pain points that this affects like ux and basically pull the potential for crosstrain operations forward a bit and we actually found a way to do this through two major evolutions of the system the first part was how to figure out a way to enable the generalized data passing but also retaining trust minimization and so optimistic verification gave us a pathway here in this kind of construction which is used by optimistic bridges and roll-ups some arbitrary data is relayed from the origin train and a window of opportunity is given to off-chain actors to call out fraud so after that window passes and let's say no fraud is is called out the data is considered finalized on the destination chain so the beauty of this system is that it only relies on the uptime of any single honest actor at any point in time to prove fraud and that's a pretty reasonable assumption as scale but it also allows us the ability to check for authenticated data which is what's needed for fully generalized cross-chain calls but like with everything there are trade-offs and for optimistic verification it's latency because you need to allow watchers some challenge period to prove fraud it necessarily increases the latency of transactions so there's no way for this to be instant or even like immediate okay so step two is um was to this evolution was to figure out how to beat this trade-off space and the way we we can do it in a decentralized system is to introduce modularity since we never want to give up trust minimization but at the same time we want to have as many nice properties as possible we can actually separate the monolithic bridging stack into different layers that specialize toward different use cases so for transactions that require authentication like they need to check the origin of the transaction those go through the fully optimistic fraud window and then afterwards any arbitrary call data can be executed for transactions like a simple transfer of an erc for example a network of off-chain actors can actually determine that it's non-fraudulent it doesn't require authentication and then actually sort short-circuit the fraud window to provide fast liquidity without waiting for the full fraud window to pass so these two things combined is actually the basis of connects to b2 it's a modular interoperability stack that supports fast and slow liquidity based on the use case so how do we build on this well first it's probably important to introduce um the main interaction point with connect as a developer xcall xcall is a primitive that we created to sort of mimic the low-level call method of solidity um the call method of solidity passes data to another contract for execution and xcal basically just does that but for crosstrain so you can pass call data from one origin chain to another destination chain and have any kind of call data be executed on the chain okay so let's see this all in practice and the best way to actually do this is to start at our dock site so this is docs.connect.network um we're going to be diving into the developer quick start but if you want to explore the site a little bit basics will give you an overview of the system in general a couple of nice diagrams and a little bit of a deeper dive into what's actually happening under the hood but for the purpose of this workshop we're going to go right into the developer quick start and immediately you can see that we have two quick starts here one for a typescript sdk which you can use if you're trying to build like a front end or some kind of node application and there's also a contracts quick start which is fully solidity and this is what we're going to dive into mostly today since the sdk is generally just like a nice wrapper around some of these functions um we can explore most if not all of the considerations around xcalling through the the contracts only so with the contracts quickstart uh we have a couple of sections here with different kinds of x calls um and and uh different features like callbacks but you can you can go through this in your own time it basically covers what we're going to talk about during this workshop but it's always nice to see this stuff in practice so we're actually going to run through the code here and i'll do some explaining about what's happening with the code so we're going to look at the zap starter kit here and um you know after you've cloned this uh and [Music] you've taken a read through like the the readme the best thing to do is actually well actually let's start with the readme so this is a starter kit for crosstrains apps and we're describing like three different kinds of transactions that you can do but there are there's only really like two different categories one is uh without call data and one one is with call data so without call data it's like simple transfers like transferring erc20s from chain to chain um you're not supplying uh any encoded call data to be executed on the other chain so this can be easily easily pushed through fast liquidity the other category is with call data and so the other two examples in this repo are the unauthenticated and the authenticated cases which we already kind of like touched upon why there are differences there so we're going to jump into the simple transfer first because it's a really easy way to see what's going on with all the x call parameters and how you actually do an x call in solidity it'd be nice to kind of talk about this too if i can make it legible but this is basically what the high level flow of the next call is doing so you as a developer you're building uh [Music] most in most cases two contracts a source contract on the origin chain and a target contract on the destination chain the source contract is what your users are going to interact with or your zap is going to interact with and then the target contract is going to host the the function that you're actually trying to execute on the other chain what happens is the source contract is going to call xcall which is a function in the connex contracts and then connex is going to route that transaction through its network of relayers and routers and things that are happening under the hood and finally push that over to the destination chain to execute the the call data that you supplied it with so in the case of this like simple contrived transfer example we're actually only messing with a source contract and the reason is because as i mentioned this transfer is a is a call to x call that doesn't contain call data so if you don't have call data it's because you don't don't actually have a target contract on the other side to call and this is actually a really simple use case but it's actually one of the it's actually one of the most used ways that you'll probably use xcall because uh sending erc20s from chain to chain is um a really really foundational uh sort of operation so diving into this transfer um will be very useful for us so let's go ahead and do that i've already cloned the zap starter kit here locally and i've done some setup already that that will save us some time but i'm going to run through everything as if i hadn't so we're on main branch here and the way this is structured is let's look at the blueprint here there's a source file that contains all the contract interactions this maps to the contract quick start in the docs and then there's an sdk interactions which maps to the sdk quickstart so we're going to be looking at this right now under transfer the single transfer.solar contract so let's open that up yeah contract to contract interactions transfer and there's our contract so before we do anything let's actually make sure we set everything up so we run the make install um this is sorry before we do that uh we actually need to make sure that we have foundry installed so foundry is like a smart contract testing and deploying toolkit it's really fast and really nice a lot of people have been starting to use this and so even on our team we're starting to use foundry quite a bit to test our contracts and do a lot of things around deploying and verification so if you don't have foundry installed already i'm not going to walk you through it because there are some nice instructions already in their repository for you to do that and we'll also download make which is a build tool if you don't already have that so back to setup we're going to do a make install so make has a make file which basically uh which basically is like um sort of like a scripting um a scripting tool where you can write uh you can write different kinds of commands that you want to shortcut with make and so make install here is just actually going to run forward install and install all the modules that we've defined that we needed so the way that forge works is when you install um when you you can install different repositories and it will actually pull them in as sub modules so in your git modules folder file you'll be able to see that there's a bunch of these sub modules that are pulled in and nxtp is is the one that we're working with connects and that is the main one that we're going to be working with today so when you run the make install it's going to do a forge install it's going to pull in all those sub modules and we'll also want to run yarn to install some dependencies that we'll use since we're also using a little bit of hard hat for its tasking now the first step after that that you'll want to make sure to do is to actually copy the dynam example into a local.net so i've already done that here the dial-in looks like this you have an origin rpc you have a destination rpc and these are urls that you can grab after signing up with an rpc provider so this can be like alchemy or infuria and you'll also want to supply your private key of a wallet that you have some tested eth to work with and then either scan key here is pulled from etherscan.io it's just a way for us to easily verify the contracts and be able to kind of read and write from a nice ui that etherscan provides so after i filled out my.net it looks like this uh obviously my rpc keys and my private key are burners so you know you can feel free to hack me but uh the only thing that will happen is i'll be a little sad that i'll ask some test that eve and once we have this filled out we can basically just run these unit tests and make sure that everything works right off the bat so these unit tests are using forge and they're going to be in this test folder here so everything that has to do with the transfer smart contract is going to be in test slash transfer the test the test contract is going to be here and we're not really going to walk through a lot of the forge testing like syntax and and stuff like that because um it's probably better for you to do that on your own and and also do a little bit of a deep dive on how to write good tests but this will be a nice start to look at and we can see that all of these tests actually ran successfully so we're pretty good to start with here okay so another thing to consider is writing integration tests so we can run this as well but just as an explainer of what this is doing it's using forge's forked mode so um the forked mode is basically creating a local copy of a blockchain based on the rpc that you're providing so in this case we're going to provide the testnet origin rpc url defined in our end file so what it's going to do it is it's going to create a local version of the optimism gorly blockchain and uh we're assuming that this blockchain already has the connects to contracts deployed to it which is true and so when you fork this blockchain it has the connects contracts and all of your tests that point to the address of the connects contract are actually running against uh a fully like emulated version of that contract so we have a couple of a forked integration tests that can be run using this command and it's actually the unit tests and the integration tests are all in the same file so if we scroll up here the transfer test unit is a contract that contains all the unit tests and then transfer test forked is a contract that contains all the fork tests so in our make file when we're running these test commands it's just matching uh this um this string and then running the the contracts the the test contracts against the match so that's the difference between running the unit tests and running the fork tests um okay so before we get the deployment um i'm actually going to want to dive into the the transfer contract code here so as i said before this is like a really really simple and contrived example but it shows you how to actually do a cross chain call and um it's actually relatively nice because you can see the flow of an erc20 from an origin chain to a to a destination chain so what's happening here is we've defined this transfer contract um we've also defined this event here which we'll emit later for just you know for tracking and for testing purposes and we also have a variable here called the conext and it is a type interface connects handler so we pulled in this iconx handler from the nxtp repo and we also pulled in call prems and x call args which are crucial structs that we need to build in order to make the x call later on we also pulled in an erc20 from soulmate just so that we have a token that we can work with and in the constructor here we're going to pass in the address of the connect handler on the chain where this source contract is going to be deployed to so basically this this transfer contract is going to x call uh into the connect contract xcall is a function of the connects contract so we need to pull that in here so the only actual function that exists here is this transfer function and it's going to take in the destination address which is like the wallet address that you want to send the funds to on the destination side it's going to take an asset which is the erc20 that we're trying to send and then it's going to need a reference to the origin domain id and the destination domain ids that we're working with so these are similar to chain ids but they're different um in the sense that every bridge kind of has their own mapping of domain id to train id and for connects that's no different we have this number that maps to the gorly chain and then this number that maps to the optimism gorly chain so these are values that you just have to that you just have to look up and we have a reference to that in our documentation that you can easily reference so um back to the docs page we have a testnet reference we will recommend for everybody to build on the production testnet contracts since staging is mostly you know there's no guarantees that's stable and it's mostly for internal team testing purposes so if you open up the production test.net contracts you'll see that we have gorilee and we have the optimism girly here and the chain id and the domain id so for most of the x call stuff we're going to be caring about the domain id because these are connect specific ids so these are what we would be passing in to the function calls here so origin domain we're going to use so we're actually going to use um optimism gourley as the origin here and we'll use gourley as the destination for uh for for running the stuff today all right so in this in this function we're instantiating the erc20 token with the address that we passed in of an already deployed token and we're immediately checking that the user has already approved some allowance of the amount that we're sending over so this is assuming that the user has gone to the token contract in some way and basically said hey i'm going to allow the transfer contract to use my funds and send it to connext because the flow of the funds here is that the user sends it to the transfer contract the transfer contract which is happening here with this transfer from and then the transfer contract approves the transfer to connect contract and then the connects contract is going to take those funds and send it across to the other chain so there's like two approvals that have to happen um and this contract is assuming that the user has already approved so that's what that requires doing and this function will reverse if that's not the case and then the token will be transferred over to the this transfer contract and then this transfer contract will approve it we'll approve the transfer to connect and here's where basically all the exciting stuff happens so we've pulled in the call primes already this structure that i mentioned before we can kind of click into it to see what um what what are the fields in the struct so we can kind of ignore most of these for now we're going to swing back to these and kind of deep dive into what all of them mean but for now the important ones are the two field which is what we already passed in like the destination wallet that is to receive the funds and this could be the same address as the user that's interacting with the contract which is usually the case actually so if you're trying to send funds and you're interacting interacting with a contract to do so you're usually trying to send it to yourself on the other side so that's why we're passing two in here call data is empty because again we're not messing with call data here we're just sending funds and then origin and destination domain are passed through the rest of these will swing back to in a moment here so x call args is the other struct that is the is actually the only argument that's passed into x call later on so x call rx just kind of wraps call params and it also has a field for the actual transacting asset so the address that we passed in and uh the amount that is to be sent so also the amount that we sent in over there and we'll also dive into this origin out a little bit later but essentially once you've put all these fields together and if you're sending funds you do this like approval dance uh all you have to do is say connex.x call and pass those parameters in okay so let's let's actually deploy this contract and see it in action so to do this we're going to consult the readme again and you can see that there are there's a deployment command for this so we'll copy that pull up a terminal here and we will just fill in the field the placeholders that we have so this one is nice and easy it's only asking for the address of the origin connect handler so remember that this is a constructor argument we are passing in where is that we're passing in the address of the connects handler and that's why we need to supply it here so again we will go back to the docs here and remember i said that we're going to be using optimism gourley as the origin chain so we're gonna we're gonna go under optimism gourley and look for the connects handler address which is this paste that in send it off and forge will do its thing okay so you can see that it's doing uh some stuff to actually deploy it and at the end here it'll give you a transaction hash of the deployment transaction as well as the contract address itself so we can take a look at this on the optimism gourley explorer so here's the contract it is deployed we see contract creation success it's all good so this is our transfer.soul on the actual optimism gourley testnet blockchain and what we really want to do now is we want to hit this transfer function with all the right parameters which should send off an x call and we want to be able to see that this token flow is going from my wallet to my wallet on the other chain so consulting the readme again we have actually a way to do this sort of live test testing with uh some hard hat tasks so we'll copy this paste that in and then okay so my recording cut off but we'll continue from exactly where we were basically i just filled in these values so origin domain we got that from the testnet reference origin being optimism gourley so we took this origin domain we paste it in here same thing for destination domain we scrolled up here and pasted that in and then for the contract address this is the transfer ad this is the transfer contract that we just deployed so the one here and then the token address is the token on the origin side so back to optimizing gourley the test token 680 we pulled that in here and then private key from the dot end and then amount this is exactly one test token so hopefully when we run this i'm going to take a note of how i have one test in my optimism gourley account and then in my gorly account i have 99.9 so i should see one test basically flow from optimism gourley to gourley and we'll send this off and twiddle our thumbs for a little bit while we wait and we can see that it's going to mint again to my origin account so i should still have one test at the end of this it's doing the approval again and you know you can actually approve like a max amount so it doesn't have to always do this approval but um this task is handling it anyway so that doesn't matter uh the transaction hash is in and we got a successful transfer so before we take a look at the wallet i want to show you how to actually track the status of this x call so it's in flight right now technically right so if we go to tracking an x call we have these sub graphs so we deploy a subgraph for every domain and these are basically like off-chain indexes that keep track of events that are emitted from contracts and these are not stored on chain these can always be queried off-chain and stored in an efficient manner so these sub-graphs allow us to kind of query for events and we have some example queries here and links to the sub-graphs for each chain so we're going to look at the origin chain first this subgraph and we're going to take the query and we'll paste it into the query tool here and it's going to want that transaction hash so copy that over paste it in send it off okay awesome so the subgraph captured this subgraph captured the event from from the origin chain so we can see that the chain id was 420 which maps optimism we have a transfer id which is very important for us in a second here and you can see that it has a bunch of other fields that might be interesting to you you might want to sanity check that the transacting amount you sent was correct that this was the right erc20 but this transfer id is really what we were looking for so this is a unique id tracked across the connect system and it's a unique id for each x call so with this you can actually track you can key into any any of the events that are emitted with the transfer id and basically track the the flow of that x call so if we go to the origin subgraph now and we copy this query that's already available and we paste that in and then you'll notice that this one wants a transfer id so we'll copy the transfer id and paste that in and because this is fast liquidity the transfer has already shown up on the other side so this status here it says executed this means that the the execution of this x call was completed on the destination chain and so my wallet now should have on gorilla one more test than it did so it was at 99.9 now it's at 100.9 cool so if you look through some of the some of the fields here you might notice that the transacting amount this time on the destination side is actually 0.05 percent less exactly and that's because routers the liquidity providers in our network take a small cut for their troubles of uh helping to relay your transaction across so what happens with fast liquidity is that we're not we're not exactly circumventing slow we're not exactly circumventing the the fraud window completely somebody has to take that lockup and the routers end up doing that so what the routers do is they have liquidity on the destination side that matches what a user wants and they say hey okay i can provide you this liquidity up front and basically just front the capital for you so the user ends up getting their funds immediately or almost immediately on the other side which was evidenced by this execution while the routers take they take up the the fraud proof lockup so for their troubles they will eventually get reimbursed but for their troubles they do take a 0.05 percent fee of of that x call and i wanted to run through the subgraph because the subgraph is really nice you can build things on top of the events that the subgraph saves and so you know now i'll make your life a little bit easier by showing you the the testnet amrock connect scan ui where you can actually provide a transfer id in the scanner site and we have like a little ui that shows you the transaction status so it was x called it was executed as yet to be reconciled the router is still in the lockup window and they haven't been reconciled yet but the user is done their their involvement here is complete at execute and they've sent their funds and they've received their funds across the chain and it took all but three minutes cool so that basically sums up the transfer contract before we go into the with call data examples i just wanted to dive into some of those other x call params so i skimmed over these because most of them were they didn't really matter for this case sort of like safe defaults that we have but i do want to dive into them so for agent here uh we're passing in message.sender because this is the address that's allowed to execute the the transaction on the destination side um what happens normally is we actually have a network of another network of off-chain agents called relayers that are they're basically the ones that are helping to do the execution of the call data on the destination side because somebody has to somebody has to do that somebody has to initiate the transaction so when you send a transaction to the other side a decentralized network of relayers where using gelato for this purpose will actually do the execution and normally the the relayers will want to take a fee for that as well because um they're going to have to pay gas and and whatnot but you as the user who's sending the x call you can also supply a agent and in this case we supplied the message.sender to the user themselves um in case the relayers don't execute so you can always execute this yourself pay the gas fee yourself potentially pay a little bit less gas fee because you're paying for like the um you're paying for the uh the relayers to do this on your behalf so it's something that they have to do and you kind of have to you you pay them a little bit to do that and so that really if you comes into play here but on test that our relay gelato is not taking any fees just to make experimenting a little bit easier and building a little bit easier but on mainnet and and beyond when we launch relayers will expect this to be enough to cover their costs so not only cover their costs in in terms of gas but also to give them a little bit bump a little bit of a bump for for their troubles um so that's agent and that's relayer fee and then for recovery this is a fallback address so in case the execution fails on the other side so let's say the uh the contract that you're calling was not implemented correctly or the call data you're passing in is not correct then it might fail on execution and if you sent funds along with that x call if you don't have a recovery address then those funds could potentially just be in limbo forever so you you have a recovery address which connects will automatically send the funds to in case of reverts on the destination on the destination side so for slow here is related to this fast path so this is an option for the user to say hey uh actually i don't really want i don't really care about um getting this quickly so i don't want to pay routers the 0.05 fee i'd rather keep all of the funds and just wait out the optimistic fraud proof window and they can totally do that you set this to true and instead of this transaction having taken three minutes and executing like almost immediately we would still be waiting for it to happen but it's up to the user's discretion you know how how fast they want those funds and whether they care about saving on that fee receive local is is a pretty complicated one so this kind of involves diving into the different types of assets that are in a bridge's ecosystem why don't we go ahead and do that because we have a diagram in the documentation here it's in the faq and basically i'm not sure if this is big enough but oh here we go so we have a couple of different asset terminologies here canonical representation adopted and local what do they all mean well the parameter here is receive local okay so keep that in mind so uh basically what what bridges do when they send tokens is they're not actually giving you the exact erc20 token that was deployed on one chain and then giving you the exact one on the other chain so there's always this concept of a canonical a canonical domain for the asset so the canonical asset is always the one that was originally deployed so in token 1's case in this example the canonical asset is in domain b so this is the canonical asset in token two's case the canonical asset is in domain a so when you bridge this token over so let's go from domain b to domain c with token one the bridge is actually locking this token up and minting a representation of it on domain c so what the user gets or you know what the user going is going to be delivered by the bridge is a representation asset and sometimes this asset is actually different than the asset that is used often on that chain so if connects bridges [Music] let's say it connects to bridges like usdc over and there's like a next flavor of the usdc it might not be the case that next usdc is the exact erc20 that's used in most d5 applications on that chain or that users like you know want to use so there might be another flavored version of usdc on that chain that's mostly adopted by users so that's what we mean by an adopted asset and in this case we want to deliver to the user the token that they actually want to use and it's usually going to be the adopted one so what happens is under the hood connext also has a amm that is basically a stable swap between the different bridge flavors the connects flavored asset and the adopted asset so at the end at the end of the x call before the token is delivered to the user it'll actually be sent through an amm which can incur some slick slippage and then the user will be delivered the adopted asset and in some cases uh the let's say in token 2 case here from a to b the next flavor version of this token on domain b is actually the adapted version so maybe everybody is using the the next token two on all their dapps and so in this case there is no need for inmate for an amm and there's uh no no need to incur that slippage so the user gets exactly the token that they want and they're cool with that but in these cases where in these cases where the token is actually not the adopted one they can say hey i actually either don't want to incur this amm slippage or i actually prefer to have this next flavored version that's where this parameter comes in that's where this receive local can be set to true and then the user will actually receive the the bridge flavored asset instead of the adopted so this is a way for them to kind of manage their own swapping across an amm if you know maybe the amm there that we would use under the hood with k'nex is not one that they want to use or they want to wait um for the slippage conditions to be favorable for them uh they can always select to receive this local bridge flavored version rather than the adopted okay i think the last one here or the last two here are related to the callbacks so callbacks are another really cool feature that we've introduced very similar to asynchronous programming where you have a function call it goes off to fetch a remote resource and you don't want to halt everything that you're doing to to wait for it so in asynchronous programming the callback is a function that will be called once that resource is is is fetched is completed so in this case the callback is the latter part of that sort of flow it's the it's the function that can be called if you choose to supply one after the destination side has been executed so this can be really useful if you [Music] want to want to confirm on the origin chain that something happened on the destination chain so you know you uh we'll dive into an example of this later but essentially this is the way for you to respond to results of the execution on the destination chain and the callback fee is uh basically the same thing as a relayer fee but for the backward direction so whereas the relayer fee you're paying for the execution on the destination chain the callback fee you're paying for execution of the callback awesome so let's take another let's take a look at the with call data examples and actually if we look at the readme you'll see that uh this we have the unauthenticated and the authenticated versions and they're both using the source and target contracts uh in the repo so uh these ones get a little bit more complicated but it's also really nice to dive into and see what we're talking about so with these examples we are going to be using call data so [Music] again it's going to be a very contrived example and there are some example use cases for why you want to use call data it's it's pretty obvious honestly and why you would want to use authenticated calls but for this we're just going to look at the code directly so we'll go into the with call data we'll actually start from the target contract so let's do this let's pull up the target contract and basically the goal here is uh now very similar to this diagram where we are going to be deploying a source contract and a target contract the target contract has the function that we want to call from source so in this case the target contract has a function that we want to call so let's start with the unauthenticated there's an update value an authenticated function that takes in an integer and basically updates this state variable in the contract with the new value that's all it does for the authenticated version it does the same exact thing but we'll get into that why that's a little bit different so for unauthenticated that's basically it for the target contract the constructor is going to take in uh well actually let's let's pause on this let's look at the source now now knowing what the target function is so the source contract is um going to pull in the same things as the transfer example um it's we're going to ignore this callback stuff uh until we get into the callback stuff later but it's going to also and we're also going to ignore promise router things because that's also callback related but essentially now it's like the same thing as the transfer contract you pull in the connects to address you give that as the constructor argument and then the function that we're calling here is now a next chain update instead of a transfer we're still taking the same thing we're taking a 2 address the origin domain destination domain and now a new value and whether this call should be authenticated or not but since we're looking at unauthenticated we're going to assume that we're passing false here so now the differences are um we are no longer going to pass any we're not we're not going to send any funds in this so we don't have to send any amount and we don't have to do that whole approval dance with the funds so we're only sending call data in these examples what happens is um you have to encode the call data and you have to know the what the selector is on on the target function so there's a nice way to kind of do this using the ketchup function you pass in the name with the the function signature of the target and that's basically like your selector and then this abi is able to encode that selector with the new value that you pass in so at the end of all this the call data here is encoded call data that is going to be executed on the target chain and what's going to be executed is uh this selector that you've that you've selected and the value that should be passed in so the x call the x call args the call params um all this is basically the same just the arguments change a little bit so the 2 here is now still going to be passed in but when we call this function the 2 has to be the address of the target a contract not the um the wallet address for example of the the last thing that we just walked through and then the call data is what we're just passing in through here encoded call data same for origin domain destination domain uh same things for the agent and recovery for slow now has to be um well actually for slow for the unauthenticated example is uh very similar to the transfer so we can choose whether we want to take the the slow path or not but in this case um we're just we're just we're just going to pass in false for the unauthenticated example so it will go through the fast path and then for receive local uh we're not going to you know we're not even messing with funds here so we're not even messing with tokens here sorry so we're going to keep that as false and then call back we'll ignore that for now and then call back fee with the airfare all zeroes for testnet and i actually realized that i didn't touch on the destination min and origin min out but in this case they're zero because we're not messing with funds however for the transfer case uh these were amount divided by 100 times 97 so essentially we were saying that the user would be okay with a three percent slippage here if that were the case so three three percent or more um then the transaction would revert on the other side and then this would basically be the slippage for the amm uh on the other side on the destination side and then this would be the slippage for the amm on the origin side because recall that there are actually two um two potential amms one from the token going going out and then one from the token going in on the destination side this diagram doesn't show it but if you imagine the if you imagine sending from domain a to domain c the user could be sending the adopted token here going through the amm which is the destination uh which is the origin min out and then having that also have to pass through the amm again on the other side which is the destination out so there's two kind of like slippage numbers here that could potentially apply um sorry so back to this we are done with these call prems the only differences were really the oh sorry these call params the only difference is really where the call data and the two address has to be the contract and then we pass all this in we um we're not sending assets so we can just use the zero address here zero for the amount 0 for the slippage and then we call x call again so now this contract we have to deploy the source and we also have to deploy the target i'm not going to run through those now because it's basically the same flow and the commands are essentially the same here so if we scroll down to deployment again you'll see that now instead of deploying one contract we deploy two and for testing we're also just going to use this hard hat task so it's going to do it's going to call that update function we're passing mostly the same things but now a new value to update and when after you've deployed these contracts and you call this function uh it should basically do all this stuff of encoding the call data and sending it through xcall and for the unauthenticated example it's basically going to have the same sort of timing since we didn't pass for slow equals true there and if we were to look at you know the subgraphs again we would see that it's executed but now uh we would be able to look at the target contract and see that this value is updated um so we might record some more videos actually show this one in action but already this this one's getting a little bit long so you can try this out yourself you can look at the deployed target contract on ether scan and check that the value is actually updated to whatever you you wanted to update it with and remember that variables in solidity are instantiated with zero so this value is originally going to be zero and you should pass in anything but that to check the difference um yeah and that'll be really cool to kind of run on your own and then the other thing the other one that i wanted to run through is the authenticated example so for this case after you've deployed source and target it's actually really nice all you have to do is call all you have to do is call this what am i looking at all you have to do is call this updated value authenticated function instead of the other one and what it'll do is and to do that is to call x chain update but pass in true for authenticated so you'll see that with this if statement if it's true it's actually going to call the authenticated version rather than the unauthenticated version and everything else is the same so however so with the authenticated version a couple extra things come into play so for target in order to uphold this like authentication and make sure that the origin is actually um that the origin sender was actually the sender that you're expecting and that it came from the right place you should write a modifier such as an only executor modifier here that checks for the origin sender and the origin domain and checks against what the contract knows is the origin contract in the origin domain so when you deploy this target contract you're actually going to pass in the origin the the address of source and the origin domain of the source so that you can always check those values and the difference here is that you're also going to pull in this library that we have which has a dot origin sender and a dot origin after you pass in the message.data to these functions it'll be able to tell it will tell you who the origin sender was and who the and what the origin was so after running these checks in a modifier you can be pretty certain that these were from the right place and then the last one the last check is to make sure that the message sender of this of this target this target function's execution was actually the connect to executor so the connect executor is just another contract it's just another part of this flow that we kind of didn't really touch on but it's not like the end part of this flow that does the actual execution and we want to make sure that it's only the connect executor that does that because anybody else if you don't check this anybody else could send a transaction to this function and kind of like spoof these values so you need all three of these um to uphold the authentication if you have any on the target function and uh for us the authentication is in the form of this like only executor like we're only allowing uh the origin sender as the source contract so what this does effectively is say nobody else can update this value through this authenticated function except for the source that sold contract on the origin domain that we expect it to be in and yeah that is pretty much it i know that last part was a little bit hand wavy but i think that going through this example yourself and actually reading through the starter here will you'll get to a very good understanding of what's happening there and the authenticated calls are where things get exciting because uh then you're able to do things like changing dow ownership contracts cross-chain and many other exciting like functionalities that aren't enabled by just like public functions right so that's going to be in the contracts quick start and you'll want to go to authenticated here this should be able to run you through the full examples and you should be able to run that on your own actually i realized the last part that i did not touch upon is the callbacks and i think this might be an important thing to not miss so the callbacks here are basically um when you so you'll notice that in the transfer contract we we said that address 0 was the callback because we don't expect to use the callback function but here we're actually passing this address the source address as the contract that implements the callback and you'll see if you scroll down a little bit that there is a callback function which is part of the i callback interface so any contract that is going to is going to implement the callback has to implement it with this i call back interface and callback is one of the abstract functions defined there so what we're saying here is the source contract is also going to be the implementer of the callback so when the value is updated on target it's going to return this new value and that new value is actually going to be sent back to the origin domain to the source contract and handled by its callback function here so data is going to include that return data so what we can see is that new value now we just have to decode that data and we get the value that was updated over here so this is what i mean by you can confirm that things happen or you can like pass pass state back from the destination domain after something has happened so this is a really neat piece of functionality that will require basically understanding everything else in addition to the callback stuff because you'll need to use everything including the callback fees but it's really an interesting way to to basically have state and data passed backwards through the call as well as forwards and again we're not going to run through that today because we're kind of low on time now but the callbacks example here will run you through how that works what the differences are between the code of using a callback and not and you'll be able to kind of track you'll be able to track the status of those x calls as well and it'll be really really cool um cool so i think that basically covers what we wanted to cut what we wanted to talk about today um the last the last last part of this is just to uh shill the k'next ether online hackathon prizes that we're sponsoring and so basically if you want to build anything crosstrain please please consider using these x calls and you can win um some some some fat stacks i believe the prize categories are um one category just for any like generic uh use of cross chain so build a unique application and make sure it's using uh cross chain functionalities that we expose through connect and then the other category is if you see a protocol that's only on a single chain at the moment that could benefit from being cross chain go ahead and fork it and add in an x call and see if you can augment that protocol to be cross chain compatible and then the third prize pool is actually a shared pool between all hackers that even attempt to run an x call so you know fork this repository uh read through the the starter examples and and run the x call and if you are a hacker with a registered uh wallet with uh youth global and you do a successful x call everybody that does so will basically split that pot awesome so that's basically it i hope you guys learned a few things and i wish you the best of luck
