haedal-hasui
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHaedal haSUI
Haedal haSUI
Haedal Protocol is a DeFi ecosystem on the SUI blockchain. haSUI is its liquid staking token (LST): stake native SUI to receive haSUI, earn staking rewards, and optionally choose validators. This skill calls the Haedal Skills API to perform stake, withdraw, instant withdraw, and claim operations via curl — no custom scripts required.
Call the haSUI HTTP APIs directly with curl.
All numeric parameters are human‑readable amounts: pass and other quantity fields as human‑readable values, without multiplying by decimals. For example, to stake 20 tokens, simply send .
amount"amount":"20"Haedal Protocol是SUI区块链上的DeFi生态系统。haSUI是其流动性质押代币(LST):质押原生SUI即可获得haSUI,赚取质押奖励,还可选择验证节点。本技能调用Haedal Skills API,通过curl执行质押、提取、即时提取和领取奖励操作——无需自定义脚本。
直接使用curl调用haSUI HTTP接口。
所有数值参数均为人类可读的金额:将及其他数量字段以人类可读的值传入,无需乘以小数位数。例如,要质押20个代币,只需传入。
amount"amount":"20"Validator when staking
质押时的验证节点
Only the stake method requires a (validator node ):
validatornode_id- Passing means "use the default validator".
0x0 - If the user does not provide a validator: show a reference list of validators and let the user choose. The user can respond with index 1–5 or the validator name. Map this to the corresponding in the table and include it in the request.
node_id - The reference list is defined in (mapping between name and node_id, indexed 1–5).
references/validators.md
Typical flow: the user says "stake hasui" without specifying a validator → present 5 reference validators (index + name) → the user replies with "1" or "Ankr", etc. → use the corresponding to call stake.
node_id仅stake方法需要传入(验证节点的):
validatornode_id- 传入****表示“使用默认验证节点”。
0x0 - 如果用户未提供验证节点:展示验证节点参考列表供用户选择。用户可回复索引1-5或验证节点名称。将其映射为表格中对应的并包含在请求中。
node_id - 参考列表定义在中(名称与node_id的映射,索引1-5)。
references/validators.md
典型流程:用户说“stake hasui”但未指定验证节点 → 展示5个参考验证节点(索引+名称)→ 用户回复“1”或“Ankr”等 → 使用对应的调用stake接口。
node_idClaiming rewards and NFTObj
领取奖励与NFTObj
The claim endpoint requires address and NFTObj (the NFT object ID that holds the rewards). When the user says "claim hasui rewards":
- Ask the user whether they want help finding the object id (if the user already knows the NFTObj, you can send it directly).
- If discovery is needed: call get_unstake_tickets_list with the user . On HTTP 200 the response body is:
addressjson{ "list": [ { "objectId": "0x...", "type": "0x...::staking::UnstakeTicket", "version": "...", "fields": { "claim_epoch": "646", "claim_timestamp_ms": "1737135496590", "id": { "id": "0x..." }, "st_amount": "1000000000", "sui_amount": "1045887315", "unstake_timestamp_ms": "1737085604741" } } ] } - Present the list to the user in a readable format — show key fields such as ,
objectId,st_amount,sui_amount,claim_epochfor each entry.claim_timestamp_ms - If there are multiple entries in the list: let the user choose which one to claim (or take the first entry if only one exists) and use that entry's as NFTObj.
objectId - Then call claim: with body
POST /api/v1/hasui/claim.{"address":"0x...","NFTObj":"<objectId from previous step>"}
Flow summary: the user says "claim hasui rewards" → ask whether to discover the object id → if yes, call get_unstake_tickets_list(address) → present the list with key details → user selects one → take the chosen as NFTObj → call claim(address, NFTObj).
objectIdclaim接口需要address和NFTObj(存储奖励的NFT对象ID)。当用户说“claim hasui rewards”时:
- 询问用户是否需要帮助查找对象ID(如果用户已知道NFTObj,可直接传入)。
- 如果需要查找:调用get_unstake_tickets_list接口并传入用户。HTTP 200响应体如下:
addressjson{ "list": [ { "objectId": "0x...", "type": "0x...::staking::UnstakeTicket", "version": "...", "fields": { "claim_epoch": "646", "claim_timestamp_ms": "1737135496590", "id": { "id": "0x..." }, "st_amount": "1000000000", "sui_amount": "1045887315", "unstake_timestamp_ms": "1737085604741" } } ] } - 以可读格式向用户展示列表:显示每个条目的关键字段,如、
objectId、st_amount、sui_amount、claim_epoch。claim_timestamp_ms - 如果列表中有多个条目:让用户选择要领取的条目(如果只有一个条目则直接使用该条目),并将该条目的作为NFTObj。
objectId - 然后调用claim接口:向传入参数
POST /api/v1/hasui/claim。{"address":"0x...","NFTObj":"<上一步获取的objectId>"}
流程总结:用户说“claim hasui rewards” → 询问是否需要查找对象ID → 如果需要,调用get_unstake_tickets_list(address) → 展示带关键信息的列表 → 用户选择条目 → 取选中条目的作为NFTObj → 调用claim(address, NFTObj)。
objectIdBase URL
基础URL
https://skillsapi.haedal.xyz/api/v1/hasuihttps://skillsapi.haedal.xyz/api/v1/hasuiRequest body
请求体
| Method | Required fields | Notes |
|---|---|---|
| stake | address, amount, validator | No object field |
| withdraw | address, amount | No object field |
| withdraw_instant | address, amount | No object field |
| claim | address, NFTObj | Requires NFT object ID, see the "Claiming rewards" flow above |
| get_unstake_tickets_list | address | Query the UnstakeTicket list for this address to obtain NFTObj |
| 方法 | 必填字段 | 说明 |
|---|---|---|
| stake | address, amount, validator | 无object字段 |
| withdraw | address, amount | 无object字段 |
| withdraw_instant | address, amount | 无object字段 |
| claim | address, NFTObj | 需要NFT对象ID,详见上方“领取奖励”流程 |
| get_unstake_tickets_list | address | 查询该地址的UnstakeTicket列表以获取NFTObj |
curl examples
curl示例
stake
Pass as to use the default validator, or use a node_id from (user can choose by index 1–5 or by name).
validator0x0references/validators.mdbash
undefined质押(stake)
传入为即可使用默认验证节点,或使用中的node_id(用户可通过索引1-5或名称选择)。
validator0x0references/validators.mdbash
undefinedUse the default validator
使用默认验证节点
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hasui/stake"
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0x0"}'
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0x0"}'
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hasui/stake"
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0x0"}'
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0x0"}'
Or specify an explicit validator node_id (for example Haedal Protocol)
或指定具体的验证节点node_id(例如Haedal Protocol)
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hasui/stake"
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0xc8a57a7ae3b814afc15a907d963a288454b2c0f1a323fd556cb2d56d85a94583"}'
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0xc8a57a7ae3b814afc15a907d963a288454b2c0f1a323fd556cb2d56d85a94583"}'
**withdraw**
```bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hasui/withdraw" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS","amount":"100"}'withdraw_instant
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hasui/withdraw_instant" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS","amount":"100"}'get_unstake_tickets_list (query the UnstakeTicket list that can be claimed, used to obtain NFTObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hasui/get_unstake_tickets_list" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS"}'When the response status is 200, the body contains . Present key fields (, , , , ) to the user, then use the selected as the NFTObj for the claim call.
{"list":[{"objectId":"...","type":"...","version":"...","fields":{...}}, ...]}objectIdst_amountsui_amountclaim_epochclaim_timestamp_mslist[].objectIdclaim (requires NFTObj, which can be obtained from get_unstake_tickets_list → list[].objectId)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hasui/claim" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS","NFTObj":"0xOBJECT_ID_FROM_LIST"}'curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hasui/stake"
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0xc8a57a7ae3b814afc15a907d963a288454b2c0f1a323fd556cb2d56d85a94583"}'
-H "Content-Type: application/json"
-d '{"address":"0xYOUR_ADDRESS","amount":"100","validator":"0xc8a57a7ae3b814afc15a907d963a288454b2c0f1a323fd556cb2d56d85a94583"}'
**提取(withdraw)**
```bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hasui/withdraw" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS","amount":"100"}'即时提取(withdraw_instant)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hasui/withdraw_instant" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS","amount":"100"}'get_unstake_tickets_list(查询可领取的UnstakeTicket列表,用于获取NFTObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hasui/get_unstake_tickets_list" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS"}'当响应状态为200时,响应体包含。将关键字段(、、、、)展示给用户,然后将选中条目的作为claim调用的NFTObj。
{"list":[{"objectId":"...","type":"...","version":"...","fields":{...}}, ...]}objectIdst_amountsui_amountclaim_epochclaim_timestamp_mslist[].objectId领取奖励(claim)(需要NFTObj,可通过get_unstake_tickets_list → list[].objectId获取)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/hasui/claim" \
-H "Content-Type: application/json" \
-d '{"address":"0xYOUR_ADDRESS","NFTObj":"0xOBJECT_ID_FROM_LIST"}'Response
响应
- stake / withdraw / withdraw_instant / claim: on HTTP 200, the body is ; use
{"txBytes":"<base64>"}to extract it. On non‑200, usejq -r '.txBytes'to return the error reason to the user.jq -r '.msg' - get_unstake_tickets_list: on HTTP 200, the body is ; use
{"list":[{"objectId","type","version","fields":{...}}, ...]}to obtain the list. Each entry'sjq -r '.list'containsfields,st_amount,sui_amount,claim_epoch,claim_timestamp_ms. Take the desired entry'sunstake_timestamp_msas the NFTObj for claim.objectId
- stake / withdraw / withdraw_instant / claim:HTTP 200响应体为;可使用
{"txBytes":"<base64>"}提取该值。非200响应时,使用jq -r '.txBytes'将错误原因返回给用户。jq -r '.msg' - get_unstake_tickets_list:HTTP 200响应体为;可使用
{"list":[{"objectId","type","version","fields":{...}}, ...]}获取列表。每个条目的jq -r '.list'包含fields、st_amount、sui_amount、claim_epoch、claim_timestamp_ms。将目标条目的unstake_timestamp_ms作为claim调用的NFTObj。objectId
MoveAbort error codes
MoveAbort错误码
When a dry-run or build call fails with , use the following mapping:
MoveAbort(..., <code>)| Code | Constant Name | Description |
|---|---|---|
| 1 | | Data does not match the program |
| 2 | | Staked SUI rewards do not match |
| 3 | | Invalid staking parameters |
| 4 | | Not enough SUI to stake |
| 5 | | No stSUI minted during staking |
| 6 | | Normal unstake ticket is still in locking period |
| 7 | | Not enough SUI to fulfill unstake |
| 8 | | Unstake amount exceeds the max SUI amount |
| 9 | | Instant unstake requires a service fee (fee not set) |
| 10 | | Commented out: not enough staked SUI for unstake |
| 11 | | Unstake stSUI amount must not be zero |
| 12 | | Staking is paused |
| 13 | | Unstaking is paused |
| 14 | | Commented out: reserved for claim |
| 15 | | Commented out: no minimum staking threshold met |
| 16 | | Unstake |
| 17 | | Claiming is paused |
| 18 | | Validator count does not match |
| 19 | | Validator not found |
| 20 | | Injected rewards amount is too low |
当预执行或构建调用失败并返回时,使用以下映射关系:
MoveAbort(..., <code>)| 错误码 | 常量名称 | 描述 |
|---|---|---|
| 1 | | 数据与程序不匹配 |
| 2 | | 质押的SUI奖励不匹配 |
| 3 | | 质押参数无效 |
| 4 | | 质押所需SUI不足 |
| 5 | | 质押过程中未铸造stSUI |
| 6 | | 普通提取票据仍处于锁定期 |
| 7 | | 提取所需SUI不足 |
| 8 | | 提取金额超过SUI最大限额 |
| 9 | | 即时提取需要服务费(未设置费用) |
| 10 | | 已注释:质押的SUI不足以进行提取 |
| 11 | | 提取的stSUI金额不能为零 |
| 12 | | 质押已暂停 |
| 13 | | 提取已暂停 |
| 14 | | 已注释:为领取奖励预留 |
| 15 | | 已注释:未达到最低质押阈值 |
| 16 | | 提取的 |
| 17 | | 领取奖励已暂停 |
| 18 | | 验证节点数量不匹配 |
| 19 | | 未找到验证节点 |
| 20 | | 注入的奖励金额过低 |