Secure Your Web3 Project Finances with Endpoint Armor: Control Access and Set Rate Limits

Irwing TelloIrwing Tello
7 min read

In the early stages of the Web3 ecosystem, managing access control and rate limits for our endpoint was quite cumbersome. Nowadays, these issues have solutions that can save our project money and prevent looping problems. If you're in finance and don't understand why your Web3 teams exceed the allocated credits in your plan, this is an effective way to address the issue.

What You Will Need

What We Will Do

What is QuickNode?

QuickNode is your partner in the Web3 space, helping you search for NFTs across different blockchains and build token-gated communities. By using various nodes, you can make your Web3 setup simpler and better.

What is Endpoint Armor?

In simple terms, this plugin lets you customize your RPC usage. For example, you can limit operations to a specific smart contract or set rate limits to prevent abuse, making sure it fits your exact needs.

Understanding how Endpoint Armor works.

First, we need an active RPC on QuickNode.

QuickNode RPC Dashboard

After that, go to the "Add-ons" tab and search for the "Endpoint Armor" add-on.

QuickNode Add-On Dashboard

Now, activate the plugin by clicking on the "Explore" button.

QuickNode Endpoint Armor Add-On

As a result, you will see details about "Endpoint Armor" ,please click on "Install for Free".

Then, wait a few minutes for endpoint armor to be installed. Refresh the "Add-ons" tab to see the update.

You should now see the "Dashboard" option. Click on it.

QuickNode Endpoint Armor Add-On: Opening Dashboard

After that, you will see the next page. Please click on the dropdown menu labeled "Select an endpoint".

QuickNode Endpoint Armor Dashboard

Then, search for your endpoint and click on "Enable Endpoint Armor".

Selecting Our Endpoint in the QuickNode Endpoint Armor Dashboard

After that, select the endpoint again, and Endpoint Armor will be activated.

QuickNode Endpoint Armor Dashboard activated

Now you can see the configuration options where you can restrict your endpoint and save money!

According to the documentation:

"At least one method name must be specified in the configuration when setting up rate limits. This is because Endpoint Armor, by default, blocks all methods that are not explicitly mentioned in the settings. Therefore, to ensure that your endpoint allows access to the required methods, you must list each method you intend to use."

For example, we have two URLs:

QuickNode's public URLs offer general security, but Endpoint Armor provides more specific customization for your solution and budget.

To use this configuration, you need to copy the RPC URL from Endpoint Armor.

In my case, this is my URL:

https://dry-methodical-sea.secure.quiknode.pro

Configuring our secure RPC on MetaMask

To begin testing our endpoint, please configure an endpoint in your wallet provider. In my case, it’s MetaMask.

Next, paste your secured endpoint into the RPC URL field, click on "Save", and fill in the network details according to your needs.

Configuring our secured rpc url on Metamask

Testing on Remix

Please create a new contract.

Remix: Smart Contract Creator

After that, paste the code from the Open Zepellin Wizard.

// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0
pragma solidity ^0.8.20;

import "@openzeppelin/contracts@5.0.2/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts@5.0.2/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts@5.0.2/token/ERC20/extensions/ERC20Pausable.sol";
import "@openzeppelin/contracts@5.0.2/access/AccessControl.sol";
import "@openzeppelin/contracts@5.0.2/token/ERC20/extensions/ERC20Permit.sol";

contract Coin is ERC20, ERC20Burnable, ERC20Pausable, AccessControl, ERC20Permit {
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor(address defaultAdmin, address pauser, address minter)
        ERC20("Coin", "MXN")
        ERC20Permit("Coin")
    {
        _grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);
        _grantRole(PAUSER_ROLE, pauser);
        _grantRole(MINTER_ROLE, minter);
    }

    function pause() public onlyRole(PAUSER_ROLE) {
        _pause();
    }

    function unpause() public onlyRole(PAUSER_ROLE) {
        _unpause();
    }

    function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
        _mint(to, amount);
    }

    // The following functions are overrides required by Solidity.

    function _update(address from, address to, uint256 value)
        internal
        override(ERC20, ERC20Pausable)
    {
        super._update(from, to, value);
    }
}

Now please compile your contract.

Compiling Our Smart Contract on Remix

After that, we need to go to our Endpoint Armor dashboard to manage the rules for our endpoint

And please paste these configuration rules.

Endpoint Armor with the proper configuration to start testing our rules

