Skip to content

chore(dapi-client,dapi-grpc): cleanup — drop unused deps, inline winston/fetch/promisify shims#3674

Closed
PastaPastaPasta wants to merge 1 commit into
dashpay:v3.1-devfrom
PastaPastaPasta:claude/esm-1-cleanup
Closed

chore(dapi-client,dapi-grpc): cleanup — drop unused deps, inline winston/fetch/promisify shims#3674
PastaPastaPasta wants to merge 1 commit into
dashpay:v3.1-devfrom
PastaPastaPasta:claude/esm-1-cleanup

Conversation

@PastaPastaPasta
Copy link
Copy Markdown
Member

@PastaPastaPasta PastaPastaPasta commented May 19, 2026

Summary

Non-breaking cleanup pass on @dashevo/dapi-client and the browser path of @dashevo/dapi-grpc. Package stays CJS, public API unchanged, no consumer changes required.

This is PR 1 of 5 in a stacked series that incrementally makes dapi-client browser-native and ESM. Each PR is independently shippable and leaves the monorepo green.

What changes

@dashevo/dapi-client

  • Replace winston with a ~30-line console-backed logger that preserves the same API (.error/.warn/.info/.verbose/.debug/.silly/.getForId).
  • Drop node-fetch and the fetch-polyfill (Node 18+ has global fetch).
  • Drop setimmediate (Node 18+ has it globally).
  • Drop the https.Agent({rejectUnauthorized: false}) self-signed-TLS branch from requestJsonRpc. Was Node-only and can't be made browser-portable. Consumers needing this must set NODE_TLS_REJECT_UNAUTHORIZED=0 or pass a custom fetch at the app layer.
  • Inline lodash/sample in ListDAPIAddressProvider (one call site).
  • Add engines.node >= 18.18.
  • Remove unused deps: winston, node-fetch, lodash, bs58, node-inspect-extracted, setimmediate.

@dashevo/dapi-grpc

  • Inline a 5-line promisify shim in clients/core/v0/web/CorePromiseClient.js and clients/platform/v0/web/PlatformPromiseClient.js, removing the require('util') from the browser bundle path. Both files document the shim so a future codegen regen does not silently reintroduce require('util').

Test plan

  • yarn workspace @dashevo/dapi-client run test:unit315 passing
  • yarn workspace @dashevo/wallet-lib run test:unit377 passing (no regression in downstream consumer)
  • yarn workspace dash run test:unit60 passing (no regression in js-dash-sdk)

Breaking changes

  • requestJsonRpc({selfSigned: true}) no longer adds a permissive https.Agent. Workaround: NODE_TLS_REJECT_UNAUTHORIZED=0 or custom fetch.
  • engines.node >= 18.18 (was unspecified; older Node lacks global fetch).

Stack

  • ➡️ PR 1 — Cleanup (this PR)
  • PR 2 — BufferUint8Array in dapi-client public surface
  • PR 3 — @dashevo/dapi-client → ESM (dual-format CJS+ESM)
  • PR 4 — @dashevo/wallet-lib → ESM
  • PR 5 — @dashevo/js-dash-sdk + @dashevo/platform-test-suite → ESM

Summary by CodeRabbit

  • Chores

    • Increased minimum Node.js version requirement to 18.18+
    • Removed unused dependencies (lodash, node-fetch, Winston)
    • Optimized bundle size by eliminating Node.js-specific polyfills
  • Bug Fixes

    • Removed self-signed HTTPS certificate verification support

Review Change Stack

…ton/fetch/promisify shims

Non-breaking cleanup pass; package stays CJS, no public API changes, no consumer changes required.

dapi-client: replace winston with a minimal console-backed logger that preserves the same API (.error/.warn/.info/.verbose/.debug/.silly/.getForId). Drop node-fetch and the lib/test/bootstrap setimmediate shim — Node 18+ has both globally. Drop the https.Agent self-signed-TLS branch from requestJsonRpc (was Node-only; consumers wanting this must configure NODE_TLS_REJECT_UNAUTHORIZED at the app layer). Inline lodash/sample in ListDAPIAddressProvider. Add engines.node >=18.18. Remove dependencies: winston, node-fetch, lodash, bs58 (unused), node-inspect-extracted (unused). Remove devDeps: setimmediate.

