haedal-vehaedal

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Haedal VeHaedal

Haedal VeHaedal

Haedal Protocol is a DeFi ecosystem on the SUI blockchain. VeHaedal is its vote-escrowed governance token: lock HAEDAL for veHaedal to earn rewards and voting power; lock duration and optional decay affect reward rates. This skill calls the Haedal Skills API for add stake, extend lock, claim rewards, decay control, and unstake — no custom scripts required.
Call the VeHaedal HTTP APIs directly with curl.
All numeric parameters are human‑readable amounts: pass
amount
and similar quantity fields as human‑readable values, without multiplying by decimals. For example, to stake 20 tokens, simply send
"amount":"20"
.
Haedal ProtocolSUI区块链上的一个DeFi生态系统。VeHaedal是其锁仓治理代币:锁定HAEDAL以获取VeHaedal,从而赚取奖励和投票权;锁仓时长及可选的衰减机制会影响奖励率。本技能调用Haedal Skills API来完成质押、延长锁仓、领取奖励、衰减控制和解锁操作——无需自定义脚本。
直接通过curl调用VeHaedal HTTP接口。
所有数值参数均为人类可读金额:传递
amount
及类似数量字段时使用人类可读数值,无需乘以小数位数。例如,要质押20个代币,只需传入
"amount":"20"

Querying veHaedal objects (get_vehaedal_list)

查询VeHaedal对象(get_vehaedal_list)

Several methods (add_to_existing_stake, extend_existing_lock, start_decay, stop_decay, unstake_and_claim) require a
vehaedalObj
— the object ID of an existing veHaedal position. When the user triggers one of these methods:
  1. Ask the user whether they already have the veHaedal object ID. If yes, use it directly.
  2. If discovery is needed: call get_vehaedal_list with the user's
    address
    . On HTTP 200 the response body is:
    json
    {
      "list": [
        {
          "objectId": "0x...",
          "fields": {
            "current_amount": "10000000000",
            "initial_amount": "10000000000",
            "is_decaying": true,
            "lock_end_time": "1803708378450",
            "lock_start_time": "1772258778450",
            "locked_amount": "10000000000",
            "original_lock_weeks": "52",
            "owner": "0x...",
            "remaining_lock_weeks_when_stopped_decay": "52",
            "token_type": { "fields": { "name": "...::haedal::HAEDAL" }, "type": "0x1::type_name::TypeName" }
          }
        }
      ]
    }
  3. Present the list to the user in a readable format — show key fields such as
    objectId
    ,
    current_amount
    ,
    locked_amount
    ,
    is_decaying
    ,
    original_lock_weeks
    ,
    lock_end_time
    for each entry.
  4. Let the user choose which veHaedal object to operate on (or take the first entry if only one exists). Use the selected
    objectId
    as the
    vehaedalObj
    parameter for the subsequent call.
Flow summary: user triggers a method that requires
vehaedalObj
→ ask if they have the object ID → if not, call get_vehaedal_list(address) → present the list → user selects one → take that
objectId
as
vehaedalObj
→ call the target method.
部分方法(add_to_existing_stake、extend_existing_lock、start_decay、stop_decay、unstake_and_claim)需要**
vehaedalObj
**——即现有VeHaedal持仓的对象ID。当用户触发这些方法时:
  1. 询问用户是否已拥有VeHaedal对象ID。如果是,直接使用该ID。
  2. 若需要查询:调用get_vehaedal_list接口并传入用户的
    address
    。HTTP 200响应的内容如下:
    json
    {
      "list": [
        {
          "objectId": "0x...",
          "fields": {
            "current_amount": "10000000000",
            "initial_amount": "10000000000",
            "is_decaying": true,
            "lock_end_time": "1803708378450",
            "lock_start_time": "1772258778450",
            "locked_amount": "10000000000",
            "original_lock_weeks": "52",
            "owner": "0x...",
            "remaining_lock_weeks_when_stopped_decay": "52",
            "token_type": { "fields": { "name": "...::haedal::HAEDAL" }, "type": "0x1::type_name::TypeName" }
          }
        }
      ]
    }
  3. 以可读格式向用户展示列表——为每个条目显示关键字段,如
    objectId
    current_amount
    locked_amount
    is_decaying
    original_lock_weeks
    lock_end_time
  4. 让用户选择要操作的VeHaedal对象(如果只有一个条目则直接使用该条目)。将选中的
    objectId
    作为后续调用的
    vehaedalObj
    参数。
流程总结:用户触发需要
vehaedalObj
的方法 → 询问用户是否拥有对象ID → 若没有,调用get_vehaedal_list(address) → 展示列表 → 用户选择 → 将选中的
objectId
作为
vehaedalObj
→ 调用目标方法。

Base URL

基础URL

https://skillsapi.haedal.xyz/api/v1/vehaedal
https://skillsapi.haedal.xyz/api/v1/vehaedal

Request body

请求体

MethodRequired fieldsNotes
add_stakesignerAddress, amount, lockWeeks, isDecayingCreates a new veHaedal position
get_vehaedal_listaddressQuery veHaedal objects owned by this address; returns
list
of objects
add_to_existing_stakesignerAddress, vehaedalObj, amountRequires an existing veHaedal object ID
extend_existing_locksignerAddress, vehaedalObj, additionalWeeksRequires an existing veHaedal object ID
start_decaysignerAddress, vehaedalObjRequires an existing veHaedal object ID
stop_decaysignerAddress, vehaedalObjRequires an existing veHaedal object ID
unstake_and_claimsignerAddress, vehaedalObjRequires an existing veHaedal object ID
claim_rewards_v2signerAddress, periodsNo object field needed
claim_rewards_v2_epoch_1signerAddressNo object field needed
方法名称必填字段说明
add_stakesignerAddress, amount, lockWeeks, isDecaying创建新的VeHaedal持仓
get_vehaedal_listaddress查询该地址名下的VeHaedal对象;返回对象列表
list
add_to_existing_stakesignerAddress, vehaedalObj, amount需要现有VeHaedal对象ID
extend_existing_locksignerAddress, vehaedalObj, additionalWeeks需要现有VeHaedal对象ID
start_decaysignerAddress, vehaedalObj需要现有VeHaedal对象ID
stop_decaysignerAddress, vehaedalObj需要现有VeHaedal对象ID
unstake_and_claimsignerAddress, vehaedalObj需要现有VeHaedal对象ID
claim_rewards_v2signerAddress, periods无需对象字段
claim_rewards_v2_epoch_1signerAddress无需对象字段

curl examples

curl示例

add_stake
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/add_stake" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","amount":"20","lockWeeks":4,"isDecaying":false}'
get_vehaedal_list (query veHaedal objects owned by an address, used to obtain vehaedalObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/get_vehaedal_list" \
  -H "Content-Type: application/json" \
  -d '{"address":"0xYOUR_ADDRESS"}'
add_to_existing_stake (requires vehaedalObj, obtainable from get_vehaedal_list → list[].objectId)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/add_to_existing_stake" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","vehaedalObj":"0xOBJECT_ID","amount":"10"}'
extend_existing_lock (requires vehaedalObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/extend_existing_lock" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","vehaedalObj":"0xOBJECT_ID","additionalWeeks":2}'
start_decay (requires vehaedalObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/start_decay" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","vehaedalObj":"0xOBJECT_ID"}'
stop_decay (requires vehaedalObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/stop_decay" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","vehaedalObj":"0xOBJECT_ID"}'
unstake_and_claim (requires vehaedalObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/unstake_and_claim" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","vehaedalObj":"0xOBJECT_ID"}'
claim_rewards_v2
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/claim_rewards_v2" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","periods":["1","2"]}'
claim_rewards_v2_epoch_1
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/claim_rewards_v2_epoch_1" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS"}'
add_stake
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/add_stake" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","amount":"20","lockWeeks":4,"isDecaying":false}'
get_vehaedal_list(查询地址名下的VeHaedal对象,用于获取vehaedalObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/get_vehaedal_list" \
  -H "Content-Type: application/json" \
  -d '{"address":"0xYOUR_ADDRESS"}'
add_to_existing_stake(需要vehaedalObj,可从get_vehaedal_list → list[].objectId获取)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/add_to_existing_stake" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","vehaedalObj":"0xOBJECT_ID","amount":"10"}'
extend_existing_lock(需要vehaedalObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/extend_existing_lock" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","vehaedalObj":"0xOBJECT_ID","additionalWeeks":2}'
start_decay(需要vehaedalObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/start_decay" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","vehaedalObj":"0xOBJECT_ID"}'
stop_decay(需要vehaedalObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/stop_decay" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","vehaedalObj":"0xOBJECT_ID"}'
unstake_and_claim(需要vehaedalObj)
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/unstake_and_claim" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","vehaedalObj":"0xOBJECT_ID"}'
claim_rewards_v2
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/claim_rewards_v2" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS","periods":["1","2"]}'
claim_rewards_v2_epoch_1
bash
curl -s -w "\n%{http_code}" -X POST "https://skillsapi.haedal.xyz/api/v1/vehaedal/claim_rewards_v2_epoch_1" \
  -H "Content-Type: application/json" \
  -d '{"signerAddress":"0xYOUR_ADDRESS"}'

Response

响应

  • add_stake / add_to_existing_stake / extend_existing_lock / start_decay / stop_decay / unstake_and_claim / claim_rewards_v2 / claim_rewards_v2_epoch_1: on HTTP 200, the body is
    {"txBytes":"<base64>"}
    ; use
    jq -r '.txBytes'
    to extract it. On non‑200, use
    jq -r '.msg'
    to extract the error reason and return it to the user.
  • get_vehaedal_list: on HTTP 200, the body is
    {"list":[{"objectId":"...","fields":{...}}, ...]}
    . Use
    jq -r '.list'
    to obtain the list, then take the desired entry's
    objectId
    as the
    vehaedalObj
    for subsequent calls.
  • add_stake / add_to_existing_stake / extend_existing_lock / start_decay / stop_decay / unstake_and_claim / claim_rewards_v2 / claim_rewards_v2_epoch_1:HTTP 200响应的内容为
    {"txBytes":"<base64>"}
    ;可使用
    jq -r '.txBytes'
    提取该值。非200响应时,使用
    jq -r '.msg'
    提取错误原因并返回给用户。
  • get_vehaedal_list:HTTP 200响应的内容为
    {"list":[{"objectId":"...","fields":{...}}, ...]}
    。可使用
    jq -r '.list'
    获取列表,然后选取所需条目的
    objectId
    作为后续调用的
    vehaedalObj

MoveAbort error codes

MoveAbort错误码

When a dry-run or build call fails with
MoveAbort(..., <code>)
, use the following mapping:
CodeConstant NameDescription
0
N/A
start_decay
: token is already in decaying state.
stop_decay
/
unstake_and_claim
: token is not in decaying state.
1
EInvalidLockDuration
Invalid lock duration, must be between 1 and 52 weeks
2
EInvalidOwner
Caller is not the owner of the veHAEDAL token
3
ENoTokensToUnstake
No tokens available to unstake (
unstaked amount
is 0)
4
EInvalidAmount
Invalid amount, must be greater than 0
5
ELockNotExpired
Lock period has not expired yet
6
ELockShouldBeExpired
Lock period should be expired
7
EMinStakeAmount
Stake amount is below the minimum required
8
EDataNotMatchProgram
Pool version does not match the current program version
9
ELockExpired
Lock period has already expired
当预执行或构建调用失败并返回
MoveAbort(..., <code>)
时,可使用以下映射关系:
错误码常量名称说明
0
N/A
start_decay
:代币已处于衰减状态。
stop_decay
/
unstake_and_claim
:代币未处于衰减状态。
1
EInvalidLockDuration
锁仓时长无效,必须在1至52周之间
2
EInvalidOwner
调用者不是VeHAEDAL代币的持有者
3
ENoTokensToUnstake
无可用代币可解锁(已解锁金额为0)
4
EInvalidAmount
金额无效,必须大于0
5
ELockNotExpired
锁仓期尚未结束
6
ELockShouldBeExpired
锁仓期应已结束
7
EMinStakeAmount
质押金额低于最低要求
8
EDataNotMatchProgram
资金池版本与当前程序版本不匹配
9
ELockExpired
锁仓期已结束