{
  "methods": {
    "eth_getBalance": "enabled",
    "eth_call": "enabled",
    "web3_sha3": "enabled",
    "eth_chainId": "enabled",
    "eth_getCode": "enabled",
    "eth_getLogs": {
      "latestBlocks": 100
    },
    "net_version": "enabled",
    "eth_gasPrice": "enabled",
    "eth_newFilter": "enabled",
    "eth_subscribe": "enabled",
    "eth_blockNumber": "enabled",
    "eth_estimateGas": "enabled",
    "eth_unsubscribe": "enabled",
    "eth_getFilterLogs": "enabled",
    "eth_getBlockByHash": "enabled",
    "web3_clientVersion": "enabled",
    "eth_sendTransaction": "enabled",
    "eth_uninstallFilter": "enabled",
    "eth_getBlockByNumber": "enabled",
    "eth_getFilterChanges": "enabled",
    "eth_getTransactionCount": "enabled",
    "eth_getTransactionByHash": "enabled",
    "eth_getTransactionReceipt": "enabled",
    "net_peerCount": "enabled",
    "net_listening": "enabled",
    "eth_protocolVersion": "enabled",
    "eth_syncing": "enabled",
    "eth_coinbase": "enabled",
    "eth_mining": "enabled",
    "eth_hashrate": "enabled",
    "eth_accounts": "enabled",
    "eth_getStorageAt": "enabled",
    "eth_getBlockTransactionCountByHash": "enabled",
    "eth_getBlockTransactionCountByNumber": "enabled",
    "eth_getUncleCountByBlockHash": "enabled",
    "eth_getUncleCountByBlockNumber": "enabled",
    "eth_sign": "enabled",
    "eth_signTransaction": "enabled",
    "eth_sendRawTransaction": "enabled",
    "eth_getTransactionByBlockHashAndIndex": "enabled",
    "eth_getTransactionByBlockNumberAndIndex": "enabled",
    "eth_getUncleByBlockHashAndIndex": "enabled",
    "eth_getUncleByBlockNumberAndIndex": "enabled",
    "eth_getCompilers": "enabled",
    "eth_compileLLL": "enabled",
    "eth_compileSolidity": "enabled",
    "eth_compileSerpent": "enabled",
    "eth_newBlockFilter": "enabled",
    "eth_newPendingTransactionFilter": "enabled"
  },
  "visitorRateLimits": {
    "reqPerSecond": 3
  },
  "endpointRateLimits": {
    "reqPerMinute": 100,
    "reqPerSecond": 5
  }
}

Then deploy your contract.

Deploying our smart contract with our secured endpoint

Let's break down these rules!

For instance, to use the "balanceOf" method, we need to make a JSON-RPC call using "eth_call".

In our rules, this method is configured as follows:

"eth_call": "enabled"

We have different types of value to be filled in the method "eth_call"

  • enabled: No limits on the number of requests.

    • Optional values:

      • reqPerHour: Maximum number of requests allowed per hour.

      • reqPerMinute: Maximum number of requests allowed per minute.

      • reqPerSecond: Maximum number of requests allowed per second.

Now, you might notice that there are many JSON-RPC methods listed. This is because, by default, not all methods are enabled.

Let's test the balanceOf method to ensure everything works as expected.

Testing our QuickNode Endpoint Armor rules on Remix

After understanding how the rules work, let's delete the line.

"eth_call": "enabled"

Now, let’s test the balanceOf method again.

You can see the error:

call to Irwing.balanceOf errored: Error occurred: Non-200 status code: '404'.

Non-200 status code: '404'

You may want to cautiously increase the gas limit if the transaction went out of gas.

This is because we restrict the method "eth_call" , we need to include the method and the options for the limits.

For example, if you want to ensure that your endpoint is only interacting with your smart contract, you need to modify this line:

        "eth_call": {
            "contractAllowlist": [
                "0xdAC17F958D2ee523a2206206994597C13D831ec7"
            ]
        }

Here’s how the line looks in the entire code:

Endpoint Armor rules with new changes about restricting one smart contract

Don’t forget to submit the changes after each modification.

Now, let’s test the method again.

You should see that everything works! ,but what happens if we change the contract and interact with the same method?

Testing with our smart contract the secured rpc

We encountered an error:

Error obtained by Remix,because we restrict the smart contract to only execute one smart contract

If we encounter an error, it means the rule is working as expected.

Use Case Example

Now, imagine you are only using your endpoint to fetch balance in the backend, but you want to ensure to only execute this, but you don't know how to do this,or you are not too technical,you can use AI.
In my case i will use ChatGPT.

