Trang này được dịch tự động. Bản gốc tiếng Anh là phiên bản chính thức. Đọc bằng tiếng Anh →
Chuyển đến nội dung chính

Ủy quyền Agent

Hỗ trợ ký đa khóa cho nhà tạo lập thị trường.

Tổng quan​

Ủy quyền agent cho phép một khóa ký chuyên dụng (agent) đặt và hủy lệnh thay mặt cho một ví giao dịch. Tính năng này hữu ích cho:

  • Bảo mật: Giữ khóa ví giao dịch trong kho lạnh, dùng khóa nóng để ký
  • Vận hành: Nhiều thành viên trong nhóm có thể ký bằng các khóa khác nhau
  • Tự động hóa: Các hệ thống tự động có thể ký bằng khóa chuyên dụng

Hai mô hình ủy quyền​

Hypercall có hai hệ thống ủy quyền riêng biệt tùy theo sản phẩm:

Sản phẩmLoại ủy quyềnNơi lưu trữCách thiết lập
Quyền chọn (REST API)Ủy quyền agentTrạng thái engine của HypercallPOST /approve-agent
PerpVí APIOn-chain (hợp đồng Account của bạn)Directive hc_update_api_wallet

Đây là hai hệ thống độc lập. Việc phê duyệt một agent để giao dịch quyền chọn không cấp quyền cho agent đó giao dịch perp, và ngược lại.

Quyền chọn: Ủy quyền Agent (Off-Chain)​

Agent ký các thông điệp EIP-712 PlaceOrder và CancelOrder thay mặt cho một ví giao dịch. API kiểm tra agent dựa trên trạng thái ủy quyền của engine trước khi lệnh đến được engine.

Perp: Ví API (On-Chain)​

Ví API ký các lệnh perp và lệnh hủy trong domain EIP-712 HypercallApiSign. Hypercall kiểm tra người ký dựa trên hợp đồng Account của bạn (isApiWalletActive()) trước khi chấp nhận lệnh. Trên tuyến TEE (mặc định của ứng dụng, và tùy chọn bật cho các client API), một enclave bảo mật nắm giữ một khóa giao dịch Hyperliquid riêng cho Account của bạn sẽ ký và gửi lệnh gốc; trên tuyến hợp đồng thông minh, một cài đặt nâng cao trong ứng dụng, lệnh đi qua hợp đồng Account của bạn. Xem Ký EIP-712 để tham khảo về cách ký và Perp để biết luồng xử lý.

Để thêm hoặc xóa một ví API, hãy gửi directive hc_update_api_wallet được ký bởi ví quản lý (manager) của tài khoản.

Mô hình này phản ánh mô hình ví API của Hyperliquid. Hyperliquid gọi chúng là ví API, còn gọi là ví agent, trong tài liệu Nonces and API wallets, và mô tả approveAgent trong tài liệu Exchange endpoint.

Chống phát lại Nonce​

Việc theo dõi nonce tuân theo mô hình nonce của Hyperliquid. Tất cả các hành động được ký (lệnh, phê duyệt/thu hồi agent, bắt tay QP) dùng chung một không gian nonce theo từng người ký. Engine lưu 100 nonce cao nhất cho mỗi địa chỉ người ký. Một nonce mới được chấp nhận nếu:

  1. !stored_set.contains(nonce): nonce không bị trùng lặp
  2. nonce > min(stored_set) khi tập đã chứa 100 phần tử: nonce lớn hơn nonce nhỏ nhất đang được lưu
  3. nonce nằm trong khoảng (T - 2 ngày, T + 1 ngày) so với dấu thời gian của máy chủ

Nonce không theo thứ tự vẫn được chấp nhận (ví dụ: nonce 105 rồi đến 102 đều hợp lệ nếu cả hai đều lớn hơn giá trị nhỏ nhất của tập). Tập được giới hạn ở 100 phần tử, vì vậy các phần tử cũ nhất sẽ bị loại bỏ khi phần tử mới được thêm vào. Điều này ngăn tài khoản bị khóa vĩnh viễn chỉ vì một nonce quá lớn.