dapi-grpc: inline the promisify shim in core/v0/web/CorePromiseClient.js and platform/v0/web/PlatformPromiseClient.js so the browser bundle no longer requires Node's util module. Both files document the shim so a future codegen regen does not silently reintroduce require('util').
@github-actions github-actions Bot added this to the v3.1.0 milestone May 19, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

📝 Walkthrough

Walkthrough

This PR eliminates Node.js-specific dependencies from js-dapi-client and gRPC clients by replacing polyfills and external libraries with lightweight inline shims. The logger is refactored from Winston to a console-based implementation, polyfill imports are removed, and TLS self-signed certificate handling is deleted. Package.json is updated to remove lodash, node-fetch, winston, and node-inspect-extracted, and Yarn PnP locators are refreshed.

Changes

Browser Compatibility Initiative

Layer / File(s) Summary
Package manifest and dependency updates
packages/js-dapi-client/package.json
Removed lodash, node-fetch, node-inspect-extracted, and winston from dependencies; added engines.node requirement of >=18.18; removed polyfills from published files list.
Logger refactor from Winston to console-based implementation
packages/js-dapi-client/lib/logger/index.js
Replaced Winston with a lightweight console logger controlled by LOG_LEVEL environment variable, implemented numeric LEVELS threshold filtering, added per-id logger caching with optional getForId(id, overrideLevel) override capability, and changed module export to build() factory function.
gRPC client promise wrapper shims
packages/dapi-grpc/clients/core/v0/web/CorePromiseClient.js, packages/dapi-grpc/clients/platform/v0/web/PlatformPromiseClient.js
Removed util.promisify imports and implemented inline Promise wrappers that convert callback-style gRPC methods to Promise-returning functions without Node polyfills.
Utility shim for random array sampling
packages/js-dapi-client/lib/dapiAddressProvider/ListDAPIAddressProvider.js
Replaced lodash/sample import with inline helper using Math.random() and Math.floor() to select array elements.
Remove fetch and setimmediate polyfill imports
packages/js-dapi-client/lib/index.js, packages/js-dapi-client/lib/test/bootstrap.js
Deleted fetch-polyfill and setimmediate side-effect imports, allowing the package to rely on Node.js 18.18+ native fetch without polyfill injection.
Remove HTTPS TLS self-signed certificate handling
packages/js-dapi-client/lib/transport/JsonRpcTransport/requestJsonRpc.js
Removed https module import and https.Agent({ rejectUnauthorized: false }) configuration, delegating TLS verification to platform defaults.
Update Yarn PnP locator mappings
.pnp.cjs
Updated virtual locator keys for node-fetch and webpack-cli, adjusted surrounding dependency list entries for buffer, cbor, chai, and mocha.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • QuantumExplorer
  • shumkov

Poem

🐰 A dash of refactor, a hop and a skip,
Node.js dependencies took their last trip,
Winston to console, utils inlined so fine,
Browser and server now share the same spine,
Platform's connectivity gets lighter to fly! 🚀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main changes: removing unused dependencies (winston, node-fetch, lodash, etc.) and inlining shims (promisify, fetch, winston logger) in dapi-client and dapi-grpc packages.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/dapi-grpc/clients/core/v0/web/CorePromiseClient.js