Rules:
{
  "methods": {
    "eth_getBalance": "enabled",
    "eth_call": "enabled",
    "web3_sha3": "enabled",
    "eth_chainId": "enabled",
    "eth_getCode": "enabled",
    "eth_getLogs": {
      "latestBlocks": 100
    },
    "net_version": "enabled",
    "eth_gasPrice": "enabled",
    "eth_newFilter": "enabled",
    "eth_subscribe": "enabled",
    "eth_blockNumber": "enabled",
    "eth_estimateGas": "enabled",
    "eth_unsubscribe": "enabled",
    "eth_getFilterLogs": "enabled",
    "eth_getBlockByHash": "enabled",
    "web3_clientVersion": "enabled",
    "eth_sendTransaction": "enabled",
    "eth_uninstallFilter": "enabled",
    "eth_getBlockByNumber": "enabled",
    "eth_getFilterChanges": "enabled",
    "eth_getTransactionCount": "enabled",
    "eth_getTransactionByHash": "enabled",
    "eth_getTransactionReceipt": "enabled",
    "net_peerCount": "enabled",
    "net_listening": "enabled",
    "eth_protocolVersion": "enabled",
    "eth_syncing": "enabled",
    "eth_coinbase": "enabled",
    "eth_mining": "enabled",
    "eth_hashrate": "enabled",
    "eth_accounts": "enabled",
    "eth_getStorageAt": "enabled",
    "eth_getBlockTransactionCountByHash": "enabled",
    "eth_getBlockTransactionCountByNumber": "enabled",
    "eth_getUncleCountByBlockHash": "enabled",
    "eth_getUncleCountByBlockNumber": "enabled",
    "eth_sign": "enabled",
    "eth_signTransaction": "enabled",
    "eth_sendRawTransaction": "enabled",
    "eth_getTransactionByBlockHashAndIndex": "enabled",
    "eth_getTransactionByBlockNumberAndIndex": "enabled",
    "eth_getUncleByBlockHashAndIndex": "enabled",
    "eth_getUncleByBlockNumberAndIndex": "enabled",
    "eth_getCompilers": "enabled",
    "eth_compileLLL": "enabled",
    "eth_compileSolidity": "enabled",
    "eth_compileSerpent": "enabled",
    "eth_newBlockFilter": "enabled",
    "eth_newPendingTransactionFilter": "enabled"
  },
  "visitorRateLimits": {
    "reqPerSecond": 3
  },
  "endpointRateLimits": {
    "reqPerMinute": 100,
    "reqPerSecond": 5
  }
}

Instruction:
I want to fetch only the balance from the backend.

Please refer to the following documentation and use only Ethereum JSON-RPC methods:
https://www.quicknode.com/docs/ethereum/endpoint-armor
https://www.quicknode.com/guides/quicknode-products/endpoint-security/how-to-secure-your-endpoint-using-endpoint-armor

Obtaining rules for Endpoint armor with chatgpt

Now you can use test these rules and improve your project finances!

Conclusion

I'm proud of you!. You stand out from other teams by protecting your endpoints and reducing the risk of endpoint abuse.

I encourage you to implement this in your product and monitor your dapp workflow to ensure you have the optimal settings as you scale your project.

We are here to support you ❤️ .

We ❤️ Feedback!

If you have any feedback or questions on this guide, let us know.
Or, feel free to reach out to us via Twitter or our Discord community server.

We’d love to hear from you!

Author: Irwing Tello

Discord: https://discord.com/invite/ADjtsHVreT

Twitter: https://twitter.com/irwingtello

LinkedIn: https://www.linkedin.com/in/irwingtello/

Email: irwing@dfhcommunity.com

Website: dfhcommunity.com

Youtube: https://www.youtube.com/@irwingtellomx

You can support my work here:

https://www.buymeacoffee.com/irwingtello

BTC: 34kXK9CpTJP1PyHKw2kUD2bt6rtGcG5CHY

EVM Address: 0x8B98F8Ff69d2A720120eD6C71A9Bc5072b8Eb46D

Solana: Ey9oVFHW79giacRZaKxigYjeihMsY7ox8jxc7Hp1sJmS

0
Subscribe to my newsletter

Read articles from Irwing Tello directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Irwing Tello
Irwing Tello

As a driven professional with a passion for technology and business, I excel at developing and implementing innovative strategies that drive value for end-users. With a background in blockchain and a strong commitment to sharing my knowledge and experience with others, I am always seeking new opportunities to promote technology and help others understand its potential to improve lives. My core activities include staying up-to-date with the latest technological advancements, participating in projects that contribute to society, building a diverse network of friends and colleagues from different countries, and fostering a supportive and inclusive community that encourages individuals to reach their full potential. Whether through public speaking engagements or hands-on collaboration with others, I am dedicated to spreading my enthusiasm for technology and driving positive change in the world.