diff --git a/content/tutorials/guide-web3js/_dir.yml b/content/tutorials/guide-web3js/_dir.yml
index c3a70959..a7dadaed 100644
--- a/content/tutorials/guide-web3js/_dir.yml
+++ b/content/tutorials/guide-web3js/_dir.yml
@@ -1,5 +1,5 @@
title: Using web3.js to interact with ZKsync
-featured: true
+featured: false
authors:
- name: ChainSafe
url: https://web3js.org/
diff --git a/content/tutorials/permissionless-paymaster/10.index.md b/content/tutorials/permissionless-paymaster/10.index.md
new file mode 100644
index 00000000..795e6ef0
--- /dev/null
+++ b/content/tutorials/permissionless-paymaster/10.index.md
@@ -0,0 +1,454 @@
+---
+title: Integrate permissionless multi-signer paymaster into your Dapp
+description: Permissionless paymaster allows multiple Dapps to sponsor gas for their users using signature verification seamlessly.
+---
+
+This tutorial shows you how to integrate this paymaster in your Dapp.
+
+In this tutorial, we will :
+
+- Create a signer address that will sign paymaster data for gas sponsorship.
+- Deposit gas funds and add the signer address in the permissionless paymaster.
+- Set up a basic frontend to interact with the ZKsync network.
+- Create a function to sign EIP-712 standard paymaster data by the signer.
+- Integrate paymaster data in frontend to sponsor transactions for users.
+
+## Prerequisites
+
+- A [Node.js](https://nodejs.org/en/download) installation running at minimum Node.js version 18.
+- Use the `yarn` or `npm` package manager. We recommend using `yarn`.
+ To install `yarn`, follow the [Yarn installation guide](https://yarnpkg.com/getting-started/install).
+- You are a bit familiar with paymaster integration on ZKsync Era.
+ If not, please refer to the first section of the [paymaster introduction](https://docs.zksync.io/build/quick-start/paymasters-introduction).
+- Get some ZKSync Sepolia Testnet ETH [using one of these faucets](https://docs.zksync.io/ecosystem/network-faucets).
+- You know how to get your [private key from your MetaMask wallet](https://support.metamask.io/hc/en-us/articles/360015289632-How-to-export-an-account-s-private-key).
+
+::callout
+
+- Some background knowledge on the concepts helpful for the tutorial:
+
+ - [EIP-712 standard for typed message signing.](https://eips.ethereum.org/EIPS/eip-712)
+
+ - [Transaction lifecycle](https://docs.zksync.io/zk-stack/concepts/transaction-lifecycle#eip-712-0x71) on ZKsync Era.
+
+ - [Gas estimation for transactions](https://docs.zksync.io/build/developer-reference/fee-model#gas-estimation-for-transactions) guide.
+
+ - [Introduction to system contracts especially NonceHolder.](https://docs.zksync.io/build/developer-reference/era-contracts/system-contracts#nonceholder)
+
+::
+
+## Overview
+The permissionless multi-signer paymaster enables ZKsync Dapps to sponsor gas for their users through signature verification.
+Signature-based verification allows Dapps to setup **custom logic** for gas sponsorship.
+
+Dapps can begin utilizing this paymaster by **simply depositing funds and adding a signer address.**
+Thus removing the need to deploy a paymaster at all or relying on any 3rd party.
+
+There are 2 primary actors involved:
+
+**Manager**: Fully managed by the Dapp, responsible for depositing/withdrawing gas funds, and adding or removing signer addresses.
+
+**Signers**: Managed by the Dapp or a trusted third party like Zyfi API. A signer’s signature is required to access gas funds by the Dapp’s user.
+
+## Multi-signer
+This paymaster allows the manager to set multiple signers through which users can have access to the gas funds. Hence, it is a one-to-many relationship.
+![manager-signer-relation-diagram](/images/permissionless-paymaster/manager-signer.jpg)
+
+## Integration
+Below the diagram provides the flow of the integration:
+
+1. Dapp decides on custom logic for each user. Let's assume that Dapp decides to sponsor gas for every approve transaction.
+
+2. Dapp calls the backend server or Zyfi API with relevant data to get the signer's signature.
+ - It is recommended that the signer's signing part is done on a secure backend server of the Dapp.
+
+3. The signer's key signs this paymaster data and returns the signature and signer address to the Dapp's frontend.
+
+4. Paymaster address and required data with signature are added to the transaction blob in the frontend.
+
+5. User gets transaction signature request pop-up on their wallet. **User only signs the transaction** and the transaction is sent on-chain.
+
+6. The paymaster validates the signature, identifies the manager related to the signer,
+deducts gas fees from the manager's balance, and pays for the user's transaction
+
+![flow](/images/permissionless-paymaster/flowDiagram.jpg)
+
+For this tutorial, we will use paymaster deployed on ZKsync sepolia testnet : [0xc1B0E2edC4cCaB51A764D7Dd8121CBf58C4D9E40](https://sepolia.explorer.zksync.io/address/0xc1B0E2edC4cCaB51A764D7Dd8121CBf58C4D9E40#transactions)
+
+## 1. Create a signer address
+The paymaster will verify signature based on this signer address.
+The private key of this signer address should be stored securely by the Dapp.
+
+- Here is an easy way to create one:
+
+```javascript
+const {Wallet} = require("zksync-ethers");
+
+const signer = Wallet.createRandom();
+
+console.log("Signer address: " + signer.address);
+console.log("Signer private key: " + signer.privateKey);
+```
+
+## 2. Deposit gas funds and add the signer address
+Navigate to ZKsync Sepolia Testnet Explorer: [0xc1B0E2edC4cCaB51A764D7Dd8121CBf58C4D9E40](https://sepolia.explorer.zksync.io/address/0xc1B0E2edC4cCaB51A764D7Dd8121CBf58C4D9E40#contract)
+Using a **different address** with test funds, call the `depositAndAddSigner()` function with 0.1 ether
+and the signer address as the function arguments.
+![deposit and add a signer](/images/permissionless-paymaster/depositAndAddSigner.png)
+
+::callout{icon="i-heroicons-exclamation-circle"}
+The depositor address is considered a "manager". A manager can deposit/withdraw gas funds and add/remove signers at any given time.
+
+- *A signer can only be linked to one manager at a time.*
+
+- *A manager can be a signer address too. (not recommended)*
+
+::
+
+## 3. Setup a basic frontend project
+
+We're going to use the [React.js web framework](https://react.dev/) to build this app.
+In addition, we're going to use the `zksync-ethers` SDK, `ethers@v5`, and `Next.js`.
+In order to focus on paymaster, we have bootstrapped a [template using `zksync-cli create`](https://github.com/ondefy/basic-frontend-template.git).
+We'll just need to implement the methods to sign and integrate paymaster into the frontend.
+Let's start!
+
+1. Clone the template project and `cd` into the folder.
+
+ ```sh
+ git clone https://github.com/ondefy/basic-frontend-template.git
+ cd ./basic-frontend-template
+ ```
+
+2. Make sure you are on the `main` branch(use `git branch` to check) and spin up the project.
+
+ ```bash
+ yarn
+ yarn dev
+ ```
+
+Navigate to `http://localhost:3000/` in a browser to see the application running.
+
+![frotend](/images/permissionless-paymaster/frontend.png)
+
+This is a simple template that allows users to approve a certain amount of DAI tokens to a spender address on ZKsync Sepolia Testnet.
+
+*Our goal for this tutorial is to sponsor this approval transaction using the paymaster.*
+
+---
+
+## 4. Create a function to sign EIP-712 typed paymaster data
+This paymaster verifies the signature signed by the signer address on the below data.
+On successful validation, it allows sponsorship for the user using manager's deposited gas funds.
+
+```solidity
+ bytes32 messageHash = keccak256(
+ abi.encode(
+ SIGNATURE_TYPEHASH,
+ _from,
+ _to,
+ _expirationTime,
+ _maxNonce,
+ _maxFeePerGas,
+ _gasLimit
+ )
+ );
+```
+
+::callout{icon="i-heroicons-exclamation-triangle"}
+For the sake of this tutorial, we will be creating the signing function in the repo itself at *"src/backend/getSignatureApiCall.ts"* path.
+
+**It is highly recommended, that signing should be done in a closed backend server for the safety of signer's private key.**
+::
+
+- Create a `.env` file in the root folder and add signer's private key as `NEXT_PUBLIC_SIGNER_PRIVATE_KEY`. Run `source .env` once done.
+
+``` [.env]
+NEXT_PUBLIC_SIGNER_PRIVATE_KEY=0xabcabc...
+```
+
+- We will create a file `backend/getSignatureApiCall.ts` with `getSignature()` function that signs required data with the help of signer as below:
+
+```javascript [src/backend/getSignatureApiCall.tsx]
+import {ethers, BigNumber} from "ethers";
+import {Contract, Wallet, Provider} from "zksync-ethers";
+import dotenv from "dotenv";
+dotenv.config();
+
+export async function getSignature(
+ from: string, to: string, expirationTime: BigNumber, maxNonce: BigNumber, maxFeePerGas: BigNumber, gasLimit: BigNumber
+){
+ const rpcUrl = process.env.ZKSYNC_RPC_URL ?? 'https://sepolia.era.zksync.dev';
+ const provider = new Provider(rpcUrl);
+ const signer = new Wallet(process.env.NEXT_PUBLIC_SIGNER_PRIVATE_KEY || "", provider);
+
+// Paymaster Sepolia Testnet address
+const paymasterAddress = "0xc1B0E2edC4cCaB51A764D7Dd8121CBf58C4D9E40";
+const paymasterAbi = [
+ "function eip712Domain() public view returns (bytes1 fields,string memory name,string memory version,uint256 chainId,address verifyingContract,bytes32 salt,uint256[] memory extensions)",
+];
+
+const paymasterContract = new Contract(
+ paymasterAddress,
+ paymasterAbi,
+ provider
+);
+// EIP-712 domain from the paymaster
+ const eip712Domain = await paymasterContract.eip712Domain();
+ const domain = {
+ name: eip712Domain[1],
+ version: eip712Domain[2],
+ chainId: eip712Domain[3],
+ verifyingContract: eip712Domain[4],
+ }
+ const types = {
+ PermissionLessPaymaster: [
+ { name: "from", type: "address"},
+ { name: "to", type: "address"},
+ { name: "expirationTime", type: "uint256"},
+ { name: "maxNonce", type: "uint256"},
+ { name: "maxFeePerGas", type: "uint256"},
+ { name: "gasLimit", type: "uint256"}
+ ]
+ };
+// -------------------- IMPORTANT --------------------
+ const values = {
+ from, // User address
+ to, // Your dapp contract address which the user will interact
+ expirationTime, // Expiration time post which the signature expires
+ maxNonce, // Max nonce of user after which signature becomes invalid
+ maxFeePerGas, // Current max gas price
+ gasLimit // Max gas limit you want to allow to your user. Ensure to add 60K gas for paymaster overhead.
+ }
+// Note: MaxNonce allows the signature to be replayed.
+// For eg: If the currentNonce of user is 5, maxNonce is set to 10. The signature will allowed to be replayed for nonce 6,7,8,9,10 on the same `to` address by the same user.
+// This is to provide flexibility to Dapps to ensure signature works if users have multiple transactions running.
+// Important: Signers are recommended to set maxNonce as current nonce of the user or as close as possible to ensure the safety of gas funds.
+// Important: Signers should set expirationTime close enough to ensure safety of funds.
+
+ return [paymasterAddress,(await signer._signTypedData(domain, types, values)), signer.address];
+}
+```
+
+## 5. Estimate gas and create paymaster data
+
+##### **5.1.** Add the `preparePaymasterParam()` function in the `src/components/WriteContract.tsx` file
+
+- This function will set expiration time, max nonce, gas fees, and gas limit and call the `getSignature()` function.
+
+::callout{icon="i-heroicons-exclamation-circle"}
+
+*Notice how we add 65K gas to the gas limit.*
+
+This is to facilitate paymaster overhead to ensure the transaction is passed successfully.
+
+All extra ETH spent will be refunded back to the manager's balance, hence, setting the gas limit high would not result in loss of funds.
+
+::
+
+- At the end, it returns `paymasterParams` data that we will add to the transaction.
+
+```javascript [src/components/WriteContract.tsx]
+'use client'
+
+import { useState } from 'react';
+import { Contract, Provider, utils } from "zksync-ethers";
+import { useAsync } from '../hooks/useAsync';
+import { daiContractConfig } from './contracts'
+import { useEthereum } from './Context';
+import { getSignature } from "../backend/getSignatureApiCall";
+import { BigNumber, ethers } from "ethers";
+const abiCoder = new ethers.utils.AbiCoder();
+
+const preparePaymasterParam = async (account:any, estimateGas: BigNumber) =>{
+ const rpcUrl = process.env.ZKSYNC_RPC_URL ?? "https://sepolia.era.zksync.dev";
+ const provider = new Provider(rpcUrl);
+ // Below part can be managed in getSignature() as well.
+ // ------------------------------------------------------------------------------------
+ // Note: Do not set maxNonce too high than current to avoid an unwanted signature replay.
+ // Consider maxNonce is as replayLimit. Setting maxNonce to currentNonce means 0 replays.
+ // Get the maxNonce allowed to user. Here we ensure it's currentNonce.
+ const maxNonce = BigNumber.from(
+ await provider.getTransactionCount(account.address || "")
+ );
+ // You can also check for min Nonce from the NonceHolder System contract to fully ensure as ZKsync support arbitrary nonce.
+ const nonceHolderAddress = "0x0000000000000000000000000000000000008003";
+ const nonceHolderAbi = [
+ "function getMinNonce(address _address) external view returns (uint256)",
+ ];
+ const nonceHolderContract = new Contract(
+ nonceHolderAddress,
+ nonceHolderAbi,
+ provider
+ );
+ const maxNonce2 = await nonceHolderContract.callStatic.getMinNonce(
+ account.address || ""
+ );
+ console.log(maxNonce2.toString());
+ // -----------------
+ // Get the expiration time. Here signature will be valid up to 120 sec.
+ const currentTimestamp = BigNumber.from(
+ (await provider.getBlock("latest")).timestamp
+ );
+ const expirationTime = currentTimestamp.add(120);
+ // Get the current gas price.
+ const maxFeePerGas = await provider.getGasPrice();
+ // Add paymaster overhead gas to be on the safe side.
+ const gasLimit = estimateGas.add(65000);
+ // ------------------------------------------------------------------------------------
+ const [paymasterAddress, signature, signerAddress] = await getSignature(
+ account.address.toString(),
+ daiContractConfig.address.toString(),
+ expirationTime,
+ maxNonce,
+ maxFeePerGas,
+ gasLimit
+ );
+ console.log("Signer: " + signerAddress);
+ // We encode the extra data to be sent to paymaster
+ // Notice how it's not required to provide from, to, maxFeePerGas, and gasLimit as per the signature above.
+ // That's because paymaster will get it from the transaction struct directly to ensure it's the correct user.
+ const innerInput = ethers.utils.arrayify(
+ abiCoder.encode(
+ ["uint256", "uint256", "address", "bytes"],
+ [
+ expirationTime, // As used in the above signature
+ maxNonce, // As used in the above signature
+ signerAddress, // The signer address
+ signature,
+ ]
+ ) // Signature created in the above snippet. get from API server
+ );
+ // getPaymasterParams function is available in zksync-ethers
+ const paymasterParams = utils.getPaymasterParams(
+ paymasterAddress, // Paymaster address
+ {
+ type: "General",
+ innerInput: innerInput,
+ }
+ );
+ // Returns paymaster params, gas fee, gas limit
+ return [paymasterParams, maxFeePerGas, gasLimit];
+ };
+```
+
+##### **5.2** Estimate gas and call the above function
+
+- In the `WriteContract` component, we will estimate the gas and call the above created `preparePaymasterParam` function
+ before the contract call for approve transaction.
+
+```javascript [src/components/WriteContract.tsx]
+ // ------------- Add above approve function call
+ // Estimate gas
+ const estimateGas = await contract.estimateGas.approve(spender,amount);
+ const [paymasterParams, maxFeePerGas, gasLimit] = await preparePaymasterParam(account, estimateGas);
+ // --------------
+ const tx = await contract.approve(spender, amount);
+
+```
+
+## 6. Add paymaster data to the transaction
+
+- We will update the approve function call by adding `paymasterParams` in the `customData` of the user transaction as below.
+
+- Ensure to set `maxFeePerGas` and `gasLimit` as signed by the signer.
+
+```javascript [src/components/WriteContract.tsx]
+
+ // Estimate gas
+ const estimateGas = await contract.estimateGas.approve(spender,amount);
+ const [paymasterParams, maxFeePerGas, gasLimit] = await preparePaymasterParam(account, estimateGas);
+
+ const tx = await contract.approve(spender, amount,{
+ maxFeePerGas,
+ gasLimit,
+ customData: { // Add custom data with paymaster params
+ paymasterParams,
+ gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
+ }
+ });
+
+```
+
+::callout{icon="i-heroicons-exclamation-circle"}
+
+- Funds are deducted as per: `gasPrice`*`gasLimit` upon successful verification.
+Dapp should ensure enough funds are deposited to avoid failures.
+
+- If a signer's private key is leaked, the respective manager will need to replace/remove the signer immediately.
+
+::
+
+- The user shall get a signature request pop-up for transaction.
+Here the user can verify that gas is not being paid from their end and only a signature is required.
+![transaction](/images/permissionless-paymaster/signatureRequest.png)
+
+::callout{icon="i-heroicons-check-circle"}
+Paymaster is successfully integrated.
+::
+
+The final integration code should look like [`permissionless-paymaster-integration` branch of the template repo.](https://github.com/ondefy/basic-frontend-template/tree/permissionless-paymaster-integration)
+
+## Refunds
+ZKsync refunds ETH to the paymaster for the unused gas.
+All refunded ETH are added back to the respective manager's balance in the **next paymaster transaction**.
+
+## Notes
+
+1. `_maxNonce` introduces flexibility to Dapps by allowing signature replay in a secure constrained way.
+The signer should ensure `_maxNonce` is not too big from the current nonce of the user and `_expirationTime` is not too far from the current timestamp.
+If `_maxNonce` is set to current nonce of the user, then the signature cannot be replayed at all.
+ - Check [here](https://github.com/ondefy/permissionless-multisigner-paymaster/blob/2436a3fd8c401e607b89960d903dc70ca3670ed0/contracts/paymasters/PermissionlessPaymaster.sol#L199-L203)
+
+ ```solidity
+
+ // Validate that the transaction generated by the API is not expired
+ if (block.timestamp > expirationTime)
+ revert Errors.PM_SignatureExpired();
+ // Validate that the nonce is not higher than the maximum allowed
+ if (_transaction.nonce > maxNonce) revert Errors.PM_InvalidNonce();
+
+ ```
+
+2. ZKsync might allow [arbitrary nonce ordering](https://docs.zksync.io/zk-stack/components/zksync-evm/bootloader#nonce-ordering) in the future.
+To ensure surety over the nonce of a user, you can add one more check by calling `getMinNonce` on the
+[NonceHolder system contract of ZKsync](https://github.com/matter-labs/era-contracts/blob/f4ae6a1b90e2c269542848ada44de669a5009290/system-contracts/contracts/interfaces/INonceHolder.sol#L17).
+For more details, check docs [here](https://docs.zksync.io/build/developer-reference/era-contracts/system-contracts#nonceholder) & [here](https://docs.zksync.io/sdk/js/ethers/api/v5/types#accountnonceordering).
+
+3. This paymaster has a gas overhead of 51K-59K gas, which is quite nominal compared to other paymaster gas overheads.
+Signer should ensure to add this overhead(60K~65K) in the `_gasLimit`.
+
+4. `_gasLimit` should be set in the near range of the estimated gas required + paymaster gas overhead.
+
+## Other functionalities
+
+1. Manager can `replaceSigner`, `addSigner`, `batchAddSigners`, `removeSigner`, `batchRemoveSigners`
+`depositAndAddSigner`, `deposit`, `withdraw`, `withdrawFull` & `withdrawAndRemoveSigners`
+
+2. `depositOnBehalf` and `rescueTokens` are public functions.
+
+3. A signer can call selfRevokeSigner to revoke their signing privileges.
+
+4. To check the latest balance of the manager including refunded ETH, call `getLatestManagerBalance`
+
+## Common Errors
+
+1. Paymaster validation errors:
+ - All paymaster-related errors can be found [here].(https://github.com/ondefy/permissionless-multisigner-paymaster/blob/main/contracts/libraries/Errors.sol)
+ - One of the common signature validation errors is that `gasLimit` and `gasPrice` are not set exactly in the transaction as signed by the signer.
+
+2. Panic due to not enough balance of the manager:
+ - Please try depositing additional ETH to the manager's balance in paymaster so it has enough funds to pay for the transaction.
+ - You can use [ZKsync native bridge or ecosystem partners](https://zksync.io/explore#bridges) (make sure Sepolia testnet is supported by selected bridge).
+
+3. Please reach out to us on [our Discord](https://discord.com/invite/KHchZXmv8Q) in case of other errors.
+
+## Learn More
+
+- Audited by [Cantina](https://www.zyfi.org/report-permissionless-paymaster-zyfi.pdf).
+- To learn more about this permissionless paymaster, check out
+ [documentation](https://docs.zyfi.org/permissionless-multi-signer-paymaster/public-good).
+- To learn more about the `zksync-ethers` SDK, check out its
+ [documentation](https://docs.zksync.io/sdk/js/ethers).
+- To learn more about the ZKsync hardhat plugins, check out their
+ [documentation](https://docs.zksync.io/build/tooling/hardhat/getting-started).
diff --git a/content/tutorials/permissionless-paymaster/_dir.yml b/content/tutorials/permissionless-paymaster/_dir.yml
new file mode 100644
index 00000000..a7ba4c63
--- /dev/null
+++ b/content/tutorials/permissionless-paymaster/_dir.yml
@@ -0,0 +1,29 @@
+title: Integrate Permissionless Multi-signer Paymaster in your Dapp
+featured: true
+authors:
+ - name: Zyfi
+ url: https://zyfi.org
+ avatar: https://avatars.githubusercontent.com/u/94560147?s=200&v=4
+github_repo: https://github.com/ondefy/permissionless-multisigner-paymaster
+tags:
+ - paymaster
+ - gas sponsorship
+ - tutorial
+ - eip-712
+summary:
+ Integrate Zyfi's signature based permissionless multi-signer paymaster in your Dapp to sponsor gas funds for your
+ users.
+description:
+ Zyfi's new permissionless paymaster allows protocols to integrate paymaster into their ecosytem without the need to
+ deploy paymaster or trusting 3rd party.
+
+what_you_will_learn:
+ - How permissionless multisignature paymaster works
+ - How to integrate this paymaster in your Dapp
+ - How to sign EIP-712 signature data required for this paymaster
+ - How to send transactions through this paymaster
+updated: 2024-07-26
+tools:
+ - zksync-cli
+ - zksync-ethers
+ - Hardhat
diff --git a/cspell-config/cspell-blockchain.txt b/cspell-config/cspell-blockchain.txt
index 0fda76bf..9ea5e40d 100644
--- a/cspell-config/cspell-blockchain.txt
+++ b/cspell-config/cspell-blockchain.txt
@@ -1,6 +1,7 @@
Aave
abis
arithmetization
+arrayify
BoxUups
Buterin
dapp
@@ -69,3 +70,4 @@ Zeeve
Zerion
Zetta
Zonic
+Zyfi
\ No newline at end of file
diff --git a/public/images/permissionless-paymaster/depositAndAddSigner.png b/public/images/permissionless-paymaster/depositAndAddSigner.png
new file mode 100644
index 00000000..49b8b03a
Binary files /dev/null and b/public/images/permissionless-paymaster/depositAndAddSigner.png differ
diff --git a/public/images/permissionless-paymaster/flowDiagram.jpg b/public/images/permissionless-paymaster/flowDiagram.jpg
new file mode 100644
index 00000000..d7e4f0c8
Binary files /dev/null and b/public/images/permissionless-paymaster/flowDiagram.jpg differ
diff --git a/public/images/permissionless-paymaster/frontend.png b/public/images/permissionless-paymaster/frontend.png
new file mode 100644
index 00000000..2b97f228
Binary files /dev/null and b/public/images/permissionless-paymaster/frontend.png differ
diff --git a/public/images/permissionless-paymaster/manager-signer.jpg b/public/images/permissionless-paymaster/manager-signer.jpg
new file mode 100644
index 00000000..bde6d5a4
Binary files /dev/null and b/public/images/permissionless-paymaster/manager-signer.jpg differ
diff --git a/public/images/permissionless-paymaster/signatureRequest.png b/public/images/permissionless-paymaster/signatureRequest.png
new file mode 100644
index 00000000..c2f9cdaf
Binary files /dev/null and b/public/images/permissionless-paymaster/signatureRequest.png differ