Skip to content

Remove Ethereum services layer from SDK#13802

Draft
rickyrombo wants to merge 1 commit intomjp-ethfrom
mjp-sdk-eth
Draft

Remove Ethereum services layer from SDK#13802
rickyrombo wants to merge 1 commit intomjp-ethfrom
mjp-sdk-eth

Conversation

@rickyrombo
Copy link
Contributor

Summary

Removes the entire Ethereum contract client abstraction from @audius/sdk and replaces it with plain functions in @audius/common that call contracts directly via viem + @audius/eth ABIs.

-1,880 lines deleted, +335 lines added across 57 files (net -1,545 lines). The new ethereum.ts module is 248 lines.

Motivation

The SDK's Ethereum services layer was heavily over-abstracted for what it actually did at runtime:

  • 11 contract client classes (AudiusToken, Staking, DelegateManager, AudiusWormhole, Governance, Registry, ClaimsManager, EthRewardsManager, ServiceProviderFactory, ServiceTypeManager, TrustedNotifierManager) — each with its own types file, config file, index file, and client file
  • Only 4 were used at runtime by the web/mobile apps, across just 3 consumer files in @audius/common
  • 7 were dead code — used only at build time by generateServicesConfig.ts or not used at all
  • Every client class wrapped a single viem readContract or writeContract call behind Zod schemas, config objects, and a class hierarchy — adding indirection without value

The runtime functionality boils down to 6 operations: balanceOf, totalStakedFor, getTotalDelegatorStake, permit, transferTokens, and a composite "full balance" helper. These don't need classes, schemas, or SDK-level config.

What changed

@audius/sdk (removals)

  • Deleted packages/sdk/src/sdk/services/Ethereum/contracts/ — all 11 contract client directories (44 files)
  • Removed 6 fields from ServicesContainer: ethPublicClient, ethWalletClient, audiusTokenClient, delegateManagerClient, stakingClient, audiusWormholeClient
  • Removed 4 runtime contract addresses from SDK config (audiusTokenAddress, audiusWormholeAddress, delegateManagerAddress, stakingAddress) — these now come directly from @audius/eth static exports
  • Cleaned createSdkWithServices.ts — removed all Ethereum client instantiation and viem client creation

@audius/common (additions)

  • New file: ethereum.ts (248 lines) containing:

    • createEthPublicClient(rpcUrl) / createEthWalletClient(rpcUrl) — pure factories, no hidden singleton state
    • getAudioBalance(), getTotalStakedFor(), getTotalDelegatorStake() — plain read functions using hardcoded addresses from @audius/eth
    • getFullAudioBalance() — composite helper (balance + staked + delegated in parallel)
    • permitAudioToken() — EIP-2612 permit via signed typed data
    • wormholeTransferTokens() — Wormhole bridge transfer via signed typed data
    • EthSigner type — minimal interface for signing operations
  • Updated consumers:

    • useAudioBalance.ts — uses createEthPublicClient + read helpers directly
    • AudiusBackend.ts — getBalance() and getAddressTotalStakedBalance() use read helpers directly; removed vestigial sdk parameter from both functions
    • WalletClient.ts — transferTokensFromEthToSol() uses createEthPublicClient/createEthWalletClient + imported write helpers; removed unnecessary sdk passthrough from callers of getAddressTotalStakedBalance
  • Added @audius/eth dependency to package.json

Design decisions

  1. Plain functions, no classes. Every function is stateless and takes its dependencies as arguments. No singletons, no hidden mutable state.
  2. Reads and writes in one module. ethereum.ts is the single place for all Ethereum contract interactions. Easy to find, easy to audit.
  3. Hardcoded addresses. @audius/eth exports addresses as const literals from a single source of truth. Removed the speculative address-override parameters that were never used.
  4. Eliminated @wormhole-foundation/sdk-base dependency. The Wormhole Solana chain ID is always 1 — hardcoded instead of importing a large SDK for a single constant.
  5. EthSigner extracted. Named type for the signing interface prevents silent breakage if the SDK wallet client shape changes.

