EIP-712 署名
このページは、Hypercall が検証するすべての EIP-712 メッセージのフィールド単位のリファレンスです。対象は、3 つのディレクティブ署名ドメイン(API ウォレット、Manager、RSM)、API ウォレットのドメインを共有するオフチェーン専用のパーペチュアル・メッセージ、そしてスタンドアロンの Physical Covered Call Quote ドメインです。REST API のオプション注文は別のドメイン Hypercall を使用します。詳しくは 認証と署名 を参照してください。
ここに記載された内容はすべて、HyperEVM メインネット(チェーン ID 999)にデプロイされたコントラクトと照合済みです。対象は 0xE6b7FaA216cabb2b38B392f577C9c826378b2240 の Exchange 0.6.1 と Account 0.2.4 です。以下のドメインセパレーターと typehash は、デプロイ済みのバイトコードに埋め込まれています。
概要
ディレクティブとは、1 つの Account に対する 1 つのアクションです。オフチェーンで署名され、Hypercall のシーケンサーが Exchange.executeUserDirective または Exchange.executeRsmDirective を通じてオンチェーンに送信します。Account は EIP-712 ダイジェストから署名者を復元し、権限を確認します。
- API ウォレット:
hc_update_api_walletで Account に登録されたアドレス(Account.isApiWalletActive)。注文とキャンセルに署名します。 - Manager: Account の所有者(
Account.manager)。API ウォレットの変更、資産の送付、アカウントモードの変更に署名します。 - RSM 署名者: プロトコルが管理する署名者(
Exchange.rsmSigner)。入金反映、出金、清算ディレクティブ、リデュースオンリーのリカバリー注文に署名します。ユーザーがこれらに署名することはありません。
ディレクティブのエンコーディング
オンチェーンでは、ディレクティブは abi.encodePacked(account, nonce, version, id, data) です。
| バイト数 | フィールド | 意味 |
|---|---|---|
| 20 | account | Account のアドレス(address) |
| 8 | nonce | 署名者の 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 のアドレス、署名者の nonce、そして 1 つの内部アクション構造体です。
<Outer>(address account,uint64 nonce,<Inner> action)<Inner>(...)
外側の型文字列には内部の型定義が付加されるため、typehash は両方をカバーします。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 を再計算します。したがって署名は、売り手、原資産ラッパー、ラッパーのシェア数量、行使価格、満期、プレミアム、クオート期限、nonce、チェーン ID、ファクトリーのアドレスを拘束します。決済トークンとその小数桁数はファクトリーの設定が正であり、個別に署名される値ではありません。このオラクルレス世代には Pyth は含まれません。売り手がボールトに資金を投入すると、クオートのダイジェストとマーケットメイカーの nonce の両方が消費されます。
署名済みクオートを送信できるのは、リクエストにエンコードされた売り手だけです。資金投入時、ライター・クレーム NFT が売り手に、ロング・オプション NFT がクオートしたマーケットメイカーにミントされます。ただし、任意の買い手許可リストが有効な場合、そのマーケットメイカーが適格な受取人である必要があります。有効な署名は資金投入を許可するものであり、権利行使を許可するものではありません。
権利行使を呼び出せるのは、現在のロング・オプション NFT の所有者だけです。この所有者限定ルールにより、ERC-721 のオペレーターが所有者の決済トークンのアローワンスを消費することを防ぎます。承認済みのオペレーターは標準の ERC-721 ルールに従って NFT を移転することは可能で、買い手ゲートが有効な間は、経済的な権利が適格な受取人に移転します。権利行使が成功すると、呼び出し元である所有者から行使代金を引き出し、その所有者に原資産を引き渡し、ロング・オプション NFT をバーンします。
EIP-712 ドメインセパレーター
3 つのディレクティブ・ドメインは同じ構造を持ち、name のみが異なります。verifyingContract はゼロアドレスのため、同じ署名はチェーン上のどの Account に対しても有効です。署名を特定の 1 つの 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 のアカウントモード(unified のみ) |
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 バイトの0x付き 16 進文字列(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 を使用してください。
テストベクターでは、エンコーダーをバイト単位で確認できるよう、プレースホルダーのアカウントと固定の nonce を使用しています。ダイジェストは keccak256(0x1901 || domainSeparator || directiveStructHash) です。
HLOrder
Account の Hyperliquid 指値注文 1 件です。
構造体:
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)
Typehash: 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: クライアント注文 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、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd |
| アクション構造体ハッシュ | 0x0fd024c6bf8f132123e63a78d50008d8c39c52e5409ef6ca87a4eec8f6eabb41 |
| ディレクティブ構造体ハッシュ | 0xd32948ee1f249b96124a6acdb5845d09aad8228512098598de6858d5484fe703 |
| 署名するダイジェスト | 0xc3c42699092fe20c7dbc4205a1027f55c28d33a682a64bd3f04e40f1d28693f5 |
このテストベクターでは、isBuy: true、limitPx: 5000000000000、sz: 100000、reduceOnly: false、encodedTif: 2、asset: 0、そして nonce と同じ値の 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 で注文を 1 件キャンセルします。ラッパーは 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)
Typehash: 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、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85 |
| アクション構造体ハッシュ | 0xa34e7bb8af0d099f9c48095924e53067bcb9b542a816445b96abebbc5646b727 |
| ディレクティブ構造体ハッシュ | 0x69d560ba5ef3e88459bde7fb8252e55dbc33627373c8f0cfcf8ef0868f59e097 |
| 署名するダイジェスト | 0x5046aba9fb33c55ce736faf63734ea66914f3f168ff0aff2229fa6f31fa9b330 |
このテストベクターでは asset: 0 と oid: 123456789 を使用しています。
HLCancelByCloid
HLOrder で設定したクライアント注文 ID で注文を 1 件キャンセルします。
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)
Typehash: 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、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5 |
| アクション構造体ハッシュ | 0xfa4ab6440f946a6e279d90972d71223c768c01c8a91dc22703a6448dbcb966d0 |
| ディレクティブ構造体ハッシュ | 0x998efb01bb9c842eea80e8cc084b9e4e7ec13b2111790e1acbfec32e49060d9d |
| 署名するダイジェスト | 0x56af82a6aa7fa50907a23c6cfe3aa556af5aa087b1157163ebf6ea0240e8d29d |
このテストベクターでは asset: 0 と cloid: 1760000000000 を使用しています。
TEE 専用のパーペチュアル・メッセージ
以下の 4 つのメッセージは、Account コントラクトではなく Hypercall API が検証します。エンクレーブがこれらを Hyperliquid 上でネイティブに実行し、対応するオンチェーンのディレクティブが存在しないためです。HLOrder と同じ HypercallApiSign ドメインと同じ API ウォレット権限を使用します(署名者は Account の有効な API ウォレットであり、Account はポートフォリオ証拠金である必要があります)。これらの typehash はコントラクトには含まれていません。nonce はミリ秒単位の Unix 時刻です。
PerpOrderTerms
HCPerpTriggerOrder と HCPerpOrderBatch はどちらもこの構造体を埋め込みます。指値の子注文は、TIF バイトに加えて triggerPx = 0、isMarket = false、tpsl = 0 で署名します。トリガーの子注文は、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
損切りまたは利確の注文 1 件で、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)
Typehash: 0x2d3104ab255275839aad254429e4be789f64a8d16b8e3e7d5f30a0db3c887b5c
テストベクター(アカウント 0x1111111111111111111111111111111111111111、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 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
1 つのグルーピングのもとで最大 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)
Typehash: 0x9d4f467a44f4b0d39f234f3b91888546ce31dcbb67ce791550901b9042c38f8b。orders 配列は、各 PerpOrderTerms 構造体ハッシュを送信順に連結したものの keccak256 としてエンコードされます。
テストベクター(アカウント 0x1111111111111111111111111111111111111111、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0x9d4f467a44f4b0d39f234f3b91888546ce31dcbb67ce791550901b9042c38f8b |
| 注文配列ハッシュ | 0x13fc75fcc69bf3b4ef7cdc3a0872c3cc1cf59440c74d366055109b6bd5ea7c98 |
| ディレクティブ構造体ハッシュ | 0x69d0b1131e386769823fe1ab3facbe8e6fc013f86a117cf95cb52b8ce2f274e0 |
| 署名するダイジェスト | 0x4b5cd34b1f254fdd9881b7674a3412807e16cade1f2ccc7a1e261482682fbd07 |
このテストベクターは grouping: 1 で 2 件の注文を含みます。GTC の指値買い注文(limitPx: 5000000000000、sz: 100000、cloid: 1760000000000)と、それに続くトリガー例の損切り注文です。
HCPerpLeverageChange
1 つのアセットのレバレッジを設定するもので、POST /v1/tee-perp/leverage/submit に送信します。leverage はゼロより大きい必要があります。
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)
Typehash: 0xe13845f0e6c16a5e1fc56b2d11fb0972faa2ec30b01e94d58c72147fa9b6a463
テストベクター(アカウント 0x1111111111111111111111111111111111111111、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 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)
Typehash: 0xf21b6881e346bbf4b8d82e8ea507cf487e58dfc08776ad662591be7d6065bdfb
テストベクター(アカウント 0x1111111111111111111111111111111111111111、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0xf21b6881e346bbf4b8d82e8ea507cf487e58dfc08776ad662591be7d6065bdfb |
| アクション構造体ハッシュ | 0x0a3ebfe48ef28a79beeee4d56e524f8a5280c38562efb697e7b1d63b3d475afc |
| ディレクティブ構造体ハッシュ | 0xae64a13943a6a35b33aeb3095763b855c58c2119daf71e1e3228d8acf2645e8b |
| 署名するダイジェスト | 0xa01806f47299010b5963a516562be3c3b44fed4f4a9e2e56c4bb601630146cdc |
このテストベクターは、time: 1760000060000 にキャンセルを予約します。
Manager 署名による準備済みキャンセル
POST /v1/tee-perp/cancels/submit-prepared は、Manager が署名するキャンセル経路です。型付きデータの構造体は使用しません。Manager は、準備済みのネイティブ Hyperliquid キャンセルのダイジェストに署名します。これは preparedRequest(base64)として渡し、managerSignature は正規の low-s 形式で指定します。さらに、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)
Typehash: 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、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0x8ebe7d19374200e5dc3ae838db74b370da95bd2b3a8aec9de85d2398dd4a9257 |
| アクション構造体ハッシュ | 0x8b6c4a9db102e9d27c9a4069b39ba35e04948129359f0c15cd5103dd101ffce7 |
| ディレクティブ構造体ハッシュ | 0x830e291835ad182f290bc3d2bff09eaf9fd33acfbe44c6ad583218cd1a8232e5 |
| 署名するダイジェスト | 0x06589077544af449314db1fa8c7aac2d277cce9e833a04992d88161ede24cbe8 |
このテストベクターでは、name に trading-bot(0x74726164696e672d626f74 を右側ゼロ埋め)、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)
Typehash: 0x71c0e0dfbddc3456015249946354324befde42b6851d1c9b26c6a29f2e0b1ac2。アクション: バージョン 1、id 9。送信: POST /v1/actions/hl_add_api_wallet。
apiWalletName は string 型のため、構造体フィールドの値は keccak256(bytes(apiWalletName)) になります。ethers と viem はこれを自動で処理します。
テストベクター(アカウント 0x1111111111111111111111111111111111111111、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 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)
Typehash: 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、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595 |
| アクション構造体ハッシュ | 0x9b8c0290da19ea1069e14833023c4621a4f043354b36b4f17d4803b1fce6e656 |
| ディレクティブ構造体ハッシュ | 0xa0cb8a72188a61289fc2685c29a424605e0a2ee7b7af3e8cfee10e1c75153e08 |
| 署名するダイジェスト | 0x7c7037f27c659a1885f744778480e6847c5d08e98fb22517265ba708b6597d10 |
このテストベクターは、5 USDC(amountWei: 500000000)をパーペチュアル(srcDex: 0)からスポット(dstDex: 4294967295)へ送付し、destination は本番の Exchange 0xE6b7FaA216cabb2b38B392f577C9c826378b2240 です。
HLSetAbstraction
Account の HyperCore アカウントモードを設定します。Account が受け付けるのは、user が自身と等しく、かつ abstraction = 2(unified アカウント)の場合のみで、それ以外はリバートします。ポートフォリオ証拠金ではこの設定が必須です。
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)
Typehash: 0xcf5fddf081e5f2a9a45aa87cb1a3c42e5aa20164566b1ad2369b6b1318eac786。アクション: バージョン 1、id 16。送信: POST /v1/actions/hl_set_abstraction。
テストベクター(アカウント 0x1111111111111111111111111111111111111111、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0xcf5fddf081e5f2a9a45aa87cb1a3c42e5aa20164566b1ad2369b6b1318eac786 |
| アクション構造体ハッシュ | 0xef6c70a3c14b9e77c710c6b3b3ee681ca270ef884bd8a64fa4064a96f3dda84e |
| ディレクティブ構造体ハッシュ | 0xdda9d0fe82b63c728c4ac42585d5998a04cabaed0f957a2cafdf31a754829c3d |
| 署名するダイジェスト | 0xf49d7d8d74596e503d6a1bdfb26653533a12a5ba3816acd992d0bd4ef378f59d |
このテストベクターでは、user に Account を、abstraction に 2 を設定しています。
HCTransferOption(予約済み)
コントラクトは HCTransferOption(address account,uint64 nonce,TransferOption action)TransferOption(address recipient,address option,uint256 amountWei)(typehash 0xa218e1158788b23987f954edc7a07659a03a03fe5ba981a5bbe44d7a146e0819、アクションバージョン 0、id 1)を定義していますが、署名者タイプは割り当てられていません。Account は Account__UserDirectiveNotSupported でリバートし、API は hc_transfer_option を拒否します。これには署名しないでください。オプショントークンの移動には、代わりに depositOption と出金を使用してください。
署名を伴わない Manager のトランザクション
一部の Manager 操作は EIP-712 メッセージではなく、Account を直接呼び出します。Account.approveZeroFeeBuilder(builder) は Hyperliquid のビルダーを最大手数料 0% で承認するもので、最初のパーペチュアル注文の前に一度実行する必要があります(オンボーディング を参照)。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 の構造体を再利用するため、typehash は API や Manager のものと同じで、ドメインセパレーターのみが異なります。Account は追加の制約を課し、清算中であってもこれらを実行します。
| メッセージ | Typehash | Account が課す制約 |
|---|---|---|
HLOrder | 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd | encodedTif は IOC(3)である必要があり、注文は reduceOnly であるか、または USDC へのスポット売り(スポットのアセット ID 10000 から 99999)で、指値が HyperCore のスポット価格から 5% を超えて下回らないこと |
HLCancel | 0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85 | なし |
HLCancelByCloid | 0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5 | なし |
HLSendAsset | 0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595 | destination は Exchange である必要があります |
RSM HLOrder のテストベクター(アカウント 0x1111111111111111111111111111111111111111、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd |
| アクション構造体ハッシュ | 0x39b4e0699f382aaad23f04740034e7c5581ba918139d2db63fbf586cc447e7db |
| ディレクティブ構造体ハッシュ | 0xe6dde5ad6d310b5ebb83c09ec28ee5568700473b885bb483b7437dca202af4f3 |
| 署名するダイジェスト | 0x57afa1e810804e768c05a467aa88ede15fdceedae5aaa840adff61a613aca469 |
RSM の HLOrder ベクターは、リデュースオンリーの IOC 売り注文です(isBuy: false、limitPx: 4800000000000、sz: 100000、reduceOnly: true、encodedTif: 3、nonce と同じ値の cloid)。Exchange.executeRsmDirective が署名を検証し、アクションを Account に転送します。
System アクション(Exchange が実行)
バージョン 255。各ラッパーは System<Action>(address account,uint64 nonce,<Action> action)<Action>(...) です。
| ラッパー | 内部型 | Typehash |
|---|---|---|
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はゼロ以外である必要があり、Account は HyperCore 上で有効化されている必要があります。 - SystemCreditOption は、必要に応じてオプションのペアをデプロイし、Account にオプショントークンをミントします。
underlyingは OpenZeppelin のShortStringワードで、ASCII を左詰めにし、最後のバイトにバイト長を格納します(BTCは0x42544300...03)。正規でないエンコーディングはリバートします。 - SystemStartLiquidation は、オークションのパラメーターを記録して Account をロックします。
marginNeededはゼロ以外である必要があります。 - SystemStopLiquidation は、
startTimeが記録された開始時刻と等しいことを要求し、Account を Manager に戻します。 - SystemWithdrawToken は、Exchange 自身の残高から HyperCore 上での Standard USDC の引き渡しをキューに入れます。
subAccount = 0、srcDex = 0、dstDexが0または4294967295、token = 0(USDC)、そしてamountWeiが EVM 単位の整数倍であることを要求します。HyperEVM のレシートだけでは、HyperCore 上での引き渡しの証明にはなりません。
SystemCreditToken のテストベクター(アカウント 0x1111111111111111111111111111111111111111、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0xe845f2049264182802994dae939dc8ac42d3ae543a7eeb530dd021428743f052 |
| アクション構造体ハッシュ | 0xc69d7c6e5c36c9789d990c6316eaff3be43980583806f41f8a8e6461b7114011 |
| ディレクティブ構造体ハッシュ | 0x7ffa37cef7e08d3a2dd5501a8648899d37bc09ebb25d148c124e12c5047476e1 |
| 署名するダイジェスト | 0x95f75e5ddb4837de3f578b8aa0d714d4b02672b18c4929e3d2dda4a266de8254 |
このベクターは 5 USDC を反映します(srcDex と dstDex が 4294967295、token: 0、amountWei: 500000000)。
SystemCreditOption のテストベクター(アカウント 0x1111111111111111111111111111111111111111、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0x65aedd5af06882e1e62d752b43b72ec62a85cacf2ca59e8ec2affc57eed9d8ae |
| アクション構造体ハッシュ | 0x4a8b563fc94d26c1da376145d5aa5d05f996232fcf9739ed0a662650e91861b6 |
| ディレクティブ構造体ハッシュ | 0x190b638f1a462469bf0d070248acfc86bbbb95ea8a9d3d97d33581c7d6bb5554 |
| 署名するダイジェスト | 0x86fb7c53bb7e139a4d5df7db2feae40e634efe09ea7509165d3cece75d75fce2 |
このベクターは BTC コール 1 枚を反映します(underlying: 0x42544300...03、expiry: 1761811200、strike: 80000、isCall: true、amountWei: 1000000000000000000)。
SystemStartLiquidation のテストベクター(アカウント 0x1111111111111111111111111111111111111111、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0x92b6a135a656e489c24fb5511684842b0ab3895c22b51e4910dee90a7d23511e |
| アクション構造体ハッシュ | 0x4cd6a7f0997eba84ef82eabd429a0d9ca80e55bd6d89d2e67eda9970d87ec803 |
| ディレクティブ構造体ハッシュ | 0x84f18dc2577978d7890c9eb269fd787d99de37039b3a08e24745398feffbd0c5 |
| 署名するダイジェスト | 0xcc72c0e7829938c9ca0a4515d759f94cc96d2f24cd51a134a430f215ed5f5d4b |
このベクターでは equity: -1500000000 と marginNeeded: 20000000000(いずれも小数 6 桁の USDC)を使用しています。
SystemStopLiquidation のテストベクター(アカウント 0x1111111111111111111111111111111111111111、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0xe1af98778e9cfd1d1a679bb0b64b6dc8aa3fb152ff6469d0a81a1c7eb87a4bd3 |
| アクション構造体ハッシュ | 0x1d900a795b328bd5fa734bd6d7f74634b98ca66eb5e45322fb1ba6400564b62b |
| ディレクティブ構造体ハッシュ | 0x977b9becdd26830f2cdf70ab40f72f24490fe6ed45822d1fc8c84120e9a46f40 |
| 署名するダイジェスト | 0xbe65f82782b14dba42e334e32dd7dcc6bf14c96824523723a186a7381f8f12af |
このベクターでは startTime: 1760000000 を使用しています。
SystemWithdrawToken のテストベクター(アカウント 0x1111111111111111111111111111111111111111、nonce 1760000000000、チェーン 999):
| ステップ | 値 |
|---|---|
| Typehash | 0x634b866e9a922bb846e297973c7a456e641b88f4e97493da9b222084d799c883 |
| アクション構造体ハッシュ | 0x10bd8d4372a09e613a6b4fb7018fcccde857ebf6cc3327d6c9a3c0f81515a076 |
| ディレクティブ構造体ハッシュ | 0x86680427965513c65a7a170730b9f4fb2e2b40e22cd18338cb004b6a7872ada2 |
| 署名するダイジェスト | 0x65cc392038decb9ccdc23b0a4a1cfbe657d3417f8cd9ebf2319b3172fb7d885c |
このベクターは、srcDex: 0、dstDex: 0、token: 0 で、5 USDC(amountWei: 500000000)を destination 0x1111111111111111111111111111111111111111 に出金します。
Nonce
各署名者は独立した nonce 空間を持ち、3 か所で追跡されます。
- Account コントラクト: 署名者ごとのビットマップ。
Account.isNonceUsed(signer, nonce)は nonce が消費済みかどうかを返します。ユーザーディレクティブは、再利用時にAccount__NonceAlreadyUsedでリバートします。nextNonceは存在せず、オンチェーンでは欠番が許容され、順序も問われません。 - Exchange コントラクト: RSM 署名者用のビットマップで、
Exchange.isNonceUsed(signer, nonce)で読み取ります。 - エンジン: 署名者ごとに最も大きい 100 個の nonce を保持します。新しい nonce は、そのセットに含まれていないこと、セットが満杯の場合は保存されている最小の nonce を上回ること、そしてサーバー時刻(ミリ秒)の 2 日前から 1 日後までの範囲に厳密に収まっていることが必要です。
nonce の起点にはミリ秒単位の現在の Unix 時刻を使用し、署名者ごとにインクリメントしてください。同じウォレットが同じミリ秒内に署名した 2 つのリクエストには異なる nonce が必要なため、カウンターを保持してください。TEE パーペチュアルのルートでは nonce がリクエストの時刻の基準にもなるため、小さな整数ではなく実際のミリ秒タイムスタンプを使用してください。
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: 自身のアドレス、nonce、アクションからダイジェストを再構築し、そのアクションに対応する API または Manager のセパレーターで署名者を復元し、権限を確認し、nonce を消費してから実行します。HL アクションは HyperCore の CoreWriter に渡されます。HC アクションは API ウォレットの登録を更新します。
- クライアント:
GET /v1/directives/{directive_id}をポーリングして最終ステータスを確認します。
TEE パーペチュアルのルートは API のステップで終了します。Hyperliquid 上で注文を実行するのは Account ではなくエンクレーブです。
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} のバッチと nonce) | ディレクティブごとに 1 つの CancelOrderByOid を持つ HLCancel |
HLRequestCancelByCloid | ディレクティブごとに 1 つの 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 | RSM が署名する、Exchange 宛ての HLSendAsset |
- 旧来の注文関数。
placeCoreOrders、cancelCoreOrders、cancelCoreOrdersByCloidは MsgPack エンコーディングとCoreSignaturesドメイン("Exchange"、チェーン ID1337)を使用していました。これらは削除されました。 nextNonce。 オンチェーンのnextNonce[signer]カウンターは存在しなくなりました。残っているのは使用済み nonce のビットマップ(isNonceUsed)のみです。- TBD とされていたメインネットのセパレーター。 以前の記述では、Manager と RSM のメインネット・セパレーターが TBD とされていました。3 つすべてが確定しており、上記の表に記載しています。
HCTransferOption。 定義されていますが、有効化されたことはありません。上記を参照してください。
セキュリティ上の考慮事項
- 鍵: Manager の鍵はハードウェアウォレットで保管してください。API ウォレットは注文とキャンセルにのみ署名します。システムごとに別の鍵を使用してください。
- nonce のリプレイ: nonce は絶対に再利用しないでください。nonce はオフチェーンで追跡し、アトミックにインクリメントしてください。
- ドメイン: メインネットでは必ずチェーン ID
999(テストネットでは998)で署名し、計算したセパレーターを上記の表と照合してください。 - 署名内容の検証: ハードウェアウォレットで署名する前に、
POST /v1/actions/{action}/typed-dataを呼び出して、自分のエンコーダーの結果と比較してください。 - オンチェーンの検証が最終判断: API は署名を事前チェックしますが、Account はすべてのディレクティブをオンチェーンで再検証します。API の受付応答を約定とみなさないでください。
- Manager と API ウォレット: Manager は所有権、API ウォレット、資産の移動を管理します。API ウォレットは取引メッセージにのみ署名します。別々の鍵を使用してください。