Getting module error when running autotask

I run a local dev setup, that is adding autotasks using the OZ client:
"@openzeppelin/defender-autotask-client": "1.48.0"
I have used your rollup example to get started, but had problems with
having the main .ts file include local import typescript files correctly, turning them into
a single .js file. It would still keep the import statement in the output file, instead of merging.

So I split the process into to 2 step, first running tsc to convert .ts files to .js,
then run the rollup and finally use the output to create my autotask.

When running the auto task I get this error:
Error: Cannot find module '@openzeppelin/defender-relay-client/lib/ethers'
Require stack:

  • /var/task/index.js
  • /opt/nodejs/autotask-wrapper.js
  • /var/runtime/index.mjs

Can you help explain why? According to this list that dependency should be available:

Maybe you even have a clue about the rollup not automatically merging the
typescript local import into the output file instead of keeping the import?

Thanks for the good stuff you provide, I hope to see TS support for autotasks :slight_smile:

:computer: Environment
OpenZeppelin Defender v.1

:1234: Code to reproduce
Initial TS code:

import {
  DefenderRelaySigner,
  DefenderRelayProvider,
}  from "@openzeppelin/defender-relay-client/lib/ethers";

Turned into JS by tsc:
const ethers_1 = require("@openzeppelin/defender-relay-client/lib/ethers");

(OFF TOPIC)
My ts import that did not work with rollup:

import { xxxABI } from "./myABI";

and the converted js ABI that works fine:
const myABI_1 = require("./myABI");

Hi Miclar! By rollup example you mean this one? By default that example asumes that you are going to import the deprecated defender-relay-client (We are working on updating these examples to @openzeppelin/defender-relay-client).
Have you tried adding the external dependency to your rollup.config.js (line 24) in addition to package.json ?

Yes, I saw the there were missing stuff in the version from the example,
and found out the packages were deprecated. So I switched to the new versions.
The problem with the dependencies are not that I did not exclude them in my
rollup output. The problem is that it cannot find packages in the online autotask env.

My rollup config:

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

export default {
    input: 'build/autotasks/test/index.js',
    output: {
        file: 'dist/index.js',
        format: 'cjs',
        exports: 'named'
    },
    plugins: [
        resolve({ preferBuiltins: true }),
        commonjs(),
        json({ compact: true }),
        typescript(),
    ],
    external: [
        ...builtins,
        'ethers',
        'web3',
        /^@openzeppelin\/defender-relay-client(\/.*)?$/,
        /^@openzeppelin\/defender-autotask-client(\/.*)?$/,
        /^@openzeppelin\/defender-autotask-utils(\/.*)?$/,
    ],
};

This description implies that you should use something like:

import * as myABI_1 from "./myABI";

You don't have to name it myABI_1 of course, I just took that from your example.

That was the output generated from tsc, since I could not run rollup directly on the ts files.
That 2 step solution actually worked, but makes the project a bit of a mess, with too many
input and output folders.

I have now tried a simpler example.
The original input (well not really TS, but put through the same setup with tsc).

const ethers = require('ethers')
const {
  DefenderRelaySigner,
  DefenderRelayProvider,
} = require('@openzeppelin/defender-relay-client/lib/ethers')

async function handler(event) {
  const provider = new DefenderRelayProvider(event)
  const {userName} = event.request.body;
  const block = await provider.getBlockNumber();
  const lastRunBlockNumber = await store.get('lastRunBlockNumber')
  let msg = (lastRunBlockNumber) ? `This Autotask was last triggered on block
     ${lastRunBlockNumber}` : 'This is the first time this Autotask has been triggered'

  return `Hello ${userName}! Current block: ${block}. ${msg}`;
}

module.exports = {
  handler,
}

The middle step JS as outputted from tsc:

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

require('ethers');
var require$$0 = require('@openzeppelin/defender-relay-client/lib/ethers');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);

const {
  DefenderRelaySigner,
  DefenderRelayProvider,
} = require$$0__default["default"];

async function handler(event) {
  const provider = new DefenderRelayProvider(event);
  const {userName} = event.request.body;
  const block = await provider.getBlockNumber();
  const lastRunBlockNumber = await store.get('lastRunBlockNumber');
  let msg = (lastRunBlockNumber) ? `This Autotask was last triggered on block
     ${lastRunBlockNumber}` : 'This is the first time this Autotask has been triggered';

  return `Hello ${userName}! Current block: ${block}. ${msg}`;
}

var test = {
  handler,
};

exports["default"] = test;

And it results in the same error code. Its clear that the module is not available.

Error
Error: Cannot find module '@openzeppelin/defender-relay-client/lib/ethers'
Require stack:
- /var/task/index.js
- /opt/nodejs/autotask-wrapper.js
- /var/runtime/index.mjs

@Miclar I just realized the scoped @openzeppelin/ dependencies are not released for autotasks environments yet, we are planning to release them the next week, sorry for the inconvenience. For now you can use defender-relay-signer package

1 Like

OK, thanks.
I just tried to remove it as external, and that seems to work,
but without additional cleaning, the code gets huge :slight_smile:
I will check again after next week :crossed_fingers:

1 Like

Any news on this? I am still getting the same error:

Error: Cannot find module '@openzeppelin/defender-relay-client/lib/ethers'
Require stack:
- /var/task/index.js
- /opt/nodejs/autotask-wrapper.js
- /var/runtime/index.mjs

Please, anyone have some info?