Skip to content

Conversation

@ericglau
Copy link
Member

@ericglau ericglau commented Sep 25, 2025

  • Adds the Download Hardhat package option for Polkadot, limited to non-upgradeable contracts for now. This extends from Solidity Wizard's Download Hardhat functionality.
  • Changes required Node version to 22, since this is a requirement of the Hardhat Polkadot plugin.

Note for code review:

  • Commit 8145433 is cherry-picked from a not-yet-merged PR, which adds extensibility to the zip-hardhat.ts file.
  • Only commit 9e22ed5 (and later, if any) is specific for this PR.

@ericglau ericglau requested a review from KitHat September 25, 2025 22:26
@ericglau ericglau requested review from a team as code owners September 25, 2025 22:26
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 25, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Bumps Node.js to 22 and setup-node to v5 in CI. Refactors Hardhat zip generation into a class. Adds a Polkadot-specific Hardhat zip generator, exports, and tests with snapshots. Updates UI overrides to function-based omit and optional override for Hardhat zip, with dynamic import in Polkadot UI.

Changes

Cohort / File(s) Summary
CI and Node version bump
.github/actions/setup/action.yml, .nvmrc
Update actions/setup-node to v5 and Node.js version from 20 to 22; no flow changes.
Hardhat zip generator refactor
packages/core/solidity/src/zip-hardhat.ts, packages/core/solidity/src/zip-hardhat.test.ts.md
Introduce HardhatZipGenerator class, restructure content generation methods, delegate zipHardhat to the class; update snapshots for changed templates/comments and unsafeAllow array syntax.
Polkadot Hardhat zip support
packages/core/solidity/src/zip-hardhat-polkadot.ts, packages/core/solidity/zip-env-hardhat-polkadot.ts, packages/core/solidity/zip-env-hardhat-polkadot.js, packages/core/solidity/src/environments/hardhat/polkadot/package.json, packages/core/solidity/src/zip-hardhat-polkadot.test.ts, packages/core/solidity/src/zip-hardhat-polkadot.test.ts.md
Add Polkadot-specific generator extending Hardhat setup, re-export/build proxies, environment package.json, end-to-end AVA test with layout/assertions, and snapshot report.
UI overrides and dynamic generation
packages/ui/src/solidity/overrides.ts, packages/ui/src/solidity/App.svelte, packages/ui/src/polkadot/App.svelte
Change omitZipHardhat from boolean to function; add optional overrideZipHardhat. Update App.svelte to call function-based omit and delegate to override when provided; Polkadot UI dynamically imports zip-env-hardhat-polkadot and routes generation.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User
  participant UI as Solidity App.svelte
  participant Ov as Overrides
  participant Gen as Core Hardhat Generator

  User->>UI: Click "Download Hardhat ZIP"
  UI->>Ov: omitZipHardhat(opts)
  alt omit = true
    UI-->>User: Skip Hardhat ZIP
  else omit = false
    UI->>Ov: overrideZipHardhat?
    alt override present
      UI->>Ov: overrideZipHardhat(contract, opts)
      Ov-->>UI: JSZip
    else no override
      UI->>Gen: zipHardhat(contract, opts)
      Gen-->>UI: JSZip
    end
    UI-->>User: Start ZIP download
  end