Testing

  • TypeScript compilation clean across all modified files
  • No runtime behavior changes — same contract calls, same addresses, same logic

@changeset-bot
Copy link

changeset-bot bot commented Mar 3, 2026

🦋 Changeset detected

Latest commit: b2d4b8c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@audius/eth Major
@audius/sdk Patch
@pedalboard/staking Patch
@audius/sdk-legacy Patch
@audius/sp-actions Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@rickyrombo rickyrombo requested a review from Copilot March 3, 2026 07:38
@gitguardian
Copy link

gitguardian bot commented Mar 3, 2026

⚠️ GitGuardian has uncovered 4 secrets following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secrets in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
10622416 Triggered Generic High Entropy Secret b2d4b8c packages/sdk/src/sdk/config/production.ts View secret
4714545 Triggered Generic High Entropy Secret b2d4b8c packages/sdk/src/sdk/config/development.ts View secret
1606950 Triggered Generic High Entropy Secret b2d4b8c packages/sdk/src/sdk/config/production.ts View secret
10622417 Triggered Generic High Entropy Secret b2d4b8c packages/sdk/src/sdk/config/development.ts View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secrets safely. Learn here the best practices.
  3. Revoke and rotate these secrets.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR removes the SDK’s Ethereum services/contract-client abstraction and migrates the remaining runtime Ethereum interactions into @audius/common as plain viem-powered functions backed by @audius/eth ABIs + mainnet addresses.

Changes:

  • Removed Ethereum clients and viem clients from @audius/sdk services container/config and deleted the Ethereum contract-client layer.
  • Added a new packages/common/src/services/ethereum/ethereum.ts module with direct read/write helpers (balance, staking/delegation reads, permit, wormhole transfer).
  • Refactored affected consumers (wallet client, backend balance helpers, query hook) to call the new common-layer helpers.

Reviewed changes

