import { signTypedData_v4 } from 'eth-sig-util'
import { fromRpcSig } from 'ethereumjs-util'
import aTokenAbi from "./aTokenAbi.json"
// ... setup your web3 provider
const aTokenAddress = "ATOKEN_ADDRESS"
const aTokenContract = new web3.eth.Contract(aTokenAbi, aTokenAddress)
const privateKey = "YOUR_PRIVATE_KEY_WITHOUT_0x"
const owner = "OWNER_ADDRESS"
const spender = "SPENDER_ADDRESS"
const value = 100 // Amount the spender is permitted
const nonce = 1 // The next valid nonce, use `_nonces()`
const deadline = 1600093162
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" },
{ name: "owner", type: "address" },
{ name: "spender", type: "address" },
{ name: "value", type: "uint256" },
{ name: "nonce", type: "uint256" },
{ name: "deadline", type: "uint256" },
verifyingContract: aTokenAddress,
const signature = signTypedData_v4(
Buffer.from(privateKey, "hex"),
// The signature can now be used to execute the transaction
const { v, r, s } = fromRpcSig(signature)
await aTokenContract.methods
throw Error(`Error permitting: ${e.message}`)