Người ký nonce là địa chỉ đã ký thông điệp EIP-712: ví API đối với lệnh, người ký được khôi phục đối với ủy quyền agent, ví QP đối với bắt tay. Client nên dùng Date.now() (epoch tính bằng mili giây) làm giá trị khởi tạo nonce và tăng dần đơn điệu.

Ủy quyền Agent cho Quyền chọn​

Ký trực tiếp​

Nếu signer == wallet, lệnh luôn được ủy quyền (tự ký).

Ký bằng Agent​

Nếu signer != wallet, người ký phải là một agent đã được ủy quyền:

  • Agent phải có mặt trong trạng thái ủy quyền do engine sở hữu
  • Ủy quyền không được hết hạn
  • Snapshot của engine và nhật ký (journal) của engine là các nguồn bền vững để khôi phục khi khởi động lại

Phê duyệt Agent​

Endpoint: POST /approve-agent

Yêu cầu: ApproveAgentRequest

{
"agent": "0x...",
"nonce": 1,
"signature": "0x..."
}

Ký:

  • Chủ sở hữu ví ký thông điệp ApproveAgent
  • Ví được suy ra từ chữ ký được khôi phục
  • Agent là trường agent trong yêu cầu

Struct EIP-712:

struct ApproveAgent {
address agent;
uint64 nonce;
}

Phản hồi: ApproveAgentResponse

{
"success": true,
"error": null
}

Ghi chú:

  • Ủy quyền agent là trạng thái engine được ghi vào journal và vẫn tồn tại sau khi khởi động lại
  • Các phê duyệt được thực hiện qua endpoint này không hết hạn

Thu hồi Agent​

Endpoint: DELETE /revoke-agent

Yêu cầu: RevokeAgentRequest

{
"agent": "0x...",
"nonce": 2,
"signature": "0x..."
}

Ký:

  • Chủ sở hữu ví ký thông điệp RevokeAgent
  • Ví được suy ra từ chữ ký được khôi phục

Struct EIP-712:

struct RevokeAgent {
address agent;
uint64 nonce;
}

Phản hồi: RevokeAgentResponse

Ghi chú:

  • Áp dụng một lệnh RevokeAgent được ghi vào journal lên trạng thái ủy quyền do engine sở hữu
  • Các bước kiểm tra ủy quyền của API giao dịch đọc trạng thái backend và thực thi việc thu hồi đối với các yêu cầu giao dịch. Việc đăng bài trên Trollbox có thể lưu cache ủy quyền agent hợp lệ lâu hơn, vì vậy một agent vừa bị thu hồi vẫn có thể đăng bài cho đến khi cache đó hết hạn hoặc việc vô hiệu hóa theo cơ chế best-effort đến được vị trí edge liên quan. Cache này không cấp quyền cho các thao tác thay đổi qua API giao dịch.
  • Agent không thể ký thay cho ví sau khi bị thu hồi

Thu hồi tất cả Agent​

Endpoint: DELETE /revoke-all-agents

Yêu cầu: { "nonce": 3, "signature": "0x..." }, được ký bởi chủ sở hữu ví trên RevokeAllAgents(uint64 nonce). Xóa mọi agent của ví được khôi phục.

Lấy danh sách Agent được ủy quyền​

Endpoint: GET /authorized-agents?wallet=...

Tham số truy vấn:

  • wallet (bắt buộc)

Phản hồi:

{
"agents": [
"0x...",
"0x..."
]
}

Ghi chú:

  • Chỉ trả về các agent đang hoạt động và chưa hết hạn

Sử dụng Agent​

Ký lệnh bằng Agent​

Sau khi agent được phê duyệt:

  1. Ký lệnh bằng ví agent: Dùng ví agent để ký các thông điệp PlaceOrder / CancelOrder
  2. Đặt trường wallet: Đặt trường wallet thành địa chỉ ví giao dịch (không phải địa chỉ agent)
  3. Xác minh ở middleware: Middleware xác minh agent đã được ủy quyền cho ví đó

Ví dụ:

// Agent wallet signs the order
const agentSigner = new ethers.Wallet(agentPrivateKey);

