diff --git a/.prettierignore b/.prettierignore
index 3f5a5547..d9130750 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -3,3 +3,4 @@ node_modules
.idea
public
**/*.md
+*.md
diff --git a/assets/custom-icons.ts b/assets/custom-icons.ts
new file mode 100644
index 00000000..c83cebe2
--- /dev/null
+++ b/assets/custom-icons.ts
@@ -0,0 +1,68 @@
+export const customIcons = {
+ custom: {
+ icons: {
+ 'metamask-logo': {
+ body: ``,
+ },
+ },
+ },
+};
diff --git a/components/content/NetworkAdder.vue b/components/content/NetworkAdder.vue
new file mode 100644
index 00000000..22d435d2
--- /dev/null
+++ b/components/content/NetworkAdder.vue
@@ -0,0 +1,48 @@
+
+
+
+
+ Add {{ chainName }}
+
+
diff --git a/content/00.build/00.zksync-101/1.zksync-overview.md b/content/00.build/00.zksync-101/1.zksync-overview.md
new file mode 100644
index 00000000..6ab0626e
--- /dev/null
+++ b/content/00.build/00.zksync-101/1.zksync-overview.md
@@ -0,0 +1,73 @@
+---
+title: zkSync overview
+description: A quick overview of what is zkSync
+---
+
+## What is zkSync?
+
+**zkSync Era** is a Layer 2 **[ZK
+rollup](https://docs.zksync.io/build/developer-reference/rollups.html#what-are-zk-rollups)**, a trustless protocol that
+uses cryptographic validity proofs to provide scalable and low-cost transactions on Ethereum. In zkSync Era, computation
+is performed off-chain and most data is stored off-chain as well. Transactions are bundled into batches before
+generating a validity proof. As all validity proofs are proven on the Ethereum mainchain, users enjoy the same security
+level as in Ethereum.
+
+zkSync Era is made to look and feel like Ethereum, but with a higher throughput and lower fees. Just like on Ethereum,
+smart contracts are written in Solidity/Vyper and can be called using the same clients as the other EVM-compatible
+chains.
+
+You don't need to register a separate private key before using it; zkSync supports existing Ethereum wallets out of the
+box.
+
+## Main features
+:check-icon Mainnet-like security with zero reliance on 3rd parties.
+
+:check-icon Permissionless EVM-compatible smart contracts.
+
+:check-icon Preserving key EVM features, such as smart contract composability.
+
+:check-icon Standard Web3 API.
+
+:check-icon State updates via transaction outputs (also known as state diffs) which provides significant cost savings
+over transaction inputs.
+
+:check-icon Native account abstraction with improvements over EIP4337 (implemented in Ethereum and other rollups).
+
+You can find [more information about zkSync Era in l2beat](https://l2beat.com/scaling/projects/zksync-era#stage).
+
+## Developer experience
+
+zkSync Era was built to provide a similar developer experience as Ethereum.
+
+:check-icon Smart contracts can be written in Solidity or Vyper.
+
+:check-icon Most contracts work out of the box so migrating projects is seamless.
+
+:check-icon Smart contracts are compiled with custom compilers: **[zksolc and
+zkvyper](https://docs.zksync.io/zk-stack/components/compiler/toolchain/overview.html)**.
+
+:check-icon Use existing frameworks
+like **[Hardhat](https://docs.zksync.io/build/tooling/hardhat/getting-started.html),** libraries like Ethers, Viem, or
+web3.js, and tools like theGraph, Thirdweb, or Chainlink.
+
+:check-icon Web3 API compatibility enables support of most developer tools.
+
+:check-icon Different **[tools for testing and debugging
+locally](https://docs.zksync.io/build/test-and-debug/getting-started.html)**.
+
+## User experience
+
+Interacting with applications built on zkSync Era is seamless, cheap and fast.
+
+- Transactions have instant confirmations and fast finality on L1.
+- Transaction fees are extremely low (see [average transaction costs
+ here](https://www.growthepie.xyz/fundamentals/transaction-costs)).
+- Transaction fees can be conveniently paid with ERC20 tokens (e.g. USDC) thanks to **[native account abstraction and
+ paymasters](https://docs.zksync.io/build/developer-reference/account-abstraction.html)**.
+- Support for existing Ethereum-based wallets like Metamask, TrustWallet, Zerion or Rabby.
+
+## Get started
+
+- Follow [this guide to add the zkSync network to your wallet](connect-zksync).
+- Get [testnet funds from one of the faucets](faucet)
+- Deploy your first smart contract to zkSync Era in the **[quickstart](quickstart)**.
diff --git a/content/00.build/00.zksync-101/2.connect-zksync.md b/content/00.build/00.zksync-101/2.connect-zksync.md
new file mode 100644
index 00000000..687faef2
--- /dev/null
+++ b/content/00.build/00.zksync-101/2.connect-zksync.md
@@ -0,0 +1,43 @@
+---
+title: Connect to zkSync
+description: Step-by-step guide to connect your wallet to zkSync.
+---
+
+## Add zkSync Era to your wallet
+
+You can add zkSync Era to your wallet using the buttons below:
+
+:network-adder{ network="mainnet" }
+:network-adder{ network="testnet" }
+
+### Manual settings
+
+To manually add zkSync Era as a custom network in your wallet, follow these steps:
+
+1. Find the “Add Network” option in your wallet (in Metamask, you can find this in the networks dropdown).
+2. Click “Add Network"
+3. Fill in the following details for the zkSync Era network you want to add:
+
+#### Mainnet network details
+
+- Network Name: `zkSync Era Mainnet`
+- RPC URL: `https://mainnet.era.zksync.io`
+- Chain ID: `324`
+- Currency Symbol: `ETH`
+- Block Explorer URL: `https://explorer.zksync.io/`
+- WebSocket URL: `wss://mainnet.era.zksync.io/ws`
+
+#### Sepolia testnet network details
+
+- Network Name: `zkSync Era Sepolia Testnet`
+- RPC URL: `https://sepolia.era.zksync.dev`
+- Chain ID: `300`
+- Currency Symbol: `ETH`
+- Block Explorer URL: `https://sepolia.explorer.zksync.io/`
+- WebSocket URL: `wss://sepolia.era.zksync.dev/ws`
+
+Click on "Save" to add the zkSync Era network to your wallet.
+
+## How to get started?
+
+Begin by [getting testnet funds from one of the available faucets](faucet).
diff --git a/content/00.build/00.zksync-101/3.faucet.md b/content/00.build/00.zksync-101/3.faucet.md
new file mode 100644
index 00000000..5ed09a50
--- /dev/null
+++ b/content/00.build/00.zksync-101/3.faucet.md
@@ -0,0 +1,45 @@
+---
+title: Network Faucets
+description: Get testnet funds to build and deploy to %%zk_testnet_name%%.
+---
+## %%zk_testnet_name%% faucets
+
+Use any of the following faucets to get funds directly on %%zk_testnet_name%%:
+
+### Chainstack
+
+[Chainstack Faucet](https://faucet.chainstack.com/zksync-testnet-faucet) is an easy to use Multi-Chain Faucet. You can
+use Chainstack Faucet to claim %%zk_testnet_name%% ETH.
+
+### LearnWeb3
+
+You can use [LearnWeb3's zkSync Sepolia Faucet](https://learnweb3.io/faucets/zksync_sepolia/) to claim zkSync Sepolia
+Testnet ETH.
+
+## Sepolia faucets
+
+::callout{icon="i-heroicons-light-bulb"}
+Use any of the following faucets to claim SepoliaETH, which you can bridge to %%zk_testnet_name%% using the [zkSync
+bridge](https://portal.zksync.io/bridge/?network=sepolia).
+::
+
+- [LearnWeb3 Sepolia faucet](https://learnweb3.io/faucets/sepolia)
+- [QuickNode Sepolia faucet](https://faucet.quicknode.com/ethereum/sepolia)
+- [Alchemy Sepolia faucet](https://sepoliafaucet.com/)
+- [Proof of Work Sepolia faucet](https://sepolia-faucet.pk910.de/)
+- [Infura Sepolia faucet](https://www.infura.io/faucet/sepolia/)
+- [Ethereum Ecosystem Sepolia faucet](https://www.ethereum-ecosystem.com/faucets/ethereum-sepolia)
+
+### Circle USDC faucet
+
+[Circle's Testnet Faucet](https://faucet.circle.com/) provides USDC on zkSync Sepolia or Ethereum
+Sepolia Testnet.
+
+### Aave ERC20 token faucet
+
+[Aave's Sepolia faucet](https://staging.aave.com/faucet/) provides popular ERC20 tokens like
+WBTC, USDT, LINK, AAVE or DAI.
+
+## Next steps
+
+Deploy your first smart contract to zkSync following the [quickstart tutorial](quickstart).
diff --git a/content/00.build/00.zksync-101/4.quickstart.md b/content/00.build/00.zksync-101/4.quickstart.md
new file mode 100644
index 00000000..d0cd30ab
--- /dev/null
+++ b/content/00.build/00.zksync-101/4.quickstart.md
@@ -0,0 +1,121 @@
+---
+title: Deploy your first contract
+description: Deploy a smart contract to zkSync from your browser in under 5 minutes
+---
+
+This tutorial shows you how to deploy and interact with a smart contract on zkSync Era in less than 5 minutes.
+It will help you get familiar with the zkSync smart contract development and deployment process using different tools.
+
+This is what we're going to do:
+
+:check-icon Build a smart contract to exchange secret messages with Zeek.
+
+:check-icon Deploy the smart contract to the %%zk_testnet_name%%.
+
+:check-icon Interact with the contract from your browser using Remix or Atlas.
+
+## Prerequisites
+
+1. Before you start, make sure that
+[you’ve configured the zkSync Sepolia tesnet in your browser wallet by following the instructions here](connect-zksync).
+2. In addition, fund your wallet with %%zk_testnet_name%% ETH using [one of the available faucets](faucet).
+
+## Review the smart contract code
+
+The smart contract will store messages from users in a hashed format and emit events with replies from Zeek.
+The entire code is as follows:
+
+```solidity
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+contract ZeekSecretMessages {
+ bytes32[] private messages;
+
+ // Event to acknowledge a new message
+ event MessageReceived(string);
+
+ constructor() {
+ // Zeek initializes the contract with a welcome message
+ emit MessageReceived("Zeek welcomes you to zkSync!");
+ }
+
+ // Function to send a "secret" message to Zeek
+ function sendMessage(string memory _message) public {
+ bytes32 hashedMessage = keccak256(abi.encodePacked(_message));
+ messages.push(hashedMessage);
+
+ // Acknowledge the message receipt with Zeek's reply
+ emit MessageReceived("ZK is the endgame - Message received!");
+ }
+
+ // Function to count the total messages sent to Zeek
+ function getTotalMessages() public view returns (uint) {
+ return messages.length;
+ }
+}
+```
+
+The Solidity smart contract contains two functions:
+
+- `sendMessage` stores the messages sent by users in the `messages` state variable.
+- `getTotalMessages` returns the number of messages stored in the smart contract.
+
+::callout{icon="i-heroicons-light-bulb"}
+zkSync Era is [EVM compatible](/build/resources/glossary#evm-compatible).
+You can write smart contracts with Solidity or Vyper and use existing popular libraries like OpenZeppelin.
+::
+
+## Deploy the contract
+
+To deploy the contract we can use either Atlas or Remix:
+
+::content-switcher
+---
+items: [{
+ label: 'Atlas',
+ partial: '_quickstart/_atlas_deploy_contract'
+}, {
+ label: 'Remix',
+ partial: '_quickstart/_remix_deploy_contract'
+}]
+---
+::
+
+## Check the contract in explorer
+
+Copy the smart contract address from Atlas/Remix and search it via the [%%zk_testnet_name%%
+explorer](%%zk_testnet_block_explorer_url%%). You’ll see the contract has a transaction from the message we just sent.
+
+![Contract in zkSync explorer](/images/101-quickstart/101-contract-deployed.png)
+
+Click on the transaction hash link to check all its details, like timestamp, the account that send it, transaction fee
+etc. The status will be “Processed” on zkSync and “Sending” on Ethereum. [Learn more about the transaction lifecycle on
+zkSync](/zk-stack/concepts/transaction-lifecycle).
+
+In the “Contract” tab you’ll see the contract source code as Atlas and Remix automatically verified the contract for us.
+When a smart contract is verified in a block explorer, it means that the source code of the contract has been published
+and matched to the compiled version on the blockchain enhancing transparency, as users can review the contract’s source
+code to understand its functions and intentions.
+
+Finally in the “Events” tab, you’ll see the replies from Zeek as these are emitted as events in our smart contract.
+
+![Contract events in zkSync explorer](/images/101-quickstart/101-contract-events.png)
+
+ZK is the endgame ✌️
+
+## Takeaways
+
+- **EVM-compatibility**: zkSync Era is EVM-compatible and you can write smart contracts in Solidity or Vyper as in
+ Ethereum.
+- **Custom compilers**: smart contracts deployed to zkSync Era must be compiled with the customs compilers: `zksolc` for
+ Solidity and `zkvyper` for Vyper.
+- **Browser-based IDEs**: Existing tools like Atlas and Remix use zkSync custom compilers under the hood.
+
+## Next steps
+
+- Join the [zkSync developer community in Discord](https://join.zksync.dev/) where you can ask any questions about this tutorial in the #dev-101
+ channel
+- Continue learning by [deploying an ERC20 token to zkSync](erc20-token).
+- Join our :external-link{text="GitHub Discussions Community" href="%%zk_git_repo_zksync-developers%%/discussions/"} to
+ help other devs building on zkSync or share your project.
diff --git a/content/00.build/00.zksync-101/5.erc20-token.md b/content/00.build/00.zksync-101/5.erc20-token.md
new file mode 100644
index 00000000..582212d5
--- /dev/null
+++ b/content/00.build/00.zksync-101/5.erc20-token.md
@@ -0,0 +1,45 @@
+---
+title: Create an ERC20 token
+description: In this tutorial you'll build and deploy an ERC20 token to %%zk_testnet_name%%
+---
+
+This tutorial shows you how to deploy and interact with an ERC20 token on %%zk_testnet_name%%.
+
+This is what we’re going to do:
+
+:check-icon Build an ERC20 token smart contract with additional custom logic
+
+:check-icon Deploy the smart contract to the %%zk_testnet_name%% using Remix or Atlas.
+
+## Prerequisites
+
+Before you start, make sure that you’ve configured the zkSync Sepolia tesnet in your browser wallet by following the
+instructions here.
+
+In addition, fund your wallet with testnet ETH on %%zk_testnet_name%%.
+
+To complete this tutorial we’ll use either Atlas or Remix. Select your preferred tool:
+
+::content-switcher
+---
+items: [{
+ label: 'Atlas',
+ partial: '_erc20_tutorial/_atlas_erc20_tutorial'
+}, {
+ label: 'Remix',
+ partial: '_erc20_tutorial/_remix_erc20_tutorial'
+}]
+---
+::
+
+## Takeaways
+
+- **zkSync is EVM compatible** and supports existing smart contract libraries like OpenZeppelin
+- **Use popular libraries like** `ethers` , `viem`, or `web3.js` to interact with smart contracts deployed on zkSync.
+
+## Next steps
+
+- Join the zkSync developer community in Discord where you can ask any questions about this tutorial in the #dev-101
+ channel
+- Continue learning by deploying an ERC20 token to zkSync Era.
+- Join our GitHub Discussions community to help other devs building on zkSync or share your project.
diff --git a/content/00.build/00.zksync-101/6.paymasters-introduction.md b/content/00.build/00.zksync-101/6.paymasters-introduction.md
new file mode 100644
index 00000000..ecec77f7
--- /dev/null
+++ b/content/00.build/00.zksync-101/6.paymasters-introduction.md
@@ -0,0 +1,183 @@
+---
+title: Paymasters introduction
+description: Learn about paymasters and use one to pay transaction fees with your own token
+---
+
+This tutorial makes use of smart contracts deployed in the previous two tutorials, [Deploy your first
+contract](quickstart) and [Create an ERC20 token](erc20-token). This section introduces one of the custom features
+of zkSync: native account abstraction and paymasters.
+
+In this tutorial we will:
+
+:check-icon Learn about paymasters.
+
+:check-icon Review the testnet paymaster smart contract code.
+
+:check-icon Use the testnet paymaster to pay transaction fees with our own ERC20 token.
+
+Before you start, make sure that you’ve configured the zkSync Sepolia tesnet in your browser wallet by [following the2.connect-zksync.md
+instructions here](2.connect-zksync.md).
+
+## What is a paymaster?
+
+Paymasters are smart contracts with a very specific function: pay the transaction fees on behalf of the user. In order
+to do so, paymasters have ETH balance which they use to pay the transaction fees to the protocol.
+
+Being smart contracts, paymasters can have logic and validations to pay, or not the transaction fees.
+
+Every paymaster has these two functions:
+
+- `validateAndPayForPaymasterTransaction` : it receives the transaction parameters (fields like `from`, `amount` , `to`
+ ), use these to do the required validations, and pay the transaction fee.
+- `postTransaction`: this function runs after the transaction is executed and it’s optional.
+
+![zksync paymaster](/images/101-paymasters/zksync-paymaster.png)
+
+## Paymaster smart contract code
+
+Although application developers are encouraged to create their own paymaster smart contract, zkSync provides a testnet
+paymaster for convenience and testing purposes.
+
+::callout{icon="i-heroicons-light-bulb"}
+The testnet paymaster address is
+[0x3cb2b87d10ac01736a65688f3e0fb1b070b3eea3](https://sepolia.explorer.zksync.io/address/0x3cb2b87d10ac01736a65688f3e0fb1b070b3eea3)
+::
+
+Here is the code:
+
+::drop-panel
+ ::panel{label="TestnetPaymaster.sol"}
+ ```solidity
+ // SPDX-License-Identifier: MIT
+
+ pragma solidity 0.8.20;
+
+ import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+
+ import "./interfaces/IPaymaster.sol";
+ import "./interfaces/IPaymasterFlow.sol";
+ import "./L2ContractHelper.sol";
+
+ // This is a dummy paymaster. It expects the paymasterInput to contain its "signature" as well as the needed exchange rate.
+ // It supports only approval-based paymaster flow.
+ contract TestnetPaymaster is IPaymaster {
+ function validateAndPayForPaymasterTransaction(
+ bytes32,
+ bytes32,
+ Transaction calldata _transaction
+ ) external payable returns (bytes4 magic, bytes memory context) {
+ // By default we consider the transaction as accepted.
+ magic = PAYMASTER_VALIDATION_SUCCESS_MAGIC;
+
+ require(msg.sender == BOOTLOADER_ADDRESS, "Only bootloader can call this contract");
+ require(_transaction.paymasterInput.length >= 4, "The standard paymaster input must be at least 4 bytes long");
+
+ bytes4 paymasterInputSelector = bytes4(_transaction.paymasterInput[0:4]);
+ if (paymasterInputSelector == IPaymasterFlow.approvalBased.selector) {
+ // While the actual data consists of address, uint256 and bytes data,
+ // the data is not needed for the testnet paymaster
+ (address token, uint256 amount, ) = abi.decode(_transaction.paymasterInput[4:], (address, uint256, bytes));
+
+ // Firstly, we verify that the user has provided enough allowance
+ address userAddress = address(uint160(_transaction.from));
+ address thisAddress = address(this);
+
+ uint256 providedAllowance = IERC20(token).allowance(userAddress, thisAddress);
+ require(providedAllowance >= amount, "The user did not provide enough allowance");
+
+ // The testnet paymaster exchanges X wei of the token to the X wei of ETH.
+ uint256 requiredETH = _transaction.gasLimit * _transaction.maxFeePerGas;
+ if (amount < requiredETH) {
+ // Important note: while this clause definitely means that the user
+ // has underpaid the paymaster and the transaction should not accepted,
+ // we do not want the transaction to revert, because for fee estimation
+ // we allow users to provide smaller amount of funds then necessary to preserve
+ // the property that if using X gas the transaction success, then it will succeed with X+1 gas.
+ magic = bytes4(0);
+ }
+
+ // Pulling all the tokens from the user
+ try IERC20(token).transferFrom(userAddress, thisAddress, amount) {} catch (bytes memory revertReason) {
+ // If the revert reason is empty or represented by just a function selector,
+ // we replace the error with a more user-friendly message
+ if (revertReason.length <= 4) {
+ revert("Failed to transferFrom from users' account");
+ } else {
+ assembly {
+ revert(add(0x20, revertReason), mload(revertReason))
+ }
+ }
+ }
+
+ // The bootloader never returns any data, so it can safely be ignored here.
+ (bool success, ) = payable(BOOTLOADER_ADDRESS).call{value: requiredETH}("");
+ require(success, "Failed to transfer funds to the bootloader");
+ } else {
+ revert("Unsupported paymaster flow");
+ }
+ }
+
+ function postTransaction(
+ bytes calldata _context,
+ Transaction calldata _transaction,
+ bytes32,
+ bytes32,
+ ExecutionResult _txResult,
+ uint256 _maxRefundedGas
+ ) external payable override {
+ // Nothing to do
+ }
+
+ receive() external payable {}
+ }
+ ```
+ ::
+::
+
+In the `validateAndPayForPaymasterTransaction` it is:
+
+1. checking that the paymasterInput is `approvalBased`.
+2. checks that the allowance of a given ERC20 is enough.
+3. Transfers the transaction fee (`requiredETH`) in ERC20 from the user’s balance to the paymaster.
+4. Transfer the transaction fee in ETH from the paymaster contract to the bootloader.
+
+## How to send a transaction through a paymaster?
+
+In order to send a transaction through a paymaster, the transaction must include the following additional parameters:
+
+- `paymasterAddress`: the smart contract address of the paymaster
+- `type`: should be `General` or `ApprovalBased` (to pay fees with ERC20 tokens)
+- `minimalAllowance`: the amount of ERC20 tokens to be approved for spending (for `approvalBased` type paymasters only).
+- `innerInput`: any payload we want to send to the paymaster (optional).
+
+We’ll see an example next.
+
+## Interacting with the testnet paymaster
+
+We’re going to interact with the `ZeekSecretMessages.sol` contract that we created in the first tutorial and use the
+ERC20 token that we deployed in the second tutorial to pay the transaction fees.
+
+::content-switcher
+---
+items: [{
+ label: 'Atlas',
+ partial: '_paymaster_intro/_atlas_paymaster_intro'
+}, {
+ label: 'Remix',
+ partial: '_paymaster_intro/_remix_paymaster_intro'
+}]
+---
+::
+
+## Takeaways
+
+- Paymasters on zkSync allow any account to pay fees with ERC20 tokens or enable gasless transactions.
+- Paymasters are smart contracts that can have any validations and rules.
+- To send a transaction through a paymaster, we only need to include additional parameters in the transaction.
+
+## Next steps
+
+- Learn more about paymasters and native account abstraction in this section of the docs.
+- Browse different paymaster examples in [this open source
+ repository](https://github.com/matter-labs/paymaster-examples).
+- Continue learning by building a GoFundMe clone on zkSync.
diff --git a/content/00.build/00.zksync-101/_dir.yml b/content/00.build/00.zksync-101/_dir.yml
new file mode 100644
index 00000000..a409bec0
--- /dev/null
+++ b/content/00.build/00.zksync-101/_dir.yml
@@ -0,0 +1 @@
+title: zkSync 101
diff --git a/content/00.build/00.zksync-101/_erc20_tutorial/_atlas_erc20_tutorial.md b/content/00.build/00.zksync-101/_erc20_tutorial/_atlas_erc20_tutorial.md
new file mode 100644
index 00000000..29731e26
--- /dev/null
+++ b/content/00.build/00.zksync-101/_erc20_tutorial/_atlas_erc20_tutorial.md
@@ -0,0 +1,130 @@
+---
+title: ERC20 token with Atlas
+---
+## Custom ERC20 token code
+
+ERC20 tokens are a standard for fungible tokens, which can be traded and represent a fixed value. You’ve used ERC20
+tokens if you’ve transacted with USDC, DAI, USDT, LINK or UNI.
+
+The ERC20 token we’re going to deploy will allow users to mint and burn tokens. The entire smart contract code is as
+follows:
+
+```solidity
+// SPDX-License-Identifier: Unlicensed
+pragma solidity ^0.8.19;
+
+import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
+import "@openzeppelin/contracts/access/Ownable.sol";
+import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
+
+contract TestToken is ERC20, Ownable, ERC20Burnable {
+ constructor(string memory name, string memory symbol) ERC20(name, symbol) {
+ _mint(msg.sender, 100 * 10 ** decimals());
+ }
+
+ function mint(address to, uint256 amount) public onlyOwner {
+ _mint(to, amount);
+ }
+}
+```
+
+::callout{icon="i-heroicons-light-bulb"}
+zkSync is [EVM compatible](/build/resources/glossary#evm-compatible), so you can use existing popular libraries like OpenZeppelin.
+::
+
+The most important features are:
+
+- `Ownable` : this extension sets the deployer account as owner of the smart contract. It also introduces the
+ `onlyOwner` modifier that restricts the execution of certain functions to the owner of the contract.
+- `ERC20Burnable`: this extension adds the `burn` and `burnFrom` functions to the smart contract. These functions
+ destroy tokens from a given account.
+- `constructor`: called on deployment, the constructor will assign the given name and symbol to the token and mint 100
+ units of it to the account that deployed the contract.
+- `mint` : this function creates new token units to a given account. It uses the `onlyOwner` modifier so it can only be
+ called from the owner account.
+
+## Deploy the smart contract
+
+Atlas is a browser-based IDE with an integrated AI assistant that allows you to write, test and deploy smart contracts
+directly from your browser. Click the button below to open the project in Atlas.
+
+:u-button{ icon="i-heroicons-code-bracket" size="xl" color="primary" variant="solid" :trailing="false"
+to="https://app.atlaszk.com/projects?template=https://github.com/uF4No/zksync-101-atlas&open=/contracts/TestToken.sol&chainId=300"
+target="_blank" label="Open smart contract in Atlas"}
+
+You can see the contract in the Atlas code editor. In the right sidebar, make sure the selected network is “zkSync Sepolia
+tesnet“ and click on **"Deploy"** to trigger the smart contract compilation and deployment.
+
+::callout{icon="i-heroicons-light-bulb"}
+Behind the scenes, Atlas is using the zkSync Era custom solidity compiler
+(named `zksolc` ) to generate ZKEVM compatible bytecode. [Learn more about zkSync custom compilers](/zk-stack/components/compiler/toolchain/overview).
+::
+
+Once compiled sign the transaction with your wallet and wait until its processed. You’ll see the contract in the
+**“Deployed contracts”** section.
+
+## Interact with the ERC20 contract
+
+In the `scripts` folder you can find the `interact.ts` script containing the following code:
+
+```ts
+import { AtlasEnvironment } from "atlas-ide";
+import TokenArtifact from "../artifacts/TestToken";
+import * as ethers from "ethers";
+
+// Address of the ERC20 token contract
+const TOKEN_CONTRACT_ADDRESS = ""
+// Wallet that will receive tokens
+const RECEIVER_WALLET = "";
+// Amount of tokens to mint in ETH format, e.g. 1.23
+const TOKEN_AMOUNT = "";
+
+export async function main (atlas: AtlasEnvironment) {
+ const provider = new ethers.providers.Web3Provider(atlas.provider);
+ const wallet = provider.getSigner();
+
+ // initialise token contract with address, abi and signer
+ const tokenContract= new ethers.Contract(
+ TOKEN_CONTRACT_ADDRESS,
+ TokenArtifact.TestToken.abi,
+ wallet
+ );
+
+ console.log("Minting tokens...");
+ const tx = await tokenContract.mint(
+ RECEIVER_WALLET,
+ ethers.utils.parseEther(TOKEN_AMOUNT)
+ );
+ await tx.wait();
+
+
+ console.log("Success!");
+ console.log(`
+ The account ${RECEIVER_WALLET} now has
+ ${await tokenContract.balanceOf(RECEIVER_WALLET)} tokens`
+ );
+
+}
+```
+
+This scripts uses `ethers` to interact with the contract we’ve just deployed.
+
+::callout{icon="i-heroicons-light-bulb"}
+Existing libraries like `ethers` , `viem` and `web3.js` can be used to interact with smart contracts deployed on zkSync.
+::
+
+Fill the following variables:
+
+- `TOKEN_CONTRACT_ADDRESS`: the contract address of the ERC20 token we just deployed.
+- `RECEIVER_WALLET`: address of a different account that will receive new tokens.
+- `TOKEN_AMOUNT`: the amount of tokens we’ll send to the account.
+
+With the `interact.ts` file open in the Atlas editor, click on the “Deploy” button to run the script and see the output
+in the terminal.
+
+![ERC20 interact script in Atlas](/images/101-erc20/atlas-erc20-interact.png)
+
+To confirm the account has received the tokens, visit the zkSync Sepolia explorer and search the receiver wallet
+address. You’ll see the new token balance in the assets table:
+
+![ERC20 tokens in account balance](/images/101-erc20/erc20-tokens-minted.png)
diff --git a/content/00.build/00.zksync-101/_erc20_tutorial/_remix_erc20_tutorial.md b/content/00.build/00.zksync-101/_erc20_tutorial/_remix_erc20_tutorial.md
new file mode 100644
index 00000000..726f558e
--- /dev/null
+++ b/content/00.build/00.zksync-101/_erc20_tutorial/_remix_erc20_tutorial.md
@@ -0,0 +1,145 @@
+---
+title: ERC20 with Remix
+---
+## Custom ERC20 token code
+
+ERC20 tokens are a standard for fungible tokens, which can be traded and represent a fixed value. You’ve used ERC20
+tokens if you’ve transacted with USDC, DAI, USDT, LINK or UNI.
+
+The ERC20 token we’re going to deploy will allow users to mint and burn tokens. The entire smart contract code is as
+follows:
+
+```solidity
+// SPDX-License-Identifier: Unlicensed
+pragma solidity ^0.8.19;
+
+import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
+import "@openzeppelin/contracts/access/Ownable.sol";
+import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
+
+contract TestToken is ERC20, Ownable, ERC20Burnable {
+ constructor(string memory name, string memory symbol)
+ ERC20(name, symbol) Ownable(msg.sender) {
+ _mint(msg.sender, 100 * 10 ** decimals());
+ }
+
+ function mint(address to, uint256 amount) public onlyOwner {
+ _mint(to, amount);
+ }
+}
+```
+
+::callout{icon="i-heroicons-light-bulb"}
+zkSync is [EVM compatible](/build/resources/glossary#evm-compatible), so you can use existing popular libraries like OpenZeppelin.
+::
+
+The most important features are:
+
+- `Ownable` : this extension sets the deployer account as owner of the smart contract. It also introduces the
+ `onlyOwner` modifier that restricts the execution of certain functions to the owner of the contract.
+- `ERC20Burnable`: this extension adds the `burn` and `burnFrom` functions to the smart contract. These functions
+ destroy tokens from a given account.
+- `constructor`: called on deployment, the constructor will assign the given name and symbol to the token and mint 100
+ units of it to the account that deployed the contract.
+- `mint` : this function creates new token units to a given account. It uses the `onlyOwner` modifier so it can only be
+ called from the owner account.
+
+## Deploy the smart contract
+
+The Remix IDE is an open-source web and desktop application that supports Ethereum smart contract development and
+deployment, offering tools for writing, testing, debugging, and deploying smart contracts written in Solidity to EVM
+compatible protocols.
+
+:display-partial{path="/_partials/_enable-remix-zksync-plugin"}
+
+Click the button below to open the project in Remix and see the contract in the Remix code editor.
+
+:u-button{ icon="i-heroicons-code-bracket" size="xl" color="primary" variant="solid" :trailing="false"
+to="https://remix.ethereum.org/#url=https://github.com/uF4No/zksync-101-remix/blob/main/contracts/TestToken.sol"
+target="_blank" label="Open smart contract in Remix" }
+
+To compile the contract, click on Compile TestToken.sol. If you get a popup message requesting permissions to access
+**`ACCESS TO "WRITEFILE" OF "FILE MANAGER"`,** click on Accept.
+
+::callout{icon="i-heroicons-light-bulb"}
+Behind the scenes, Remix is using the zkSync Era custom solidity compiler (named `zksolc` ) to generate ZKEVM compatible
+bytecode. [Learn more about zkSync custom compilers](/zk-stack/components/compiler/toolchain/overview).
+::
+
+We will use our wallet’s configured network to connect and deploy our smart contract so make sure your wallet is
+currently connected to the %%zk_testnet_name%%. In Remix, under the Environment Section, select “Wallet” and click on
+“Connect Wallet”.
+
+To deploy the contract, click on “Deploy” and sign the transaction on your wallet. Congratulations, your ERC20 token
+contract is now deployed on %%zk_testnet_name%%!
+
+## Interact with the ERC20 contract
+
+In the `scripts` folder you can find the `interact.ts` script containing the following code:
+
+```typescript
+import {ethers} from "ethers";
+
+// Address of the ERC20 token contract
+const TOKEN_CONTRACT_ADDRESS = ""
+// Wallet that will receive tokens
+const RECEIVER_WALLET = "";
+// Amount of tokens to mint in ETH format, e.g. 1.23
+const TOKEN_AMOUNT = "123.55";
+
+(async () => {
+ try {
+
+ // Note that the script needs the ABI which is generated from the compilation artifact.
+ // Make sure contract is compiled for zkSync and artifacts are generated
+ const artifactsPath = `browser/contracts/artifacts/TestToken.json` // Change this for different path
+
+ const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
+
+ // 'web3Provider' is a remix global variable object
+ const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner(0)
+
+ // initialise token contract with address, abi and signer
+ const tokenContract= new ethers.Contract(TOKEN_CONTRACT_ADDRESS, metadata.abi, signer);
+
+ console.log("Minting tokens...");
+ const tx = await tokenContract.mint(
+ RECEIVER_WALLET,
+ ethers.utils.parseEther(TOKEN_AMOUNT)
+ );
+ console.log(`Mint transaction is ${tx.hash}`)
+ await tx.wait();
+ console.log("Success!");
+
+ const balance = await tokenContract.balanceOf(RECEIVER_WALLET)
+
+ console.log(`The account ${RECEIVER_WALLET} now has ${balance} tokens`)
+
+ } catch (e) {
+ console.log(e.message)
+ }
+})()
+
+```
+
+This scripts uses `ethers` to interact with the contract we’ve just deployed.
+
+::callout{icon="i-heroicons-light-bulb"}
+Existing libraries like `ethers` , `viem` and `web3.js` can be used to interact with smart contracts deployed on zkSync.
+::
+
+Fill the following variables:
+
+- `TOKEN_CONTRACT_ADDRESS`: the contract address of the ERC20 token we just deployed.
+- `RECEIVER_WALLET`: address of a different account that will receive new tokens.
+- `TOKEN_AMOUNT`: the amount of tokens we’ll send to the account.
+
+With the `interact.ts` file open in the editor, click on the “▶️” button to run the script and see the output in the
+terminal.
+
+![ERC20 interact script in Remix](/images/101-erc20/remix-erc20-interact.png)
+
+To confirm the account has received the tokens, visit the zkSync Sepolia explorer and search the receiver wallet
+address. You’ll see the new token balance in the assets table:
+
+![ERC20 tokens in account balance](/images/101-erc20/erc20-tokens-minted.png)
diff --git a/content/00.build/00.zksync-101/_paymaster_intro/_atlas_paymaster_intro.md b/content/00.build/00.zksync-101/_paymaster_intro/_atlas_paymaster_intro.md
new file mode 100644
index 00000000..0fd94293
--- /dev/null
+++ b/content/00.build/00.zksync-101/_paymaster_intro/_atlas_paymaster_intro.md
@@ -0,0 +1,133 @@
+---
+title: Paymaster with Atlas
+---
+
+Click the following button to open the project in Atlas:
+
+:u-button{ icon="i-heroicons-code-bracket" size="xl" color="primary" variant="solid" :trailing="false"
+to="https://app.atlaszk.com/projects?template=https://github.com/uF4No/zksync-101-atlas&open=/scripts/paymaster-transaction.ts&chainId=300"
+target="_blank" label="Open script in Atlas"}
+
+It’ll open the script to send a transaction via the paymaster. Let’s go through the most important parts:
+
+### Retrieve the token balance
+
+```typescript
+// retrieve and print the current balance of the wallet
+let ethBalance = await provider.getBalance(walletAddress)
+let tokenBalance = await tokenContract.balanceOf(walletAddress)
+console.log(`Account ${walletAddress} has ${ethers.utils.formatEther(ethBalance)} ETH`);
+console.log(`Account ${walletAddress} has ${ethers.utils.formatUnits(tokenBalance, 18)} tokens`);
+```
+
+In this part we’re retrieving the ETH and ERC20 token balances of the account. We’ll compare them after the transaction
+is executed to see the difference.
+
+### Estimate transaction fee
+
+```typescript
+// retrieve the testnet paymaster address
+const testnetPaymasterAddress = await zkProvider.getTestnetPaymasterAddress();
+
+console.log(`Testnet paymaster address is ${testnetPaymasterAddress}`);
+
+const gasPrice = await provider.getGasPrice();
+
+// define paymaster parameters for gas estimation
+const paramsForFeeEstimation = utils.getPaymasterParams(testnetPaymasterAddress, {
+ type: "ApprovalBased",
+ token: TOKEN_CONTRACT_ADDRESS,
+ // set minimalAllowance to 1 for estimation
+ minimalAllowance: ethers.BigNumber.from(1),
+ // empty bytes as testnet paymaster does not use innerInput
+ innerInput: new Uint8Array(0),
+});
+
+// estimate gasLimit via paymaster
+const gasLimit = await messagesContract.estimateGas.sendMessage(NEW_MESSAGE, {
+ customData: {
+ gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
+ paymasterParams: paramsForFeeEstimation,
+ },
+});
+
+// fee calculated in ETH will be the same in
+// ERC20 token using the testnet paymaster
+const fee = gasPrice * gasLimit;
+```
+
+1. Retrieve the testnet paymaster address.
+2. Generate the paymaster parameters to estimate the transaction fees passing the paymaster address, token address, and
+ `ApprovalBased` as the paymaster flow type.
+3. Retrieve the `gasLimit` of sending the transaction with the paymaster params.
+4. Calculate the final estimated fee which is equal to `gasPrice` multiplied by `gasLimit`.
+
+### Send the transaction
+
+```typescript
+// new paymaster params with fee as minimalAllowance
+ const paymasterParams = utils.getPaymasterParams(testnetPaymasterAddress, {
+ type: "ApprovalBased",
+ token: TOKEN_CONTRACT_ADDRESS,
+ // provide estimated fee as allowance
+ minimalAllowance: fee,
+ // empty bytes as testnet paymaster does not use innerInput
+ innerInput: new Uint8Array(0),
+ });
+
+ // full overrides object including maxFeePerGas and maxPriorityFeePerGas
+ const txOverrides = {
+ maxFeePerGas: gasPrice,
+ maxPriorityFeePerGas: "1",
+ gasLimit,
+ customData: {
+ gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
+ paymasterParams,
+ }
+ }
+
+ console.log(`Sign the transaction in your wallet`);
+
+ // send transaction with additional paymaster params as overrides
+ const txHandle = await messagesContract.sendMessage(NEW_MESSAGE, txOverrides);
+```
+
+1. Create the new paymaster params with the calculated `fee` as `minimalAllowance` .
+2. Complete the transaction overrides object with `maxFeePerGas`, `maxPriorityFeePerGas` and `gasPerPubdata`
+3. Send the transaction including the `txOverrides`
+
+### Compare the final balance
+
+```typescript
+ethBalance = await provider.getBalance(walletAddress)
+tokenBalance = await tokenContract.balanceOf(walletAddress)
+console.log(`Account ${walletAddress} now has ${ethers.utils.formatEther(ethBalance)} ETH`);
+console.log(`Account ${walletAddress} now has ${ethers.utils.formatUnits(tokenBalance, 18)} tokens`);
+```
+
+Finally we retrieve and print the ETH and ERC20 balances to see how they’ve changed.
+
+## Run the script
+
+To run the script, first enter the addresses of the `ZeekSecretMessages.sol` and `TestToken.sol` contracts that we
+deployed previously ([here](/build/zksync-101/quickstart) and
+[here](/build/zksync-101/erc20-token)) in the following variables at the beginning of
+the script:
+
+```typescript
+// Address of the ZeekMessages contract
+const ZEEK_MESSAGES_CONTRACT_ADDRESS = "";
+// Address of the ERC20 token contract
+const TOKEN_CONTRACT_ADDRESS = ""
+// Message to be sent to the contract
+const NEW_MESSAGE = "This tx cost me no ETH!";
+```
+
+Next, make sure the script file is selected in the Atlas editor and click on the “Deploy” button.
+
+![ERC20 interact script in Remix](/images/101-paymasters/atlas-paymaster-script.png)
+
+You’ll see the progress in the console.
+
+If everything worked as expected, only the ERC20 balance will decrease, meaning the fee was paid with the ERC20 token
+instead of ETH.
diff --git a/content/00.build/00.zksync-101/_paymaster_intro/_remix_paymaster_intro.md b/content/00.build/00.zksync-101/_paymaster_intro/_remix_paymaster_intro.md
new file mode 100644
index 00000000..9c51f482
--- /dev/null
+++ b/content/00.build/00.zksync-101/_paymaster_intro/_remix_paymaster_intro.md
@@ -0,0 +1,139 @@
+---
+title: Paymaster with Remix
+---
+
+::callout{icon="i-heroicons-exclamation-triangle" color="amber"}
+Remix does not support `zksync-ethers` yet so you can not use it to run this script. Use Atlas instead.
+::
+
+To open the project in Remix, use the “Clone” option from the file explorer to import it from the following GitHub
+repository:`https://github.com/uF4No/zksync-101-remix`
+
+![Clone repo in Remix](/images/remix-plugin-clone-repo.gif)
+
+Once the project is imported, open the `scripts/paymaster-transaction.ts` file, which contains the code to send a
+transaction via the paymaster. Let’s go through the most important parts:
+
+### Retrieve the token balance
+
+```typescript
+// retrieve and print the current balance of the wallet
+let ethBalance = await provider.getBalance(walletAddress)
+let tokenBalance = await tokenContract.balanceOf(walletAddress)
+console.log(`Account ${walletAddress} has ${ethers.utils.formatEther(ethBalance)} ETH`);
+console.log(`Account ${walletAddress} has ${ethers.utils.formatUnits(tokenBalance, 18)} tokens`);
+```
+
+In this part we’re retrieving the ETH and ERC20 token balances of the account. We’ll compare them after the transaction
+is executed to see the difference.
+
+### Estimate transaction fee
+
+```typescript
+// retrieve the testnet paymaster address
+const testnetPaymasterAddress = await zkProvider.getTestnetPaymasterAddress();
+
+console.log(`Testnet paymaster address is ${testnetPaymasterAddress}`);
+
+const gasPrice = await provider.getGasPrice();
+
+// define paymaster parameters for gas estimation
+const paramsForFeeEstimation = utils.getPaymasterParams(testnetPaymasterAddress, {
+ type: "ApprovalBased",
+ token: TOKEN_CONTRACT_ADDRESS,
+ // set minimalAllowance to 1 for estimation
+ minimalAllowance: ethers.BigNumber.from(1),
+ // empty bytes as testnet paymaster does not use innerInput
+ innerInput: new Uint8Array(0),
+});
+
+// estimate gasLimit via paymaster
+const gasLimit = await messagesContract.estimateGas.sendMessage(NEW_MESSAGE, {
+ customData: {
+ gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
+ paymasterParams: paramsForFeeEstimation,
+ },
+});
+
+// fee calculated in ETH will be the same in
+// ERC20 token using the testnet paymaster
+const fee = gasPrice * gasLimit;
+```
+
+In this part of the script we:
+
+1. Retrieve the testnet paymaster address.
+2. Generate the paymaster parameters to estimate the transaction fees passing the paymaster address, token address, and
+ `ApprovalBased` as the paymaster flow type.
+3. Retrieve the `gasLimit` of sending the transaction with the paymaster params.
+4. Calculate the final estimated fee which is equal to `gasPrice` multiplied by `gasLimit`.
+
+### Send the transaction
+
+```typescript
+// new paymaster params with fee as minimalAllowance
+const paymasterParams = utils.getPaymasterParams(testnetPaymasterAddress, {
+ type: "ApprovalBased",
+ token: TOKEN_CONTRACT_ADDRESS,
+ // provide estimated fee as allowance
+ minimalAllowance: fee,
+ // empty bytes as testnet paymaster does not use innerInput
+ innerInput: new Uint8Array(0),
+});
+
+// full overrides object including maxFeePerGas and maxPriorityFeePerGas
+const txOverrides = {
+ maxFeePerGas: gasPrice,
+ maxPriorityFeePerGas: "1",
+ gasLimit,
+ customData: {
+ gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
+ paymasterParams,
+ }
+}
+
+console.log(`Sign the transaction in your wallet`);
+
+// send transaction with additional paymaster params as overrides
+const txHandle = await messagesContract.sendMessage(NEW_MESSAGE, txOverrides);
+```
+
+1. Create the new paymaster params with the calculated `fee` as `minimalAllowance` .
+2. Complete the transaction overrides object with `maxFeePerGas`, `maxPriorityFeePerGas` and `gasPerPubdata`
+3. Send the transaction including the `txOverrides`
+
+### Compare the final balance
+
+```typescript
+ethBalance = await provider.getBalance(walletAddress)
+tokenBalance = await tokenContract.balanceOf(walletAddress)
+console.log(`Account ${walletAddress} now has ${ethers.utils.formatEther(ethBalance)} ETH`);
+console.log(`Account ${walletAddress} now has ${ethers.utils.formatUnits(tokenBalance, 18)} tokens`);
+```
+
+Finally we retrieve and print the ETH and ERC20 balances to see how they’ve changed.
+
+## Run the script
+
+To run the script, first enter the addresses of the `ZeekSecretMessages.sol` and `TestToken.sol` contracts that we
+deployed previously ([here](/build/zksync-101/quickstart) and
+[here](/build/zksync-101/erc20-token)) in the following variables at the beginning of
+the script:
+
+```typescript
+// Address of the ZeekMessages contract
+const ZEEK_MESSAGES_CONTRACT_ADDRESS = "";
+// Address of the ERC20 token contract
+const TOKEN_CONTRACT_ADDRESS = ""
+// Message to be sent to the contract
+const NEW_MESSAGE = "This tx cost me no ETH!";
+```
+
+Next, make sure the script file is selected in the Remix editor and click on the “▶️” button.
+
+
+
+You’ll see the progress in the console.
+
+If everything worked as expected, only the ERC20 balance will decrease, meaning the fee was paid with the ERC20 token
+instead of ETH.
diff --git a/content/00.build/00.zksync-101/_quickstart/_atlas_deploy_contract.md b/content/00.build/00.zksync-101/_quickstart/_atlas_deploy_contract.md
new file mode 100644
index 00000000..d9179e74
--- /dev/null
+++ b/content/00.build/00.zksync-101/_quickstart/_atlas_deploy_contract.md
@@ -0,0 +1,31 @@
+---
+title: Quickstart with Atlas
+---
+Atlas is a browser-based IDE with an integrated AI assistant that allows you to write, test and deploy smart contracts
+directly from your browser. Click the button below to open the project in Atlas.
+
+:u-button{ icon="i-heroicons-code-bracket" size="xl" color="primary" variant="solid" :trailing="false"
+to="https://app.atlaszk.com/projects?template=https://github.com/uF4No/zksync-101-atlas&open=/contracts/ZeekSecretMessages.sol&chainId=300"
+target="_blank" label="Open smart contract in Atlas"}
+
+You can see the contract in the Atlas code editor. On the right side, make sure the selected network is “zkSync Sepolia
+tesnet“ and click on **“Deploy”** to trigger the smart contract compilation and deployment.
+
+::callout{icon="i-heroicons-light-bulb"}
+Behind the scenes, Atlas is using the zkSync Era custom solidity compiler
+(named `zksolc` ) to generate ZKEVM compatible bytecode. [Learn more about zkSync custom compilers](/zk-stack/components/compiler/toolchain/overview).
+::
+
+![Contract in Atlas](/images/101-quickstart/101-atlas-contract.png)
+
+Once compiled sign the transaction with your wallet and wait until its processed. You’ll see the contract in the
+“Deployed contracts” section. Congratulations, you’ve deployed your first smart contract to %%zk_testnet_name%%!
+
+Below the contract name you can find its deployment address. The “Live Contract State” section displays the smart
+contract balance and the value returned by the `getTotalMessages` function.
+
+![Contract deployed](/images/101-quickstart/101-atlas-deployed.png)
+
+The “Write Functions” section contains the form to interact with the `sendMessage` function. Write a message, click the
+“Run” button and confirm the transaction in your wallet. You’ll see that the `getTotalMessages` is updated to `1`. That
+means our contract is storing the messages as expected! But how can we see the replies from Zeek?
diff --git a/content/00.build/00.zksync-101/_quickstart/_remix_deploy_contract.md b/content/00.build/00.zksync-101/_quickstart/_remix_deploy_contract.md
new file mode 100644
index 00000000..9a14bc44
--- /dev/null
+++ b/content/00.build/00.zksync-101/_quickstart/_remix_deploy_contract.md
@@ -0,0 +1,39 @@
+---
+title: Quickstart with Remix
+---
+
+The Remix IDE is an open-source web and desktop application that supports Ethereum smart contract development and
+deployment, offering tools for writing, testing, debugging, and deploying smart contracts written in Solidity to EVM
+compatible protocols.
+
+:display_partial{path="/_partials/_enable-remix-zksync-plugin"}
+
+Click the button below to open the project in Remix and see the contract in the Remix code editor.
+
+:u-button{ icon="i-heroicons-code-bracket" size="xl" color="primary" variant="solid" :trailing="false"
+to="https://remix.ethereum.org/#url=https://github.com/uF4No/zksync-101-remix/blob/master/contracts/ZeekSecretMessages.sol"
+target="_blank" label="Open smart contract in Remix"}
+
+To compile the contract, click on Compile ZeeksSecretMessages.sol. If you get a popup message requesting permissions to
+access **`ACCESS TO "WRITEFILE" OF "FILE MANAGER"`,** click on Accept.
+
+::callout{icon="i-heroicons-light-bulb"}
+Behind the scenes, Remix is using the zkSync Era custom solidity compiler
+(named `zksolc` ) to generate ZKEVM compatible bytecode. [Learn more about zkSync custom compilers](/zk-stack/components/compiler/toolchain/overview).
+::
+
+We will use our wallet’s configured network to connect and deploy our smart contract so make sure your wallet is
+currently connected to the %%zk_testnet_name%%. In Remix, under the Environment Section, select “Wallet” and click on
+“Connect Wallet”.
+
+To deploy the contract, click on “Deploy” and sign the transaction on your wallet. Congratulations, you’ve deployed your
+first contract to %%zk_testnet_name%%!
+
+Below the contract name you can find the address where the contract is deployed. The “Interact” section displays the
+forms to interact with the `getTotalMessages` and `sendMessage` functions.
+
+![Remix interact zkSync contract](/images/101-quickstart/101-remix-interact.png)
+
+Write a message in the form, click the “sendMessage” button and confirm the transaction in your wallet. Once processed,
+click the `getTotalMessages` and check the response in the terminal, which should be `1`. That means our contract is
+storing the messages as expected! But how can we see the replies from Zeek?
diff --git a/content/00.build/10.quick-start/00.index.md b/content/00.build/10.quick-start/00.index.md
index b8a82653..46ae2f8f 100644
--- a/content/00.build/10.quick-start/00.index.md
+++ b/content/00.build/10.quick-start/00.index.md
@@ -46,7 +46,7 @@ If you are unfamiliar with both, choose Node.js.
### Setup era local node (optional)
Our Quickstart series will have you compile and deploy contracts to
-zkSync Sepolia testnet which requires you to have ETH in your wallet for funding transactions.
+%%zk_testnet_name%% which requires you to have ETH in your wallet for funding transactions.
Alternatively, our `zksync-cli` tool provides a way for you to setup a test node locally.
This era local node allows for quicker testing and debugging processes without incurring testnet transaction costs.
@@ -123,18 +123,18 @@ Quickly set up `foundry-zksync` by following these steps:
## Fund your wallet
-If you did not set up a local era node for development and plan to use zkSync Sepolia testnet, you will need testnet ETH to fund transactions.
+If you did not set up a local era node for development and plan to use %%zk_testnet_name%%, you will need testnet ETH to fund transactions.
1. Obtaining Testnet ETH:
- Use the [LearnWeb3 faucet](https://learnweb3.io/faucets/zksync_sepolia/)
- to directly receive testnet ETH on zkSync Sepolia.
+ to directly receive testnet ETH on %%zk_testnet_name%%.
- Alternatively, acquire SepoliaETH from [recommended faucets](https://www.notion.so/tooling/network-faucets.md) and
- transfer it to the zkSync Sepolia testnet via the [zkSync bridge](https://portal.zksync.io/bridge/?network=sepolia).
+ transfer it to the %%zk_testnet_name%% via the [zkSync bridge](https://portal.zksync.io/bridge/?network=sepolia).
1. Verify your balance:
- - Check your wallet's balance using the [zkSync Sepolia explorer](https://sepolia.explorer.zksync.io/).
+ - Check your wallet's balance using the [%%zk_testnet_name%% explorer](https://sepolia.explorer.zksync.io/).
---
diff --git a/content/00.build/10.quick-start/_partials/_setup-wallet.md b/content/00.build/10.quick-start/_partials/_setup-wallet.md
index 9f4712ad..c9715ecd 100644
--- a/content/00.build/10.quick-start/_partials/_setup-wallet.md
+++ b/content/00.build/10.quick-start/_partials/_setup-wallet.md
@@ -2,7 +2,7 @@
title: Set up your wallet
---
-Deploying contracts on the zkSync Sepolia testnet requires having testnet ETH.
+Deploying contracts on the %%zk_testnet_name%% requires having testnet ETH.
If you're working within the local development environment,
you can utilize pre-configured rich wallets and skip this step.
For testnet deployments, you should have your wallet funded from the [previous step](/build/quick-start#fund-your-wallet).
diff --git a/content/00.build/40.tooling/20.hardhat/10.getting-started.md b/content/00.build/40.tooling/20.hardhat/10.getting-started.md
index 11b7c1c7..4bdef4c0 100644
--- a/content/00.build/40.tooling/20.hardhat/10.getting-started.md
+++ b/content/00.build/40.tooling/20.hardhat/10.getting-started.md
@@ -41,7 +41,7 @@ or the [vyper-example](%%zk_git_repo_hardhat-zksync%%/tree/main/examples/vyper-e
- You are already familiar with deploying smart contracts on zkSync.
-- A wallet with sufficient Sepolia `ETH` on Ethereum and zkSync Era Testnet to pay for deploying smart contracts.
+- A wallet with sufficient Sepolia `ETH` on Ethereum and %%zk_testnet_name%% to pay for deploying smart contracts.
-To transfer Sepolia ETH to zkSync testnet use [bridges](https://zksync.io/explore#bridges).
+To transfer Sepolia ETH to %%zk_testnet_name%% use [bridges](https://zksync.io/explore#bridges).
::
Include your deployment script in the `deploy` folder and execute it running:
diff --git a/content/00.build/40.tooling/20.hardhat/60.hardhat-zksync-deploy.md b/content/00.build/40.tooling/20.hardhat/60.hardhat-zksync-deploy.md
index 5b7a172b..74ba473e 100644
--- a/content/00.build/40.tooling/20.hardhat/60.hardhat-zksync-deploy.md
+++ b/content/00.build/40.tooling/20.hardhat/60.hardhat-zksync-deploy.md
@@ -14,7 +14,7 @@ To use the `hardhat-zksync-deploy` in your project, we recommend that:
- You are already familiar with deploying smart contracts on zkSync Era.
-- A wallet with sufficient Sepolia `ETH` on Ethereum and zkSync Era Testnet to pay for deploying smart contracts on testnet.
+- A wallet with sufficient Sepolia `ETH` on Ethereum and %%zk_testnet_name%% to pay for deploying smart contracts on testnet.
- Get testnet `ETH` for zkSync Era using [bridges](https://zksync.io/explore#bridges) to bridge funds to zkSync.
diff --git a/content/00.build/40.tooling/30.foundry/10.overview.md b/content/00.build/40.tooling/30.foundry/10.overview.md
index aeb8f546..64fcda45 100644
--- a/content/00.build/40.tooling/30.foundry/10.overview.md
+++ b/content/00.build/40.tooling/30.foundry/10.overview.md
@@ -23,7 +23,7 @@ For more details and contributions, visit the [GitHub repository](%%zk_git_repo_
- **Smart Contract Deployment**: Easily deploy smart contracts to zkSync mainnet, testnet, or a local test node.
- **Asset Bridging**: Bridge assets between L1 and L2, facilitating seamless transactions across layers.
-- **Contract Interaction**: Call and send transactions to deployed contracts on zkSync testnet or local test node.
+- **Contract Interaction**: Call and send transactions to deployed contracts on %%zk_testnet_name%% or local test node.
- **Solidity Testing**: Write tests in Solidity for a familiar testing environment.
- **Fuzz Testing**: Benefit from fuzz testing, complete with shrinking of inputs and printing of counter-examples.
- **Remote RPC Forking**: Utilize remote RPC forking mode.
diff --git a/content/00.build/40.tooling/30.foundry/20.getting-started.md b/content/00.build/40.tooling/30.foundry/20.getting-started.md
index 68ec2f93..581a8e50 100644
--- a/content/00.build/40.tooling/30.foundry/20.getting-started.md
+++ b/content/00.build/40.tooling/30.foundry/20.getting-started.md
@@ -143,7 +143,7 @@ forge create [OPTIONS] --rpc-url --chain --priva
- `--factory-deps `: Specify factory dependencies.
**Example:**
-Deploy `Greeter.sol` to zkSync Sepolia testnet:
+Deploy `Greeter.sol` to %%zk_testnet_name%%:
Click to view the `Greeter.sol` contract
@@ -269,15 +269,15 @@ Learn how to query chain IDs, retrieve client versions, check L2 ETH balances, o
Expected Output: `270`, indicating the Chain ID of your local zkSync node.
-- **zkSync Sepolia Testnet:**
+- **%%zk_testnet_name%%:**
- For the zkSync Sepolia Testnet, use:
+ For the %%zk_testnet_name%%, use:
```sh
cast chain-id --rpc-url %%zk_testnet_rpc_url%%
```
- Expected Output: `300`, the Chain ID for the zkSync Sepolia Testnet.
+ Expected Output: `300`, the Chain ID for the %%zk_testnet_name%%.
### Client Version Information
diff --git a/content/00.build/60.test-and-debug/40.hardhat.md b/content/00.build/60.test-and-debug/40.hardhat.md
index 663b04c9..bbd71d29 100644
--- a/content/00.build/60.test-and-debug/40.hardhat.md
+++ b/content/00.build/60.test-and-debug/40.hardhat.md
@@ -121,7 +121,7 @@ Our aim is comprehensive coverage. Here are the test scenarios we will cover:
4. **Event Emission**: Ensure an event is emitted when changing the greeting.
Each of these test cases will rely on a common setup,
-which involves creating a provider connected to the zkSync testnet, initializing a wallet with a known private key,
+which involves creating a provider connected to the %%zk_testnet_name%%, initializing a wallet with a known private key,
and deploying the `Greeter` contract.
Let's refactor our test file with the provided script:
diff --git a/content/00.build/70.api-reference/00.index.md b/content/00.build/70.api-reference/00.index.md
index d283cf47..3e651274 100644
--- a/content/00.build/70.api-reference/00.index.md
+++ b/content/00.build/70.api-reference/00.index.md
@@ -26,7 +26,7 @@ Generally, these limits are ample, ranging from 10 to 100 requests per second (R
## Testnet
-- **Network Name**: zkSync Era Testnet
+- **Network Name**: %%zk_testnet_name%%
- **RPC URL**: https://testnet.era.zksync.dev
- **WebSocket URL**: wss://testnet.era.zksync.dev/ws
- **Chain ID**: 280
diff --git a/content/00.build/70.api-reference/20.zks-rpc.md b/content/00.build/70.api-reference/20.zks-rpc.md
index 453d1ea7..1c25060d 100644
--- a/content/00.build/70.api-reference/20.zks-rpc.md
+++ b/content/00.build/70.api-reference/20.zks-rpc.md
@@ -186,8 +186,8 @@ curl --request POST \
## `zks_getTestnetPaymaster`
-Retrieves the testnet paymaster address, specifically for interactions within the zkSync Sepolia Testnet environment.
-**Note: This method is only applicable for zkSync Sepolia Testnet.**
+Retrieves the testnet paymaster address, specifically for interactions within the %%zk_testnet_name%% environment.
+**Note: This method is only applicable for %%zk_testnet_name%%.**
#### Parameters
diff --git a/content/_partials/_enable-remix-zksync-plugin.md b/content/_partials/_enable-remix-zksync-plugin.md
new file mode 100644
index 00000000..341f9049
--- /dev/null
+++ b/content/_partials/_enable-remix-zksync-plugin.md
@@ -0,0 +1,15 @@
+---
+title: Enable zkSync plugin in Remix
+---
+### Enable the Remix zkSync plugin
+
+To deploy smart contracts to zkSync via Remix you need to enable the zkSync plugin.
+
+1. Open :external-link{text="the Remix website" href="https://remix.ethereum.org/"}
+2. Click on the **“🔌 Plugin Manager”** button in the bottom-left corner
+3. Search “zksync” and click on the **"Activate"** button.
+
+![Enable zkSync plugin in Remix](/images/enable-remix-plugin.gif)
+
+Once activated, you’ll see a new menu item with the zkSync logo. Click on it to see the different options to compile,
+deploy, and interact with smart contracts on zkSync.
diff --git a/content/_zksync.json b/content/_zksync.json
index 968972f8..d711b872 100644
--- a/content/_zksync.json
+++ b/content/_zksync.json
@@ -12,7 +12,7 @@
"block_explorer_url": "https://explorer.zksync.io"
},
"testnet": {
- "name": "zkSync Era Testnet",
+ "name": "zkSync Sepolia Testnet",
"identifier": "sepolia",
"rpc_url": "https://sepolia.era.zksync.dev",
"websocket_url": "wss://sepolia.era.zksync.dev/ws",
diff --git a/cspell-config/cspell-blockchain.txt b/cspell-config/cspell-blockchain.txt
index 52d59646..e87b2d03 100644
--- a/cspell-config/cspell-blockchain.txt
+++ b/cspell-config/cspell-blockchain.txt
@@ -1,3 +1,4 @@
+Aave
arithmetization
BoxUups
Buterin
@@ -31,5 +32,7 @@ viem
Vitalik
vyper
Weth
+IERC
+mload
Yul
Zeeve
diff --git a/cspell-config/cspell-dev.txt b/cspell-config/cspell-dev.txt
index 6561d367..2ba40f08 100644
--- a/cspell-config/cspell-dev.txt
+++ b/cspell-config/cspell-dev.txt
@@ -22,6 +22,11 @@ dockerized
Diataxis
ewasm
fontaine
+zksolc
+zkvyper
+ZKEVM
+zkout
+nomicfoundation
.getu128
.interm
inttoptr
@@ -79,6 +84,13 @@ tokio
.umin.
Vue
vue
+Viem
+viem
+Zerion
+Rabby
+tesnet
+devs
+
zext
// devs
diff --git a/cspell-config/cspell-zksync.txt b/cspell-config/cspell-zksync.txt
index 1cee5f54..c5ca94cd 100644
--- a/cspell-config/cspell-zksync.txt
+++ b/cspell-config/cspell-zksync.txt
@@ -1,7 +1,9 @@
// zkSync-related words
boojum
+Zeek
MatterLabs
Zeek
+Zeeks
zkcast
ZKEVM
zkevm
diff --git a/nuxt.config.ts b/nuxt.config.ts
index c80f06c4..9aa5fbcd 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -1,5 +1,6 @@
import { getIconCollections } from '@egoist/tailwindcss-icons';
import { zksyncIcons } from './assets/zksync-icons';
+import { customIcons } from './assets/custom-icons';
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
@@ -45,6 +46,7 @@ export default defineNuxtConfig({
icons: {
collections: {
...zksyncIcons,
+ ...customIcons,
...getIconCollections(['heroicons', 'simple-icons', 'logos', 'devicon']),
},
},
diff --git a/package.json b/package.json
index d6df4047..aef2aaba 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,6 @@
"@iconify-json/devicon": "^1.1.39",
"@iconify-json/heroicons": "^1.1.20",
"@iconify-json/simple-icons": "^1.1.95",
- "@iconify-json/zondicons": "^1.1.8",
"@nuxt/content": "^2.12.1",
"@nuxt/fonts": "^0.3.0",
"@nuxt/image": "^1.6.0",
diff --git a/public/images/101-erc20/atlas-erc20-interact.png b/public/images/101-erc20/atlas-erc20-interact.png
new file mode 100644
index 00000000..ceacfd19
Binary files /dev/null and b/public/images/101-erc20/atlas-erc20-interact.png differ
diff --git a/public/images/101-erc20/erc20-tokens-minted.png b/public/images/101-erc20/erc20-tokens-minted.png
new file mode 100644
index 00000000..c9a90746
Binary files /dev/null and b/public/images/101-erc20/erc20-tokens-minted.png differ
diff --git a/public/images/101-erc20/remix-erc20-interact.png b/public/images/101-erc20/remix-erc20-interact.png
new file mode 100644
index 00000000..c085f6bc
Binary files /dev/null and b/public/images/101-erc20/remix-erc20-interact.png differ
diff --git a/public/images/101-paymasters/atlas-paymaster-script.png b/public/images/101-paymasters/atlas-paymaster-script.png
new file mode 100644
index 00000000..e6c189f0
Binary files /dev/null and b/public/images/101-paymasters/atlas-paymaster-script.png differ
diff --git a/public/images/101-paymasters/zksync-paymaster.png b/public/images/101-paymasters/zksync-paymaster.png
new file mode 100644
index 00000000..c9fc4b20
Binary files /dev/null and b/public/images/101-paymasters/zksync-paymaster.png differ
diff --git a/public/images/101-quickstart/101-atlas-contract.png b/public/images/101-quickstart/101-atlas-contract.png
new file mode 100644
index 00000000..624c7b3e
Binary files /dev/null and b/public/images/101-quickstart/101-atlas-contract.png differ
diff --git a/public/images/101-quickstart/101-atlas-deployed.png b/public/images/101-quickstart/101-atlas-deployed.png
new file mode 100644
index 00000000..75502858
Binary files /dev/null and b/public/images/101-quickstart/101-atlas-deployed.png differ
diff --git a/public/images/101-quickstart/101-contract-deployed.png b/public/images/101-quickstart/101-contract-deployed.png
new file mode 100644
index 00000000..69dcf922
Binary files /dev/null and b/public/images/101-quickstart/101-contract-deployed.png differ
diff --git a/public/images/101-quickstart/101-contract-events.png b/public/images/101-quickstart/101-contract-events.png
new file mode 100644
index 00000000..84c0f4ab
Binary files /dev/null and b/public/images/101-quickstart/101-contract-events.png differ
diff --git a/public/images/101-quickstart/101-remix-interact.png b/public/images/101-quickstart/101-remix-interact.png
new file mode 100644
index 00000000..c6511fae
Binary files /dev/null and b/public/images/101-quickstart/101-remix-interact.png differ
diff --git a/public/images/enable-remix-plugin.gif b/public/images/enable-remix-plugin.gif
new file mode 100644
index 00000000..0ff173e6
Binary files /dev/null and b/public/images/enable-remix-plugin.gif differ
diff --git a/public/images/remix-plugin-clone-repo.gif b/public/images/remix-plugin-clone-repo.gif
new file mode 100644
index 00000000..a7d422ee
Binary files /dev/null and b/public/images/remix-plugin-clone-repo.gif differ