EIP-712 서명
이 페이지는 Hypercall이 검증하는 모든 EIP-712 메시지에 대한 필드 단위 레퍼런스입니다. 세 가지 디렉티브 서명 도메인(API 지갑, Manager, RSM), API 지갑 도메인을 공유하는 오프체인 전용 퍼프 메시지, 그리고 독립형 Physical Covered Call Quote 도메인을 다룹니다. REST API의 옵션 주문은 별도의 도메인인 Hypercall을 사용합니다. 인증 및 서명을 참고하십시오.
이 페이지의 모든 내용은 HyperEVM 메인넷(체인 ID 999)에 배포된 컨트랙트를 기준으로 검증되었습니다. 대상은 0xE6b7FaA216cabb2b38B392f577C9c826378b2240에 배포된 Exchange 0.6.1과 Account 0.2.4입니다. 아래의 도메인 구분자(domain separator)와 타입해시는 배포된 바이트코드에 내장되어 있습니다.
개요
디렉티브는 하나의 Account에 대한 하나의 작업으로, 오프체인에서 서명되고 Hypercall의 시퀀서가 Exchange.executeUserDirective 또는 Exchange.executeRsmDirective를 통해 온체인에 제출합니다. Account는 EIP-712 다이제스트에서 서명자를 복원하고 권한을 확인합니다.
- API 지갑:
hc_update_api_wallet으로 Account에 등록된 주소입니다(Account.isApiWalletActive). 주문과 취소에 서명합니다. - Manager: Account 소유자입니다(
Account.manager). API 지갑 변경, 자산 전송, 계정 모드 변경에 서명합니다. - RSM 서명자: 프로토콜이 관리합니다(
Exchange.rsmSigner). 입금 반영, 출금, 청산 디렉티브, 감소 전용(reduce-only) 복구 주문에 서명합니다. 사용자는 이에 서명하지 않습니다.
디렉티브 인코딩
온체인에서 디렉티브는 abi.encodePacked(account, nonce, version, id, data)입니다.
| 바이트 | 필드 | 의미 |
|---|---|---|
| 20 | account | Account 주소 (address) |
| 8 | nonce | 서명자의 논스 (uint64) |
| 1 | version | 작업 계열 |
| 3 | id | 계열 내 작업 ID |
| 나머지 | data | 내부 작업 구조체의 abi.encode |
| 버전 | 계열 | 작업 ID |
|---|---|---|
0 | HyperCall (HC) | 2 API 지갑 업데이트. 1(옵션 이전)은 예약되어 있으며 거부됩니다. |
1 | HyperLiquid (HL) | 1 지정가 주문, 9 API 지갑 추가, 10 oid로 취소, 11 cloid로 취소, 13 자산 전송, 16 추상화 설정 |
255 | System | 1 토큰 입금 반영, 2 옵션 입금 반영, 3 청산 시작, 4 청산 중지, 5 토큰 출금 |
이 바이트 문자열을 직접 만들 필요는 없습니다. 타입 데이터에 서명한 뒤 account, nonce, action, signature를 API에 제출하면 API가 디렉티브를 인코딩합니다.
타입 데이터 구조
모든 디렉티브는 동일한 외부 구조를 가집니다. Account 주소, 서명자의 논스, 그리고 하나의 내부 작업 구조체입니다.
<Outer>(address account,uint64 nonce,<Inner> action)<Inner>(...)
외부 타입 문자열 뒤에 내부 타입 정의가 붙으므로 타입해시는 두 가지를 모두 포함합니다. EIP-712 용어로 primaryType은 외부 이름이고, types에는 두 항목이 모두 들어가며, message는 { account, nonce, action }입니다. 필드 순서는 타입 문자열의 일부이므로 정확히 일치해야 합니다.
서명이 필요 없는 자금 입금 진입점
모든 자금 관련 호출이 EIP-712 작업인 것은 아닙니다. 다음 메서드는 지불하는 지갑이나 라우터가 직접 보내는 트랜잭션입니다.
function depositUsdcFor(address account, uint256 amount) external;
function depositOption(address account, address token, uint256 amount) external;
depositUsdcFor는 msg.sender가 USDC 지불자일 뿐이므로 의도적으로 서명을 요구하지 않습니다. 입금이 반영되는 Hypercall 계정은 명시적인 account 인자이며 UsdcDeposit.account 이벤트 필드에 기록됩니다. 라우터와 zap이 이 메서드를 호출할 수 있으므로, 인덱서와 백엔드 서비스는 입금 귀속 판단에 msg.sender를 사용해서는 안 됩니다.
depositOption은 msg.sender의 옵션 토큰을 소각하고 RSM 인덱서를 위해 Deposit(account, msg.sender, token, amount)를 발생시킵니다. 옵션 입금 반영 경로는 이벤트 기반이며, 입금자의 manager, 에이전트, RSM 서명을 사용하지 않습니다.
독립형 도메인: 실물 인도형 커버드콜 호가
실물 인도형 커버드콜 호가는 선택한 체인에 배포된 팩토리가 검증합니다. Exchange 검증자나 그 제로 주소 도메인을 사용하지 않습니다.
도메인:
{
"name": "Hypercall Physical Covered Call",
"version": "1",
"chainId": "<selected chain id>",
"verifyingContract": "<exact PhysicalCoveredCallFactory address>"
}
서명자: PhysicalCoveredCallQuote.marketMaker에 인코딩된 마켓메이커입니다.
정규 중첩 타입:
AssetTerms(address underlyingWrapper)
OptionTerms(address seller,uint256 underlyingAmount,uint64 strikeX8,uint64 expiry)
PhysicalCoveredCallRequest(bytes32 rfqId,AssetTerms asset,OptionTerms option)AssetTerms(address underlyingWrapper)OptionTerms(address seller,uint256 underlyingAmount,uint64 strikeX8,uint64 expiry)
PhysicalCoveredCallQuote(bytes32 requestHash,bytes32 quoteId,address marketMaker,uint256 premiumSettlement,uint64 quoteDeadline,uint64 nonce)
팩토리는 호가 서명자를 복원하기 전에 전체 중첩 요청으로부터 requestHash를 다시 계산합니다. 따라서 서명은 매도자, 기초자산 래퍼, 래퍼 지분 수량, 행사가, 만기, 프리미엄, 호가 유효기한, 논스, 체인 ID, 팩토리 주소를 모두 바인딩합니다. 결제 토큰과 소수점 자릿수는 별도로 서명되는 값이 아니라 팩토리 설정이 기준입니다. 이 오라클 없는 세대에는 Pyth가 사용되지 않습니다. 매도자가 볼트에 자금을 넣을 때 호가 다이제스트와 마켓메이커 논스가 모두 소비됩니다.
요청에 인코딩된 매도자만 서명된 호가를 제출할 수 있습니다. 자금 투입 시 작성자 청구권(writer-claim) NFT는 매도자에게, 롱 옵션 NFT는 호가를 낸 마켓메이커에게 발행됩니다. 단, 선택적 매수자 허용 목록이 활성화된 경우 해당 마켓메이커가 적격 수령자여야 합니다. 유효한 서명은 자금 투입을 승인할 뿐 행사를 승인하지는 않습니다.
현재 롱 옵션 NFT 소유자만 행사를 호출할 수 있습니다. 이 소유자 전용 규칙은 ERC-721 오퍼레이터가 소유자의 결제 토큰 허용량(allowance)을 소비하는 것을 막습니다. 승인된 오퍼레이터는 표준 ERC-721 규칙에 따라 NFT를 이전할 수 있으며, 매수자 게이트가 활성화된 동안에는 경제적 권리가 적격 수령자에게 이전됩니다. 행사가 성공하면 호출자 겸 소유자로부터 행사가 대금을 가져오고, 해당 소유자에게 기초자산을 인도한 뒤 롱 옵션 NFT를 소각합니다.
EIP-712 도메인 구분자
세 디렉티브 도메인은 같은 구조를 사용하며 name만 다릅니다. verifyingContract가 제로 주소이므로 같은 서명이 해당 체인의 모든 Account에서 유효하며, 메시지 내부의 Account 주소가 서명을 하나의 Account에 바인딩합니다.
{
"name": "<DomainName>",
"version": "1",
"chainId": <chainId>,
"verifyingContract": "0x0000000000000000000000000000000000000000"
}
도메인 타입은 EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)입니다.
체인 ID: 메인넷 999, 테스트넷 998. Account는 자신이 실행 중인 체인에 따라 구분자를 선택하므로 테스트넷 서명은 메인넷에서 절대 검증되지 않습니다.
| 도메인 | name | version | 서명자 | 체인 | 구분자 |
|---|---|---|---|---|---|
| API 지갑 | HypercallApiSign | 1 | API 지갑 | 999 | 0x462ae8a3a67da57ddd088e60be368536f992b8bf369d13e64e620c51993e5ebb |
| API 지갑 | HypercallApiSign | 1 | API 지갑 | 998 | 0x339bee4c00da9a5361f687797205c8d03f323659f5d9dc9e0505b9437ddee25e |
| Manager | HypercallManagerSign | 1 | Manager | 999 | 0xc9b5b0b8b0d9d7ba716326acbf795cfe431ef960a25a8f958d6569bea2f1516e |
| Manager | HypercallManagerSign | 1 | Manager | 998 | 0xd1f76b6138be892c14b71b0569bdb049cb44f239d34c78ef1ffaacd2466f9f18 |
| RSM | HypercallRsmSign | 1 | RSM 서명자 | 999 | 0x3d0cae2af623c614099dbadd67a1e1457fabde576aa270a70a57e39bf338a7be |
| RSM | HypercallRsmSign | 1 | RSM 서명자 | 998 | 0x650b282053fb61d3fd477bdc28f6434311fe905e27cc4ca643e87e802c45938c |
서명하기 전에 구분자를 직접 계산하여 비교하십시오.
import { ethers } from "ethers";
const separator = ethers.TypedDataEncoder.hashDomain({
name: "HypercallApiSign",
version: "1",
chainId: 999,
verifyingContract: ethers.ZeroAddress
});
// 0x462ae8a3a67da57ddd088e60be368536f992b8bf369d13e64e620c51993e5ebb
메시지 레퍼런스
서명자 및 엔드포인트 매트릭스
| 메시지 | 도메인 | 서명자 | 제출 대상 | 실행 내용 |
|---|---|---|---|---|
HLOrder | API | API 지갑 | POST /v1/tee-perp/orders/submit 또는 POST /v1/actions/hl_limit_order | Hyperliquid 지정가 주문 |
HLCancel | API | API 지갑 | POST /v1/tee-perp/cancels/submit-by-oid 또는 POST /v1/actions/hl_cancel_by_oid | oid로 취소 |
HLCancelByCloid | API | API 지갑 | POST /v1/tee-perp/cancels/submit 또는 POST /v1/actions/hl_cancel_by_cloid | cloid로 취소 |
HCPerpTriggerOrder | API | API 지갑 | POST /v1/tee-perp/orders/submit-trigger | 네이티브 트리거 주문 (TEE 전용) |
HCPerpOrderBatch | API | API 지갑 | POST /v1/tee-perp/orders/submit-batch | 네이티브 주문 배치 (TEE 전용) |
HCPerpLeverageChange | API | API 지갑 | POST /v1/tee-perp/leverage/submit | 레버리지 변경 (TEE 전용) |
HCPerpScheduleCancel | API | API 지갑 | POST /v1/tee-perp/schedule-cancel/submit | 데드맨 스위치 (TEE 전용) |
HCUpdateApiWallet | Manager | Manager | POST /v1/actions/hc_update_api_wallet | Account API 지갑 레지스트리 |
HLAddApiWallet | Manager | Manager | POST /v1/actions/hl_add_api_wallet | HyperCore API 지갑 승인 |
HLSendAsset | Manager | Manager | POST /v1/actions/hl_send_asset | Account에서의 HyperCore sendAsset |
HLSetAbstraction | Manager | Manager | POST /v1/actions/hl_set_abstraction | HyperCore 계정 모드 (통합 계정만) |
HCTransferOption | Manager | Manager | 허용되지 않음 | 예약됨, 온체인에서 거부 |
HLOrder, HLCancel, HLCancelByCloid, HLSendAsset | RSM | RSM 서명자 | 시퀀서 전용 | Account를 통한 복구 주문 및 스윕 |
System* | RSM | RSM 서명자 | 시퀀서 전용 | Exchange를 통한 입금 반영, 출금, 청산 |
모든 /v1/actions/{action} 경로는 account, nonce, action, signature를 받습니다. POST /v1/actions/{action}/typed-data는 해당 요청에 대해 서명할 정확한 타입 데이터를 반환하므로, 인코더를 확인하는 가장 쉬운 방법입니다. GET /v1/directives/{directive_id}는 온체인 결과를 보고합니다. 요청 스키마는 API 레퍼런스에 있습니다.
전송 규약
nonce와 모든uint64,uint128,uint256필드는9007199254740991이하의 JSON 정수 또는 10진수 문자열입니다. 그보다 큰 값은 문자열을 사용하십시오.signature는 65바이트0x16진수 문자열(r || s || v)입니다.v는0,1,27,28중 하나일 수 있습니다.bytes32필드는0x접두사가 붙은 32바이트 16진수입니다. 주소는 체크섬 형식 또는 소문자 16진수입니다.- 퍼프 가격과 수량은 HyperCore의
1e8정수입니다. 예를 들어$50,000은5000000000000,0.001코인은100000입니다.
API 지갑 디렉티브 (HypercallApiSign)
Account의 활성 API 지갑이 서명합니다. 체인 ID 999, name HypercallApiSign을 사용하십시오.
테스트 벡터는 플레이스홀더 계정과 고정 논스를 사용하므로 인코더를 바이트 단위로 확인할 수 있습니다. 다이제스트는 keccak256(0x1901 || domainSeparator || directiveStructHash)입니다.
HLOrder
Account의 Hyperliquid 지정가 주문 하나입니다.
구조체:
struct LimitOrder {
uint32 asset;
bool isBuy;
uint64 limitPx;
uint64 sz;
bool reduceOnly;
uint8 encodedTif;
uint128 cloid;
}
struct HLOrder {
address account;
uint64 nonce;
LimitOrder action;
}
정규 EIP-712 타입:
HLOrder(address account,uint64 nonce,LimitOrder action)LimitOrder(uint32 asset,bool isBuy,uint64 limitPx,uint64 sz,bool reduceOnly,uint8 encodedTif,uint128 cloid)
타입해시: 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd. 서명자: API 지갑. 작업: 버전 1, id 1.
asset: Hyperliquid 자산 인덱스입니다.GET /v1/tee-perp/markets에서 Hypercall이 허용하는 퍼프 시장과 그 인덱스를 확인할 수 있습니다.isBuy: 매수는true, 매도는false입니다.limitPx,sz: 가격과 수량에1e8을 곱한 값입니다.reduceOnly: 주문이 포지션을 줄이기만 할 수 있으면true입니다.encodedTif: ALO =1, GTC =2, IOC =3. 그 외의 값은 거부됩니다.cloid: 0이 아닌 클라이언트 주문 ID입니다. 이후 cloid로 취소할 때 사용합니다.
예시 (ethers.js):
const domain = {
name: "HypercallApiSign",
version: "1",
chainId: 999,
verifyingContract: ethers.ZeroAddress
};
const types = {
LimitOrder: [
{ name: "asset", type: "uint32" },
{ name: "isBuy", type: "bool" },
{ name: "limitPx", type: "uint64" },
{ name: "sz", type: "uint64" },
{ name: "reduceOnly", type: "bool" },
{ name: "encodedTif", type: "uint8" },
{ name: "cloid", type: "uint128" }
],
HLOrder: [
{ name: "account", type: "address" },
{ name: "nonce", type: "uint64" },
{ name: "action", type: "LimitOrder" }
]
};
const message = {
account: managedAccount,
nonce: selectedNonce,
action: {
asset: 0,
isBuy: true,
limitPx: 5000000000000n,
sz: 100000n,
reduceOnly: false,
encodedTif: 2,
cloid: selectedNonce
}
};
const signature = await apiWalletSigner.signTypedData(domain, types, message);
테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd |
| 작업 구조체 해시 | 0x0fd024c6bf8f132123e63a78d50008d8c39c52e5409ef6ca87a4eec8f6eabb41 |
| 디렉티브 구조체 해시 | 0xd32948ee1f249b96124a6acdb5845d09aad8228512098598de6858d5484fe703 |
| 서명할 다이제스트 | 0xc3c42699092fe20c7dbc4205a1027f55c28d33a682a64bd3f04e40f1d28693f5 |
테스트 벡터는 isBuy: true, limitPx: 5000000000000, sz: 100000, reduceOnly: false, encodedTif: 2, asset: 0을 사용하며 cloid는 논스와 같습니다.
제출: account, nonce, action, signature와 함께 POST /v1/tee-perp/orders/submit. Hypercall이 증거금 검사를 수행한 뒤, 보안 엔클레이브가 Hypercall 빌더 코드를 붙인 네이티브 Hyperliquid 주문에 서명하여 전송합니다. Account manager는 먼저 Account.approveZeroFeeBuilder로 해당 빌더를 승인해야 합니다. 온보딩을 참고하십시오. 전체 흐름은 무기한 계약을 참고하십시오.
{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 1760000000000,
"action": {
"asset": 0,
"isBuy": true,
"limitPx": "5000000000000",
"sz": "100000",
"reduceOnly": false,
"encodedTif": 2,
"cloid": "1760000000000"
},
"signature": "0x<65 byte signature>"
}
동일한 서명 메시지는 POST /v1/actions/hl_limit_order에서도 허용됩니다. 이 경로는 메시지를 온체인 디렉티브로 인코딩하며, Exchange.executeUserDirective와 Account.performCoreAction을 통해 실행됩니다.
HLCancel
Hyperliquid 주문 ID로 주문 하나를 취소합니다. 래퍼는 HLCancel이고 내부 구조체는 CancelOrderByOid입니다.
struct CancelOrderByOid {
uint32 asset;
uint64 oid; // Order ID assigned by HyperCore
}
struct HLCancel {
address account;
uint64 nonce;
CancelOrderByOid action;
}
HLCancel(address account,uint64 nonce,CancelOrderByOid action)CancelOrderByOid(uint32 asset,uint64 oid)
타입해시: 0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85. 서명자: API 지갑. 작업: 버전 1, id 10. 제출: POST /v1/tee-perp/cancels/submit-by-oid 또는 POST /v1/actions/hl_cancel_by_oid.
const types = {
CancelOrderByOid: [
{ name: "asset", type: "uint32" },
{ name: "oid", type: "uint64" }
],
HLCancel: [
{ name: "account", type: "address" },
{ name: "nonce", type: "uint64" },
{ name: "action", type: "CancelOrderByOid" }
]
};
const message = {
account: managedAccount,
nonce: selectedNonce,
action: { asset: 0, oid: 123456789n }
};
const signature = await apiWalletSigner.signTypedData(domain, types, message);
테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85 |
| 작업 구조체 해시 | 0xa34e7bb8af0d099f9c48095924e53067bcb9b542a816445b96abebbc5646b727 |
| 디렉티브 구조체 해시 | 0x69d560ba5ef3e88459bde7fb8252e55dbc33627373c8f0cfcf8ef0868f59e097 |
| 서명할 다이제스트 | 0x5046aba9fb33c55ce736faf63734ea66914f3f168ff0aff2229fa6f31fa9b330 |
테스트 벡터는 asset: 0과 oid: 123456789를 사용합니다.
HLCancelByCloid
HLOrder에 설정한 클라이언트 주문 ID로 주문 하나를 취소합니다.
struct CancelOrderByCloid {
uint32 asset;
uint128 cloid; // Client order ID
}
struct HLCancelByCloid {
address account;
uint64 nonce;
CancelOrderByCloid action;
}
HLCancelByCloid(address account,uint64 nonce,CancelOrderByCloid action)CancelOrderByCloid(uint32 asset,uint128 cloid)
타입해시: 0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5. 서명자: API 지갑. 작업: 버전 1, id 11. 제출: POST /v1/tee-perp/cancels/submit 또는 POST /v1/actions/hl_cancel_by_cloid.
const types = {
CancelOrderByCloid: [
{ name: "asset", type: "uint32" },
{ name: "cloid", type: "uint128" }
],
HLCancelByCloid: [
{ name: "account", type: "address" },
{ name: "nonce", type: "uint64" },
{ name: "action", type: "CancelOrderByCloid" }
]
};
const message = {
account: managedAccount,
nonce: selectedNonce,
action: { asset: 0, cloid: 1760000000000n }
};
const signature = await apiWalletSigner.signTypedData(domain, types, message);
테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5 |
| 작업 구조체 해시 | 0xfa4ab6440f946a6e279d90972d71223c768c01c8a91dc22703a6448dbcb966d0 |
| 디렉티브 구조체 해시 | 0x998efb01bb9c842eea80e8cc084b9e4e7ec13b2111790e1acbfec32e49060d9d |
| 서명할 다이제스트 | 0x56af82a6aa7fa50907a23c6cfe3aa556af5aa087b1157163ebf6ea0240e8d29d |
테스트 벡터는 asset: 0과 cloid: 1760000000000을 사용합니다.
TEE 전용 퍼프 메시지
이 네 가지 메시지는 Account 컨트랙트가 아니라 Hypercall API가 검증합니다. 엔클레이브가 Hyperliquid에서 네이티브로 실행하며 대응하는 온체인 디렉티브가 없기 때문입니다. HLOrder와 동일한 HypercallApiSign 도메인과 동일한 API 지갑 권한을 사용합니다(서명자는 Account의 활성 API 지갑이어야 하고, Account는 포트폴리오 증거금 모드여야 합니다). 이들의 타입해시는 컨트랙트에 포함되어 있지 않습니다. 논스는 밀리초 단위 Unix 시간입니다.
PerpOrderTerms
HCPerpTriggerOrder와 HCPerpOrderBatch는 모두 이 구조체를 포함합니다. 지정가 하위 주문은 triggerPx = 0, isMarket = false, tpsl = 0과 함께 TIF 바이트에 서명합니다. 트리거 하위 주문은 encodedTif = 0, 양수 triggerPx, 그리고 tpsl 값 1(이익실현) 또는 2(손절)에 서명합니다.
struct PerpOrderTerms {
uint32 asset;
bool isBuy;
uint64 limitPx;
uint64 sz;
bool reduceOnly;
uint8 encodedTif;
uint64 triggerPx;
bool isMarket;
uint8 tpsl;
uint128 cloid;
}
HCPerpTriggerOrder
손절 또는 이익실현 주문 하나로, POST /v1/tee-perp/orders/submit-trigger에 제출합니다. 요청의 action.orderType은 트리거여야 합니다.
struct HCPerpTriggerOrder {
address account;
uint64 nonce;
PerpOrderTerms order;
}
HCPerpTriggerOrder(address account,uint64 nonce,PerpOrderTerms action)PerpOrderTerms(uint32 asset,bool isBuy,uint64 limitPx,uint64 sz,bool reduceOnly,uint8 encodedTif,uint64 triggerPx,bool isMarket,uint8 tpsl,uint128 cloid)
타입해시: 0x2d3104ab255275839aad254429e4be789f64a8d16b8e3e7d5f30a0db3c887b5c
테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0x2d3104ab255275839aad254429e4be789f64a8d16b8e3e7d5f30a0db3c887b5c |
| 작업 구조체 해시 | 0x285b3186be219b92d7159419288c0dce9bc4ad7bfc9536e009ebf24bd67f434c |
| 디렉티브 구조체 해시 | 0xaa03e40b34b15e7e932ae827921930e7538387b596ef1040dbcc791e69021299 |
| 서명할 다이제스트 | 0xc46aadc390b66c235af15e199e188ab23fb7f7f1b9237f6c2849c264c28d94da |
테스트 벡터는 감소 전용 시장가 손절 매도입니다. asset: 0, isBuy: false, limitPx: 4800000000000(최악 가격), sz: 100000, reduceOnly: true, encodedTif: 0, triggerPx: 4900000000000, isMarket: true, tpsl: 2, cloid: 1760000000001.
HCPerpOrderBatch
하나의 그룹 아래 최대 100개의 주문으로, POST /v1/tee-perp/orders/submit-batch에 제출합니다. 모든 주문은 서로 다른 cloid를 사용해야 합니다. grouping은 0(그룹 없음), 1(normalTpsl), 2(positionTpsl) 중 하나입니다. 배치는 속도 제한 상 주문 1건으로 계산됩니다.
struct HCPerpOrderBatch {
address account;
uint64 nonce;
uint8 grouping;
PerpOrderTerms[] orders;
}
HCPerpOrderBatch(address account,uint64 nonce,uint8 grouping,PerpOrderTerms[] orders)PerpOrderTerms(uint32 asset,bool isBuy,uint64 limitPx,uint64 sz,bool reduceOnly,uint8 encodedTif,uint64 triggerPx,bool isMarket,uint8 tpsl,uint128 cloid)
타입해시: 0x9d4f467a44f4b0d39f234f3b91888546ce31dcbb67ce791550901b9042c38f8b. orders 배열은 제출 순서대로 연결한 PerpOrderTerms 구조체 해시들의 keccak256으로 인코딩됩니다.
테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0x9d4f467a44f4b0d39f234f3b91888546ce31dcbb67ce791550901b9042c38f8b |
| 주문 배열 해시 | 0x13fc75fcc69bf3b4ef7cdc3a0872c3cc1cf59440c74d366055109b6bd5ea7c98 |
| 디렉티브 구조체 해시 | 0x69d0b1131e386769823fe1ab3facbe8e6fc013f86a117cf95cb52b8ce2f274e0 |
| 서명할 다이제스트 | 0x4b5cd34b1f254fdd9881b7674a3412807e16cade1f2ccc7a1e261482682fbd07 |
테스트 벡터는 grouping: 1이며 두 개의 주문으로 구성됩니다. GTC 지정가 매수(limitPx: 5000000000000, sz: 100000, cloid: 1760000000000) 다음에 트리거 예시의 손절 주문이 이어집니다.
HCPerpLeverageChange
자산 하나의 레버리지를 설정하며, POST /v1/tee-perp/leverage/submit에 제출합니다. leverage는 0보다 커야 합니다.
struct PerpLeverageChange {
uint32 asset;
bool isCross;
uint32 leverage;
}
struct HCPerpLeverageChange {
address account;
uint64 nonce;
PerpLeverageChange action;
}
HCPerpLeverageChange(address account,uint64 nonce,PerpLeverageChange action)PerpLeverageChange(uint32 asset,bool isCross,uint32 leverage)
타입해시: 0xe13845f0e6c16a5e1fc56b2d11fb0972faa2ec30b01e94d58c72147fa9b6a463
테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0xe13845f0e6c16a5e1fc56b2d11fb0972faa2ec30b01e94d58c72147fa9b6a463 |
| 작업 구조체 해시 | 0x0e6e271dd56192d7fb1f37ea2eaffecfbbe2d1f79cac78dce6a6930bb8cc253e |
| 디렉티브 구조체 해시 | 0xe04b169bbb0e20042308e5aad1036ce60eda75f484a4d6093dc60f2c2231129e |
| 서명할 다이제스트 | 0xb2a43487152a7cecc73d2b6b84d817a58dd02c559b05289a8d8e1b5c3d25e266 |
테스트 벡터는 asset: 0에 교차 레버리지 5배를 설정합니다.
HCPerpScheduleCancel
Hyperliquid의 데드맨 스위치로, time(Unix 밀리초, 최소 7초 이후)에 모든 미체결 주문을 취소합니다. POST /v1/tee-perp/schedule-cancel/submit에 제출합니다. 예약된 취소를 해제하려면 요청에서 time을 생략하고 time = 0에 서명하십시오. 명시적으로 0을 보내면 거부됩니다.
struct PerpScheduleCancel {
uint64 time;
}
struct HCPerpScheduleCancel {
address account;
uint64 nonce;
PerpScheduleCancel action;
}
HCPerpScheduleCancel(address account,uint64 nonce,PerpScheduleCancel action)PerpScheduleCancel(uint64 time)
타입해시: 0xf21b6881e346bbf4b8d82e8ea507cf487e58dfc08776ad662591be7d6065bdfb
테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0xf21b6881e346bbf4b8d82e8ea507cf487e58dfc08776ad662591be7d6065bdfb |
| 작업 구조체 해시 | 0x0a3ebfe48ef28a79beeee4d56e524f8a5280c38562efb697e7b1d63b3d475afc |
| 디렉티브 구조체 해시 | 0xae64a13943a6a35b33aeb3095763b855c58c2119daf71e1e3228d8acf2645e8b |
| 서명할 다이제스트 | 0xa01806f47299010b5963a516562be3c3b44fed4f4a9e2e56c4bb601630146cdc |
테스트 벡터는 time: 1760000060000에 취소를 예약합니다.
Manager 서명 사전 준비 취소
POST /v1/tee-perp/cancels/submit-prepared는 manager가 서명하는 취소 경로입니다. 타입 데이터 구조체를 사용하지 않습니다. Manager는 사전 준비된 네이티브 Hyperliquid 취소의 다이제스트에 서명합니다. 이는 preparedRequest(base64)로 전달되며, 정규 low-s 형식의 managerSignature와 manager 지갑을 인증하는 타임스탬프 포함 authenticationSignature가 함께 제공됩니다. 요청 스키마는 API 레퍼런스를 참고하십시오.
Manager 디렉티브 (HypercallManagerSign)
Account manager가 서명합니다. 체인 ID 999, name HypercallManagerSign을 사용하십시오. Account는 signer == manager를 요구합니다. POST /v1/actions/{action}으로 제출합니다.
HCUpdateApiWallet
Account에서 name 아래 저장된 API 지갑을 추가, 교체 또는 제거(addr = 0x0)합니다.
struct UpdateApiWallet {
bytes32 name; // Wallet label, ASCII left-aligned and zero padded
address addr; // API wallet address, zero to remove
}
struct HCUpdateApiWallet {
address account;
uint64 nonce;
UpdateApiWallet action;
}
HCUpdateApiWallet(address account,uint64 nonce,UpdateApiWallet action)UpdateApiWallet(bytes32 name,address addr)
타입해시: 0x8ebe7d19374200e5dc3ae838db74b370da95bd2b3a8aec9de85d2398dd4a9257. 작업: 버전 0, id 2. 제출: action을 { "name": "0x...", "addr": "0x..." }로 하여 POST /v1/actions/hc_update_api_wallet.
const domain = {
name: "HypercallManagerSign",
version: "1",
chainId: 999,
verifyingContract: ethers.ZeroAddress
};
const types = {
UpdateApiWallet: [
{ name: "name", type: "bytes32" },
{ name: "addr", type: "address" }
],
HCUpdateApiWallet: [
{ name: "account", type: "address" },
{ name: "nonce", type: "uint64" },
{ name: "action", type: "UpdateApiWallet" }
]
};
const message = {
account: accountAddress,
nonce: selectedNonce,
action: {
name: ethers.encodeBytes32String("trading-bot"),
addr: apiWalletAddress
}
};
const signature = await managerSigner.signTypedData(domain, types, message);
테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0x8ebe7d19374200e5dc3ae838db74b370da95bd2b3a8aec9de85d2398dd4a9257 |
| 작업 구조체 해시 | 0x8b6c4a9db102e9d27c9a4069b39ba35e04948129359f0c15cd5103dd101ffce7 |
| 디렉티브 구조체 해시 | 0x830e291835ad182f290bc3d2bff09eaf9fd33acfbe44c6ad583218cd1a8232e5 |
| 서명할 다이제스트 | 0x06589077544af449314db1fa8c7aac2d277cce9e833a04992d88161ede24cbe8 |
테스트 벡터는 name trading-bot(0x74726164696e672d626f74 뒤를 0으로 채움)과 addr 0x2222222222222222222222222222222222222222를 사용합니다. 전체 API 지갑 흐름은 온보딩을 참고하십시오. Account는 ApiWalletUpdated(name, addr)를 발생시킵니다.
HLAddApiWallet
HyperCore에서 Account에 대한 Hyperliquid API 지갑을 승인합니다.
struct AddApiWallet {
address apiWalletAddress;
string apiWalletName; // An empty name replaces the main API wallet
}
struct HLAddApiWallet {
address account;
uint64 nonce;
AddApiWallet action;
}
HLAddApiWallet(address account,uint64 nonce,AddApiWallet action)AddApiWallet(address apiWalletAddress,string apiWalletName)
타입해시: 0x71c0e0dfbddc3456015249946354324befde42b6851d1c9b26c6a29f2e0b1ac2. 작업: 버전 1, id 9. 제출: POST /v1/actions/hl_add_api_wallet.
apiWalletName은 string이므로 구조체 필드 값은 keccak256(bytes(apiWalletName))입니다. Ethers와 viem은 이를 자동으로 처리합니다.
테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0x71c0e0dfbddc3456015249946354324befde42b6851d1c9b26c6a29f2e0b1ac2 |
| 작업 구조체 해시 | 0xed32a441b0ee59c0252f5dff3411766289c9c35c19e3152b0b2b204176c2c7cd |
| 디렉티브 구조체 해시 | 0xb990a3dfb4e8d96243539f8758b3a55249b217542bb4112f4f88ed67ec516ed9 |
| 서명할 다이제스트 | 0x584886d020316085de0e0dec16331b8e990558be3e8fd004c47200abbebed518 |
테스트 벡터는 apiWalletAddress 0x2222222222222222222222222222222222222222와 apiWalletName hl-bot을 사용합니다.
HLSendAsset
HyperCore의 Account에서 대상 주소로 자산을 전송합니다.
struct SendAsset {
address destination; // Recipient
address subAccount; // Recipient sub-account, zero for main
uint32 srcDex; // Source dex: 0 = perps, 4294967295 = spot
uint32 dstDex; // Destination dex: 0 = perps, 4294967295 = spot
uint64 token; // HyperCore token index (0 = USDC)
uint64 amountWei; // Amount in HyperCore wei (USDC: 1e8 per dollar)
}
struct HLSendAsset {
address account;
uint64 nonce;
SendAsset action;
}
HLSendAsset(address account,uint64 nonce,SendAsset action)SendAsset(address destination,address subAccount,uint32 srcDex,uint32 dstDex,uint64 token,uint64 amountWei)
타입해시: 0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595. 작업: 버전 1, id 13. 제출: POST /v1/actions/hl_send_asset.
const types = {
SendAsset: [
{ name: "destination", type: "address" },
{ name: "subAccount", type: "address" },
{ name: "srcDex", type: "uint32" },
{ name: "dstDex", type: "uint32" },
{ name: "token", type: "uint64" },
{ name: "amountWei", type: "uint64" }
],
HLSendAsset: [
{ name: "account", type: "address" },
{ name: "nonce", type: "uint64" },
{ name: "action", type: "SendAsset" }
]
};
const message = {
account: accountAddress,
nonce: selectedNonce,
action: {
destination: recipientAddress,
subAccount: ethers.ZeroAddress,
srcDex: 0,
dstDex: 0xFFFFFFFF, // spot
token: 0, // USDC
amountWei: 500000000n // 5 USDC
}
};
const signature = await managerSigner.signTypedData(domain, types, message);
테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595 |
| 작업 구조체 해시 | 0x9b8c0290da19ea1069e14833023c4621a4f043354b36b4f17d4803b1fce6e656 |
| 디렉티브 구조체 해시 | 0xa0cb8a72188a61289fc2685c29a424605e0a2ee7b7af3e8cfee10e1c75153e08 |
| 서명할 다이제스트 | 0x7c7037f27c659a1885f744778480e6847c5d08e98fb22517265ba708b6597d10 |
테스트 벡터는 destination을 프로덕션 Exchange 0xE6b7FaA216cabb2b38B392f577C9c826378b2240로 하여 퍼프(srcDex: 0)에서 현물(dstDex: 4294967295)로 5 USDC(amountWei: 500000000)를 전송합니다.
HLSetAbstraction
Account의 HyperCore 계정 모드를 설정합니다. Account는 user가 자기 자신이고 abstraction = 2(통합 계정)인 경우만 허용하며, 그 외에는 되돌립니다(revert). 포트폴리오 증거금에는 이 설정이 필요합니다.
struct SetAbstraction {
address user; // Must equal the Account
uint8 abstraction; // Must be 2 (unified account)
}
struct HLSetAbstraction {
address account;
uint64 nonce;
SetAbstraction action;
}
HLSetAbstraction(address account,uint64 nonce,SetAbstraction action)SetAbstraction(address user,uint8 abstraction)
타입해시: 0xcf5fddf081e5f2a9a45aa87cb1a3c42e5aa20164566b1ad2369b6b1318eac786. 작업: 버전 1, id 16. 제출: POST /v1/actions/hl_set_abstraction.
테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0xcf5fddf081e5f2a9a45aa87cb1a3c42e5aa20164566b1ad2369b6b1318eac786 |
| 작업 구조체 해시 | 0xef6c70a3c14b9e77c710c6b3b3ee681ca270ef884bd8a64fa4064a96f3dda84e |
| 디렉티브 구조체 해시 | 0xdda9d0fe82b63c728c4ac42585d5998a04cabaed0f957a2cafdf31a754829c3d |
| 서명할 다이제스트 | 0xf49d7d8d74596e503d6a1bdfb26653533a12a5ba3816acd992d0bd4ef378f59d |
테스트 벡터는 user를 Account로, abstraction을 2로 설정합니다.
HCTransferOption (예약됨)
컨트랙트에는 HCTransferOption(address account,uint64 nonce,TransferOption action)TransferOption(address recipient,address option,uint256 amountWei)(타입해시 0xa218e1158788b23987f954edc7a07659a03a03fe5ba981a5bbe44d7a146e0819, 작업 버전 0, id 1)이 정의되어 있지만 할당된 서명자 유형이 없습니다. Account는 Account__UserDirectiveNotSupported로 되돌리며, API는 hc_transfer_option을 거부합니다. 이 메시지에 서명하지 마십시오. 옵션 토큰은 depositOption과 출금을 통해 이동하십시오.
서명 없는 Manager 트랜잭션
일부 manager 작업은 EIP-712 메시지가 아니라 Account를 직접 호출합니다. Account.approveZeroFeeBuilder(builder)는 최대 수수료 0%로 Hyperliquid 빌더를 승인하며, 첫 퍼프 주문 전에 한 번 반드시 실행해야 합니다(온보딩 참고). Account.transferTo(recipient, token, amount)는 HyperEVM에서 Account 밖으로 토큰을 이동합니다. 두 작업 모두 msg.sender == manager를 요구하며, Account가 청산 중일 때는 되돌려집니다.
RSM 디렉티브 (HypercallRsmSign)
RSM 서명자가 서명하고 시퀀서가 제출합니다. 입금 반영, 출금 처리, 청산 시작 및 중지, 감소 전용 IOC 복구 주문 제출을 수행합니다. 마켓메이커와 사용자는 이에 서명하거나 제출하지 않습니다. 프로토콜이 Account에 대해 수행할 수 있는 작업을 검증할 수 있도록 문서화되어 있습니다. 체인 ID 999, name HypercallRsmSign을 사용하십시오. Exchange는 signer == rsmSigner(현재 메인넷에서는 0x502E7fAbF34E84EeB115C34FE947b79A94dF886E)를 확인하며, 호출자는 SEQUENCER_ROLE을 보유해야 합니다.
RSM 주문 및 스윕 (Account가 실행)
이 메시지들은 RSM 도메인 아래에서 HL 구조체를 재사용하므로, 타입해시는 API 및 manager의 것과 같고 도메인 구분자만 다릅니다. Account는 추가 제약 조건을 적용하며, 청산 중에도 이를 실행합니다.
| 메시지 | 타입해시 | Account가 적용하는 제약 조건 |
|---|---|---|
HLOrder | 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd | encodedTif는 IOC(3)여야 하며, 주문은 reduceOnly이거나 HyperCore 현물 가격 대비 5% 이하로 낮게 제한된 USDC 대상 현물 매도(현물 자산 id 10000~99999)여야 합니다 |
HLCancel | 0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85 | 없음 |
HLCancelByCloid | 0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5 | 없음 |
HLSendAsset | 0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595 | destination은 Exchange여야 합니다 |
RSM HLOrder 테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd |
| 작업 구조체 해시 | 0x39b4e0699f382aaad23f04740034e7c5581ba918139d2db63fbf586cc447e7db |
| 디렉티브 구조체 해시 | 0xe6dde5ad6d310b5ebb83c09ec28ee5568700473b885bb483b7437dca202af4f3 |
| 서명할 다이제스트 | 0x57afa1e810804e768c05a467aa88ede15fdceedae5aaa840adff61a613aca469 |
RSM HLOrder 벡터는 감소 전용 IOC 매도입니다(isBuy: false, limitPx: 4800000000000, sz: 100000, reduceOnly: true, encodedTif: 3, cloid는 논스와 동일). Exchange.executeRsmDirective가 서명을 검증하고 작업을 Account로 전달합니다.
시스템 작업 (Exchange가 실행)
버전 255. 각 래퍼는 System<Action>(address account,uint64 nonce,<Action> action)<Action>(...) 형식입니다.
| 래퍼 | 내부 타입 | 타입해시 |
|---|---|---|
SystemCreditToken | CreditToken(uint32 srcDex,uint32 dstDex,uint64 token,uint64 amountWei) | 0xe845f2049264182802994dae939dc8ac42d3ae543a7eeb530dd021428743f052 |
SystemCreditOption | CreditOption(bytes32 underlying,uint256 expiry,uint256 strike,bool isCall,uint256 amountWei) | 0x65aedd5af06882e1e62d752b43b72ec62a85cacf2ca59e8ec2affc57eed9d8ae |
SystemStartLiquidation | StartLiquidation(int256 equity,uint256 marginNeeded) | 0x92b6a135a656e489c24fb5511684842b0ab3895c22b51e4910dee90a7d23511e |
SystemStopLiquidation | StopLiquidation(uint256 startTime) | 0xe1af98778e9cfd1d1a679bb0b64b6dc8aa3fb152ff6469d0a81a1c7eb87a4bd3 |
SystemWithdrawToken | WithdrawToken(address destination,address subAccount,uint32 srcDex,uint32 dstDex,uint64 token,uint64 amountWei) | 0x634b866e9a922bb846e297973c7a456e641b88f4e97493da9b222084d799c883 |
전체 외부 타입 문자열:
SystemCreditToken(address account,uint64 nonce,CreditToken action)CreditToken(uint32 srcDex,uint32 dstDex,uint64 token,uint64 amountWei)
SystemCreditOption(address account,uint64 nonce,CreditOption action)CreditOption(bytes32 underlying,uint256 expiry,uint256 strike,bool isCall,uint256 amountWei)
SystemStartLiquidation(address account,uint64 nonce,StartLiquidation action)StartLiquidation(int256 equity,uint256 marginNeeded)
SystemStopLiquidation(address account,uint64 nonce,StopLiquidation action)StopLiquidation(uint256 startTime)
SystemWithdrawToken(address account,uint64 nonce,WithdrawToken action)WithdrawToken(address destination,address subAccount,uint32 srcDex,uint32 dstDex,uint64 token,uint64 amountWei)
- SystemCreditToken은 HyperCore의 현물 또는 퍼프 토큰을 Account에 반영합니다.
amountWei는 0이 아니어야 하며, Account는 HyperCore에서 활성화되어 있어야 합니다. - SystemCreditOption은 Account에 옵션 토큰을 발행하며, 필요한 경우 옵션 페어를 배포합니다.
underlying은 OpenZeppelinShortString워드로, ASCII를 왼쪽 정렬하고 마지막 바이트에 바이트 길이를 둡니다(BTC는0x42544300...03). 정규 형식이 아닌 인코딩은 되돌려집니다. - SystemStartLiquidation은 경매 파라미터를 기록하고 Account를 잠급니다.
marginNeeded는 0이 아니어야 합니다. - SystemStopLiquidation은
startTime이 기록된 시작 시각과 같아야 하며, Account를 manager에게 반환합니다. - SystemWithdrawToken은 Exchange 자체 잔고에서 HyperCore로의 Standard USDC 인도를 대기열에 넣습니다.
subAccount = 0,srcDex = 0,dstDex는0또는4294967295,token = 0(USDC), 그리고 EVM 단위의 정수배인amountWei가 필요합니다. HyperEVM 영수증만으로는 HyperCore에서의 인도를 증명할 수 없습니다.
SystemCreditToken 테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0xe845f2049264182802994dae939dc8ac42d3ae543a7eeb530dd021428743f052 |
| 작업 구조체 해시 | 0xc69d7c6e5c36c9789d990c6316eaff3be43980583806f41f8a8e6461b7114011 |
| 디렉티브 구조체 해시 | 0x7ffa37cef7e08d3a2dd5501a8648899d37bc09ebb25d148c124e12c5047476e1 |
| 서명할 다이제스트 | 0x95f75e5ddb4837de3f578b8aa0d714d4b02672b18c4929e3d2dda4a266de8254 |
이 벡터는 5 USDC를 반영합니다(srcDex와 dstDex는 4294967295, token: 0, amountWei: 500000000).
SystemCreditOption 테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0x65aedd5af06882e1e62d752b43b72ec62a85cacf2ca59e8ec2affc57eed9d8ae |
| 작업 구조체 해시 | 0x4a8b563fc94d26c1da376145d5aa5d05f996232fcf9739ed0a662650e91861b6 |
| 디렉티브 구조체 해시 | 0x190b638f1a462469bf0d070248acfc86bbbb95ea8a9d3d97d33581c7d6bb5554 |
| 서명할 다이제스트 | 0x86fb7c53bb7e139a4d5df7db2feae40e634efe09ea7509165d3cece75d75fce2 |
이 벡터는 BTC 콜옵션 1계약을 반영합니다(underlying: 0x42544300...03, expiry: 1761811200, strike: 80000, isCall: true, amountWei: 1000000000000000000).
SystemStartLiquidation 테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0x92b6a135a656e489c24fb5511684842b0ab3895c22b51e4910dee90a7d23511e |
| 작업 구조체 해시 | 0x4cd6a7f0997eba84ef82eabd429a0d9ca80e55bd6d89d2e67eda9970d87ec803 |
| 디렉티브 구조체 해시 | 0x84f18dc2577978d7890c9eb269fd787d99de37039b3a08e24745398feffbd0c5 |
| 서명할 다이제스트 | 0xcc72c0e7829938c9ca0a4515d759f94cc96d2f24cd51a134a430f215ed5f5d4b |
이 벡터는 equity: -1500000000과 marginNeeded: 20000000000을 사용합니다(둘 다 소수점 6자리 USDC).
SystemStopLiquidation 테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0xe1af98778e9cfd1d1a679bb0b64b6dc8aa3fb152ff6469d0a81a1c7eb87a4bd3 |
| 작업 구조체 해시 | 0x1d900a795b328bd5fa734bd6d7f74634b98ca66eb5e45322fb1ba6400564b62b |
| 디렉티브 구조체 해시 | 0x977b9becdd26830f2cdf70ab40f72f24490fe6ed45822d1fc8c84120e9a46f40 |
| 서명할 다이제스트 | 0xbe65f82782b14dba42e334e32dd7dcc6bf14c96824523723a186a7381f8f12af |
이 벡터는 startTime: 1760000000을 사용합니다.
SystemWithdrawToken 테스트 벡터 (계정 0x1111111111111111111111111111111111111111, 논스 1760000000000, 체인 999):
| 단계 | 값 |
|---|---|
| 타입해시 | 0x634b866e9a922bb846e297973c7a456e641b88f4e97493da9b222084d799c883 |
| 작업 구조체 해시 | 0x10bd8d4372a09e613a6b4fb7018fcccde857ebf6cc3327d6c9a3c0f81515a076 |
| 디렉티브 구조체 해시 | 0x86680427965513c65a7a170730b9f4fb2e2b40e22cd18338cb004b6a7872ada2 |
| 서명할 다이제스트 | 0x65cc392038decb9ccdc23b0a4a1cfbe657d3417f8cd9ebf2319b3172fb7d885c |
이 벡터는 srcDex: 0, dstDex: 0, token: 0으로 destination 0x1111111111111111111111111111111111111111에 5 USDC(amountWei: 500000000)를 출금합니다.
논스
각 서명자는 독립적인 논스 공간을 가지며, 세 곳에서 추적됩니다.
- Account 컨트랙트: 서명자별 비트맵입니다.
Account.isNonceUsed(signer, nonce)는 논스가 소비되었는지 여부를 반환합니다. 사용자 디렉티브가 논스를 재사용하면Account__NonceAlreadyUsed로 되돌려집니다.nextNonce는 없으며, 온체인에서는 간격이 허용되고 순서도 상관없습니다. - Exchange 컨트랙트: RSM 서명자용 비트맵으로,
Exchange.isNonceUsed(signer, nonce)로 조회합니다. - 엔진: 서명자별로 가장 큰 논스 100개를 보관합니다. 새 논스는 이 집합에 없어야 하고, 집합이 가득 찬 경우 저장된 가장 작은 논스보다 커야 하며, 밀리초 단위 서버 시간 기준 2일 전부터 1일 후 사이의 범위 안에 엄격히 있어야 합니다.
현재 Unix 밀리초 시간을 논스 시드로 사용하고 서명자별로 증가시키십시오. 같은 지갑이 같은 밀리초에 서명한 두 요청은 서로 다른 논스가 필요하므로 카운터를 유지하십시오. TEE 퍼프 경로에서는 논스가 요청의 시간 기준점이기도 하므로, 작은 정수가 아닌 실제 밀리초 타임스탬프를 사용하십시오.
function isNonceUsed(address signer, uint256 nonce) external view returns (bool);
서명 검증 흐름
- 오프체인: 서명자가 EIP-712 다이제스트(
0x1901 || domainSeparator || structHash)를 구성하고 서명합니다. - API: Hypercall이 서명자를 복원하고 활성 API 지갑 또는 manager인지 확인한 뒤, 주문의 경우 엔진 증거금 검사를 수행하고 디렉티브를 대기열에 넣습니다. 응답에는 실제 처리 단계, 거부 상세 정보, 트랜잭션 해시가 포함됩니다.
- 시퀀서:
Exchange.executeUserDirective(directive, signature)를 제출합니다. Exchange는 Account가 존재하는지 확인하고Account.executeUserDirective로 전달합니다. - Account: 자신의 주소, 논스, 작업으로부터 다이제스트를 다시 구성하고, 해당 작업에 맞는 API 또는 manager 구분자로 서명자를 복원한 뒤, 권한을 확인하고 논스를 소비한 다음 실행합니다. HL 작업은 HyperCore CoreWriter로 전달됩니다. HC 작업은 API 지갑 레지스트리를 업데이트합니다.
- 클라이언트: 최종 상태를 확인하기 위해
GET /v1/directives/{directive_id}를 폴링합니다.
TEE 퍼프 경로는 API 단계 이후에서 끝납니다. Account가 아니라 엔클레이브가 Hyperliquid에서 주문을 실행합니다.
Example (HLOrder):
1. API wallet signs HLOrder with the managed account, a unique nonce, and one LimitOrder action
2. Client posts account, nonce, action, and signature to /v1/tee-perp/orders/submit
3. Hypercall recovers the API wallet and applies portfolio-margin admission
4. The enclave signs and sends the native Hyperliquid order with the Hypercall builder code
5. Client reads the stage from the response and polls for subsequent status
지원 중단 및 제거된 항목
다음 항목은 이 페이지의 이전 버전에 있었으나 더 이상 배포된 시스템의 일부가 아닙니다. 이를 기반으로 구축된 통합을 마이그레이션할 수 있도록 나열합니다.
- Processor 및 ActionCaster 인코딩.
Processor컨트랙트와 ActionCaster 메시지 인코딩은 Exchange0.2.0(2026년 2월)에서 제거되었습니다. Account 디렉티브는 이제Exchange.executeUserDirective와 CoreWriter를 거칩니다. 배포된 Exchange0.6.1에는 이전 진입점이 전혀 없습니다. - 자체 구조체를 가진 Exchange 진입점.
hlRequestOrder,hlRequestCancel,hlRequestCancelByCloid,hlActionSendAsset,hcActionWithdrawToken,hcActionWithdrawOption,rsmCommandRebalance,rsmCommandRepay는 제거되었습니다. 대체 항목은 다음과 같습니다.
| 제거된 메시지 | 대체 항목 |
|---|---|
HLRequestCancel (HLCancel{asset,oid} 배치와 논스) | 디렉티브당 CancelOrderByOid 하나를 가진 HLCancel |
HLRequestCancelByCloid | 디렉티브당 CancelOrderByCloid 하나를 가진 HLCancelByCloid |
HLActionSendAsset (account, nonce, destination, srcDex, dstDex, token, amountWei) | subAccount가 추가된 SendAsset을 사용하는 HLSendAsset |
HCActionWithdrawToken | 엔진이 출금을 승인한 후 시퀀서가 실행하는 RSM 서명 SystemWithdrawToken |
HCActionWithdrawOption | 옵션 입금 반영은 RSM SystemCreditOption, 입금은 depositOption 사용 |
RsmCommandRebalance | RSM 서명 HLOrder (감소 전용 IOC) |
RsmCommandRepay | Exchange로 보내는 RSM 서명 HLSendAsset |
- 레거시 주문 함수.
placeCoreOrders,cancelCoreOrders,cancelCoreOrdersByCloid는 MsgPack 인코딩과CoreSignatures도메인("Exchange", 체인 ID1337)을 사용했습니다. 이들은 제거되었습니다. nextNonce. 온체인nextNonce[signer]카운터는 더 이상 존재하지 않습니다. 사용된 논스 비트맵(isNonceUsed)만 남아 있습니다.- TBD로 표시된 메인넷 구분자. 이전 문서에서는 manager 및 RSM 메인넷 구분자를 TBD로 표기했습니다. 세 가지 모두 확정되었으며 위에 나열되어 있습니다.
HCTransferOption. 정의되어 있지만 활성화된 적이 없습니다. 위 내용을 참고하십시오.
보안 고려사항
- 키: manager 키는 하드웨어 지갑에 보관하십시오. API 지갑은 주문과 취소에만 서명하므로 시스템별로 별도의 키를 사용하십시오.
- 논스 재사용: 논스를 절대 재사용하지 마십시오. 오프체인에서 논스를 추적하고 원자적으로 증가시키십시오.
- 도메인: 메인넷에서는 항상 체인 ID
999(테스트넷은998)로 서명하고, 계산한 구분자를 위 표와 대조하십시오. - 서명 내용 확인: 하드웨어 지갑으로 서명하기 전에
POST /v1/actions/{action}/typed-data를 호출하여 자체 인코더 결과와 비교하십시오. - 온체인 검증이 최종입니다: API가 서명을 사전 검사하지만, Account는 모든 디렉티브를 온체인에서 다시 검증합니다. API 응답을 실행 완료로 간주하지 마십시오.
- Manager와 API 지갑의 구분: manager는 소유권, API 지갑, 자산 이동을 제어합니다. API 지갑은 거래 메시지에만 서명합니다. 별도의 키를 사용하십시오.