Loading
sequenceDiagram
  autonumber
  participant PolyUI as Polkadot App.svelte
  participant Dyn as Dynamic Import
  participant PGen as zipHardhatPolkadot
  participant HGen as HardhatZipGenerator

  PolyUI->>Dyn: import("@openzeppelin/wizard/zip-env-hardhat-polkadot")
  Dyn-->>PolyUI: { zipHardhatPolkadot }
  PolyUI->>PGen: zipHardhatPolkadot(contract, opts)
  PGen->>HGen: Extend Hardhat config (add @parity/hardhat-polkadot)
  HGen-->>PolyUI: JSZip (Polkadot Hardhat project)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • KitHat
  • gonzaotc

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title accurately summarizes the primary change of the pull request by stating that a Hardhat Polkadot zip download option is being added, matching the PR’s main intent to extend the Download Hardhat feature for Polkadot.
Description Check ✅ Passed The PR description accurately describes the changeset across multiple files and commits. It explicitly mentions two key changes: (1) adding a Download Hardhat package option for Polkadot limited to non-upgradeable contracts, which is reflected in the new zip-hardhat-polkadot.ts module, new test files, UI updates with dynamic imports and overrides system, and (2) updating the required Node version to 22, which is clearly shown in the .github/actions/setup/action.yml and .nvmrc file changes. The description also provides helpful context about the cherry-picked commit from another PR that adds extensibility to zip-hardhat.ts. The level of detail is appropriate and specific, including the rationale for the Node upgrade and the current limitation of the feature.

Comment @coderabbitai help to get the list of available commands and usage tips.

@socket-security
Copy link

socket-security bot commented Sep 25, 2025

Caution

Review the following alerts detected in dependencies.

According to your organization's Security Policy, you must resolve all "Block" alerts before proceeding. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Block Low
ajv@6.12.6 is a AI-detected potential code anomaly.

Notes: The code represents a conventional, non-obfuscated part of AJV’s custom keyword support. No direct malicious actions are evident within this module. Security concerns mainly arise from the broader supply chain: the external rule implementation (dotjs/custom), the definition schema, and any user-supplied keyword definitions. The dynamic compilation path (compile(metaSchema, true)) should be exercised with trusted inputs. Recommended follow-up: review the contents of the external modules and monitor the inputs supplied to addKeyword/definitionSchema to ensure no unsafe behavior is introduced during validation or data handling.

Confidence: 1.00

Severity: 0.60

From: yarn.locknpm/ajv@6.12.6

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/ajv@6.12.6. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Block Low
prettier@3.6.2 is a AI-detected potential code anomaly.

Notes: No definitive malware detected in this fragment. The main security concern is supply-chain risk from dynamically loading plugins from potentially untrusted sources. To mitigate, enforce strict plugin provenance, disable remote plugin loading, verify plugin integrity, and apply least-privilege execution for plugins.

Confidence: 1.00

Severity: 0.60

From: package.jsonnpm/prettier@3.6.2

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/prettier@3.6.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Block Low
rxjs@7.8.2 is a AI-detected potential code anomaly.

Notes: The code is a conventional, well-scoped implementation of an RxJS-like concat operator. No malicious behavior, data exfiltration, or suspicious I/O detected in this fragment. Security risk is low; malware likelihood is negligible for this isolated operator function.

Confidence: 1.00

Severity: 0.60

From: yarn.locknpm/rxjs@7.8.2

ℹ Read more on: This package | This alert | What is an AI-detected potential code anomaly?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: An AI system found a low-risk anomaly in this package. It may still be fine to use, but you should check that it is safe before proceeding.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/rxjs@7.8.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
packages/core/solidity/src/environments/hardhat/polkadot/package.json (1)

11-16: Consider version range strategy for dependencies.

The package uses caret (^) version ranges for all dependencies. While this allows for minor/patch updates, consider whether stricter pinning is appropriate for critical dependencies like the Polkadot plugin.

For more stability, consider exact version pinning for newer/experimental dependencies:

  "devDependencies": {
    "@openzeppelin/contracts": "^5.4.0",
-   "@parity/hardhat-polkadot": "^0.1.9",
+   "@parity/hardhat-polkadot": "0.1.9",
    "@nomicfoundation/hardhat-toolbox": "^6.1.0",
    "hardhat": "^2.16.1"
  }
packages/core/solidity/src/zip-hardhat-polkadot.test.ts (1)

121-123: Consider extracting the duplicate asString helper

This asString function duplicates the one already available in packages/core/stellar/src/utils/zip-test.ts.

