@nktkas/hyperliquid 0.24.3 → 0.25.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -32
- package/esm/mod.d.ts +11 -11
- package/esm/mod.d.ts.map +1 -1
- package/esm/mod.js +2 -1
- package/esm/mod.js.map +1 -0
- package/esm/src/clients/exchange.d.ts +29 -25
- package/esm/src/clients/exchange.d.ts.map +1 -1
- package/esm/src/clients/exchange.js +54 -53
- package/esm/src/clients/exchange.js.map +1 -0
- package/esm/src/clients/info.d.ts +80 -20
- package/esm/src/clients/info.d.ts.map +1 -1
- package/esm/src/clients/info.js +312 -73
- package/esm/src/clients/info.js.map +1 -0
- package/esm/src/clients/multiSign.d.ts +11 -7
- package/esm/src/clients/multiSign.d.ts.map +1 -1
- package/esm/src/clients/multiSign.js +2 -1
- package/esm/src/clients/multiSign.js.map +1 -0
- package/esm/src/clients/subscription.d.ts +9 -9
- package/esm/src/clients/subscription.d.ts.map +1 -1
- package/esm/src/clients/subscription.js +29 -27
- package/esm/src/clients/subscription.js.map +1 -0
- package/esm/src/{base.d.ts → errors.d.ts} +1 -1
- package/esm/src/errors.d.ts.map +1 -0
- package/esm/src/{base.js → errors.js} +1 -0
- package/esm/src/errors.js.map +1 -0
- package/esm/src/schemas/_base.d.ts +14 -0
- package/esm/src/schemas/_base.d.ts.map +1 -0
- package/esm/src/schemas/_base.js +15 -0
- package/esm/src/schemas/_base.js.map +1 -0
- package/esm/src/schemas/exchange/requests.d.ts +8953 -0
- package/esm/src/schemas/exchange/requests.d.ts.map +1 -0
- package/esm/src/schemas/exchange/requests.js +1414 -0
- package/esm/src/schemas/exchange/requests.js.map +1 -0
- package/esm/src/schemas/exchange/responses.d.ts +567 -0
- package/esm/src/schemas/exchange/responses.d.ts.map +1 -0
- package/esm/src/schemas/exchange/responses.js +244 -0
- package/esm/src/schemas/exchange/responses.js.map +1 -0
- package/esm/src/schemas/explorer/requests.d.ts +44 -0
- package/esm/src/schemas/explorer/requests.d.ts.map +1 -0
- package/esm/src/schemas/explorer/requests.js +33 -0
- package/esm/src/schemas/explorer/requests.js.map +1 -0
- package/esm/src/schemas/explorer/responses.d.ts +360 -0
- package/esm/src/schemas/explorer/responses.d.ts.map +1 -0
- package/esm/src/schemas/explorer/responses.js +57 -0
- package/esm/src/schemas/explorer/responses.js.map +1 -0
- package/esm/src/schemas/info/accounts.d.ts +2159 -0
- package/esm/src/schemas/info/accounts.d.ts.map +1 -0
- package/esm/src/schemas/info/accounts.js +623 -0
- package/esm/src/schemas/info/accounts.js.map +1 -0
- package/esm/src/schemas/info/assets.d.ts +974 -0
- package/esm/src/schemas/info/assets.d.ts.map +1 -0
- package/esm/src/schemas/info/assets.js +285 -0
- package/esm/src/schemas/info/assets.js.map +1 -0
- package/esm/src/schemas/info/markets.d.ts +155 -0
- package/esm/src/schemas/info/markets.d.ts.map +1 -0
- package/esm/src/schemas/info/markets.js +70 -0
- package/esm/src/schemas/info/markets.js.map +1 -0
- package/esm/src/schemas/info/orders.d.ts +957 -0
- package/esm/src/schemas/info/orders.d.ts.map +1 -0
- package/esm/src/schemas/info/orders.js +298 -0
- package/esm/src/schemas/info/orders.js.map +1 -0
- package/esm/src/schemas/info/requests.d.ts +924 -0
- package/esm/src/schemas/info/requests.d.ts.map +1 -0
- package/esm/src/schemas/info/requests.js +687 -0
- package/esm/src/schemas/info/requests.js.map +1 -0
- package/esm/src/schemas/info/validators.d.ts +326 -0
- package/esm/src/schemas/info/validators.d.ts.map +1 -0
- package/esm/src/schemas/info/validators.js +126 -0
- package/esm/src/schemas/info/validators.js.map +1 -0
- package/esm/src/schemas/info/vaults.d.ts +447 -0
- package/esm/src/schemas/info/vaults.d.ts.map +1 -0
- package/esm/src/schemas/info/vaults.js +111 -0
- package/esm/src/schemas/info/vaults.js.map +1 -0
- package/esm/src/schemas/mod.d.ts +101 -0
- package/esm/src/schemas/mod.d.ts.map +1 -0
- package/esm/src/schemas/mod.js +115 -0
- package/esm/src/schemas/mod.js.map +1 -0
- package/esm/src/schemas/subscriptions/requests.d.ts +332 -0
- package/esm/src/schemas/subscriptions/requests.d.ts.map +1 -0
- package/esm/src/schemas/subscriptions/requests.js +259 -0
- package/esm/src/schemas/subscriptions/requests.js.map +1 -0
- package/esm/src/schemas/subscriptions/responses.d.ts +3643 -0
- package/esm/src/schemas/subscriptions/responses.d.ts.map +1 -0
- package/esm/src/schemas/subscriptions/responses.js +234 -0
- package/esm/src/schemas/subscriptions/responses.js.map +1 -0
- package/esm/src/signing/_signTypedData/ethers.js +1 -0
- package/esm/src/signing/_signTypedData/ethers.js.map +1 -0
- package/esm/src/signing/_signTypedData/mod.js +1 -0
- package/esm/src/signing/_signTypedData/mod.js.map +1 -0
- package/esm/src/signing/_signTypedData/private_key.js +1 -0
- package/esm/src/signing/_signTypedData/private_key.js.map +1 -0
- package/esm/src/signing/_signTypedData/viem.js +1 -0
- package/esm/src/signing/_signTypedData/viem.js.map +1 -0
- package/esm/src/signing/mod.d.ts +109 -29
- package/esm/src/signing/mod.d.ts.map +1 -1
- package/esm/src/signing/mod.js +136 -29
- package/esm/src/signing/mod.js.map +1 -0
- package/esm/src/transports/base.d.ts +4 -4
- package/esm/src/transports/base.d.ts.map +1 -1
- package/esm/src/transports/base.js +3 -2
- package/esm/src/transports/base.js.map +1 -0
- package/esm/src/transports/http/http_transport.d.ts +3 -2
- package/esm/src/transports/http/http_transport.d.ts.map +1 -1
- package/esm/src/transports/http/http_transport.js +1 -0
- package/esm/src/transports/http/http_transport.js.map +1 -0
- package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts +1 -1
- package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
- package/esm/src/transports/websocket/_hyperliquid_event_target.js +1 -0
- package/esm/src/transports/websocket/_hyperliquid_event_target.js.map +1 -0
- package/esm/src/transports/websocket/_reconnecting_websocket.js +1 -0
- package/esm/src/transports/websocket/_reconnecting_websocket.js.map +1 -0
- package/esm/src/transports/websocket/_websocket_async_request.js +1 -0
- package/esm/src/transports/websocket/_websocket_async_request.js.map +1 -0
- package/esm/src/transports/websocket/websocket_transport.d.ts +9 -1
- package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
- package/esm/src/transports/websocket/websocket_transport.js +4 -0
- package/esm/src/transports/websocket/websocket_transport.js.map +1 -0
- package/package.json +6 -5
- package/script/mod.d.ts +11 -11
- package/script/mod.d.ts.map +1 -1
- package/script/mod.js +2 -1
- package/script/mod.js.map +1 -0
- package/script/src/clients/exchange.d.ts +29 -25
- package/script/src/clients/exchange.d.ts.map +1 -1
- package/script/src/clients/exchange.js +60 -59
- package/script/src/clients/exchange.js.map +1 -0
- package/script/src/clients/info.d.ts +80 -20
- package/script/src/clients/info.d.ts.map +1 -1
- package/script/src/clients/info.js +312 -73
- package/script/src/clients/info.js.map +1 -0
- package/script/src/clients/multiSign.d.ts +11 -7
- package/script/src/clients/multiSign.d.ts.map +1 -1
- package/script/src/clients/multiSign.js +2 -1
- package/script/src/clients/multiSign.js.map +1 -0
- package/script/src/clients/subscription.d.ts +9 -9
- package/script/src/clients/subscription.d.ts.map +1 -1
- package/script/src/clients/subscription.js +29 -27
- package/script/src/clients/subscription.js.map +1 -0
- package/script/src/{base.d.ts → errors.d.ts} +1 -1
- package/script/src/errors.d.ts.map +1 -0
- package/script/src/{base.js → errors.js} +1 -0
- package/script/src/errors.js.map +1 -0
- package/script/src/schemas/_base.d.ts +14 -0
- package/script/src/schemas/_base.d.ts.map +1 -0
- package/script/src/schemas/_base.js +51 -0
- package/script/src/schemas/_base.js.map +1 -0
- package/script/src/schemas/exchange/requests.d.ts +8953 -0
- package/script/src/schemas/exchange/requests.d.ts.map +1 -0
- package/script/src/schemas/exchange/requests.js +1450 -0
- package/script/src/schemas/exchange/requests.js.map +1 -0
- package/script/src/schemas/exchange/responses.d.ts +567 -0
- package/script/src/schemas/exchange/responses.d.ts.map +1 -0
- package/script/src/schemas/exchange/responses.js +280 -0
- package/script/src/schemas/exchange/responses.js.map +1 -0
- package/script/src/schemas/explorer/requests.d.ts +44 -0
- package/script/src/schemas/explorer/requests.d.ts.map +1 -0
- package/script/src/schemas/explorer/requests.js +69 -0
- package/script/src/schemas/explorer/requests.js.map +1 -0
- package/script/src/schemas/explorer/responses.d.ts +360 -0
- package/script/src/schemas/explorer/responses.d.ts.map +1 -0
- package/script/src/schemas/explorer/responses.js +93 -0
- package/script/src/schemas/explorer/responses.js.map +1 -0
- package/script/src/schemas/info/accounts.d.ts +2159 -0
- package/script/src/schemas/info/accounts.d.ts.map +1 -0
- package/script/src/schemas/info/accounts.js +659 -0
- package/script/src/schemas/info/accounts.js.map +1 -0
- package/script/src/schemas/info/assets.d.ts +974 -0
- package/script/src/schemas/info/assets.d.ts.map +1 -0
- package/script/src/schemas/info/assets.js +321 -0
- package/script/src/schemas/info/assets.js.map +1 -0
- package/script/src/schemas/info/markets.d.ts +155 -0
- package/script/src/schemas/info/markets.d.ts.map +1 -0
- package/script/src/schemas/info/markets.js +106 -0
- package/script/src/schemas/info/markets.js.map +1 -0
- package/script/src/schemas/info/orders.d.ts +957 -0
- package/script/src/schemas/info/orders.d.ts.map +1 -0
- package/script/src/schemas/info/orders.js +334 -0
- package/script/src/schemas/info/orders.js.map +1 -0
- package/script/src/schemas/info/requests.d.ts +924 -0
- package/script/src/schemas/info/requests.d.ts.map +1 -0
- package/script/src/schemas/info/requests.js +724 -0
- package/script/src/schemas/info/requests.js.map +1 -0
- package/script/src/schemas/info/validators.d.ts +326 -0
- package/script/src/schemas/info/validators.d.ts.map +1 -0
- package/script/src/schemas/info/validators.js +162 -0
- package/script/src/schemas/info/validators.js.map +1 -0
- package/script/src/schemas/info/vaults.d.ts +447 -0
- package/script/src/schemas/info/vaults.d.ts.map +1 -0
- package/script/src/schemas/info/vaults.js +147 -0
- package/script/src/schemas/info/vaults.js.map +1 -0
- package/script/src/schemas/mod.d.ts +101 -0
- package/script/src/schemas/mod.d.ts.map +1 -0
- package/script/src/schemas/mod.js +157 -0
- package/script/src/schemas/mod.js.map +1 -0
- package/script/src/schemas/subscriptions/requests.d.ts +332 -0
- package/script/src/schemas/subscriptions/requests.d.ts.map +1 -0
- package/script/src/schemas/subscriptions/requests.js +295 -0
- package/script/src/schemas/subscriptions/requests.js.map +1 -0
- package/script/src/schemas/subscriptions/responses.d.ts +3643 -0
- package/script/src/schemas/subscriptions/responses.d.ts.map +1 -0
- package/script/src/schemas/subscriptions/responses.js +270 -0
- package/script/src/schemas/subscriptions/responses.js.map +1 -0
- package/script/src/signing/_signTypedData/ethers.js +1 -0
- package/script/src/signing/_signTypedData/ethers.js.map +1 -0
- package/script/src/signing/_signTypedData/mod.js +1 -0
- package/script/src/signing/_signTypedData/mod.js.map +1 -0
- package/script/src/signing/_signTypedData/private_key.js +1 -0
- package/script/src/signing/_signTypedData/private_key.js.map +1 -0
- package/script/src/signing/_signTypedData/viem.js +1 -0
- package/script/src/signing/_signTypedData/viem.js.map +1 -0
- package/script/src/signing/mod.d.ts +109 -29
- package/script/src/signing/mod.d.ts.map +1 -1
- package/script/src/signing/mod.js +138 -33
- package/script/src/signing/mod.js.map +1 -0
- package/script/src/transports/base.d.ts +4 -4
- package/script/src/transports/base.d.ts.map +1 -1
- package/script/src/transports/base.js +4 -3
- package/script/src/transports/base.js.map +1 -0
- package/script/src/transports/http/http_transport.d.ts +3 -2
- package/script/src/transports/http/http_transport.d.ts.map +1 -1
- package/script/src/transports/http/http_transport.js +1 -0
- package/script/src/transports/http/http_transport.js.map +1 -0
- package/script/src/transports/websocket/_hyperliquid_event_target.d.ts +1 -1
- package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
- package/script/src/transports/websocket/_hyperliquid_event_target.js +1 -0
- package/script/src/transports/websocket/_hyperliquid_event_target.js.map +1 -0
- package/script/src/transports/websocket/_reconnecting_websocket.js +1 -0
- package/script/src/transports/websocket/_reconnecting_websocket.js.map +1 -0
- package/script/src/transports/websocket/_websocket_async_request.js +1 -0
- package/script/src/transports/websocket/_websocket_async_request.js.map +1 -0
- package/script/src/transports/websocket/websocket_transport.d.ts +9 -1
- package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
- package/script/src/transports/websocket/websocket_transport.js +4 -0
- package/script/src/transports/websocket/websocket_transport.js.map +1 -0
- package/src/mod.ts +28 -0
- package/src/src/clients/exchange.ts +2246 -0
- package/src/src/clients/info.ts +2076 -0
- package/src/src/clients/multiSign.ts +183 -0
- package/src/src/clients/subscription.ts +841 -0
- package/src/src/errors.ts +7 -0
- package/src/src/schemas/_base.ts +43 -0
- package/src/src/schemas/exchange/requests.ts +3057 -0
- package/src/src/schemas/exchange/responses.ts +540 -0
- package/src/src/schemas/explorer/requests.ts +65 -0
- package/src/src/schemas/explorer/responses.ts +138 -0
- package/src/src/schemas/info/accounts.ts +1490 -0
- package/src/src/schemas/info/assets.ts +693 -0
- package/src/src/schemas/info/markets.ts +171 -0
- package/src/src/schemas/info/orders.ts +597 -0
- package/src/src/schemas/info/requests.ts +1369 -0
- package/src/src/schemas/info/validators.ts +299 -0
- package/src/src/schemas/info/vaults.ts +262 -0
- package/src/src/schemas/mod.ts +121 -0
- package/src/src/schemas/subscriptions/requests.ts +504 -0
- package/src/src/schemas/subscriptions/responses.ts +576 -0
- package/src/src/signing/_signTypedData/ethers.ts +59 -0
- package/src/src/signing/_signTypedData/mod.ts +121 -0
- package/src/src/signing/_signTypedData/private_key.ts +229 -0
- package/src/src/signing/_signTypedData/viem.ts +55 -0
- package/src/src/signing/mod.ts +572 -0
- package/src/src/transports/base.ts +54 -0
- package/src/src/transports/http/http_transport.ts +208 -0
- package/src/src/transports/websocket/_hyperliquid_event_target.ts +118 -0
- package/src/src/transports/websocket/_reconnecting_websocket.ts +404 -0
- package/src/src/transports/websocket/_websocket_async_request.ts +229 -0
- package/src/src/transports/websocket/websocket_transport.ts +394 -0
- package/esm/src/base.d.ts.map +0 -1
- package/esm/src/signing/_sorter.d.ts +0 -127
- package/esm/src/signing/_sorter.d.ts.map +0 -1
- package/esm/src/signing/_sorter.js +0 -693
- package/esm/src/types/exchange/requests.d.ts +0 -1345
- package/esm/src/types/exchange/requests.d.ts.map +0 -1
- package/esm/src/types/exchange/requests.js +0 -1
- package/esm/src/types/exchange/responses.d.ts +0 -233
- package/esm/src/types/exchange/responses.d.ts.map +0 -1
- package/esm/src/types/exchange/responses.js +0 -1
- package/esm/src/types/explorer/requests.d.ts +0 -32
- package/esm/src/types/explorer/requests.d.ts.map +0 -1
- package/esm/src/types/explorer/requests.js +0 -1
- package/esm/src/types/explorer/responses.d.ts +0 -58
- package/esm/src/types/explorer/responses.d.ts.map +0 -1
- package/esm/src/types/explorer/responses.js +0 -1
- package/esm/src/types/info/accounts.d.ts +0 -864
- package/esm/src/types/info/accounts.d.ts.map +0 -1
- package/esm/src/types/info/accounts.js +0 -1
- package/esm/src/types/info/assets.d.ts +0 -354
- package/esm/src/types/info/assets.d.ts.map +0 -1
- package/esm/src/types/info/assets.js +0 -1
- package/esm/src/types/info/markets.d.ts +0 -79
- package/esm/src/types/info/markets.d.ts.map +0 -1
- package/esm/src/types/info/markets.js +0 -1
- package/esm/src/types/info/orders.d.ts +0 -266
- package/esm/src/types/info/orders.d.ts.map +0 -1
- package/esm/src/types/info/orders.js +0 -1
- package/esm/src/types/info/requests.d.ts +0 -640
- package/esm/src/types/info/requests.d.ts.map +0 -1
- package/esm/src/types/info/requests.js +0 -1
- package/esm/src/types/info/validators.d.ts +0 -147
- package/esm/src/types/info/validators.d.ts.map +0 -1
- package/esm/src/types/info/validators.js +0 -1
- package/esm/src/types/info/vaults.d.ts +0 -119
- package/esm/src/types/info/vaults.d.ts.map +0 -1
- package/esm/src/types/info/vaults.js +0 -1
- package/esm/src/types/mod.d.ts +0 -38
- package/esm/src/types/mod.d.ts.map +0 -1
- package/esm/src/types/mod.js +0 -24
- package/esm/src/types/subscriptions/requests.d.ts +0 -154
- package/esm/src/types/subscriptions/requests.d.ts.map +0 -1
- package/esm/src/types/subscriptions/requests.js +0 -1
- package/esm/src/types/subscriptions/responses.d.ts +0 -238
- package/esm/src/types/subscriptions/responses.d.ts.map +0 -1
- package/esm/src/types/subscriptions/responses.js +0 -1
- package/script/src/base.d.ts.map +0 -1
- package/script/src/signing/_sorter.d.ts +0 -127
- package/script/src/signing/_sorter.d.ts.map +0 -1
- package/script/src/signing/_sorter.js +0 -696
- package/script/src/types/exchange/requests.d.ts +0 -1345
- package/script/src/types/exchange/requests.d.ts.map +0 -1
- package/script/src/types/exchange/requests.js +0 -2
- package/script/src/types/exchange/responses.d.ts +0 -233
- package/script/src/types/exchange/responses.d.ts.map +0 -1
- package/script/src/types/exchange/responses.js +0 -2
- package/script/src/types/explorer/requests.d.ts +0 -32
- package/script/src/types/explorer/requests.d.ts.map +0 -1
- package/script/src/types/explorer/requests.js +0 -2
- package/script/src/types/explorer/responses.d.ts +0 -58
- package/script/src/types/explorer/responses.d.ts.map +0 -1
- package/script/src/types/explorer/responses.js +0 -2
- package/script/src/types/info/accounts.d.ts +0 -864
- package/script/src/types/info/accounts.d.ts.map +0 -1
- package/script/src/types/info/accounts.js +0 -2
- package/script/src/types/info/assets.d.ts +0 -354
- package/script/src/types/info/assets.d.ts.map +0 -1
- package/script/src/types/info/assets.js +0 -2
- package/script/src/types/info/markets.d.ts +0 -79
- package/script/src/types/info/markets.d.ts.map +0 -1
- package/script/src/types/info/markets.js +0 -2
- package/script/src/types/info/orders.d.ts +0 -266
- package/script/src/types/info/orders.d.ts.map +0 -1
- package/script/src/types/info/orders.js +0 -2
- package/script/src/types/info/requests.d.ts +0 -640
- package/script/src/types/info/requests.d.ts.map +0 -1
- package/script/src/types/info/requests.js +0 -2
- package/script/src/types/info/validators.d.ts +0 -147
- package/script/src/types/info/validators.d.ts.map +0 -1
- package/script/src/types/info/validators.js +0 -2
- package/script/src/types/info/vaults.d.ts +0 -119
- package/script/src/types/info/vaults.d.ts.map +0 -1
- package/script/src/types/info/vaults.js +0 -2
- package/script/src/types/mod.d.ts +0 -38
- package/script/src/types/mod.d.ts.map +0 -1
- package/script/src/types/mod.js +0 -25
- package/script/src/types/subscriptions/requests.d.ts +0 -154
- package/script/src/types/subscriptions/requests.d.ts.map +0 -1
- package/script/src/types/subscriptions/requests.js +0 -2
- package/script/src/types/subscriptions/responses.d.ts +0 -238
- package/script/src/types/subscriptions/responses.d.ts.map +0 -1
- package/script/src/types/subscriptions/responses.js +0 -2
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module contains functions for generating Hyperliquid transaction signatures.
|
|
3
|
+
*
|
|
4
|
+
* @example Signing an L1 action
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { signL1Action } from "@nktkas/hyperliquid/signing";
|
|
7
|
+
* import { CancelRequest, parser } from "@nktkas/hyperliquid/schemas";
|
|
8
|
+
*
|
|
9
|
+
* const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
|
|
10
|
+
*
|
|
11
|
+
* const action = parser(CancelRequest.entries.action)({ // for correct signature generation
|
|
12
|
+
* type: "cancel",
|
|
13
|
+
* cancels: [
|
|
14
|
+
* { a: 0, o: 12345 },
|
|
15
|
+
* ],
|
|
16
|
+
* });
|
|
17
|
+
* const nonce = Date.now();
|
|
18
|
+
*
|
|
19
|
+
* const signature = await signL1Action({ wallet: privateKey, action, nonce });
|
|
20
|
+
*
|
|
21
|
+
* // Send the signed action to the Hyperliquid API
|
|
22
|
+
* const response = await fetch("https://api.hyperliquid.xyz/exchange", {
|
|
23
|
+
* method: "POST",
|
|
24
|
+
* headers: { "Content-Type": "application/json" },
|
|
25
|
+
* body: JSON.stringify({ action, signature, nonce }),
|
|
26
|
+
* });
|
|
27
|
+
* const body = await response.json();
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example Signing a user-signed action
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { signUserSignedAction, userSignedActionEip712Types } from "@nktkas/hyperliquid/signing";
|
|
33
|
+
* import { ApproveAgentRequest, parser } from "@nktkas/hyperliquid/schemas";
|
|
34
|
+
*
|
|
35
|
+
* const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
|
|
36
|
+
*
|
|
37
|
+
* const action = parser(ApproveAgentRequest.entries.action)({ // for correct signature generation
|
|
38
|
+
* type: "approveAgent",
|
|
39
|
+
* signatureChainId: "0x66eee",
|
|
40
|
+
* hyperliquidChain: "Mainnet",
|
|
41
|
+
* agentAddress: "0x...",
|
|
42
|
+
* agentName: "Agent",
|
|
43
|
+
* nonce: Date.now(),
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* const signature = await signUserSignedAction({
|
|
47
|
+
* wallet: privateKey,
|
|
48
|
+
* action,
|
|
49
|
+
* types: userSignedActionEip712Types[action.type],
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* // Send the signed action to the Hyperliquid API
|
|
53
|
+
* const response = await fetch("https://api.hyperliquid.xyz/exchange", {
|
|
54
|
+
* method: "POST",
|
|
55
|
+
* headers: { "Content-Type": "application/json" },
|
|
56
|
+
* body: JSON.stringify({ action, signature, nonce: action.nonce }),
|
|
57
|
+
* });
|
|
58
|
+
* const body = await response.json();
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* @example Signing a multi-signature action
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { signL1Action, signMultiSigAction } from "@nktkas/hyperliquid/signing";
|
|
64
|
+
* import { MultiSigRequest, parser, ScheduleCancelRequest } from "@nktkas/hyperliquid/schemas";
|
|
65
|
+
* import { privateKeyToAccount } from "npm:viem/accounts";
|
|
66
|
+
*
|
|
67
|
+
* const wallet = privateKeyToAccount("0x..."); // or `ethers`, private key directly
|
|
68
|
+
* const multiSigUser = "0x...";
|
|
69
|
+
*
|
|
70
|
+
* const action = parser(ScheduleCancelRequest.entries.action)({ // for correct signature generation
|
|
71
|
+
* type: "scheduleCancel",
|
|
72
|
+
* time: Date.now() + 10000,
|
|
73
|
+
* });
|
|
74
|
+
* const nonce = Date.now();
|
|
75
|
+
*
|
|
76
|
+
* // Create the required number of signatures
|
|
77
|
+
* const signatures = await Promise.all(["0x...", "0x..."].map(async (signerPrivKey) => {
|
|
78
|
+
* return await signL1Action({
|
|
79
|
+
* wallet: signerPrivKey as `0x${string}`,
|
|
80
|
+
* action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), action],
|
|
81
|
+
* nonce,
|
|
82
|
+
* });
|
|
83
|
+
* }));
|
|
84
|
+
*
|
|
85
|
+
* // // or user-signed action
|
|
86
|
+
* // const signatures = await Promise.all(["0x...", "0x..."].map(async (signerPrivKey) => {
|
|
87
|
+
* // return await signUserSignedAction({
|
|
88
|
+
* // wallet: signerPrivKey as `0x${string}`,
|
|
89
|
+
* // action: {
|
|
90
|
+
* // ...action,
|
|
91
|
+
* // payloadMultiSigUser: multiSigUser,
|
|
92
|
+
* // outerSigner: wallet.address,
|
|
93
|
+
* // },
|
|
94
|
+
* // types: userSignedActionEip712Types[action.type],
|
|
95
|
+
* // });
|
|
96
|
+
* // }));
|
|
97
|
+
*
|
|
98
|
+
* // Then use signatures in the multi-sig action
|
|
99
|
+
* const multiSigAction = parser(MultiSigRequest.entries.action)({
|
|
100
|
+
* type: "multiSig",
|
|
101
|
+
* signatureChainId: "0x66eee",
|
|
102
|
+
* signatures,
|
|
103
|
+
* payload: {
|
|
104
|
+
* multiSigUser,
|
|
105
|
+
* outerSigner: wallet.address,
|
|
106
|
+
* action,
|
|
107
|
+
* },
|
|
108
|
+
* });
|
|
109
|
+
* const multiSigSignature = await signMultiSigAction({ wallet, action: multiSigAction, nonce });
|
|
110
|
+
*
|
|
111
|
+
* // Send the multi-sig action to the Hyperliquid API
|
|
112
|
+
* const response = await fetch("https://api.hyperliquid.xyz/exchange", {
|
|
113
|
+
* method: "POST",
|
|
114
|
+
* headers: { "Content-Type": "application/json" },
|
|
115
|
+
* body: JSON.stringify({ action: multiSigAction, signature: multiSigSignature, nonce }),
|
|
116
|
+
* });
|
|
117
|
+
* const body = await response.json();
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* @module
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
import { keccak_256 } from "@noble/hashes/sha3";
|
|
124
|
+
import { etc } from "@noble/secp256k1";
|
|
125
|
+
import { encode as encodeMsgpack } from "@msgpack/msgpack";
|
|
126
|
+
import {
|
|
127
|
+
type AbstractWallet,
|
|
128
|
+
getWalletAddress,
|
|
129
|
+
getWalletChainId,
|
|
130
|
+
type Signature,
|
|
131
|
+
signTypedData,
|
|
132
|
+
} from "./_signTypedData/mod.js";
|
|
133
|
+
|
|
134
|
+
export { type AbstractWallet, getWalletAddress, getWalletChainId, type Signature };
|
|
135
|
+
|
|
136
|
+
/** EIP-712 type definitions for user-signed actions. */
|
|
137
|
+
export const userSignedActionEip712Types = {
|
|
138
|
+
approveAgent: {
|
|
139
|
+
"HyperliquidTransaction:ApproveAgent": [
|
|
140
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
141
|
+
{ name: "agentAddress", type: "address" },
|
|
142
|
+
{ name: "agentName", type: "string" },
|
|
143
|
+
{ name: "nonce", type: "uint64" },
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
approveBuilderFee: {
|
|
147
|
+
"HyperliquidTransaction:ApproveBuilderFee": [
|
|
148
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
149
|
+
{ name: "maxFeeRate", type: "string" },
|
|
150
|
+
{ name: "builder", type: "address" },
|
|
151
|
+
{ name: "nonce", type: "uint64" },
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
cDeposit: {
|
|
155
|
+
"HyperliquidTransaction:CDeposit": [
|
|
156
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
157
|
+
{ name: "wei", type: "uint64" },
|
|
158
|
+
{ name: "nonce", type: "uint64" },
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
convertToMultiSigUser: {
|
|
162
|
+
"HyperliquidTransaction:ConvertToMultiSigUser": [
|
|
163
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
164
|
+
{ name: "signers", type: "string" },
|
|
165
|
+
{ name: "nonce", type: "uint64" },
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
cWithdraw: {
|
|
169
|
+
"HyperliquidTransaction:CWithdraw": [
|
|
170
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
171
|
+
{ name: "wei", type: "uint64" },
|
|
172
|
+
{ name: "nonce", type: "uint64" },
|
|
173
|
+
],
|
|
174
|
+
},
|
|
175
|
+
multiSig: {
|
|
176
|
+
"HyperliquidTransaction:SendMultiSig": [
|
|
177
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
178
|
+
{ name: "multiSigActionHash", type: "bytes32" },
|
|
179
|
+
{ name: "nonce", type: "uint64" },
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
sendAsset: {
|
|
183
|
+
"HyperliquidTransaction:SendAsset": [
|
|
184
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
185
|
+
{ name: "destination", type: "string" },
|
|
186
|
+
{ name: "sourceDex", type: "string" },
|
|
187
|
+
{ name: "destinationDex", type: "string" },
|
|
188
|
+
{ name: "token", type: "string" },
|
|
189
|
+
{ name: "amount", type: "string" },
|
|
190
|
+
{ name: "fromSubAccount", type: "string" },
|
|
191
|
+
{ name: "nonce", type: "uint64" },
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
spotSend: {
|
|
195
|
+
"HyperliquidTransaction:SpotSend": [
|
|
196
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
197
|
+
{ name: "destination", type: "string" },
|
|
198
|
+
{ name: "token", type: "string" },
|
|
199
|
+
{ name: "amount", type: "string" },
|
|
200
|
+
{ name: "time", type: "uint64" },
|
|
201
|
+
],
|
|
202
|
+
},
|
|
203
|
+
tokenDelegate: {
|
|
204
|
+
"HyperliquidTransaction:TokenDelegate": [
|
|
205
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
206
|
+
{ name: "validator", type: "address" },
|
|
207
|
+
{ name: "wei", type: "uint64" },
|
|
208
|
+
{ name: "isUndelegate", type: "bool" },
|
|
209
|
+
{ name: "nonce", type: "uint64" },
|
|
210
|
+
],
|
|
211
|
+
},
|
|
212
|
+
usdClassTransfer: {
|
|
213
|
+
"HyperliquidTransaction:UsdClassTransfer": [
|
|
214
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
215
|
+
{ name: "amount", type: "string" },
|
|
216
|
+
{ name: "toPerp", type: "bool" },
|
|
217
|
+
{ name: "nonce", type: "uint64" },
|
|
218
|
+
],
|
|
219
|
+
},
|
|
220
|
+
usdSend: {
|
|
221
|
+
"HyperliquidTransaction:UsdSend": [
|
|
222
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
223
|
+
{ name: "destination", type: "string" },
|
|
224
|
+
{ name: "amount", type: "string" },
|
|
225
|
+
{ name: "time", type: "uint64" },
|
|
226
|
+
],
|
|
227
|
+
},
|
|
228
|
+
withdraw3: {
|
|
229
|
+
"HyperliquidTransaction:Withdraw": [
|
|
230
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
231
|
+
{ name: "destination", type: "string" },
|
|
232
|
+
{ name: "amount", type: "string" },
|
|
233
|
+
{ name: "time", type: "uint64" },
|
|
234
|
+
],
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Create a hash of the L1 action.
|
|
240
|
+
* @example
|
|
241
|
+
* ```ts
|
|
242
|
+
* import { signL1Action } from "@nktkas/hyperliquid/signing";
|
|
243
|
+
* import { CancelRequest, parser } from "@nktkas/hyperliquid/schemas";
|
|
244
|
+
*
|
|
245
|
+
* const action = parser(CancelRequest.entries.action)({ // for correct signature generation
|
|
246
|
+
* type: "cancel",
|
|
247
|
+
* cancels: [
|
|
248
|
+
* { a: 0, o: 12345 },
|
|
249
|
+
* ],
|
|
250
|
+
* });
|
|
251
|
+
* const nonce = Date.now();
|
|
252
|
+
*
|
|
253
|
+
* const actionHash = createL1ActionHash({ action, nonce });
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
256
|
+
export function createL1ActionHash(args: {
|
|
257
|
+
/** The action to be hashed (hash depends on key order). */
|
|
258
|
+
action: Record<string, unknown> | unknown[];
|
|
259
|
+
/** The current timestamp in ms. */
|
|
260
|
+
nonce: number;
|
|
261
|
+
/** Optional vault address used in the action. */
|
|
262
|
+
vaultAddress?: `0x${string}`;
|
|
263
|
+
/** Optional expiration time of the action in ms since the epoch. */
|
|
264
|
+
expiresAfter?: number;
|
|
265
|
+
}): `0x${string}` {
|
|
266
|
+
const { action, nonce, vaultAddress, expiresAfter } = args;
|
|
267
|
+
|
|
268
|
+
// 1. Action
|
|
269
|
+
const actionBytes = encodeMsgpack(action);
|
|
270
|
+
|
|
271
|
+
// 2. Nonce
|
|
272
|
+
const nonceBytes = toUint64Bytes(nonce);
|
|
273
|
+
|
|
274
|
+
// 3. Vault address
|
|
275
|
+
const vaultMarker = vaultAddress ? new Uint8Array([1]) : new Uint8Array([0]);
|
|
276
|
+
const vaultBytes = vaultAddress ? etc.hexToBytes(vaultAddress.slice(2)) : new Uint8Array();
|
|
277
|
+
|
|
278
|
+
// 4. Expires after
|
|
279
|
+
const expiresMarker = expiresAfter !== undefined ? new Uint8Array([0]) : new Uint8Array();
|
|
280
|
+
const expiresBytes = expiresAfter !== undefined ? toUint64Bytes(expiresAfter) : new Uint8Array();
|
|
281
|
+
|
|
282
|
+
// Create a hash
|
|
283
|
+
const bytes = etc.concatBytes(
|
|
284
|
+
actionBytes,
|
|
285
|
+
nonceBytes,
|
|
286
|
+
vaultMarker,
|
|
287
|
+
vaultBytes,
|
|
288
|
+
expiresMarker,
|
|
289
|
+
expiresBytes,
|
|
290
|
+
);
|
|
291
|
+
const hash = keccak_256(bytes);
|
|
292
|
+
return `0x${etc.bytesToHex(hash)}`;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function toUint64Bytes(n: bigint | number | string): Uint8Array {
|
|
296
|
+
const bytes = new Uint8Array(8);
|
|
297
|
+
new DataView(bytes.buffer).setBigUint64(0, BigInt(n));
|
|
298
|
+
return bytes;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Sign an L1 action.
|
|
303
|
+
* @example
|
|
304
|
+
* ```ts
|
|
305
|
+
* import { signL1Action } from "@nktkas/hyperliquid/signing";
|
|
306
|
+
* import { CancelRequest, parser } from "@nktkas/hyperliquid/schemas";
|
|
307
|
+
*
|
|
308
|
+
* const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
|
|
309
|
+
*
|
|
310
|
+
* const action = parser(CancelRequest.entries.action)({ // for correct signature generation
|
|
311
|
+
* type: "cancel",
|
|
312
|
+
* cancels: [
|
|
313
|
+
* { a: 0, o: 12345 },
|
|
314
|
+
* ],
|
|
315
|
+
* });
|
|
316
|
+
* const nonce = Date.now();
|
|
317
|
+
*
|
|
318
|
+
* const signature = await signL1Action({ wallet: privateKey, action, nonce });
|
|
319
|
+
*
|
|
320
|
+
* // Send the signed action to the Hyperliquid API
|
|
321
|
+
* const response = await fetch("https://api.hyperliquid.xyz/exchange", {
|
|
322
|
+
* method: "POST",
|
|
323
|
+
* headers: { "Content-Type": "application/json" },
|
|
324
|
+
* body: JSON.stringify({ action, signature, nonce }),
|
|
325
|
+
* });
|
|
326
|
+
* const body = await response.json();
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
329
|
+
export async function signL1Action(args: {
|
|
330
|
+
/** Wallet to sign the action. */
|
|
331
|
+
wallet: AbstractWallet;
|
|
332
|
+
/** The action to be signed (hash depends on key order). */
|
|
333
|
+
action: Record<string, unknown> | unknown[];
|
|
334
|
+
/** The current timestamp in ms. */
|
|
335
|
+
nonce: number;
|
|
336
|
+
/** Indicates if the action is for the testnet. (default: false) */
|
|
337
|
+
isTestnet?: boolean;
|
|
338
|
+
/** Optional vault address used in the action. */
|
|
339
|
+
vaultAddress?: `0x${string}`;
|
|
340
|
+
/** Optional expiration time of the action in ms since the epoch. */
|
|
341
|
+
expiresAfter?: number;
|
|
342
|
+
}): Promise<Signature> {
|
|
343
|
+
const {
|
|
344
|
+
wallet,
|
|
345
|
+
action,
|
|
346
|
+
nonce,
|
|
347
|
+
isTestnet = false,
|
|
348
|
+
vaultAddress,
|
|
349
|
+
expiresAfter,
|
|
350
|
+
} = args;
|
|
351
|
+
|
|
352
|
+
const actionHash = createL1ActionHash({ action, nonce, vaultAddress, expiresAfter });
|
|
353
|
+
const message = {
|
|
354
|
+
source: isTestnet ? "b" : "a",
|
|
355
|
+
connectionId: actionHash,
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
return await signTypedData({
|
|
359
|
+
wallet,
|
|
360
|
+
domain: {
|
|
361
|
+
name: "Exchange",
|
|
362
|
+
version: "1",
|
|
363
|
+
chainId: 1337, // hyperliquid requires chainId to be 1337
|
|
364
|
+
verifyingContract: "0x0000000000000000000000000000000000000000",
|
|
365
|
+
},
|
|
366
|
+
types: {
|
|
367
|
+
Agent: [
|
|
368
|
+
{ name: "source", type: "string" },
|
|
369
|
+
{ name: "connectionId", type: "bytes32" },
|
|
370
|
+
],
|
|
371
|
+
},
|
|
372
|
+
primaryType: "Agent",
|
|
373
|
+
message,
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Sign a user-signed action.
|
|
379
|
+
* @example
|
|
380
|
+
* ```ts
|
|
381
|
+
* import { signUserSignedAction, userSignedActionEip712Types } from "@nktkas/hyperliquid/signing";
|
|
382
|
+
* import { ApproveAgentRequest, parser } from "@nktkas/hyperliquid/schemas";
|
|
383
|
+
*
|
|
384
|
+
* const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
|
|
385
|
+
*
|
|
386
|
+
* const action = parser(ApproveAgentRequest.entries.action)({ // for correct signature generation
|
|
387
|
+
* type: "approveAgent",
|
|
388
|
+
* signatureChainId: "0x66eee",
|
|
389
|
+
* hyperliquidChain: "Mainnet",
|
|
390
|
+
* agentAddress: "0x...",
|
|
391
|
+
* agentName: "Agent",
|
|
392
|
+
* nonce: Date.now(),
|
|
393
|
+
* });
|
|
394
|
+
*
|
|
395
|
+
* const signature = await signUserSignedAction({
|
|
396
|
+
* wallet: privateKey,
|
|
397
|
+
* action,
|
|
398
|
+
* types: userSignedActionEip712Types[action.type],
|
|
399
|
+
* });
|
|
400
|
+
*
|
|
401
|
+
* // Send the signed action to the Hyperliquid API
|
|
402
|
+
* const response = await fetch("https://api.hyperliquid.xyz/exchange", {
|
|
403
|
+
* method: "POST",
|
|
404
|
+
* headers: { "Content-Type": "application/json" },
|
|
405
|
+
* body: JSON.stringify({ action, signature, nonce: action.nonce }),
|
|
406
|
+
* });
|
|
407
|
+
* const body = await response.json();
|
|
408
|
+
* ```
|
|
409
|
+
*/
|
|
410
|
+
export async function signUserSignedAction(args: {
|
|
411
|
+
/** Wallet to sign the action. */
|
|
412
|
+
wallet: AbstractWallet;
|
|
413
|
+
/** The action to be signed (hex strings must be in lower case). */
|
|
414
|
+
action:
|
|
415
|
+
& {
|
|
416
|
+
signatureChainId: `0x${string}`;
|
|
417
|
+
[key: string]: unknown;
|
|
418
|
+
}
|
|
419
|
+
// special case for multi-sign payload
|
|
420
|
+
& (
|
|
421
|
+
| { payloadMultiSigUser: `0x${string}`; outerSigner: `0x${string}` }
|
|
422
|
+
| { payloadMultiSigUser?: undefined; outerSigner?: undefined }
|
|
423
|
+
);
|
|
424
|
+
/** The types of the action (hash depends on key order). */
|
|
425
|
+
types: {
|
|
426
|
+
[key: string]: {
|
|
427
|
+
name: string;
|
|
428
|
+
type: string;
|
|
429
|
+
}[];
|
|
430
|
+
};
|
|
431
|
+
}): Promise<Signature> {
|
|
432
|
+
let { wallet, action, types } = args;
|
|
433
|
+
|
|
434
|
+
if (action.type === "approveAgent" && !action.agentName) { // special case for `approveAgent`
|
|
435
|
+
action = { ...action, agentName: "" }; // set to empty string instead of null
|
|
436
|
+
}
|
|
437
|
+
if ("payloadMultiSigUser" in action && "outerSigner" in action) { // special case for multi-sign payload
|
|
438
|
+
types = structuredClone(types); // for safe mutation
|
|
439
|
+
Object.values(types)[0].splice( // array mutation
|
|
440
|
+
1, // after `hyperliquidChain`
|
|
441
|
+
0, // do not remove any elements
|
|
442
|
+
{ name: "payloadMultiSigUser", type: "address" },
|
|
443
|
+
{ name: "outerSigner", type: "address" },
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return await signTypedData({
|
|
448
|
+
wallet,
|
|
449
|
+
domain: {
|
|
450
|
+
name: "HyperliquidSignTransaction",
|
|
451
|
+
version: "1",
|
|
452
|
+
chainId: parseInt(action.signatureChainId),
|
|
453
|
+
verifyingContract: "0x0000000000000000000000000000000000000000",
|
|
454
|
+
},
|
|
455
|
+
types,
|
|
456
|
+
primaryType: Object.keys(types)[0],
|
|
457
|
+
message: action,
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Sign a multi-signature action.
|
|
463
|
+
* @example
|
|
464
|
+
* ```ts
|
|
465
|
+
* import { signL1Action, signMultiSigAction } from "@nktkas/hyperliquid/signing";
|
|
466
|
+
* import { MultiSigRequest, parser, ScheduleCancelRequest } from "@nktkas/hyperliquid/schemas";
|
|
467
|
+
* import { privateKeyToAccount } from "npm:viem/accounts";
|
|
468
|
+
*
|
|
469
|
+
* const wallet = privateKeyToAccount("0x..."); // or `ethers`, private key directly
|
|
470
|
+
* const multiSigUser = "0x...";
|
|
471
|
+
*
|
|
472
|
+
* const action = parser(ScheduleCancelRequest.entries.action)({ // for correct signature generation
|
|
473
|
+
* type: "scheduleCancel",
|
|
474
|
+
* time: Date.now() + 10000,
|
|
475
|
+
* });
|
|
476
|
+
* const nonce = Date.now();
|
|
477
|
+
*
|
|
478
|
+
* // Create the required number of signatures
|
|
479
|
+
* const signatures = await Promise.all(["0x...", "0x..."].map(async (signerPrivKey) => {
|
|
480
|
+
* return await signL1Action({
|
|
481
|
+
* wallet: signerPrivKey as `0x${string}`,
|
|
482
|
+
* action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), action],
|
|
483
|
+
* nonce,
|
|
484
|
+
* });
|
|
485
|
+
* }));
|
|
486
|
+
*
|
|
487
|
+
* // // or user-signed action
|
|
488
|
+
* // const signatures = await Promise.all(["0x...", "0x..."].map(async (signerPrivKey) => {
|
|
489
|
+
* // return await signUserSignedAction({
|
|
490
|
+
* // wallet: signerPrivKey as `0x${string}`,
|
|
491
|
+
* // action: {
|
|
492
|
+
* // ...action,
|
|
493
|
+
* // payloadMultiSigUser: multiSigUser,
|
|
494
|
+
* // outerSigner: wallet.address,
|
|
495
|
+
* // },
|
|
496
|
+
* // types: userSignedActionEip712Types[action.type],
|
|
497
|
+
* // });
|
|
498
|
+
* // }));
|
|
499
|
+
*
|
|
500
|
+
* // Then use signatures in the multi-sig action
|
|
501
|
+
* const multiSigAction = parser(MultiSigRequest.entries.action)({
|
|
502
|
+
* type: "multiSig",
|
|
503
|
+
* signatureChainId: "0x66eee",
|
|
504
|
+
* signatures,
|
|
505
|
+
* payload: {
|
|
506
|
+
* multiSigUser,
|
|
507
|
+
* outerSigner: wallet.address,
|
|
508
|
+
* action,
|
|
509
|
+
* },
|
|
510
|
+
* });
|
|
511
|
+
* const multiSigSignature = await signMultiSigAction({ wallet, action: multiSigAction, nonce });
|
|
512
|
+
*
|
|
513
|
+
* // Send the multi-sig action to the Hyperliquid API
|
|
514
|
+
* const response = await fetch("https://api.hyperliquid.xyz/exchange", {
|
|
515
|
+
* method: "POST",
|
|
516
|
+
* headers: { "Content-Type": "application/json" },
|
|
517
|
+
* body: JSON.stringify({ action: multiSigAction, signature: multiSigSignature, nonce }),
|
|
518
|
+
* });
|
|
519
|
+
* const body = await response.json();
|
|
520
|
+
* ```
|
|
521
|
+
*/
|
|
522
|
+
export async function signMultiSigAction(args: {
|
|
523
|
+
/** Wallet to sign the action. */
|
|
524
|
+
wallet: AbstractWallet;
|
|
525
|
+
/** The action to be signed (hash depends on key order). */
|
|
526
|
+
action: {
|
|
527
|
+
signatureChainId: `0x${string}`;
|
|
528
|
+
[key: string]: unknown;
|
|
529
|
+
};
|
|
530
|
+
/** The current timestamp in ms. */
|
|
531
|
+
nonce: number;
|
|
532
|
+
/** Indicates if the action is for the testnet. (default: false) */
|
|
533
|
+
isTestnet?: boolean;
|
|
534
|
+
/** Optional vault address used in the action. */
|
|
535
|
+
vaultAddress?: `0x${string}`;
|
|
536
|
+
/** Optional expiration time of the action in ms since the epoch. */
|
|
537
|
+
expiresAfter?: number;
|
|
538
|
+
}): Promise<Signature> {
|
|
539
|
+
let {
|
|
540
|
+
wallet,
|
|
541
|
+
action,
|
|
542
|
+
nonce,
|
|
543
|
+
isTestnet = false,
|
|
544
|
+
vaultAddress,
|
|
545
|
+
expiresAfter,
|
|
546
|
+
} = args;
|
|
547
|
+
|
|
548
|
+
if ("type" in action) {
|
|
549
|
+
action = structuredClone(action); // for safe mutation
|
|
550
|
+
delete action.type;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
const multiSigActionHash = createL1ActionHash({ action, nonce, vaultAddress, expiresAfter });
|
|
554
|
+
const message = {
|
|
555
|
+
hyperliquidChain: isTestnet ? "Testnet" : "Mainnet",
|
|
556
|
+
multiSigActionHash,
|
|
557
|
+
nonce,
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
return await signTypedData({
|
|
561
|
+
wallet,
|
|
562
|
+
domain: {
|
|
563
|
+
name: "HyperliquidSignTransaction",
|
|
564
|
+
version: "1",
|
|
565
|
+
chainId: parseInt(action.signatureChainId),
|
|
566
|
+
verifyingContract: "0x0000000000000000000000000000000000000000",
|
|
567
|
+
},
|
|
568
|
+
types: userSignedActionEip712Types.multiSig,
|
|
569
|
+
primaryType: Object.keys(userSignedActionEip712Types.multiSig)[0],
|
|
570
|
+
message,
|
|
571
|
+
});
|
|
572
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { HyperliquidError } from "../errors.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Interface representing a REST transport.
|
|
5
|
+
* Handles communication with Hyperliquid API endpoints.
|
|
6
|
+
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint | Info endpoint}
|
|
7
|
+
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint | Exchange endpoint}
|
|
8
|
+
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/post-requests | Websocket post requests}
|
|
9
|
+
*/
|
|
10
|
+
export interface IRequestTransport extends Partial<AsyncDisposable> {
|
|
11
|
+
/** Indicates this transport uses testnet endpoint(s). */
|
|
12
|
+
isTestnet: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Sends a request to the Hyperliquid API.
|
|
15
|
+
* @param endpoint - The API endpoint to send the request to.
|
|
16
|
+
* @param payload - The payload to send with the request.
|
|
17
|
+
* @param signal - An {@linkcode https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | AbortSignal}. If this option is set, the request can be canceled by calling {@linkcode https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort | abort()} on the corresponding {@linkcode https://developer.mozilla.org/en-US/docs/Web/API/AbortController | AbortController}.
|
|
18
|
+
* @returns A promise that resolves with parsed JSON response body.
|
|
19
|
+
*/
|
|
20
|
+
request<T>(endpoint: "info" | "exchange", payload: unknown, signal?: AbortSignal): Promise<T>;
|
|
21
|
+
request<T>(endpoint: "info" | "exchange" | "explorer", payload: unknown, signal?: AbortSignal): Promise<T>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Interface representing an event subscription transport.
|
|
26
|
+
* Handles WebSocket subscriptions for real-time updates.
|
|
27
|
+
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions | Websocket subscriptions}
|
|
28
|
+
*/
|
|
29
|
+
export interface ISubscriptionTransport extends Partial<AsyncDisposable> {
|
|
30
|
+
/**
|
|
31
|
+
* Subscribes to a Hyperliquid event channel.
|
|
32
|
+
* @param channel - The event channel to listen to.
|
|
33
|
+
* @param payload - The payload to send with the subscription request.
|
|
34
|
+
* @param listener - The function to call when the event is dispatched.
|
|
35
|
+
* @returns A promise that resolves with a {@link Subscription} object to manage the subscription lifecycle.
|
|
36
|
+
*/
|
|
37
|
+
subscribe<T>(channel: string, payload: unknown, listener: (data: CustomEvent<T>) => void): Promise<Subscription>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Controls event subscription lifecycle. */
|
|
41
|
+
export interface Subscription {
|
|
42
|
+
/** Unsubscribes from the event and sends an unsubscribe request to the server. */
|
|
43
|
+
unsubscribe(): Promise<void>;
|
|
44
|
+
/** Signal that aborts when resubscription fails during reconnection. */
|
|
45
|
+
resubscribeSignal?: AbortSignal;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Thrown when a transport error occurs. */
|
|
49
|
+
export class TransportError extends HyperliquidError {
|
|
50
|
+
constructor(message?: string, options?: ErrorOptions) {
|
|
51
|
+
super(message, options);
|
|
52
|
+
this.name = "TransportError";
|
|
53
|
+
}
|
|
54
|
+
}
|