@layerzerolabs/hyperliquid-composer
Version:
LayerZero Labs reference EVM OmniChain Fungible Token (OFT) implementation for Hyperliquid
352 lines (337 loc) • 13.1 kB
text/typescript
import { Wallet, ethers } from 'ethers';
import { Hex } from '@layerzerolabs/lz-utilities';
import { Logger } from '@layerzerolabs/io-devtools';
import dotenv from 'dotenv';
declare function setRequestEvmContract(wallet: Wallet, isTestnet: boolean, evmSpotTokenAddress: string, evmExtraWeiDecimals: number, coreSpotTokenId: number, logLevel: string): Promise<any>;
declare function setFinalizeEvmContract(wallet: Wallet, isTestnet: boolean, coreSpotTokenId: number, nonce: number, logLevel: string): Promise<any>;
declare function useBigBlock(wallet: Wallet, isTestnet: boolean, logLevel: string): Promise<any>;
declare function useSmallBlock(wallet: Wallet, isTestnet: boolean, logLevel: string): Promise<any>;
interface BaseInfoRequest {
type: string;
[key: string]: unknown;
}
/** Base structure for exchange requests. */
interface BaseExchangeRequest {
/** Action to perform. */
action: {
/** Type of action. */
type: string;
/** Additional action parameters. */
[key: string]: unknown;
};
/** Unique request identifier (recommended current timestamp in ms). */
nonce: number;
/** Cryptographic signature. */
signature: {
r: Hex;
s: Hex;
v: number;
};
}
/** Base structure for exchange responses. */
interface BaseExchangeResponse {
/** Response status */
status: 'ok' | 'err';
/** Error message or success data */
response: string | {
/** Type of response. */
type: string;
/** Specific data for the operation. */
data?: unknown;
};
}
interface Signature {
r: string;
s: string;
v: number;
}
type ValueType = number | bigint | string | boolean | null | Uint8Array | readonly ValueType[] | ValueMap | BaseInfoRequest;
interface ValueMap {
[key: string]: ValueType;
}
declare const HYPERLIQUID_URLS: {
MAINNET: string;
TESTNET: string;
};
declare const RPC_URLS: {
MAINNET: string;
TESTNET: string;
};
declare const CHAIN_IDS: {
MAINNET: number;
TESTNET: number;
};
declare const ENDPOINTS: {
INFO: string;
EXCHANGE: string;
};
declare const MAX_HYPERCORE_SUPPLY: number;
/**
* These are the token ids for USDC on hypercore mainnet and testnet
* It can be reproduced by grabbing the entire spotMeta and finding USDC because Hyperliquid does not have an API to target query an asset (April 8, 2025)
* - curl -X POST "https://api.hyperliquid.xyz/info" -H "Content-Type: application/json" -d '{"type": "spotMeta"}' > spotOut.json
* - Goto tokens and the first entry should be USDC with an index of 0
*/
declare const USDC_TOKEN_ID: {
MAINNET: number;
TESTNET: number;
};
declare function toAssetBridgeAddress(tokenIndex: number): string;
interface CoreSpotMetaData {
name: string;
szDecimals: number;
weiDecimals: number;
index: number;
tokenId: string;
isCanonical: boolean;
evmContract: null | {
address: string;
evm_extra_wei_decimals: number;
};
fullName: string | null;
deployerTradingFeeShare: string;
}
interface TxData {
from: string;
txHash: string;
nonce: number;
weiDiff: number;
assetBridgeAddress: string;
connected: boolean;
}
interface UserGenesis$1 {
userAndWei: Array<{
address: string;
wei: string;
}>;
existingTokenAndWei: Array<{
token: number;
wei: string;
}>;
blacklistUsers: string[];
}
interface CoreSpotDeployment {
coreSpot: CoreSpotMetaData;
txData: TxData;
userGenesis: UserGenesis$1;
}
interface SpotMeta {
tokens: CoreSpotMetaData[];
}
type SpotInfoBalance = [address: string, balance: string];
interface SpotInfo {
name: string;
maxSupply: string;
totalSupply: string;
circulatingSupply: string;
szDecimals: number;
weiDecimals: number;
midPx: string;
markPx: string;
prevDayPx: string;
genesis: {
userBalances: SpotInfoBalance[];
existingTokenBalances: SpotInfoBalance[];
};
deployer: string;
deployGas: string;
deployTime: string;
seededUsdc: string;
nonCirculatingUserBalances: SpotInfoBalance[];
futureEmissions: string;
}
interface DeployState {
token: number;
spec: {
name: string;
szDecimals: number;
weiDecimals: number;
};
fullName: string | null;
spots: number[];
maxSupply: number;
hyperliquidityGenesisBalance: string;
totalGenesisBalanceWei: string;
userGenesisBalances: [string, string][];
existingTokenGenesisBalances: [number, string][];
}
interface GasAuction {
startTimeSeconds: number;
durationSeconds: number;
startGas: string;
currentGas: string | null;
endGas: string;
}
interface SpotDeployStates {
states: DeployState[];
gasAuction: GasAuction;
}
/**
* This is an optional action that can be performed at any time after
* RegisterToken2. While the fee share defaults to 100%, this action
* can be resent multiple times as long as the fee share is not increasing.
* @param token - The token
* @param share - The deployer trading fee share. Range: ["0%", "100%"]. Examples: "0.012%", "99.4%"
*/
interface SetDeployerTradingFeeShare {
token: number;
share: string;
}
/**
* UserGenesis can be called multiple times
* @param token - The token involved in the genesis.
* @param userAndWei - A list of tuples of user address and genesis amount (wei).
* @param existingTokenAndWei - A list of tuples of existing token and total genesis amount for holders of that token (wei).
* @param blacklistUsers - A list of tuples of users and blacklist status (True if blacklist, False to remove existing blacklisted user).
*/
interface UserGenesis {
token: number;
userAndWei: Array<[string, string]>;
existingTokenAndWei: Array<[number, string]>;
blacklistUsers?: Array<[string, boolean]>;
}
/**
* Genesis denotes the initial creation of a token with a maximum supply.
* @param maxSupply - Checksum ensureing all calls to UserGenesis succeeded
* @param noHyperliquidity - Set hyperliquidity balance to 0.
*/
interface Genesis {
token: number;
maxSupply: string;
noHyperliquidity: boolean;
}
/**
* @param tokens - [base token index, quote token index]
* @dev The base token index is the token index of the token that will be used as the base for the spot.
* @dev The quote token index is the token index of the token that will be used as the quote for the spot - this is the token that will be used to pay the trading fee like USDC.
*/
interface RegisterSpot {
tokens: [number, number];
}
/**
* @param spot - The spot index (different from base token index)
* @param startPx - The starting price.
* @param orderSz - The size of each order (float, not wei)
* @param nOrders - The number of orders. If "noHyperliquidity" was set to True, then this must be 0.
* @param nSeededLevels - The number of levels the deployer wishes to seed with usdc instead of tokens.
*/
interface RegisterHyperliquidity {
spot: number;
startPx: string;
orderSz: string;
nOrders: number;
nSeededLevels?: number;
}
interface EvmUserModifyRequest extends BaseExchangeRequest {
action: {
type: 'evmUserModify';
usingBigBlocks: boolean;
};
}
interface EvmSpotDeploy extends BaseExchangeRequest {
action: {
type: 'spotDeploy';
requestEvmContract: {
token: number;
address: string;
evmExtraWeiDecimals: number;
};
};
}
interface FinalizeEvmContract extends BaseExchangeRequest {
action: {
type: 'finalizeEvmContract';
token: number;
input: {
create: {
nonce: number;
};
};
};
}
interface SpotDeployAction extends BaseExchangeRequest {
action: {
type: 'spotDeploy';
setDeployerTradingFeeShare: SetDeployerTradingFeeShare;
} | {
type: 'spotDeploy';
userGenesis: UserGenesis;
} | {
type: 'spotDeploy';
genesis: Genesis;
} | {
type: 'spotDeploy';
registerSpot: RegisterSpot;
} | {
type: 'spotDeploy';
registerHyperliquidity: RegisterHyperliquidity;
};
}
declare function getSpotMeta(wallet: Wallet | null, isTestnet: boolean, logLevel: string, tokenIndex: string): Promise<CoreSpotMetaData>;
declare function getHipTokenInfo(wallet: Wallet | null, isTestnet: boolean, logLevel: string, tokenAddress: string): Promise<SpotInfo>;
declare function getSpotDeployState(deployerAddres: string, isTestnet: boolean, logLevel: string): Promise<SpotDeployStates>;
declare function setTradingFeeShare(wallet: Wallet, isTestnet: boolean, coreSpotTokenId: number, share: string, logLevel: string): Promise<any>;
declare function setUserGenesis(wallet: Wallet, isTestnet: boolean, coreSpotTokenId: number, action: string, logLevel: string): Promise<{
responseForUserGenesis: {};
responseForBlacklistUsers: {};
}>;
declare function setGenesis(wallet: Wallet, isTestnet: boolean, coreSpotTokenId: number, logLevel: string): Promise<any>;
declare function setNoHyperliquidity(wallet: Wallet, isTestnet: boolean, tokenIndex: number, logLevel: string): Promise<any>;
declare function registerSpot(wallet: Wallet, isTestnet: boolean, coreSpotTokenId: number, logLevel: string): Promise<any>;
/**
* @dev Creates a keccak hash based on the packed action, nonce, and vault address.
* @dev I just ripped off - https://github.com/hyperliquid-dex/hyperliquid-python-sdk/blob/master/hyperliquid/utils/signing.py#L137-L145
*
* @param action - The action data to be packed with MessagePack.
* @param vaultAddress - The vault address as a hex string or null.
* @param nonce - A numeric nonce.
*
* @returns The keccak hash as a hex string.
*/
declare function computeL1ActionHash(action: ValueType, nonce: number, vaultAddress: string | null): string;
/**
* Sign an L1 action.
*
* @dev Signature generation depends on the order of the action keys.
* @dev I just ripped off - https://github.com/hyperliquid-dex/hyperliquid-python-sdk/blob/master/hyperliquid/utils/signing.py#L152-L177
*
* @param args.wallet - Wallet to sign the action.
* @param args.action - The action to be signed.
* @param args.nonce - Unique request identifier (recommended current timestamp in ms).
* @param args.isTestnet - Indicates if the action is for the testnet. Default is `false`.
* @param args.vaultAddress - Optional vault address used in the action.
*
* @returns The signature components r, s, and v.
*/
declare function signL1Action(args: {
wallet: Wallet;
action: ValueType;
nonce: number;
isTestnet?: boolean;
vaultAddress: Hex | null;
}): Promise<{
r: Hex;
s: Hex;
v: number;
}>;
declare function getTimestampMs(): number;
declare function getHyperliquidWallet(privateKey?: string): Promise<ethers.Wallet>;
declare class HyperliquidClient {
private readonly client;
private readonly baseUrl;
private readonly isTestnet;
private readonly logger;
constructor(isTestnet: boolean, logLevel: string);
submitHyperliquidAction(endpoint: string, wallet: Wallet | null, action: ValueType): Promise<any>;
}
declare function getCoreSpotDeployment(index: string | number, isTestnet: boolean, logger?: Logger): CoreSpotDeployment;
declare function writeCoreSpotDeployment(index: string | number, isTestnet: boolean, coreSpotDeployment: CoreSpotDeployment, logger?: Logger): void;
declare function writeUpdatedCoreSpotDeployment(index: string | number, isTestnet: boolean, tokenFullName: string, tokenAddress: string, txData: TxData, logger?: Logger): void;
declare function writeNativeSpotConnected(index: string | number, isTestnet: boolean, connected: boolean, weiDiff: number, logger?: Logger): void;
declare function getHyperEVMOAppDeployment(oapp_config: string, network: string, logger?: Logger): Promise<{
contractName: string;
deployment: string;
}>;
declare function getERC20abi(): Promise<any>;
declare function loadEnv(): dotenv.DotenvParseOutput;
export { type BaseExchangeRequest, type BaseExchangeResponse, type BaseInfoRequest, CHAIN_IDS, type CoreSpotDeployment, type CoreSpotMetaData, type DeployState, ENDPOINTS, type EvmSpotDeploy, type EvmUserModifyRequest, type FinalizeEvmContract, type GasAuction, HYPERLIQUID_URLS, HyperliquidClient, MAX_HYPERCORE_SUPPLY, RPC_URLS, type Signature, type SpotDeployAction, type SpotDeployStates, type SpotInfo, type SpotInfoBalance, type SpotMeta, type TxData, USDC_TOKEN_ID, type UserGenesis$1 as UserGenesis, type ValueMap, type ValueType, computeL1ActionHash, getCoreSpotDeployment, getERC20abi, getHipTokenInfo, getHyperEVMOAppDeployment, getHyperliquidWallet, getSpotDeployState, getSpotMeta, getTimestampMs, loadEnv, registerSpot, setFinalizeEvmContract, setGenesis, setNoHyperliquidity, setRequestEvmContract, setTradingFeeShare, setUserGenesis, signL1Action, toAssetBridgeAddress, useBigBlock, useSmallBlock, writeCoreSpotDeployment, writeNativeSpotConnected, writeUpdatedCoreSpotDeployment };