Copilot reviewed 58 out of 58 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/sdk/src/sdk/types.ts Removes Ethereum-related service typings from the SDK services container.
packages/sdk/src/sdk/services/index.ts Stops re-exporting the SDK Ethereum services module.
packages/sdk/src/sdk/services/Ethereum/index.ts Leftover barrel export updated, but now points at a deleted module (see comment).
packages/sdk/src/sdk/services/Ethereum/contracts/types.ts Deletes shared Ethereum contract client config/types.
packages/sdk/src/sdk/services/Ethereum/contracts/getDefaultConfig.ts Deletes default Ethereum viem PublicClient creation helper.
packages/sdk/src/sdk/services/Ethereum/contracts/TrustedNotifierManager/types.ts Deletes TrustedNotifierManager client config type.
packages/sdk/src/sdk/services/Ethereum/contracts/TrustedNotifierManager/index.ts Deletes TrustedNotifierManager client barrel exports.
packages/sdk/src/sdk/services/Ethereum/contracts/TrustedNotifierManager/getDefaultConfig.ts Deletes TrustedNotifierManager default config helper.
packages/sdk/src/sdk/services/Ethereum/contracts/TrustedNotifierManager/TrustedNotifierManagerClient.ts Deletes TrustedNotifierManager client wrapper class.
packages/sdk/src/sdk/services/Ethereum/contracts/Staking/types.ts Deletes Staking client config types.
packages/sdk/src/sdk/services/Ethereum/contracts/Staking/index.ts Deletes Staking client barrel exports.
packages/sdk/src/sdk/services/Ethereum/contracts/Staking/getDefaultConfig.ts Deletes Staking address defaulting via SDK config.
packages/sdk/src/sdk/services/Ethereum/contracts/Staking/StakingClient.ts Deletes Staking client wrapper (readContract wrappers).
packages/sdk/src/sdk/services/Ethereum/contracts/ServiceTypeManager/types.ts Deletes ServiceTypeManager client config types.
packages/sdk/src/sdk/services/Ethereum/contracts/ServiceTypeManager/index.ts Deletes ServiceTypeManager client barrel exports.
packages/sdk/src/sdk/services/Ethereum/contracts/ServiceTypeManager/getDefaultConfig.ts Deletes ServiceTypeManager default config + hardcoded service-type constants.
packages/sdk/src/sdk/services/Ethereum/contracts/ServiceTypeManager/ServiceTypeManagerClient.ts Deletes ServiceTypeManager client wrapper class.
packages/sdk/src/sdk/services/Ethereum/contracts/ServiceProviderFactory/types.ts Deletes ServiceProviderFactory client config types.
packages/sdk/src/sdk/services/Ethereum/contracts/ServiceProviderFactory/index.ts Deletes ServiceProviderFactory client barrel exports.
packages/sdk/src/sdk/services/Ethereum/contracts/ServiceProviderFactory/getDefaultConfig.ts Deletes ServiceProviderFactory default config + hardcoded service-type constants.
packages/sdk/src/sdk/services/Ethereum/contracts/ServiceProviderFactory/ServiceProviderFactoryClient.ts Deletes ServiceProviderFactory client wrapper class.
packages/sdk/src/sdk/services/Ethereum/contracts/Registry/types.ts Deletes Registry client config type.
packages/sdk/src/sdk/services/Ethereum/contracts/Registry/index.ts Deletes Registry client barrel exports.
packages/sdk/src/sdk/services/Ethereum/contracts/Registry/getDefaultConfig.ts Deletes Registry default config helper.
packages/sdk/src/sdk/services/Ethereum/contracts/Registry/RegistryClient.ts Deletes Registry client wrapper class.
packages/sdk/src/sdk/services/Ethereum/contracts/Governance/types.ts Deletes Governance client config type.
packages/sdk/src/sdk/services/Ethereum/contracts/Governance/index.ts Deletes Governance client barrel exports.
packages/sdk/src/sdk/services/Ethereum/contracts/Governance/getDefaultConfig.ts Deletes Governance default config helper.
packages/sdk/src/sdk/services/Ethereum/contracts/Governance/GovernanceClient.ts Deletes Governance client wrapper class.
packages/sdk/src/sdk/services/Ethereum/contracts/EthereumContract.ts Deletes abstract base class that created per-contract PublicClients.
packages/sdk/src/sdk/services/Ethereum/contracts/EthRewardsManager/types.ts Deletes EthRewardsManager client config type.
packages/sdk/src/sdk/services/Ethereum/contracts/EthRewardsManager/index.ts Deletes EthRewardsManager client barrel exports.
packages/sdk/src/sdk/services/Ethereum/contracts/EthRewardsManager/getDefaultConfig.ts Deletes EthRewardsManager default config helper.
packages/sdk/src/sdk/services/Ethereum/contracts/EthRewardsManager/EthRewardsManagerClient.ts Deletes EthRewardsManager client wrapper class.
packages/sdk/src/sdk/services/Ethereum/contracts/DelegateManager/types.ts Deletes DelegateManager client config types.
packages/sdk/src/sdk/services/Ethereum/contracts/DelegateManager/index.ts Deletes DelegateManager client barrel exports.
packages/sdk/src/sdk/services/Ethereum/contracts/DelegateManager/getDefaultConfig.ts Deletes DelegateManager address defaulting via SDK config.
packages/sdk/src/sdk/services/Ethereum/contracts/DelegateManager/DelegateManagerClient.ts Deletes DelegateManager client wrapper class.
packages/sdk/src/sdk/services/Ethereum/contracts/ClaimsManager/types.ts Deletes ClaimsManager client config type.
packages/sdk/src/sdk/services/Ethereum/contracts/ClaimsManager/index.ts Deletes ClaimsManager client barrel exports.
packages/sdk/src/sdk/services/Ethereum/contracts/ClaimsManager/getDefaultConfig.ts Deletes ClaimsManager default config helper.
packages/sdk/src/sdk/services/Ethereum/contracts/ClaimsManager/ClaimsManagerClient.ts Deletes ClaimsManager client wrapper class.
packages/sdk/src/sdk/services/Ethereum/contracts/AudiusWormhole/types.ts Deletes AudiusWormhole client config + schema-based params.
packages/sdk/src/sdk/services/Ethereum/contracts/AudiusWormhole/index.ts Deletes AudiusWormhole client barrel exports.
packages/sdk/src/sdk/services/Ethereum/contracts/AudiusWormhole/getDefaultConfig.ts Deletes AudiusWormhole address defaulting via SDK config.
packages/sdk/src/sdk/services/Ethereum/contracts/AudiusWormhole/AudiusWormholeClient.ts Deletes AudiusWormhole client wrapper class (typed-data + writeContract).
packages/sdk/src/sdk/services/Ethereum/contracts/AudiusToken/types.ts Deletes AudiusToken client config + schema-based params.
packages/sdk/src/sdk/services/Ethereum/contracts/AudiusToken/index.ts Deletes AudiusToken client barrel exports.
packages/sdk/src/sdk/services/Ethereum/contracts/AudiusToken/getDefaultConfig.ts Deletes AudiusToken address defaulting via SDK config.
packages/sdk/src/sdk/services/Ethereum/contracts/AudiusToken/AudiusTokenClient.ts Deletes AudiusToken client wrapper class (permit + balanceOf).
packages/sdk/src/sdk/scripts/generateServicesConfig.ts Replaces SDK Ethereum contract clients with direct viem calls using @audius/eth ABIs.
packages/sdk/src/sdk/createSdkWithServices.ts Removes Ethereum client instantiation and Ethereum service wiring from SDK initialization.
packages/sdk/src/sdk/config/types.ts Removes Ethereum contract addresses from SDK config type.
packages/sdk/src/sdk/config/production.ts Updates production config node list and removes Ethereum contract addresses from config.
packages/sdk/src/sdk/config/development.ts Reformats dev config and removes Ethereum contract addresses from config.
packages/eth/src/trusted-notifier-manager/trustedNotifierManager.ts Converts contract wrapper class to { abi, address } export.
packages/eth/src/trusted-notifier-manager/index.ts Removes submodule barrel exports.
packages/eth/src/trusted-notifier-manager/constants.ts Removes separate address constant file.
packages/eth/src/staking/staking.ts Converts contract wrapper class to { abi, address } export.
packages/eth/src/staking/index.ts Removes submodule barrel export.
packages/eth/src/service-type-manager/serviceTypeManager.ts Converts wrapper class to { abi, address } export; adds exported VALIDATOR_SERVICE_TYPE.
packages/eth/src/service-type-manager/index.ts Removes submodule barrel exports.
packages/eth/src/service-type-manager/constants.ts Removes separate address constant file.
packages/eth/src/service-provider-factory/serviceProviderFactory.ts Converts wrapper class to { abi, address } export.
packages/eth/src/service-provider-factory/index.ts Removes submodule barrel exports.
packages/eth/src/service-provider-factory/constants.ts Removes separate address constant file.
packages/eth/src/registry/registry.ts Converts wrapper class to { abi, address } export.
packages/eth/src/registry/index.ts Removes submodule barrel exports.
packages/eth/src/registry/constants.ts Removes separate address constant file.
packages/eth/src/index.ts Updates root exports to explicit deep exports + shared constants/types.
packages/eth/src/governance/index.ts Removes submodule barrel exports.
packages/eth/src/governance/governance.ts Converts wrapper class to { abi, address } export.
packages/eth/src/governance/constants.ts Removes separate address constant file.
packages/eth/src/eth-rewards-manager/index.ts Removes submodule barrel exports.
packages/eth/src/eth-rewards-manager/ethRewardsManager.ts Converts wrapper class to { abi, address } export.
packages/eth/src/eth-rewards-manager/constants.ts Removes separate address constant file.
packages/eth/src/delegate-manager/index.ts Removes submodule barrel export.
packages/eth/src/delegate-manager/delegateManager.ts Converts wrapper class to { abi, address } export.
packages/eth/src/claims-manager/index.ts Removes submodule barrel exports.
packages/eth/src/claims-manager/constants.ts Removes separate address constant file.
packages/eth/src/claims-manager/claimsManager.ts Converts wrapper class to { abi, address } export.
packages/eth/src/audius-wormhole/index.ts Removes submodule barrel export.
packages/eth/src/audius-wormhole/audiusWormhole.ts Converts wrapper class to { abi, address, domain, types } export for typed-data signing.
packages/eth/src/audius-token/index.ts Removes submodule barrel export.
packages/eth/src/audius-token/audiusToken.ts Converts wrapper class to { abi, address, domain, types } export for typed-data signing.
packages/eth/package.json Removes direct viem dependency and marks package as side-effect free.
packages/eth/README.md Expands documentation and examples for the new @audius/eth export shape.
packages/common/src/services/wallet-client/WalletClient.ts Migrates ETH→SOL transfer flow to use common ethereum helpers.
packages/common/src/services/ethereum/ethereum.ts Adds new centralized Ethereum utilities module (reads + permit + wormhole transfer).
packages/common/src/services/audius-backend/AudiusBackend.ts Replaces SDK Ethereum clients with common ethereum read helpers; removes sdk arg.
packages/common/src/api/tan-query/wallets/useAudioBalance.ts Replaces SDK Ethereum clients with common ethereum read helpers (and adds env dependency).
packages/common/package.json Adds @audius/eth dependency for direct ABI/address imports.
package-lock.json Updates lockfile for dependency graph changes.
.changeset/itchy-pants-unite.md Declares a major release for @audius/eth reflecting the breaking export/API shift.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

export * from './contracts/AudiusWormhole'
export * from './contracts/Registry'
export * from './contracts/Governance'
export * from './contracts'
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

export * from './contracts' points to a module that no longer exists (the contracts/ directory is deleted in this PR). This will cause the SDK package to fail TypeScript compilation/module resolution even if services/index.ts no longer re-exports Ethereum. Remove this file entirely, or change it to not re-export a non-existent path.

Copilot uses AI. Check for mistakes.
throw new Error('No wallet address available')
}

const deadline = BigInt(Date.now() + ONE_HOUR_IN_MS)
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

deadline is being set using Date.now() milliseconds, but the comment says “one hour” and EIP-2612 deadlines are typically Unix timestamps in seconds (checked against block.timestamp). Using ms makes the permit effectively valid for ~55k years, which is likely unintended and weakens the safety of expiring permits. Use a seconds-based timestamp (consistent with wormholeTransferTokens) or rename/comment to reflect the intended unit.

Suggested change
const deadline = BigInt(Date.now() + ONE_HOUR_IN_MS)
const deadline = BigInt(Math.floor(Date.now() / 1000) + 60 * 60)

Copilot uses AI. Check for mistakes.
Comment on lines +98 to +100
const ethPublicClient = createEthPublicClient(this.env.ETH_PROVIDER_URL)
const ethWalletClient = createEthWalletClient(this.env.ETH_PROVIDER_URL)

Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

createEthWalletClient(this.env.ETH_PROVIDER_URL) will create a WalletClient backed by a raw JSON-RPC URL, which typically cannot sign or relay transactions (public RPCs won’t have the user’s account unlocked, and won’t pay gas). This looks like a regression for permit/transferTokens flows that previously relied on an EIP-1193/custom transport (e.g. identity relay) to submit transactions. Consider constructing the WalletClient using the same relay/custom transport used elsewhere, or pass an already-configured WalletClient into this method instead of deriving it from ETH_PROVIDER_URL.

Copilot uses AI. Check for mistakes.
Comment on lines +46 to +51
/** Create a viem WalletClient for Ethereum mainnet. */
export const createEthWalletClient = (rpcUrl: string) =>
createWalletClient({
chain: mainnet,
transport: http(rpcUrl)
})
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

createEthWalletClient currently always uses http(rpcUrl) transport. A WalletClient created this way can only send transactions if the RPC node can sign for the from address (unlocked/local account), which is usually not true in browser/mobile contexts. To prevent accidental misuse, consider (a) removing this factory and requiring callers to provide a WalletClient/transport, or (b) renaming/documenting it as a server-side/unlocked-account helper and adding an alternative helper for the identity-relay/EIP-1193 transport pattern.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants