diff --git a/docs/evm/cadence/batched-evm-transactions.md b/docs/evm/cadence/batched-evm-transactions.md
new file mode 100644
index 0000000000..2c70ef9ee5
--- /dev/null
+++ b/docs/evm/cadence/batched-evm-transactions.md
@@ -0,0 +1,737 @@
+---
+title: Batched EVM Transactions Using Cadence
+sidebar_label: Batched EVM Transactions
+sidebar_position: 6
+---
+
+Integrating Cadence into EVM applications on Flow enables developers to leverage the best of both worlds. This guide
+demonstrates how to batch EVM transactions using Cadence, allowing applications to embed multiple EVM transactions in a
+single Cadence transaction, conditioning final execution on the success of all EVM transactions.
+
+This feature can supercharge your EVM application by unlocking experiences otherwise impossible on traditional EVM
+platforms.
+
+## Objectives
+
+After completing this guide, you'll be able to
+
+- Construct a Cadence transaction that executes several EVM transactions such that if any EVM transaction fails, the
+ entire set will revert
+- Read and write from smart contract functions on [EVM Flowscan]
+- Run a Cadence transaction from the browser using [Flow Runner]
+- Install conceptual understanding of Cadence X EVM interactions
+- Inspect multiple EVM transactions embedded in a Cadence transaction with [Flowscan] block explorer
+- Write code that interacts with the EVM via a COA
+
+## Prerequisites
+
+Before you dive in, make sure you have the following configured:
+
+- [MetaMask] installed in your browser with an active account
+- [Flow Wallet extension] installed in your browser with an active account
+- Both wallets funded with Testnet FLOW. See the [Faucet guide] for more information.
+
+## Overview
+
+For the purposes of demonstration, this walkthrough will focus on relatively simple EVM operations in addition to first
+creating a [Cadence-controlled EVM account (COA)]. Specifically, we will:
+
+- Wrap FLOW as WFLOW
+- Approve an ERC721 to transfer WFLOW in exchange for an NFT mint
+- Mint an ERC721 token - this ERC721 has a 50% chance of failing (using [onchain VRF] to determine success)
+
+These operations let us focus on the **core concepts** of this guide:
+
+1. **Batching EVM transactions** using Cadence
+2. **Conditioning execution** on the results of those EVM transactions.
+
+However, using these same principles, you'll have the power to address much more complex and interesting. For instance,
+replace wrapping FLOW with a DEX swap. Or instead of minting an ERC721, purchase an NFT listing from a marketplace.
+Combine these two and suddenly you can purchase NFTs with any ERC20 token, all in a single Cadence transaction,
+reverting everything if a single step fails.
+
+The point is, while a simple use case, this guide will give you the tools to build much more complex and interesting
+applications. So let's get started!
+
+## Components
+
+As mentioned in the [Overview], this guide involves three main actions:
+
+- Wrapping FLOW as WFLOW
+- Approving an ERC721 to transfer WFLOW in exchange for an NFT mint
+- Minting an ERC721 token
+
+Before interacting with these contracts, let's dig in a bit more into the components of this guide.
+
+### Wrap FLOW as WFLOW
+
+On Flow EVM, FLOW is the native currency and similar to other EVM platforms, the native currency is not accessible as an
+ERC20 token. To interact with ERC20 contracts, you need to wrap FLOW as WFLOW (Wrapped FLOW). This is Flow's equivalent
+of WETH on Ethereum.
+
+:::tip
+
+You can find WFLOW deployed to `0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e` on Flow [Testnet] & [Mainnet] and source
+code in the [`@onflow/flow-sol-utils` repository].
+
+:::
+
+### Approve ERC721 Transfer
+
+Our example `MaybeMintERC721` contract accepts WFLOW in exchange for minting an NFT. However, the contract cannot move
+WFLOW without your permission. To allow the contract to move your WFLOW, you must approve the contract to transfer
+enough of your WFLOW to mint the NFT.
+
+### Mint ERC721 Token
+
+Finally, we'll mint an ERC721 token using the `MaybeMintERC721` contract. This contract has a 50% chance of failing,
+simulating a real-world scenario where purchasing an NFT might fail - say a listing was purchased before your
+transaction was processed.
+
+Importantly, if this transaction fails, we want to revert the entire sequence of transactions. After all, you wrapped
+FLOW to WFLOW and approved the ERC721 transfer specifically to mint this NFT. If the mint fails, you want to unwind
+everything. This is where batching EVM transactions using Cadence is extremely powerful.
+
+## Interacting with the Contracts
+
+Before taking the easy route, let's first interact with the contracts individually to better understand the process and
+status quo user experience. Realistically, this is your only option for completing the whole process on other EVM
+platforms.
+
+:::tip
+
+Recall in [Prerequisites] that you need to have both MetaMask and Flow Wallet installed and funded with Testnet FLOW.
+Make sure you've done so before proceeding.
+
+:::
+
+### Using MetaMask
+
+#### 1. Wrap FLOW
+
+Our first action will be to wrap enough FLOW to cover the cost of minting the `MaybeMintERC721` token. To do this, we'll
+interact with the `WFLOW` contract on Testnet. There are a number of ways we could interact with this contract - Remix
+IDE, Foundry's CLI, Hardhat, etc. - but for the purposes of this guide, we'll use the [Flowscan EVM block explorer].
+
+Navigate to the WFLOW Testnet contract on Flowscan: [WFLOW]. Ensure you're on the `Write Contract` tab which allows you
+to interact with the contract's mutating functions.
+
+Before you can interact with the contract, you need to connect your MetaMask wallet to the [Flowscan EVM block
+explorer]. Click the `Connect` button in the top right corner and follow the prompts to connect your MetaMask wallet.
+
+:::warning
+
+There are two **separate** block explorers for Flow - one for Cadence activity and another for EVM activity. This is
+unique to Flow and is due to the fact that Cadence & EVM are separate runtimes, with EVM effectively emulated within
+Cadence. This orientation - that of EVM running within Cadence - means that the Cadence-side explorer has visibility to
+EVM transactions embedded within a Cadence transaction.
+
+Practically, this means that any transactions ran using a Flow account can be viewed on the Cadence explorer while any
+transactions run using an EVM account can be viewed on the EVM explorer.
+
+:::
+
+![Connect wallet to Flowscan](./flowscan-connect.png)
+
+Once connected, you should see your address in the top right corner and above the contract's functions.
+
+Now we can wrap FLOW. Click on the `deposit` method which will drop down an input field for the amount of FLOW you want
+to wrap. The mint amount for the `MaybeMintERC721` contract is 1 whole FLOW which in EVM terms is `1e18 wei` - `wei`
+being the smallest unit of an EVM's native currency (inherited from Ethereum's units - more on Ether units [here]).
+
+As shown below, put `1 000 000 000 000 000 000` in the input field for `deposit`.
+
+![Deposit 1 FLOW to WFLOW contract](./wflow-deposit.png)
+
+You can now click the `Write` button to submit the transaction. Once MetaMask prompts you to sign the transaction, click
+`Confirm` and give it a few seconds to process.
+
+
+![Confirm WFLOW deposit in MetaMask](./wflow-deposit-confirm.png)
+
+
+Once confirmed, you should be able to see WFLOW balance in your tokens list in MetaMask - if not, you can click on
+`Import Tokens` and paste the WFLOW contract address found on the Flowscan page and refresh your list.
+
+
+![WFLOW in MetaMask](./wflow-in-metamask-tokens.png)
+
+
+#### 2. Approve WFLOW Transfer
+
+Now that you have your WFLOW, you'll need to approve the `MaybeMintERC721` contract to transfer your WFLOW. From the
+same WFLOW page in Flowscan, click on the `approve` method. This time, you'll need to input the `MaybeMintERC721`
+contract address - `0x2E2Ed0Cfd3AD2f1d34481277b3204d807Ca2F8c2` - and the amount of WFLOW you want to approve - again `1
+000 000 000 000 000 000` WFLOW.
+
+![Approve MaybeMintERC721 for 1 WFLOW in Flowscan](./wflow-approve.png)
+
+Click `Write` to submit the transaction. To be clear, this does not complete a transfer, but allows the
+`MaybeMintERC721` contract to transfer your WFLOW on your behalf which will execute in the next step.
+
+#### 3. Mint ERC721 Token
+
+Finally, we'll attempt to mint the ERC721 token using the `MaybeMintERC721` contract. Navigate to the `MaybeMintERC721`
+contract on Flowscan: [MaybeMintERC721].
+
+Again, you'll be met with the contract functions on the `Write Contract` tab. Click on the `mint` function which takes
+no arguments - just click on `Write` and then `Confirm` in the resulting MetaMask window.
+
+This contract has a 50% chance of failing on mint using onchain randomness. If it fails, simply mint again until it
+succeeds.
+
+On success, you can click on your NFTs in MetaMask to see your newly minted token.
+
+
+![MaybeMintERC721 in MetaMask NFT list](./maybe-mint-in-metamask.png)
+
+
+#### Recap
+
+This process is cumbersome and requires multiple transactions, each of which could fail. Given the intent of the process
+- minting an NFT - if this were a case where the NFT was a limited edition or time-sensitive, you'd be left with WFLOW
+wrapped and approved for transfer, but no NFT and would need to manually unwind the process.
+
+Or you could just use Cadence to batch these transactions and revert everything if the mint fails. Let's do that.
+
+### Using Flow Wallet
+
+Before diving into the how, let's execute the batched version of everything we just did using Flow Wallet. This will
+give you a sense of the power of Cadence and the Flow blockchain.
+
+The transaction below, like all Cadence transactions, is scripted, allowing us to execute a series of actions. It may
+look like a lot at first, but we will break it down step by step in the following sections.
+
+
+
+wrap_and_mint.cdc
+
+```cadence
+// TESTNET IMPORTS
+import FungibleToken from 0x9a0766d93b6608b7
+import FlowToken from 0x7e60df042a9c0868
+import EVM from 0x8c5303eaa26202d6
+
+/// This transaction demonstrates how multiple EVM calls can be batched in a single Cadence transaction via
+/// CadenceOwnedAccount (COA), performing the following actions:
+///
+/// 1. Configures a COA in the signer's account if needed
+/// 2. Funds the signer's COA with enough FLOW to cover the WFLOW cost of minting an ERC721 token
+/// 3. Wraps FLOW as WFLOW - EVM call 1
+/// 4. Approves the example MaybeMintERC721 contract which accepts WFLOW to move the mint amount - EVM call 2
+/// 5. Attempts to mint an ERC721 token - EVM call 3
+///
+/// Importantly, the transaction is reverted if any of the EVM interactions fail returning the account to the original
+/// state before the transaction was executed across Cadence & EVM.
+///
+/// For more context, see https://github.com/onflow/batched-evm-exec-example
+///
+/// @param wflowAddressHex: The EVM address hex of the WFLOW contract as a String
+/// @param maybeMintERC721AddressHex: The EVM address hex of the ERC721 contract as a String
+///
+transaction(wflowAddressHex: String, maybeMintERC721AddressHex: String) {
+
+ let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount
+ let mintCost: UFix64
+ let wflowAddress: EVM.EVMAddress
+ let erc721Address: EVM.EVMAddress
+
+ prepare(signer: auth(SaveValue, BorrowValue, IssueStorageCapabilityController, PublishCapability, UnpublishCapability) &Account) {
+ /* COA configuration & assigment */
+ //
+ let storagePath = /storage/evm
+ let publicPath = /public/evm
+ // Configure a COA if one is not found in storage at the default path
+ if signer.storage.type(at: storagePath) == nil {
+ // Create & save the CadenceOwnedAccount (COA) Resource
+ let newCOA <- EVM.createCadenceOwnedAccount()
+ signer.storage.save(<-newCOA, to: storagePath)
+
+ // Unpublish any existing Capability at the public path if it exists
+ signer.capabilities.unpublish(publicPath)
+ // Issue & publish the public, unentitled COA Capability
+ let coaCapability = signer.capabilities.storage.issue<&EVM.CadenceOwnedAccount>(storagePath)
+ signer.capabilities.publish(coaCapability, at: publicPath)
+ }
+
+ // Assign the COA reference to the transaction's coa field
+ self.coa = signer.storage.borrow(from: storagePath)
+ ?? panic("A CadenceOwnedAccount (COA) Resource could not be found at path ".concat(storagePath.toString())
+ .concat(" - ensure the COA Resource is created and saved at this path to enable EVM interactions"))
+
+ /* Fund COA with cost of mint */
+ //
+ // Borrow authorized reference to signer's FlowToken Vault
+ let sourceVault = signer.storage.borrow(
+ from: /storage/flowTokenVault
+ ) ?? panic("The signer does not store a FlowToken Vault object at the path "
+ .concat("/storage/flowTokenVault. ")
+ .concat("The signer must initialize their account with this vault first!"))
+ // Withdraw from the signer's FlowToken Vault
+ self.mintCost = 1.0
+ let fundingVault <- sourceVault.withdraw(amount: self.mintCost) as! @FlowToken.Vault
+ // Deposit the mint cost into the COA
+ self.coa.deposit(from: <-fundingVault)
+
+ /* Set the WFLOW contract address */
+ //
+ // View the cannonical WFLOW contract at:
+ // https://evm-testnet.flowscan.io/address/0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e
+ self.wflowAddress = EVM.addressFromString(wflowAddressHex)
+
+ /* Assign the ERC721 EVM Address */
+ //
+ // Deserialize the provided ERC721 hex string to an EVM address
+ self.erc721Address = EVM.addressFromString(maybeMintERC721AddressHex)
+ }
+
+ pre {
+ self.coa.balance().inFLOW() >= self.mintCost:
+ "CadenceOwnedAccount holds insufficient FLOW balance to mint - "
+ .concat("Ensure COA has at least ".concat(self.mintCost.toString()).concat(" FLOW"))
+ }
+
+ execute {
+ /* Wrap FLOW in EVM as WFLOW */
+ //
+ // Encode calldata & set value
+ let depositCalldata = EVM.encodeABIWithSignature("deposit()", [])
+ let value = EVM.Balance(attoflow: 0)
+ value.setFLOW(flow: self.mintCost)
+ // Call the WFLOW contract, wrapping the sent FLOW
+ let wrapResult = self.coa.call(
+ to: self.wflowAddress,
+ data: depositCalldata,
+ gasLimit: 15_000_000,
+ value: value
+ )
+ assert(
+ wrapResult.status == EVM.Status.successful,
+ message: "Wrapping FLOW as WFLOW failed: ".concat(wrapResult.errorMessage)
+ )
+
+ /* Approve the ERC721 address for the mint amount */
+ //
+ // Encode calldata approve(address,uint) calldata, providing the ERC721 address & mint amount
+ let approveCalldata = EVM.encodeABIWithSignature(
+ "approve(address,uint256)",
+ [self.erc721Address, UInt256(1_000_000_000_000_000_000)]
+ )
+ // Call the WFLOW contract, approving the ERC721 address to move the mint amount
+ let approveResult = self.coa.call(
+ to: self.wflowAddress,
+ data: approveCalldata,
+ gasLimit: 15_000_000,
+ value: EVM.Balance(attoflow: 0)
+ )
+ assert(
+ approveResult.status == EVM.Status.successful,
+ message: "Approving ERC721 address on WFLOW contract failed: ".concat(approveResult.errorMessage)
+ )
+
+ /* Attempt to mint ERC721 */
+ //
+ // Encode the mint() calldata
+ let mintCalldata = EVM.encodeABIWithSignature("mint()", [])
+ // Call the ERC721 contract, attempting to mint
+ let mintResult = self.coa.call(
+ to: self.erc721Address,
+ data: mintCalldata,
+ gasLimit: 15_000_000,
+ value: EVM.Balance(attoflow: 0)
+ )
+ // If mint fails, all other actions in this transaction are reverted
+ assert(
+ mintResult.status == EVM.Status.successful,
+ message: "Minting ERC721 token failed: ".concat(mintResult.errorMessage)
+ )
+ }
+}
+
+```
+
+
+You can run the transaction at the following link using the community-developed Flow Runner tool: [`wrap_and_mint.cdc`].
+
+This transaction takes two arguments:
+- WFLOW contract address: `0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e`
+- MaybeMintERC721 contract address: `0x2E2Ed0Cfd3AD2f1d34481277b3204d807Ca2F8c2`
+
+Before running, ensure that the network section - bottom right corner - displays Testnet. If not, click and select
+`Testnet` as your network and refresh. Once you've confirmed you're Flow Runner is targeting Testnet, copy these
+addresses and paste them into the respective fields on the Flow Runner page. Click `Run` on the top left and follow the
+prompts to connect your Flow Wallet and sign the transaction.
+
+:::warning
+
+Although we are running a manual transaction for the purposes of this walkthrough, you should always be careful to
+review the transaction details before signing and submitting.
+
+:::
+
+Again, since the ERC721 has a 50% chance of failing, you may need to run the transaction multiple times until it
+succeeds. However note that if the mint fails, the entire transaction will revert, unwinding the wrapped FLOW and
+approval.
+
+Again, since the ERC721 has a 50% chance of failure and the success of the transaction is conditioned on successfully
+minting, your transaction may fail. If it does fail, importantly the entire transaction reverts, unwinding the wrapped
+FLOW deposit and approval - the wrapping and approval transactions **do not execute** in the event of mint failure! This
+is the main takeaway of this guide, that you embed a whole sequence of EVM transactions into one atomic operation using
+Cadence and if the primary intent (or intents) does not execute, everything else is reverted as well.
+
+In our case, you'll want to submit a transaction until one succeeds. Once you submit a successful transaction, you'll
+see a transaction ID with event logs in the Flow Runner output. Let's take a closer look at the transaction and its
+results in the Flowscan block explorer.
+
+![Flow Runner output on successful transaction execution](./flow-runner-successful-output.png)
+
+Copy your transaction ID and go to the Flowscan Testnet Cadence block explorer: [Flowscan Cadence].
+
+Pasting your transaction ID into the search bar will show you the transaction details, including the Cadence script,
+execution status, and event logs. Click on the `EVM` tab to view the EVM transactions batched in the Cadence
+transaction.
+
+![Embedded EVM transactions on Flowscan](./evm-embed-flowscan.png)
+
+Clicking on the transactions will open up the EVM transaction in Flowscan's EVM block explorer. If you view the EVM
+transactions in order, you'll notice that they aggregate the same actions we took manually in the MetaMask section, but
+this time in a single Cadence transaction!
+
+## Breaking it Down
+
+Now that we can relate to the pain of manually executing these transactions and we've seen the magic you can work with
+Cadence, let's understand what's going on under the hood.
+
+To recap, our Cadence transaction does the following, reverting if any step fails:
+
+1. Wraps FLOW as WFLOW
+2. Approves the `MaybeMintERC721` contract to move WFLOW
+3. Attempts to mint a `MaybeMintERC721` token
+
+But how does our Flow account interact with EVM from the Cadence runtime? As you'll recall from the [Interacting with
+COA](./interacting-with-coa.md) guide, we use a Cadence-owned account (COA) to interact with EVM contracts from Cadence.
+
+A COA is a [resource] providing an interface through which Cadence can interact with the EVM runtime. This is
+importantly ***in addition*** to the traditional routes you'd normally access normal EVMs - e.g. via the JSON-RPC API.
+And with this interface, we can take advantage of all of the benefits of Cadence - namely here scripted transactions and
+conditional execution.
+
+So in addition to the above steps, our transaction first configures a COA in the signer's account if one doesn't already
+exist. It then funds the COA with enough FLOW to cover the mint cost, sourcing funds from the signing Flow account's
+Cadence Vault. Finally, it wraps FLOW as WFLOW, approves the ERC721 contract to move the mint amount, and attempts to
+mint the ERC721 token.
+
+Let's see what each step looks like in the transaction code.
+
+### COA Configuration
+
+The first step in our transaction is to configure a COA in the signer's account if one doesn't already exist. This is
+done by creating a new COA resource and saving it to the signer account's storage. A public Capability on the COA is
+then issued and published on the signer's account, allowing anyone to deposit FLOW into the COA, affecting its EVM
+balance.
+
+```cadence
+/* COA configuration & assignment */
+//
+let storagePath = /storage/evm
+let publicPath = /public/evm
+// Configure a COA if one is not found in storage at the default path
+if signer.storage.type(at: storagePath) == nil {
+ // Create & save the CadenceOwnedAccount (COA) Resource
+ let newCOA <- EVM.createCadenceOwnedAccount()
+ signer.storage.save(<-newCOA, to: storagePath)
+
+ // Unpublish any existing Capability at the public path if it exists
+ signer.capabilities.unpublish(publicPath)
+ // Issue & publish the public, unentitled COA Capability
+ let coaCapability = signer.capabilities.storage.issue<&EVM.CadenceOwnedAccount>(storagePath)
+ signer.capabilities.publish(coaCapability, at: publicPath)
+}
+
+// Assign the COA reference to the transaction's coa field
+self.coa = signer.storage.borrow(from: storagePath)
+ ?? panic("A CadenceOwnedAccount (COA) Resource could not be found at path ".concat(storagePath.toString())
+ .concat(" - ensure the COA Resource is created and saved at this path to enable EVM interactions"))
+```
+
+At the end of this section, the transaction now has an reference authorized with the `EVM.Call` [entitlement] to use in
+the `execute` block which can be used call into EVM.
+
+You can run a transaction that does just this step here: [`setup_coa.cdc`]
+
+Since you ran the all-in-one transaction previously, your account already has a COA configured in which case the linked
+transaction won't do anything. You can lookup your Testnet account's EVM address with the script below to confirm you
+have a COA configured. Simply input your Testnet Flow address and click `Run`.
+
+
+
+### Funding the COA
+
+Next, we fund the COA with enough FLOW to cover the mint cost. This is done by withdrawing FLOW from the signer's
+FlowToken Vault and depositing it into the COA.
+
+```cadence
+/* Fund COA with cost of mint */
+//
+// Borrow authorized reference to signer's FlowToken Vault
+let sourceVault = signer.storage.borrow(
+ from: /storage/flowTokenVault
+ ) ?? panic("The signer does not store a FlowToken Vault object at the path "
+ .concat("/storage/flowTokenVault. ")
+ .concat("The signer must initialize their account with this vault first!"))
+// Withdraw from the signer's FlowToken Vault
+self.mintCost = 1.0
+let fundingVault <- sourceVault.withdraw(amount: self.mintCost) as! @FlowToken.Vault
+// Deposit the mint cost into the COA
+self.coa.deposit(from: <-fundingVault)
+```
+
+Taking a look at the full transaction, we can see an explicit check that the COA has enough FLOW to cover the mint cost
+before proceeding into the transaction's `execute` block.
+
+```cadence
+pre {
+ self.coa.balance().inFLOW() >= self.mintCost:
+ "CadenceOwnedAccount holds insufficient FLOW balance to mint - "
+ .concat("Ensure COA has at least ".concat(self.mintCost.toString()).concat(" FLOW"))
+}
+```
+
+This isn't absolutely necessary as successive steps would fail on this condition, but helps provide enhanced error
+messages in the event of insufficient funds.
+
+You can run the above block in a transaction here which will move 1 FLOW from your account's Cadence FLOW balance to
+your account's EVM balance, depositing it directly to your pre-configured COA: [`fund_coa.cdc`]
+
+After running the linked transaction, you can check your COA's FLOW balance with the script below, just enter your COA's
+EVM address (which you can get from the previous script). The resulting balance should be 1.0 (unless you've funded your
+COA prior to this walkthrough).
+
+
+
+### Setting our EVM Contract Targets
+
+The last step in our transaction's `prepare` block is to deserialize the provided WFLOW and ERC721 contract addresses
+from hex strings to EVM addresses.
+
+```cadence
+/* Set the WFLOW contract address */
+//
+// View the cannonical WFLOW contract at:
+// https://evm-testnet.flowscan.io/address/0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e
+self.wflowAddress = EVM.addressFromString(wflowAddressHex)
+
+/* Assign the ERC721 EVM Address */
+//
+// Deserialize the provided ERC721 hex string to an EVM address
+self.erc721Address = EVM.addressFromString(maybeMintERC721AddressHex)
+```
+
+### Wrapping FLOW as WFLOW
+
+Next, we're on to the first EVM interaction - wrapping FLOW as WFLOW. This is done by encoding the `deposit()` function
+call and setting the call value to the mint cost. The COA then calls the WFLOW contract with the encoded calldata, gas
+limit, and value.
+
+```cadence
+/* Wrap FLOW in EVM as WFLOW */
+//
+// Encode calldata & set value
+let depositCalldata = EVM.encodeABIWithSignature("deposit()", [])
+let value = EVM.Balance(attoflow: 0)
+value.setFLOW(flow: self.mintCost)
+// Call the WFLOW contract, wrapping the sent FLOW
+let wrapResult = self.coa.call(
+ to: self.wflowAddress,
+ data: depositCalldata,
+ gasLimit: 15_000_000,
+ value: value
+)
+assert(
+ wrapResult.status == EVM.Status.successful,
+ message: "Wrapping FLOW as WFLOW failed: ".concat(wrapResult.errorMessage)
+)
+```
+
+Setting the value of the call transmits FLOW along with the call to the contract, accessible in solidity as `msg.value`.
+
+:::tip
+
+You'll notice a general pattern among all EVM calls in this transaction:
+
+1. Encoding the calldata
+2. Calling the contract
+3. Asserting the call was successful
+
+Here we're just interested in a successful call, but we could access return data if it were expected and relevant for
+our Cadence transaction. This returned data is accessible from the `data` field on the `EVM.Result` object returned from
+`coa.call(...)`. This data would then be decoded using `EVM.decodeABI(...)`. More on this in later guides.
+
+:::
+
+You can run the above code as a transaction here: [`wrap_flow.cdc`]
+
+After running the transaction, your COA should have a WFLOW balance of 1.0 WFLOW. Confirm your WFLOW balance by running
+the script below, providing your Flow account address, the WFLOW address of `0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e`
+and your COA's EVM address (retrieved from a previous script):
+
+
+
+Since Solidity does not support decimal precision, the returned balance will look like a large number. In the case of
+WFLOW, we can recover the decimals by shifting the decimal place 18 digits to the left. Your account should have `1`
+WFLOW or `1000000000000000000` as returned.
+
+:::warning
+
+Note that the number of places to shift varies by ERC20 implementation -- the default value is 18, but it's not safe to
+assume this value. You can check a token's decimal places by calling `ERC20.decimals()(uint8)`.
+
+:::
+
+### Approving the ERC721 Contract
+
+Once the FLOW is wrapped as WFLOW, we approve the ERC721 contract to move the mint amount. This is done by encoding the
+`approve(address,uint256)` calldata and calling the WFLOW contract with the encoded calldata.
+
+```cadence
+/* Approve the ERC721 address for the mint amount */
+//
+// Encode calldata approve(address,uint) calldata, providing the ERC721 address & mint amount
+let approveCalldata = EVM.encodeABIWithSignature(
+ "approve(address,uint256)",
+ [self.erc721Address, UInt256(1_000_000_000_000_000_000)]
+ )
+// Call the WFLOW contract, approving the ERC721 address to move the mint amount
+let approveResult = self.coa.call(
+ to: self.wflowAddress,
+ data: approveCalldata,
+ gasLimit: 15_000_000,
+ value: EVM.Balance(attoflow: 0)
+)
+assert(
+ approveResult.status == EVM.Status.successful,
+ message: "Approving ERC721 address on WFLOW contract failed: ".concat(approveResult.errorMessage)
+)
+```
+
+You can run this approval using the transaction, passing the WFLOW address of
+`0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e` and MaybeMintERC721 address of `0x2E2Ed0Cfd3AD2f1d34481277b3204d807Ca2F8c2`
+: [`approve_maybe_mint_erc721.cdc`]
+
+The linked transaction will perform the approval step, authorizing the ERC721 to transfer WFLOW to cover the mint cost
+when `mint()` is called. Confirm the contract allowance by running the script below. Pass your Flow address, WFLOW
+address, ERC721 address, and your COA's EVM address.
+
+
+
+The result is the amount of your WFLOW balance the ERC721 is allowed to transfer, which after the transaction should be
+`1` WFLOW, or `1000000000000000000` as returned.
+
+### Minting the ERC721 Token
+
+Finally, we attempt to mint the ERC721 token. This is done by encoding the `mint()` calldata and calling the ERC721
+contract with the encoded calldata. If the mint fails, the entire transaction is reverted.
+
+```cadence
+/* Attempt to mint ERC721 */
+//
+// Encode the mint() calldata
+let mintCalldata = EVM.encodeABIWithSignature("mint()", [])
+// Call the ERC721 contract, attempting to mint
+let mintResult = self.coa.call(
+ to: self.erc721Address,
+ data: mintCalldata,
+ gasLimit: 15_000_000,
+ value: EVM.Balance(attoflow: 0)
+)
+// If mint fails, all other actions in this transaction are reverted
+assert(
+ mintResult.status == EVM.Status.successful,
+ message: "Minting ERC721 token failed: ".concat(mintResult.errorMessage)
+)
+```
+
+You can run the minting transaction here, passing the ERC721 address of `0x2E2Ed0Cfd3AD2f1d34481277b3204d807Ca2F8c2`:
+[`mint.cdc`]
+
+Again, this transaction may fail. But if you executed all the prior stepwise transactions according to the walkthrough,
+you can try again until the mint succeeds. Recall that you can view your transaction details using Cadence [Flowscan]
+which will also let you view the embedded EVM transactions in the `EVM` tab. Try it out, and see if you can figure out
+how to get your minted NFT's URI with the script below.
+
+
+
+### Recap
+
+All of the stepwise transactions you just executed are compiled in the first Cadence transaction we ran. Hopefully,
+going through the process step by step illuminates the power and flexibility of Cadence, allowing you to write
+transactions as simple or as complex as you want.
+
+While lengthy transactions can be intimidating and even a bit verbose at times, the flexibility afforded by the language
+means you are only limited by your imagination. Cadence transactions allow you to support the most streamlined of
+experiences, incorporating as many contracts as needed to support your use case.
+
+## Conclusion
+
+In this guide, we've demonstrated how to batch EVM transactions using Cadence, allowing you to conditionally execute
+multiple EVM transactions in a single Cadence transaction. While this guide focused on relatively simple EVM operations,
+the principles can be applied to much more complex and interesting applications.
+
+In the process, you learned how to:
+
+- Read and write from smart contract functions on EVM Flowscan
+- Run a Cadence transaction from the browser using [Flow Runner]
+- Execute batched EVM transactions via a COA in a Cadence transaction
+- Condition final transaction execution on success of all EVM transactions
+- Inspect multiple EVM transactions embedded in a Cadence transaction with [Flowscan] block explorer
+
+The biggest takeaway here isn't the specific actions taken in this walkthrough, but the overarching concept that you can
+use **Cadence as an orchestration layer** to **extend existing EVM contracts**, creating unique user experiences with
+the power **to differentiate your Web3 application**.
+
+With these basics in hand, you're ready to start building more complex applications that leverage the power of Cadence
+and the Flow blockchain. How will you use these features to build Web3's next killer app?
+
+## Further Reading
+
+Now that you've experienced the power of Cadence and EVM interactions firsthand, we recommend checking out the following
+guides to deepen your understanding:
+
+- [How EVM on Flow Works] - Learn more about the Flow EVM and how it differs from traditional EVM platforms
+- [Interacting with COAs] - Get a fuller picture of how Cadence interacts with EVM contracts via Cadence-owned accounts
+- [Cadence Transactions] - Learn more about the Cadence transaction model
+
+Ready to level up your Cadence skills? Take a look at [these Cadence tutorials].
+
+
+
+[EVM Flowscan]: https://evm.flowscan.io/
+[Flow Runner]: https://run.dnz.dev/
+[Flowscan]: https://www.flowscan.io/
+[MetaMask]: https://metamask.io/download/
+[Flow Wallet extension]: https://wallet.flow.com/download
+[Faucet guide]: ../../ecosystem/faucets.md
+[Cadence-controlled EVM account (COA)]: ./interacting-with-coa.md
+[onchain VRF]: ../guides/vrf.md
+[Overview]: #overview
+[Testnet]: https://evm-testnet.flowscan.io/token/0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e?tab=contract
+[Mainnet]: https://evm.flowscan.io/token/0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e?tab=contract
+[`@onflow/flow-sol-utils` repository]: https://github.com/onflow/flow-sol-utils
+[Prerequisites]: #prerequisites
+[Flowscan EVM block explorer]: https://www.evm-testnet.flowscan.io/
+[WFLOW]: https://evm-testnet.flowscan.io/token/0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e?tab=write_contract
+[here]: https://docs.soliditylang.org/en/v0.8.28/units-and-global-variables.html#ether-units
+[MaybeMintERC721]: https://evm-testnet.flowscan.io/address/0x2E2Ed0Cfd3AD2f1d34481277b3204d807Ca2F8c2?tab=write_contract
+[`wrap_and_mint.cdc`]: https://run.dnz.dev/snippet/4fe0d43fdaf968b9
+[Flowscan Cadence]: https://testnet.flowscan.io/
+[resource]: https://cadence-lang.org/docs/solidity-to-cadence#resources
+[entitlement]: https://cadence-lang.org/docs/language/access-control#entitlements
+[How EVM on Flow Works]: ../how-it-works.md
+[Interacting with COAs]: ./interacting-with-coa.md
+[Cadence Transactions]: ../../build/basics/transactions.md
+[these Cadence tutorials]: https://cadence-lang.org/docs/tutorial/first-steps
+[`setup_coa.cdc`]: https://run.dnz.dev/snippet/4ec75e1f4165fa05
+[`fund_coa.cdc`]: https://run.dnz.dev/snippet/0e7370601bd9123b
+[`wrap_flow.cdc`]: https://run.dnz.dev/snippet/9dbfb784da5300fb
+[`approve_maybe_mint_erc721.cdc`]: https://run.dnz.dev/snippet/1b503d82f9a2c5a7
+[`mint.cdc`]: https://run.dnz.dev/snippet/fd7c4dda536d006e
\ No newline at end of file
diff --git a/docs/evm/cadence/cadence-embedded-evm-txns.png b/docs/evm/cadence/cadence-embedded-evm-txns.png
new file mode 100644
index 0000000000..00a96876f0
Binary files /dev/null and b/docs/evm/cadence/cadence-embedded-evm-txns.png differ
diff --git a/docs/evm/cadence/evm-embed-flowscan.png b/docs/evm/cadence/evm-embed-flowscan.png
new file mode 100644
index 0000000000..74b4f2845e
Binary files /dev/null and b/docs/evm/cadence/evm-embed-flowscan.png differ
diff --git a/docs/evm/cadence/flow-runner-successful-output.png b/docs/evm/cadence/flow-runner-successful-output.png
new file mode 100644
index 0000000000..06ece46e62
Binary files /dev/null and b/docs/evm/cadence/flow-runner-successful-output.png differ
diff --git a/docs/evm/cadence/flowscan-connect.png b/docs/evm/cadence/flowscan-connect.png
new file mode 100644
index 0000000000..02c44670c9
Binary files /dev/null and b/docs/evm/cadence/flowscan-connect.png differ
diff --git a/docs/evm/cadence/maybe-mint-in-metamask.png b/docs/evm/cadence/maybe-mint-in-metamask.png
new file mode 100644
index 0000000000..fe9b02f602
Binary files /dev/null and b/docs/evm/cadence/maybe-mint-in-metamask.png differ
diff --git a/docs/evm/cadence/vm-bridge.md b/docs/evm/cadence/vm-bridge.md
index d45d3358ac..7504cdd363 100644
--- a/docs/evm/cadence/vm-bridge.md
+++ b/docs/evm/cadence/vm-bridge.md
@@ -1,7 +1,7 @@
---
title: Cross-VM Bridge
sidebar_label: Cross-VM Bridge
-sidebar_position: 6
+sidebar_position: 7
---
# Cross-VM Bridge
diff --git a/docs/evm/cadence/wflow-approve.png b/docs/evm/cadence/wflow-approve.png
new file mode 100644
index 0000000000..56b76b853f
Binary files /dev/null and b/docs/evm/cadence/wflow-approve.png differ
diff --git a/docs/evm/cadence/wflow-deposit-confirm.png b/docs/evm/cadence/wflow-deposit-confirm.png
new file mode 100644
index 0000000000..6af9d88d2f
Binary files /dev/null and b/docs/evm/cadence/wflow-deposit-confirm.png differ
diff --git a/docs/evm/cadence/wflow-deposit.png b/docs/evm/cadence/wflow-deposit.png
new file mode 100644
index 0000000000..b0d30eaa5c
Binary files /dev/null and b/docs/evm/cadence/wflow-deposit.png differ
diff --git a/docs/evm/cadence/wflow-in-metamask-tokens.png b/docs/evm/cadence/wflow-in-metamask-tokens.png
new file mode 100644
index 0000000000..a327bd7580
Binary files /dev/null and b/docs/evm/cadence/wflow-in-metamask-tokens.png differ
diff --git a/src/css/custom.css b/src/css/custom.css
index d4030eaa0c..4bf5b9062b 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -114,4 +114,10 @@
.markdown h1 {
--ifm-h1-font-size: 3rem;
margin-bottom: calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading));
+}
+
+.portrait-screenshot-wrapper img {
+ width: 300px;
+ display: block;
+ margin: 0 auto;
}
\ No newline at end of file