Consider importing the shared utility instead:

-async function asString(item: JSZipObject) {
-  return Buffer.from(await item.async('arraybuffer')).toString();
-}
+import { asString } from '../../stellar/src/utils/zip-test';

Or if cross-package imports aren't desired, extract it to a shared test utilities module within the solidity package.

packages/core/solidity/src/zip-hardhat-polkadot.ts (1)

57-62: Extra whitespace in gitignore template

The gitignore template has inconsistent indentation with extra spaces at the beginning and end.

Clean up the formatting:

  protected getGitIgnoreHardhatIgnition(): string {
-    return `
-# Hardhat Ignition default folder for deployments against a local Polkadot Revive Dev node
-ignition/deployments/chain-420420420
-    `;
+    return `
+# Hardhat Ignition default folder for deployments against a local Polkadot Revive Dev node
+ignition/deployments/chain-420420420`;
  }
packages/core/solidity/src/zip-hardhat.ts (1)

64-73: Consider validating constructor argument types

The code assumes that non-address constructor arguments need manual setting, but doesn't validate the actual types. This could be enhanced to provide more specific guidance based on the actual argument types.

Consider providing more specific placeholders based on the argument type:

  private declareVariables(args: FunctionArgument[]): Lines[] {
    const vars = [];
    for (let i = 0; i < args.length; i++) {
      if (args[i]!.type === 'address') {
        vars.push(`const ${args[i]!.name} = (await ethers.getSigners())[${i}].address;`);
      } else {
+       const argType = typeof args[i]!.type === 'string' ? args[i]!.type : 'contract';
+       const placeholder = this.getPlaceholderForType(argType);
        vars.push(`// TODO: Set the following constructor argument`);
-       vars.push(`// const ${args[i]!.name} = ...;`);
+       vars.push(`// const ${args[i]!.name} = ${placeholder};`);
      }
    }
    return vars;
  }
+ 
+ private getPlaceholderForType(type: string): string {
+   switch(type) {
+     case 'uint256': return '1000';
+     case 'string': return '"example"';
+     case 'bool': return 'true';
+     default: return '...';
+   }
+ }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a90806 and 9e22ed5.

⛔ Files ignored due to path filters (3)
  • packages/core/solidity/src/environments/hardhat/polkadot/package-lock.json is excluded by !**/package-lock.json
  • packages/core/solidity/src/zip-hardhat-polkadot.test.ts.snap is excluded by !**/*.snap
  • packages/core/solidity/src/zip-hardhat.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (13)
  • .github/actions/setup/action.yml (1 hunks)
  • .nvmrc (1 hunks)
  • packages/core/solidity/src/environments/hardhat/polkadot/package.json (1 hunks)
  • packages/core/solidity/src/zip-hardhat-polkadot.test.ts (1 hunks)
  • packages/core/solidity/src/zip-hardhat-polkadot.test.ts.md (1 hunks)
  • packages/core/solidity/src/zip-hardhat-polkadot.ts (1 hunks)
  • packages/core/solidity/src/zip-hardhat.test.ts.md (7 hunks)
  • packages/core/solidity/src/zip-hardhat.ts (4 hunks)
  • packages/core/solidity/zip-env-hardhat-polkadot.js (1 hunks)
  • packages/core/solidity/zip-env-hardhat-polkadot.ts (1 hunks)
  • packages/ui/src/polkadot/App.svelte (2 hunks)
  • packages/ui/src/solidity/App.svelte (2 hunks)
  • packages/ui/src/solidity/overrides.ts (3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-09-24T20:55:43.331Z
Learnt from: CoveMB
PR: OpenZeppelin/contracts-wizard#665
File: packages/ui/src/solidity/remix.node.test.ts:0-0
Timestamp: 2025-09-24T20:55:43.331Z
Learning: In the OpenZeppelin contracts-wizard project, the UI package tests use AVA framework which provides browser API polyfills, so `atob` and other browser APIs are available in the test environment.

Applied to files:

  • packages/core/solidity/src/zip-hardhat-polkadot.test.ts
📚 Learning: 2025-08-15T23:23:13.097Z
Learnt from: ernestognw
PR: OpenZeppelin/contracts-wizard#609
File: packages/core/solidity/src/signer.ts:31-38
Timestamp: 2025-08-15T23:23:13.097Z
Learning: In OpenZeppelin contracts-wizard, the `setUpgradeableAccount` function deliberately sets `c.upgradeable = false` after upgradeable setup to exclude EIP712Upgradeable and ERC7739Upgradeable variants (avoiding per-call SLOAD overhead). This architectural pattern necessitates manual `_disableInitializers()` setup in both account.ts and signer.ts since the standard upgradeable constructor logic doesn't apply when upgradeability is disabled post-setup.

Applied to files:

  • packages/core/solidity/src/zip-hardhat.test.ts.md
📚 Learning: 2025-08-15T22:52:34.129Z
Learnt from: ernestognw
PR: OpenZeppelin/contracts-wizard#609
File: packages/core/solidity/src/account.ts:89-0
Timestamp: 2025-08-15T22:52:34.129Z
Learning: In OpenZeppelin contracts-wizard, non-upgradeable accounts still require initializer logic (Initializable, _disableInitializers(), and initialize() function) because ERC-4337 accounts are typically deployed by factories as minimal clone proxies, which cannot use constructors effectively for initialization. This is the intended deployment pattern for ERC-4337 account abstraction, even for non-upgradeable accounts.

Applied to files:

  • packages/core/solidity/src/zip-hardhat.test.ts.md
🧬 Code graph analysis (3)
packages/core/solidity/src/zip-hardhat-polkadot.test.ts (2)
packages/core/solidity/src/zip-hardhat-polkadot.ts (1)
  • zipHardhatPolkadot (65-67)
packages/core/stellar/src/utils/zip-test.ts (1)
  • asString (15-15)
packages/core/solidity/src/zip-hardhat-polkadot.ts (2)
packages/core/solidity/src/zip-hardhat.ts (1)
  • HardhatZipGenerator (91-307)
packages/core/solidity/hardhat.config.js (1)
  • SOLIDITY_VERSION (11-11)
packages/core/solidity/src/zip-hardhat.ts (3)
packages/core/solidity/src/contract.ts (2)
  • Contract (3-14)
  • FunctionArgument (65-68)
packages/core/solidity/src/utils/format-lines.ts (1)
  • formatLinesWithSpaces (9-11)
packages/core/solidity/src/print.ts (1)
  • printContract (23-57)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (solidity, default)
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (14)
.nvmrc (1)

1-1: Node.js 22 upgrade aligns with PR requirements.

Node.js v22 has officially moved into Active LTS status and the node.js 22 will enter long-term support (LTS) in October, making this a stable choice for production. The upgrade from Node 20 to 22 supports the Hardhat Polkadot plugin requirement mentioned in PR objectives.

.github/actions/setup/action.yml (1)

6-8: GitHub Actions setup properly updated for Node.js 22.

The action correctly updates both the setup-node version to v5.0.0 and Node.js version to 22, maintaining consistency with the .nvmrc change. The commit hash ensures reproducible builds.

packages/core/solidity/src/zip-hardhat-polkadot.test.ts.md (1)

1-201: Test snapshot looks comprehensive and properly structured.

The snapshot covers all essential files for a Hardhat Polkadot project including contracts, configuration, package.json, ignition modules, tests, and documentation. The content demonstrates proper integration of Polkadot-specific configuration like polkavm: true and Polkadot Revive-specific settings.

packages/core/solidity/src/zip-hardhat.test.ts.md (2)

107-107: Comment improvement enhances clarity.

The update from "Set addresses for the contract arguments below" to "Set values for the constructor arguments below" improves clarity and accuracy, as constructor arguments aren't limited to addresses.

Also applies to: 266-266, 373-373, 465-465, 546-546, 644-645, 667-667


645-645: Array format for unsafeAllow corrects Hardhat Upgrades API usage.

The change from { unsafeAllow: 'constructor' } to { unsafeAllow: ['constructor'] } aligns with the correct Hardhat Upgrades API format, which expects an array of strings rather than a single string.

Also applies to: 667-667

packages/core/solidity/zip-env-hardhat-polkadot.ts (1)

1-1: Clean re-export structure maintains API consistency.

The simple re-export pattern follows the established convention for environment-specific entry points and properly exposes the Polkadot Hardhat functionality.

packages/ui/src/polkadot/App.svelte (3)

7-7: Type imports added for enhanced type safety.

Adding explicit type imports for Contract and GenericOptions improves type safety for the new override functions.


12-14: Dynamic import implementation enables lazy loading.

The dynamic import pattern efficiently loads the Polkadot-specific module only when needed, reducing initial bundle size while maintaining functionality.


23-29: Function-based override provides conditional Hardhat zip generation.

The implementation properly uses the new override API:

  • omitZipHardhat function correctly excludes upgradeable contracts (which aren't supported for Polkadot per PR objectives)
  • overrideZipHardhat async function properly awaits the dynamic module and delegates to zipHardhatPolkadot
packages/core/solidity/zip-env-hardhat-polkadot.js (1)

1-1: Simple proxy module follows established patterns.

The CommonJS proxy correctly routes to the built distribution file, maintaining consistency with other environment entry points in the project.

packages/ui/src/solidity/App.svelte (2)

146-146: LGTM! Clean migration to function-based override

The change from a boolean check to a function call overrides.omitZipHardhat(opts) provides better flexibility for conditional logic based on the options.


204-207: Good implementation of override pattern for Hardhat zip generation

The conditional logic properly checks for the presence of overrideZipHardhat and falls back to the default zipHardhat when not provided. This allows ecosystem-specific customization while maintaining backward compatibility.

packages/ui/src/solidity/overrides.ts (1)

24-29: Well-designed extensibility for Hardhat zip generation

The conversion of omitZipHardhat to a function and addition of overrideZipHardhat provides a clean extension point for ecosystem-specific Hardhat configurations. The optional nature of overrideZipHardhat maintains backward compatibility.

packages/core/solidity/src/zip-hardhat.ts (1)

91-307: Excellent refactoring to class-based architecture

The refactoring from procedural code to the HardhatZipGenerator class provides excellent extensibility, as demonstrated by the Polkadot subclass. The protected methods allow for selective overriding while maintaining the core logic.

@ericglau ericglau changed the title Add Hardhat Polkadot zip option Add download Hardhat Polkadot zip option Sep 26, 2025
Copy link
Contributor

@CoveMB CoveMB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good 🌾 (did not test UI as Polkadot button is hiden)

const ignitionModule = (c: Contract) => {
const deployArguments = getAddressArgs(c);
const contractVariableName = lowerFirstCharacter(c.name);
private lowerFirstCharacter(str: string): string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe could be moved to utils

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is just a one-liner that is called from one place, so it seems fine to leave it

omitFeatures: defineOmitFeatures(),
omitZipFoundry: true,
omitZipHardhat: true, // Disabled until Polkadot-specific config is added for the download package
omitZipHardhat: (opts?: GenericOptions) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if (now or later) it could be a good idea to extract download logic in their own components to keep App.svelte leaner

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which parts are you referring to? The download logic in App.svelte seems small, as the logic is mostly in the zip-hardhat-*.ts files.

@socket-security
Copy link

socket-security bot commented Oct 22, 2025

@ericglau ericglau requested a review from CoveMB October 22, 2025 17:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants