feat(hypercore): support transfers from HyperEVM and HyperCore#481
feat(hypercore): support transfers from HyperEVM and HyperCore#481kiseln wants to merge 5 commits into
Conversation
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: c40335b The changes in this PR will be included in the next version bump. This PR includes changesets to release 8 packages
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 |
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts: # packages/core/tests/bridge.test.ts
There was a problem hiding this comment.
Pull request overview
Adds HyperEVM as a supported EVM source/destination path and introduces a new @omni-bridge/hypercore package for building and submitting Hyperliquid Core sendToEvmWithData actions.
Changes:
- Registers HyperEVM bridge addresses, chain IDs, validation support, RPC/proof configuration, and EVM package docs.
- Adds
@omni-bridge/hypercorewith builders, encoders, typed-data signing helpers, spot metadata lookup, submit helper, tests, README, and package wiring. - Updates SDK exports, TypeScript project references, lockfile, and changeset configuration.
Reviewed changes
Copilot reviewed 29 out of 31 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
tsconfig.json |
Adds the HyperCore package to project references. |
packages/sdk/tsconfig.json |
Adds SDK project reference to HyperCore. |
packages/sdk/src/index.ts |
Re-exports the HyperCore package from the umbrella SDK. |
packages/sdk/package.json |
Adds HyperCore workspace dependency. |
packages/hypercore/tsconfig.json |
Defines TypeScript config for the new package. |
packages/hypercore/package.json |
Defines package metadata, exports, and dependencies. |
packages/hypercore/README.md |
Documents HyperCore usage and helper APIs. |
packages/hypercore/src/builder.ts |
Builds unsigned HyperCore transfer actions and typed data. |
packages/hypercore/src/config.ts |
Adds Hyperliquid API URLs, chain IDs, and defaults. |
packages/hypercore/src/encoders.ts |
Encodes HyperEVM release and bridge-init action payloads. |
packages/hypercore/src/format-amount.ts |
Formats bigint amounts as Hyperliquid decimal strings. |
packages/hypercore/src/index.ts |
Exposes the HyperCore public API. |
packages/hypercore/src/spot-meta.ts |
Resolves and caches Hyperliquid spot metadata. |
packages/hypercore/src/submit.ts |
Posts signed actions to Hyperliquid /exchange. |
packages/hypercore/src/typed-data.ts |
Constructs EIP-712 typed data and signature helpers. |
packages/hypercore/src/types.ts |
Defines action and exchange envelope types. |
packages/hypercore/tests/builder.test.ts |
Tests transfer action construction and metadata caching. |
packages/hypercore/tests/encoders.test.ts |
Tests action payload ABI encoding. |
packages/hypercore/tests/format-amount.test.ts |
Tests amount formatting vectors and validation. |
packages/hypercore/tests/typed-data.test.ts |
Tests typed-data digest behavior and signature recovery. |
packages/evm/src/proof.ts |
Adds HyperEVM RPC URLs and viem chain configs. |
packages/evm/README.md |
Documents HyperEVM support in the EVM builder. |
packages/core/tests/bridge.test.ts |
Updates validation tests for HyperEVM support. |
packages/core/src/utils/hyperliquid.ts |
Adds helper for inbound Hyperliquid transfer params. |
packages/core/src/utils/address.ts |
Treats HyperEVM as an EVM-compatible chain. |
packages/core/src/index.ts |
Exports Hyperliquid helper APIs. |
packages/core/src/config.ts |
Registers HyperEVM addresses and chain IDs. |
packages/core/src/bridge.ts |
Enables HyperEVM contract lookup and validation flow. |
bun.lock |
Records new workspace package and dependency wiring. |
.changeset/hypercore-support.md |
Adds release notes and package bumps. |
.changeset/config.json |
Adds HyperCore to the fixed-version package group. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| hyperliquidChain: HYPERLIQUID_CHAIN[this.network], | ||
| signatureChainId: this.signatureChainId, | ||
| token: spotInfo.spotId, | ||
| amount: formatAmount(params.amount, spotInfo.decimals), |
| destinationChainId: HYPEREVM_CHAIN_ID[this.network], | ||
| gasLimit, | ||
| data: data.hex, | ||
| nonce: currentMsNonce(), |
There was a problem hiding this comment.
@kiseln for sdk-rs it was fine (I even removed initial version with atomic and replaced with timestamp), because people won't call it that often, but for frontend where sdk-js is used, it's a bit more critical
There was a problem hiding this comment.
On a millisecond level seems good enough for me. Also we can't really synchronize it across many front-end users
| export { | ||
| createHyperCoreBuilder, | ||
| type HyperCoreBuilder, | ||
| type HyperCoreBuilderConfig, | ||
| type HyperCoreTransferParams, | ||
| type HyperCoreUnsignedAction, | ||
| } from "./builder.js" |
| export { type PostExchangeActionOptions, postExchangeAction } from "./submit.js" | ||
| export { |
| interface SpotMetaToken { | ||
| name: string | ||
| fullName?: string | null | ||
| szDecimals: number | ||
| weiDecimals: number | ||
| tokenId: string | ||
| evmContract?: { | ||
| address: string | ||
| evm_extra_wei_decimals: number | ||
| } | null | ||
| } |
| <ResponseField name="params" type="HyperCoreTransferParams" required> | ||
| <Expandable title="HyperCoreTransferParams"> | ||
| <ResponseField name="spotId" type="string" required> | ||
| Hyperliquid spot identifier in the canonical `"NAME:0x<32hex>"` form (e.g. `"USDC:0x6d1e7cde53ba9467b783cb7c530ce054"`). Names alone are **not** accepted: Hyperliquid permits multiple tokens to share a `name`, so the 32-byte `tokenId` is the only unambiguous handle. |
| // Hyperliquid helpers | ||
| export { buildHyperliquidTransferParams, HYPERLIQUID_MESSAGE } from "./utils/hyperliquid.js" |
Summary
Adds two outbound source-chain paths that were previously unsupported:
@omni-bridge/evmbuilder.@omni-bridge/hypercorepackage that builds the EIP-712sendToEvmWithDatauser-signed action posted to Hyperliquid's/exchange.Changes
HyperEVM as EVM source
packages/core/src/config.ts: registershlevmbridge address (0xf353b40fC144d1c6c5BCdda712fa6De833016aF9, same on mainnet+testnet) and chain ids 999/998.packages/core/src/utils/address.ts:HyperEvmjoinsEvmChainKindandisEvmChain().packages/core/src/bridge.ts: drops the two "not yet configured/supported" throws.packages/evm/src/proof.ts: wires HyperEVM RPC URLs and viem chain definitions (hyperEvm,hyperliquidEvmTestnet).@omni-bridge/hypercore(new package)builder.ts:createHyperCoreBuilder({network})+buildTransfer({spotToken, amount, recipient, ...}). PicksACTION_TRANSFER(0x00) for HyperEVM recipients (pool release) orACTION_INIT_TRANSFER(0x01) for any other chain (routes viaOmniBridge.initTransfer). OptionalhlBridgeToken/decimals/spotIdoverrides skip the/infolookup.encoders.ts: ABI encoders for the two actiondatapayloads.typed-data.ts: EIP-712 domain + type list + precomputed digest forHyperliquidTransaction:SendToEvmWithData.spot-meta.ts: resolves spot name →{spotId, hlBridgeToken, decimals}via/info { type: "spotMeta" }, memoized per session.submit.ts:postExchangeAction()thin POST helper for/exchange.format-amount.ts: bigint+decimals → Hyperliquid decimal-string format.Wiring
@omni-bridge/sdkumbrella re-exports the new package; roottsconfig.jsonreferences it.Technical details
OmniAddressprefix: HyperCore reuseshlevm:(matches the Rust SDK); source-side mechanism is selected by builder choice, not by address prefix.signatureChainIddefaults to0x66eeeto match the Hyperliquid Python SDK convention. Only its cross-chain uniqueness matters for replay protection; the value isn't tied to Arbitrum.szDecimals + evmExtraWeiDecimals, the HyperEVM↔HyperCore linking invariant.