Skip to content

Instantly share code, notes, and snippets.

@nelson-david
Created September 4, 2024 04:11
Show Gist options
  • Save nelson-david/ddcbe1a1bedf0ea6669a52ee7a778107 to your computer and use it in GitHub Desktop.
Save nelson-david/ddcbe1a1bedf0ea6669a52ee7a778107 to your computer and use it in GitHub Desktop.
# EIP-2612 Implementation in Next.js

## Overview
This implementation showcases how we can integrate the EIP-2612 standard (permit function) into a Next.js application. EIP-2612 allows for gasless approvals in Ethereum-based tokens.

## Installation
To get started, you need to have Node.js and npm installed. Then, initialize a Next.js project and install the necessary dependencies.

```bash
npx create-next-app eip2612-nextjs
cd eip2612-nextjs
npm install ethers

EIP-2612 Contract Example

Here’s a basic ERC-20 contract with the permit function that follows the EIP-2612 standard:

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

contract MyToken is ERC20, ERC20Permit {
    constructor() ERC20("MyToken", "MTK") ERC20Permit("MyToken") {
        _mint(msg.sender, 1000000 * 10 ** 18);
    }
}

This smart contract allows for the permit function, enabling token approvals via signatures instead of requiring on-chain transactions for approval.

Frontend Integration

In your Next.js application, create a simple form to handle the permit function using the user's signature.

pages/index.js

import { useState } from "react";
import { ethers } from "ethers";

export default function Home() {
  const [amount, setAmount] = useState("");
  const [signature, setSignature] = useState("");
  const [spender, setSpender] = useState("");

  const handlePermit = async () => {
    const provider = new ethers.providers.Web3Provider(window.ethereum);
    const signer = provider.getSigner();
    const address = await signer.getAddress();
    
    const domain = {
      name: "MyToken",
      version: "1",
      chainId: 1,
      verifyingContract: "0xYourContractAddress",
    };

    const types = {
      Permit: [
        { name: "owner", type: "address" },
        { name: "spender", type: "address" },
        { name: "value", type: "uint256" },
        { name: "nonce", type: "uint256" },
        { name: "deadline", type: "uint256" },
      ],
    };

    const value = {
      owner: address,
      spender,
      value: ethers.utils.parseUnits(amount, 18).toString(),
      nonce: 0, // Replace with actual nonce value
      deadline: Math.floor(Date.now() / 1000) + 60 * 20, // 20 minutes from now
    };

    const signature = await signer._signTypedData(domain, types, value);
    setSignature(signature);
  };

  return (
    <div>
      <h1>EIP-2612 Permit Example</h1>
      <input
        type="text"
        placeholder="Spender Address"
        value={spender}
        onChange={(e) => setSpender(e.target.value)}
      />
      <input
        type="number"
        placeholder="Amount"
        value={amount}
        onChange={(e) => setAmount(e.target.value)}
      />
      <button onClick={handlePermit}>Sign Permit</button>
      {signature && (
        <div>
          <h3>Signature:</h3>
          <p>{signature}</p>
        </div>
      )}
    </div>
  );
}

Explanation

  • Domain: This is the EIP-712 domain separator that includes the token's name, version, chainId, and contract address.
  • Types: Defines the structure of the permit data according to the EIP-2612 standard.
  • Value: The actual permit data containing the owner's address, spender's address, amount, nonce, and deadline.
  • Signature: After signing the data with the user's private key, the resulting signature is displayed on the frontend.

Conclusion

This is a basic implementation of EIP-2612 in a Next.js app. You can extend it to include sending the signed permit to your smart contract for further processing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment