Error: Cannot find module 'hardhat'

Hi, I'm currently following this guide https://docs.openzeppelin.com/defender/v2/guide/meta-tx#create-action and am currently on the last step where I'm accessing the action through the webhook. However, the action logs show that it fails each time with the error

Error: Cannot find module 'hardhat'
Require stack:
- /var/task/index.js
- /opt/nodejs/autotask-wrapper.js
- /var/runtime/index.mjs

My code for the action is the same as in the guide

const { Defender } = require('@openzeppelin/defender-sdk');
const { ethers } = require('hardhat');

const FORWARDER_ABI = require('../src/forwarder').forwarderABI;
const FORWARDER_ADDRESS= require('../deploy.json').forwarder;

// Tutorial from https://docs.openzeppelin.com/defender/v2/guide/meta-tx

async function relay(forwarder, request, signature, whitelist) {
  // Users can have roles and only validate their request based on roles in whitelist
  const accepts = !whitelist || whitelist.includes(request.to);
  if (!accepts) throw new Error(`Rejected requrest to ${request.to}`);

  const valid = await forwarder.verify(request, signature);
  if (!valid) throw new Error('Invalid request.');

  const gasLimit = (parseInt(request.gas) + 50000).toString();
  return await forwarder.execute(request, signature, { gasLimit });
};

async function handler(event) {
  // Parse webhook payload
  if (!event.request || !event.request.body) throw new Error(`Missing payload`);
  const { request, signature } = event.request.body;
  console.log('Relaying', request);

  // Initialize Relayer provider and signer, and forwarder contract
  const creds = { ... event };

  const client = new Defender(creds);

  const provider = client.relaySigner.getProvider();
  const signer = client.relaySigner.getSigner(provider, { speed: 'fast' });
  const forwarder = new ethers.Contract(FORWARDER_ADDRESS, FORWARDER_ABI, signer);

  // Relay transaction!
  const tx = await relay(forwarder, request, signature);
  console.log(`Sent meta-tx: ${tx.hash}`);
  return { txHash: tx.hash };
};

module.exports = {
  handler,
  relay
};

Is there a way around this or to fix it?

:computer: Environment

I'm using hardhat and Defender sdk

Okay, I found out after this post that I can use Rollup to assign a bundle to the file but I can't for the life of me figure out how to get the files for both forwarderABI and FORWARDER_ADDRESS as it keeps returning errors for that.

My currrent rollup is the same as the github

import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import builtins from 'builtin-modules';

export default {
  input: 'action/index.mjs',
  output: {
    file: 'build/action/index.js',
    format: 'cjs',
    exports: 'auto',
  },
  plugins: [
    resolve({ preferBuiltins: true }),
    commonjs(),
    json({ compact: true }),
  ],
  external: [
    ...builtins,
    'ethers',
    'web3',
    'axios',
    /^defender-relay-client(\/.*)?$/,
  ],
};

With my action code being

const { Defender } = require('@openzeppelin/defender-sdk');
const { ethers } = require('ethers');

const { forwarderABI } = require('../src/forwarder');
const FORWARDER_ADDRESS= require('../deploy.json').forwarder;

// Tutorial from https://docs.openzeppelin.com/defender/v2/guide/meta-tx

async function relay(forwarder, request, signature, whitelist) {
  // Users can have roles and only validate their request based on roles in whitelist
  const accepts = !whitelist || whitelist.includes(request.to);
  if (!accepts) throw new Error(`Rejected requrest to ${request.to}`);

  const valid = await forwarder.verify(request, signature);
  if (!valid) throw new Error('Invalid request.');

  const gasLimit = (parseInt(request.gas) + 50000).toString();
  return await forwarder.execute(request, signature, { gasLimit });
};

async function handler(event) {
  // Parse webhook payload
  if (!event.request || !event.request.body) throw new Error(`Missing payload`);
  const { request, signature } = event.request.body;
  console.log('Relaying', request);

  // Initialize Relayer provider and signer, and forwarder contract
  const creds = { ... event };

  const client = new Defender(creds);

  const provider = client.relaySigner.getProvider();
  const signer = client.relaySigner.getSigner(provider, { speed: 'fast' });
  const forwarder = new ethers.Contract(FORWARDER_ADDRESS, forwarderABI, signer);

  // Relay transaction!
  const tx = await relay(forwarder, request, signature);
  console.log(`Sent meta-tx: ${tx.hash}`);
  return { txHash: tx.hash };
};

module.exports = {
  handler,
  relay
};

My code to createAction is

require('dotenv').config();

const { Defender } = require('@openzeppelin/defender-sdk');
const { readFileSync, appendFileSync } = require('fs');

async function main() {
  const { relayer: { relayerId }} = JSON.parse(readFileSync('./relay.json'))
  const creds = { apiKey: process.env.DEFENDER_API_KEY, apiSecret: process.env.DEFENDER_API_SECRET_KEY };
  const client = new Defender(creds);

  const { actionId } = await client.action.create({
    name: "Relayer Meta Transactions",
    encodedZippedCode: await client.action.getEncodedZippedCodeFromFolder('./build/action'),
    relayerId: relayerId,
    trigger: {
      type: 'webhook'
    },
    paused: false
  });

  console.log("Action created with ID", actionId);

  appendFileSync('.env', `\nACTION_ID="${actionId}"`, function (err) {
    if (err) throw err;
 });
}

if (require.main === module) {
  main().catch(console.error);
}

Am I missing something or misunderstanding how to use rollup?