Skip to content

feat(exchange): support always_place (a) on modify / batchModify#145

Merged
nktkas merged 2 commits into
nktkas:mainfrom
roscoe-infinex:feat/modify-always-place
Jun 17, 2026
Merged

feat(exchange): support always_place (a) on modify / batchModify#145
nktkas merged 2 commits into
nktkas:mainfrom
roscoe-infinex:feat/modify-always-place

Conversation

@roscoe-infinex

Copy link
Copy Markdown
Contributor

Summary

Adds the optional action-level a (always_place) boolean to the modify and batchModify action schemas, per the Hyperliquid exchange-endpoint docs.

Why

Hyperliquid added always_place to modify/batchModify (announced in the HL API channel, messages 325 + 327). Per the docs:

  • a: true places the resulting order even if the cancel did not succeed.
  • a: false requires the new order to be non-trigger with TIF Alo, or a non-executable Gtc order, and must be omitted when false"actions hashed with a: false will be rejected."

Once HL enforces the new semantics, a modify that targets a trigger order (TP/SL) is rejected unless the action carries a: true. Today the SDK has no way to send it: the field isn't in the schema, so canonicalize throws Key "a" exists in data but not in schema (and it's part of the signed L1 action, so it can't be injected after signing).

What

  • Add a: v.optional(v.boolean()) as the last entry of the modify and batchModify action objects, so canonicalize orders it to match HL's documented wire layout { type, oid, order, a } / { type, batchModify… modifies, a }. Making it v.optional (and never serializing false) preserves the omit-when-false rule, since absent optionals are dropped before hashing.
  • Add JSDoc describing the semantics and the omit-when-false constraint.
  • Add an always-place sample to modify/batchModify tests so schemaCoverage exercises the new optional field.

Testing

deno task check passes (fmt, lint incl. the valibot plugins, type check, jsdoc-sync, export-sync). The live-API test cases require a funded testnet key (per CONTRIBUTING), so I couldn't run the network portion locally — the added samples set a: true on a trigger modify and should exercise the new path under your CI.

Reference

roscoe-infinex and others added 2 commits June 17, 2026 15:42
Hyperliquid added an optional action-level `a` (always_place) boolean to the
`modify` and `batchModify` actions (HL API channel msgs 325 + 327). Per the
exchange-endpoint docs:

- `a: true` places the resulting order even if the cancel did not succeed.
- `a: false` requires a non-trigger order with TIF Alo, or a non-executable
  GTC order, and must be omitted entirely (actions hashed with `a: false`
  are rejected).

Without it, a modify targeting a trigger (TP/SL) order is rejected, and the
field can't be added by callers because `canonicalize` rejects keys absent
from the schema. This adds `a: v.optional(v.boolean())` as the last entry of
both action schemas (so canonical key order matches HL's `{type, oid, order, a}`),
with JSDoc, and adds an always-place sample to each method's test for schema
coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nktkas

nktkas commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Thanks for your contribution!

@nktkas
nktkas merged commit 514e84d into nktkas:main Jun 17, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants