hashgraph / hashgraph/asset-tokenization-studio

npm install fails on a clean clone: prepare hook runs hardhat compile before deps are linked, and HH19 masks an ERR_REQUIRE_ESM from did-jwt → @scure/base@2

Open
#1,406 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
33
Forks
28
Avg merge
15h 36m
Merged PRs (30d)
8

Description

A clean clone cannot install. Two separate issues compound, and neither error message points at its cause.

Environment: Node 20.17.0, npm 10.8.2, macOS 15.5 arm64.

## Reproduction

```bash
git clone --depth 1 https://github.com/hashgraph/asset-tokenization-studio
cd asset-tokenization-studio
npm install
```

```
npm error code 1
npm error path .../packages/ats/contracts
npm error command sh -c npx hardhat compile
npm error Error HH19: Your project is an ESM project (you have "type": "module" set in
npm error your package.json) but your Hardhat config file uses the .js extension.
npm error
npm error Rename the file to use the .cjs to fix this problem.
```

`node_modules` is left empty.

## Problem 1 — HH19 is misleading and sends you the wrong way

Both conditions the error asserts are false for this repo:

- `packages/ats/contracts/package.json` has `"type": "commonjs"`, not `"module"`
- the config is `hardhat.config.ts` — there is no `.js` config anywhere in the repo

So following the instruction (rename to `.cjs`) cannot help. The real cause only surfaces with `--show-stack-traces`:

```
Caused by: Error [ERR_REQUIRE_ESM]: require() of ES Module
node_modules/did-jwt/node_modules/@scure/base/index.js
from node_modules/did-jwt/lib/index.cjs not supported.
```

`did-jwt@8.0.18` depends on `@scure/base@^2.0.0`, which is ESM-only, and requires it from a CommonJS entry point. Hardhat catches that while loading the config and re-reports it as HH19.

Dependency path:

```
@hashgraph/asset-tokenization-contracts
└─ @terminal3/ecdsa_vc@0.1.30
└─ @terminal3/vc_core@0.0.33
└─ did-jwt@8.0.18
└─ @scure/base@^2.0.0 ← ESM-only, required from CJS
```

**Workaround:** pin `@scure/base` to `1.2.6` via a root `overrides` entry. `overrides` alone was not sufficient here — npm still left a nested `did-jwt/node_modules/@scure/base@2.0.0` that had to be deleted before the hoisted 1.2.6 resolved.

**Suggested fix:** constrain `@scure/base` to `^1.2` through `overrides` in the root manifest, or raise it with `did-jwt`.

## Problem 2 — prepare runs before dependencies exist, and --ignore-scripts does not stop it

`packages/ats/contracts/package.json`:

```json
"scripts": { "prepare": "npx hardhat compile" }
```

npm runs `prepare` for a workspace during install, before that workspace's dependencies are linked. So the first thing a clean clone does is invoke `hardhat` with no `node_modules`.

`npm install --ignore-scripts` did not suppress it — same failure, same empty `node_modules`. The only thing that worked was editing the `prepare` script out, installing, then compiling explicitly.

**Suggested fix:** drop `prepare` and rely on `ats:build` / `ats:setup`, which already run `ats:contracts:build`. Compiling contracts is a build step rather than a package-preparation step, and placing it in `prepare` makes a clean clone depend on a tool it has not installed yet.

## A working sequence, for anyone hitting this meanwhile

```bash
# 1. remove the prepare hook from packages/ats/contracts/package.json
# 2. add to the root package.json:
# "overrides": { "@scure/base": "1.2.6" }
npm install
rm -rf node_modules/did-jwt/node_modules/@scure/base # force the hoisted copy
npm run ats:contracts:build
npm run ats:sdk:build
npm run ats:web:dev
```

After that the web app starts and works correctly — we issued an ERC-1400 equity through it on Hedera testnet with no further trouble. This is purely a first-install problem.

Contributor guide

Open the contributing guide

Research direction

Reproduce the clean-clone failure with npm install, then inspect package.json at the repository root and packages/ats/contracts/package.json, especially the overrides and prepare script. Verify the change with a fresh install and the existing ats:contracts:build, ats:sdk:build, and ats:web:dev commands; done means installation succeeds without manual edits and the listed builds run.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
build-system, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.