const message = {
wallet: "0x...", // Trading wallet (not agent)
symbol: "BTC-20250131-100000-C",
side: "Buy",
size: "0.1",
price: "100.0",
tif: "gtc",
clientId: "mm-1",
nonce: 1
};

// Sign with agent wallet
const signature = await agentSigner._signTypedData(domain, types, message);

// Send request. The REST body uses snake_case `client_id`.
const { clientId, ...rest } = message;
const response = await fetch('/order', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
...rest,
client_id: clientId,
signature
})
});

Lệnh hàng loạt với Agent​

Các endpoint hàng loạt xác minh ủy quyền agent cho từng mục:

  • Mỗi lệnh trong POST /bulk_order có thể được ký bởi một agent khác nhau
  • Ủy quyền agent được kiểm tra cho từng mục
  • Nếu bất kỳ mục nào không vượt qua kiểm tra ủy quyền agent, mục đó trả về lỗi trong BulkOrderResult

Kiểm tra ủy quyền​

Middleware (Lệnh đơn)​

Endpoint:

  • POST /order
  • DELETE /order
  • DELETE /order_cloid

Kiểm tra: signature_and_agent_middleware xác minh:

  1. Khôi phục chữ ký thành công
  2. Người ký được ủy quyền (signer == wallet HOẶC agent đã được ủy quyền)

Handler (Lệnh hàng loạt)​

Endpoint:

  • POST /bulk_order
  • DELETE /bulk_order
  • DELETE /bulk_order_cloid

Kiểm tra: Xác minh từng mục trong handler:

  1. Khôi phục chữ ký cho từng mục
  2. Kiểm tra ủy quyền agent cho từng mục

Lưu trữ ủy quyền​

Ủy quyền agent là trạng thái do engine sở hữu. Các lệnh ApproveAgent và RevokeAgent được ghi vào journal, được khôi phục thông qua việc phát lại engine, và được cung cấp qua snapshot đọc để API kiểm tra.

Logic ủy quyền​

Ủy quyền người ký sử dụng logic OR tường minh:

  • Ký trực tiếp: signer == wallet.
  • Ký bằng agent: snapshot của engine chứa một bản ghi ủy quyền cho wallet_address == <wallet> và agent_address == <signer>, và expires_at không có hoặc nằm trong tương lai.

Hết hạn​

Engine hỗ trợ trường expires_at cho một ủy quyền và coi agent đã hết hạn là chưa được ủy quyền. POST /approve-agent không đặt trường này, vì vậy các agent được phê duyệt qua API vẫn hoạt động cho đến khi bị thu hồi.

Lưu ý bảo mật​

  1. Bảo mật khóa agent: Bảo vệ khóa riêng của agent (dùng ví phần cứng hoặc hệ thống quản lý khóa an toàn)
  2. Kiểm tra định kỳ: Thường xuyên rà soát các agent được ủy quyền qua GET /authorized-agents
  3. Thu hồi agent không dùng: Thu hồi các agent không còn cần thiết

Thực hành tốt nhất​

  1. Dùng agent cho tự động hóa: Giữ khóa ví giao dịch trong kho lạnh, dùng agent cho các hệ thống tự động
  2. Giới hạn phạm vi agent: Chỉ phê duyệt những agent cần quyền truy cập
  3. Giám sát việc sử dụng agent: Theo dõi agent nào đang đặt lệnh
  4. Thu hồi kịp thời: Thu hồi agent ngay lập tức khi không còn cần thiết

Sự cố thường gặp​

"Signer 0x... is not authorized to act for wallet 0x..."​

Nguyên nhân: Agent chưa được phê duyệt hoặc ủy quyền đã hết hạn/bị thu hồi.

Giải pháp: Phê duyệt agent qua POST /approve-agent hoặc ký trực tiếp bằng ví.

Ủy quyền Agent không hoạt động​

Nguyên nhân:

  • Agent không có mặt trong trạng thái ủy quyền do engine sở hữu
  • Ủy quyền đã bị thu hồi
  • Ủy quyền đã hết hạn

Giải pháp: Kiểm tra trạng thái agent qua GET /authorized-agents?wallet=....