Oops! Something went wrong! :(

ESLint: 9.39.4

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

packages/js-dapi-client/lib/logger/index.js

Oops! Something went wrong! :(

ESLint: 9.39.4

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

.pnp.cjs

Oops! Something went wrong! :(

ESLint: 9.39.4

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

  • 2 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
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.

🧹 Nitpick comments (3)
packages/js-dapi-client/package.json (1)

74-76: ⚡ Quick win

Consider loosening the Node.js engine requirement to >= 18.0.0 or >= 18.2.0.

The codebase uses fetch() (available in Node 18.0+, stable in 18.2+) and Buffer (available since Node 0.1+). No APIs requiring Node 18.18+ were found, and no dependencies explicitly require that version. The presence of a setImmediate polyfill in devDependencies further suggests the package was designed to support older Node versions. Unless there's a specific stability concern with Node 18.0–18.17 or an undocumented dependency requirement, the engine constraint can safely be lowered to accommodate a broader range of Node 18 users.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/js-dapi-client/package.json` around lines 74 - 76, The engines field
currently pins Node to ">=18.18" which is stricter than necessary; update the
"engines" entry in package.json (the "node" key) to a looser requirement such as
">=18.2.0" or ">=18.0.0" depending on desired support (use ">=18.2.0" if you
want to require the stable fetch implementation), and ensure package.json's
"engines" object reflects the new version range.
packages/dapi-grpc/clients/platform/v0/web/PlatformPromiseClient.js (1)

6-9: ⚖️ Poor tradeoff

Consider extracting the promisify shim to a shared utility.

The promisify implementation is duplicated identically in CorePromiseClient.js (lines 4-7). While both implementations are correct, extracting to a shared module would follow DRY principles.

However, given that these files appear to be generated (based on the codegen template comment) and the PR goal is minimal invasiveness, the current approach is acceptable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dapi-grpc/clients/platform/v0/web/PlatformPromiseClient.js` around
lines 6 - 9, The file duplicates a small promisify shim also present in
CorePromiseClient.js; extract this function into a shared utility (e.g., a new
module exporting promisify) and update PlatformPromiseClient.js and
CorePromiseClient.js to import and use that shared promisify export instead of
redefining it so the duplicate implementation is removed and both files call the
same exported function.
packages/js-dapi-client/lib/logger/index.js (1)

1-7: 💤 Low value

Use camelCase for the module constants.

LOG_LEVEL and LEVELS should follow the repo's JS naming convention (logLevel, levels).

As per coding guidelines, "Use camelCase for variables and functions in JS/TS".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/js-dapi-client/lib/logger/index.js` around lines 1 - 7, Rename the
module constants to camelCase: change LOG_LEVEL to logLevel and LEVELS to levels
(leave cache as is or rename to camelCase if desired), then update every usage
and export/import in this file to reference logLevel and levels (including the
initialization expression that reads process.env.LOG_LEVEL and the object keys).
Also update any external consumers/imports that import LOG_LEVEL or LEVELS to
use the new names (or provide backward-compatible aliases in this module while
updating references), and run tests to ensure no unresolved references remain.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/dapi-grpc/clients/platform/v0/web/PlatformPromiseClient.js`:
- Around line 6-9: The file duplicates a small promisify shim also present in
CorePromiseClient.js; extract this function into a shared utility (e.g., a new
module exporting promisify) and update PlatformPromiseClient.js and
CorePromiseClient.js to import and use that shared promisify export instead of
redefining it so the duplicate implementation is removed and both files call the
same exported function.

In `@packages/js-dapi-client/lib/logger/index.js`:
- Around line 1-7: Rename the module constants to camelCase: change LOG_LEVEL to
logLevel and LEVELS to levels (leave cache as is or rename to camelCase if
desired), then update every usage and export/import in this file to reference
logLevel and levels (including the initialization expression that reads
process.env.LOG_LEVEL and the object keys). Also update any external
consumers/imports that import LOG_LEVEL or LEVELS to use the new names (or
provide backward-compatible aliases in this module while updating references),
and run tests to ensure no unresolved references remain.

In `@packages/js-dapi-client/package.json`:
- Around line 74-76: The engines field currently pins Node to ">=18.18" which is
stricter than necessary; update the "engines" entry in package.json (the "node"
key) to a looser requirement such as ">=18.2.0" or ">=18.0.0" depending on
desired support (use ">=18.2.0" if you want to require the stable fetch
implementation), and ensure package.json's "engines" object reflects the new
version range.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8a698a9b-0b2a-47c0-996d-4e24da3e1133

📥 Commits

Reviewing files that changed from the base of the PR and between 6a3b904 and 9812cf7.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (10)
  • .pnp.cjs
  • packages/dapi-grpc/clients/core/v0/web/CorePromiseClient.js
  • packages/dapi-grpc/clients/platform/v0/web/PlatformPromiseClient.js
  • packages/js-dapi-client/lib/dapiAddressProvider/ListDAPIAddressProvider.js
  • packages/js-dapi-client/lib/index.js
  • packages/js-dapi-client/lib/logger/index.js
  • packages/js-dapi-client/lib/test/bootstrap.js
  • packages/js-dapi-client/lib/transport/JsonRpcTransport/requestJsonRpc.js
  • packages/js-dapi-client/package.json
  • packages/js-dapi-client/polyfills/fetch-polyfill.js
💤 Files with no reviewable changes (4)
  • packages/js-dapi-client/lib/index.js
  • packages/js-dapi-client/lib/test/bootstrap.js
  • packages/js-dapi-client/polyfills/fetch-polyfill.js
  • packages/js-dapi-client/lib/transport/JsonRpcTransport/requestJsonRpc.js

Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

Two convergent blocking issues: the karma test bootstrap still require()s a polyfill file deleted in this PR (browser test suite will fail at module resolution), and the JSON-RPC transport silently ignores the selfSigned flag while ListDAPIAddressProvider still actively sets allowSelfSignedCertificate = true for regtest/localhost addresses, breaking local Dashmate workflows. Two non-blocking follow-ups around dead test coverage and a leftover devDependency.

🔴 2 blocking | 🟡 1 suggestion(s) | 💬 1 nitpick(s)

4 additional finding(s)

blocking: Karma bootstrap requires deleted fetch-polyfill

packages/js-dapi-client/lib/test/karma/bootstrap.js (line 1)

Line 1 still has require('../../../polyfills/fetch-polyfill');, but this PR deletes packages/js-dapi-client/polyfills/fetch-polyfill.js (the polyfills/ directory no longer exists in the worktree). karma.conf.js loads lib/test/karma/loader.js, which in turn requires this bootstrap, so webpack bundling for yarn workspace @dashevo/dapi-client test:browsers will fail at module resolution before any spec runs. Since package.json defines test as test:coverage && test:browsers, the package-level yarn test is broken on this SHA. With Node 18+ providing global fetch and modern browsers having it natively, the require can simply be dropped.

require('setimmediate');
blocking: `selfSigned` is now silently ignored despite still being produced for regtest

packages/js-dapi-client/lib/transport/JsonRpcTransport/requestJsonRpc.js (line 14)

requestJsonRpc still accepts selfSigned and embeds it in requestInfo, but the call to fetch(url, requestOptions) at line 49 no longer attaches any TLS override. This is not just dead API surface: lib/dapiAddressProvider/ListDAPIAddressProvider.js:31-41 actively rewrites local/regtest masternodes to https://127.0.0.1 and sets allowSelfSignedCertificate = true, which JsonRpcTransport continues to forward into this function. As a result, core JSON-RPC calls (getBestBlockHash, getBlockHash, etc.) against local Dashmate nodes will now fail TLS verification with no recovery path. Either restore an opt-in mechanism (e.g., expose a custom-fetch hook or document NODE_TLS_REJECT_UNAUTHORIZED=0) and stop forwarding a flag that does nothing, or remove the regtest self-signed branch in ListDAPIAddressProvider so callers aren't left with a broken local workflow. At minimum, update the JSDoc and DAPIAddress.js docs to note the parameter is inert.

suggestion: Self-signed cert test is now a tautology

packages/js-dapi-client/test/unit/transport/JsonRpcTransport/requestJsonRpc.spec.js (line 76)

should make https rpc request with self-signed certificate and return result only asserts expect(result).to.equal('passed') against a stubbed fetch. The production branch it used to cover (new https.Agent({ rejectUnauthorized: false }) injected onto requestOptions.agent) was removed in this PR, but the test still passes because nothing about selfSigned is asserted on the fetch call. As written it provides zero coverage of the documented selfSigned parameter. Delete it or rewrite it to assert that selfSigned=true is now a no-op (e.g., fetch is invoked with no agent property), so future regressions in this path are caught.

nitpick: `setimmediate` still in devDependencies after PR claims removal

packages/js-dapi-client/package.json (line 64)

The PR description lists setimmediate under removed deps, but "setimmediate": "^1.0.5" remains in devDependencies because lib/test/karma/bootstrap.js:2 still does require('setimmediate'). Either remove the devDependency together with the karma require (browsers in scope here have setImmediate polyfilled via webpack's process shim or it's unused) or correct the PR description. Mostly a description/diff mismatch, not a runtime defect.

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

- [BLOCKING] In `packages/js-dapi-client/lib/test/karma/bootstrap.js`:1-1: Karma bootstrap requires deleted fetch-polyfill
  Line 1 still has `require('../../../polyfills/fetch-polyfill');`, but this PR deletes `packages/js-dapi-client/polyfills/fetch-polyfill.js` (the `polyfills/` directory no longer exists in the worktree). `karma.conf.js` loads `lib/test/karma/loader.js`, which in turn requires this bootstrap, so webpack bundling for `yarn workspace @dashevo/dapi-client test:browsers` will fail at module resolution before any spec runs. Since `package.json` defines `test` as `test:coverage && test:browsers`, the package-level `yarn test` is broken on this SHA. With Node 18+ providing global `fetch` and modern browsers having it natively, the require can simply be dropped.
- [BLOCKING] In `packages/js-dapi-client/lib/transport/JsonRpcTransport/requestJsonRpc.js`:14-49: `selfSigned` is now silently ignored despite still being produced for regtest
  `requestJsonRpc` still accepts `selfSigned` and embeds it in `requestInfo`, but the call to `fetch(url, requestOptions)` at line 49 no longer attaches any TLS override. This is not just dead API surface: `lib/dapiAddressProvider/ListDAPIAddressProvider.js:31-41` actively rewrites local/regtest masternodes to `https://127.0.0.1` and sets `allowSelfSignedCertificate = true`, which `JsonRpcTransport` continues to forward into this function. As a result, core JSON-RPC calls (`getBestBlockHash`, `getBlockHash`, etc.) against local Dashmate nodes will now fail TLS verification with no recovery path. Either restore an opt-in mechanism (e.g., expose a custom-fetch hook or document `NODE_TLS_REJECT_UNAUTHORIZED=0`) and stop forwarding a flag that does nothing, or remove the regtest self-signed branch in `ListDAPIAddressProvider` so callers aren't left with a broken local workflow. At minimum, update the JSDoc and `DAPIAddress.js` docs to note the parameter is inert.
- [SUGGESTION] In `packages/js-dapi-client/test/unit/transport/JsonRpcTransport/requestJsonRpc.spec.js`:76-99: Self-signed cert test is now a tautology
  `should make https rpc request with self-signed certificate and return result` only asserts `expect(result).to.equal('passed')` against a stubbed `fetch`. The production branch it used to cover (`new https.Agent({ rejectUnauthorized: false })` injected onto `requestOptions.agent`) was removed in this PR, but the test still passes because nothing about `selfSigned` is asserted on the fetch call. As written it provides zero coverage of the documented `selfSigned` parameter. Delete it or rewrite it to assert that `selfSigned=true` is now a no-op (e.g., `fetch` is invoked with no `agent` property), so future regressions in this path are caught.
- [NITPICK] In `packages/js-dapi-client/package.json`:64-64: `setimmediate` still in devDependencies after PR claims removal
  The PR description lists `setimmediate` under removed deps, but `"setimmediate": "^1.0.5"` remains in `devDependencies` because `lib/test/karma/bootstrap.js:2` still does `require('setimmediate')`. Either remove the devDependency together with the karma require (browsers in scope here have `setImmediate` polyfilled via webpack's process shim or it's unused) or correct the PR description. Mostly a description/diff mismatch, not a runtime defect.

Inline posting hit GitHub HTTP 422, so I posted the same verified findings as a top-level review body.

@PastaPastaPasta
Copy link
Copy Markdown
Member Author

Closing — reopening as upstream→upstream so CI runs against secrets/runners. New PR link will be added shortly.

@PastaPastaPasta
Copy link
Copy Markdown
Member Author

Reopened as #3679 (upstream→upstream so CI runs against repo secrets/runners).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants