@h2protocol/v4-client-js 1.3.17-h2.1

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.
Files changed (456) hide show
  1. package/.env +1 -0
  2. package/.eslintignore +2 -0
  3. package/.eslintrc.js +15 -0
  4. package/.gitleaks.toml +24 -0
  5. package/.gitleaksignore +1 -0
  6. package/.nvmrc +1 -0
  7. package/.prettierignore +3 -0
  8. package/.prettierrc.json +6 -0
  9. package/.releaserc +10 -0
  10. package/.vscode/launch.json +11 -0
  11. package/LICENSE +13 -0
  12. package/README.md +83 -0
  13. package/__native__/__ios__/v4-native-client.js +235529 -0
  14. package/__tests__/clients/composite-client.test.ts +140 -0
  15. package/__tests__/helpers/baseClients.ts +23 -0
  16. package/__tests__/helpers/constants.ts +130 -0
  17. package/__tests__/lib/helpers.test.ts +53 -0
  18. package/__tests__/lib/util.test.ts +77 -0
  19. package/__tests__/lib/validation.test.ts +289 -0
  20. package/__tests__/modules/client/AccountEndpoints.test.ts +236 -0
  21. package/__tests__/modules/client/FaucetEndpoint.test.ts +14 -0
  22. package/__tests__/modules/client/MarketsEndpoints.test.ts +84 -0
  23. package/__tests__/modules/client/Transfers.test.ts +44 -0
  24. package/__tests__/modules/client/UtilityEndpoints.test.ts +29 -0
  25. package/__tests__/modules/client/ValidatorGetEndpoints.test.ts +50 -0
  26. package/__tests__/modules/client/ValidatorPostEndpoints.test.ts +52 -0
  27. package/__tests__/modules/client/constants.ts +5 -0
  28. package/__tests__/modules/onboarding.test.ts +66 -0
  29. package/build/cjs/__tests__/clients/composite-client.test.js +130 -0
  30. package/build/cjs/__tests__/helpers/baseClients.js +29 -0
  31. package/build/cjs/__tests__/helpers/constants.js +110 -0
  32. package/build/cjs/__tests__/lib/helpers.test.js +45 -0
  33. package/build/cjs/__tests__/lib/util.test.js +67 -0
  34. package/build/cjs/__tests__/lib/validation.test.js +254 -0
  35. package/build/cjs/__tests__/modules/client/AccountEndpoints.test.js +171 -0
  36. package/build/cjs/__tests__/modules/client/FaucetEndpoint.test.js +15 -0
  37. package/build/cjs/__tests__/modules/client/MarketsEndpoints.test.js +69 -0
  38. package/build/cjs/__tests__/modules/client/Transfers.test.js +44 -0
  39. package/build/cjs/__tests__/modules/client/UtilityEndpoints.test.js +28 -0
  40. package/build/cjs/__tests__/modules/client/ValidatorGetEndpoints.test.js +46 -0
  41. package/build/cjs/__tests__/modules/client/ValidatorPostEndpoints.test.js +53 -0
  42. package/build/cjs/__tests__/modules/client/constants.js +7 -0
  43. package/build/cjs/__tests__/modules/onboarding.test.js +50 -0
  44. package/build/cjs/examples/account_endpoints.js +129 -0
  45. package/build/cjs/examples/batch_cancel_orders_example.js +93 -0
  46. package/build/cjs/examples/composite_example.js +50 -0
  47. package/build/cjs/examples/constants.js +35 -0
  48. package/build/cjs/examples/faucet_endpoint.js +23 -0
  49. package/build/cjs/examples/gov_add_new_market.js +77 -0
  50. package/build/cjs/examples/human_readable_orders.json +86 -0
  51. package/build/cjs/examples/human_readable_short_term_orders.json +42 -0
  52. package/build/cjs/examples/json-encoding.js +32 -0
  53. package/build/cjs/examples/long_term_order_cancel_example.js +63 -0
  54. package/build/cjs/examples/markets_endpoints.js +134 -0
  55. package/build/cjs/examples/native_examples.js +112 -0
  56. package/build/cjs/examples/noble_example.js +88 -0
  57. package/build/cjs/examples/optimal_node.js +70 -0
  58. package/build/cjs/examples/permissioned_keys_example.js +104 -0
  59. package/build/cjs/examples/raw_orders.json +130 -0
  60. package/build/cjs/examples/short_term_order_cancel_example.js +54 -0
  61. package/build/cjs/examples/short_term_order_composite_example.js +68 -0
  62. package/build/cjs/examples/test.js +50 -0
  63. package/build/cjs/examples/transfer_example_deposit.js +29 -0
  64. package/build/cjs/examples/transfer_example_send.js +42 -0
  65. package/build/cjs/examples/transfer_example_subaccount_transfer.js +29 -0
  66. package/build/cjs/examples/transfer_example_withdraw.js +30 -0
  67. package/build/cjs/examples/transfer_example_withdraw_other.js +42 -0
  68. package/build/cjs/examples/utility_endpoints.js +42 -0
  69. package/build/cjs/examples/validator_get_example.js +158 -0
  70. package/build/cjs/examples/validator_post_example.js +76 -0
  71. package/build/cjs/examples/wallet_address.js +22 -0
  72. package/build/cjs/examples/websocket_example.js +36 -0
  73. package/build/cjs/examples/websocket_orderbook_example.js +196 -0
  74. package/build/cjs/package.json +1 -0
  75. package/build/cjs/src/clients/composite-client.js +788 -0
  76. package/build/cjs/src/clients/constants.js +303 -0
  77. package/build/cjs/src/clients/faucet-client.js +36 -0
  78. package/build/cjs/src/clients/helpers/chain-helpers.js +178 -0
  79. package/build/cjs/src/clients/helpers/request-helpers.js +65 -0
  80. package/build/cjs/src/clients/indexer-client.js +56 -0
  81. package/build/cjs/src/clients/lib/axios/axiosRequest.js +34 -0
  82. package/build/cjs/src/clients/lib/axios/errors.js +28 -0
  83. package/build/cjs/src/clients/lib/axios/index.js +23 -0
  84. package/build/cjs/src/clients/lib/axios/types.js +11 -0
  85. package/build/cjs/src/clients/lib/cctpProto.js +3242 -0
  86. package/build/cjs/src/clients/lib/errors.js +58 -0
  87. package/build/cjs/src/clients/lib/registry.js +51 -0
  88. package/build/cjs/src/clients/modules/account.js +223 -0
  89. package/build/cjs/src/clients/modules/composer.js +405 -0
  90. package/build/cjs/src/clients/modules/get.js +403 -0
  91. package/build/cjs/src/clients/modules/local-wallet.js +59 -0
  92. package/build/cjs/src/clients/modules/markets.js +54 -0
  93. package/build/cjs/src/clients/modules/post.js +391 -0
  94. package/build/cjs/src/clients/modules/proto-includes.js +69 -0
  95. package/build/cjs/src/clients/modules/rest.js +33 -0
  96. package/build/cjs/src/clients/modules/signer.js +93 -0
  97. package/build/cjs/src/clients/modules/tendermintClient.js +137 -0
  98. package/build/cjs/src/clients/modules/utility.js +44 -0
  99. package/build/cjs/src/clients/modules/vault.js +25 -0
  100. package/build/cjs/src/clients/native.js +1280 -0
  101. package/build/cjs/src/clients/noble-client.js +75 -0
  102. package/build/cjs/src/clients/socket-client.js +301 -0
  103. package/build/cjs/src/clients/subaccount.js +33 -0
  104. package/build/cjs/src/clients/types.js +43 -0
  105. package/build/cjs/src/clients/validator-client.js +81 -0
  106. package/build/cjs/src/index.js +73 -0
  107. package/build/cjs/src/lib/constants.js +23 -0
  108. package/build/cjs/src/lib/errors.js +37 -0
  109. package/build/cjs/src/lib/helpers.js +98 -0
  110. package/build/cjs/src/lib/onboarding.js +75 -0
  111. package/build/cjs/src/lib/trading-key-utils.js +108 -0
  112. package/build/cjs/src/lib/utils.js +79 -0
  113. package/build/cjs/src/lib/validation.js +150 -0
  114. package/build/cjs/src/network_optimizer.js +96 -0
  115. package/build/cjs/src/types.js +25 -0
  116. package/build/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  117. package/build/esm/__tests__/clients/composite-client.test.d.ts +2 -0
  118. package/build/esm/__tests__/clients/composite-client.test.d.ts.map +1 -0
  119. package/build/esm/__tests__/clients/composite-client.test.js +128 -0
  120. package/build/esm/__tests__/helpers/baseClients.d.ts +19 -0
  121. package/build/esm/__tests__/helpers/baseClients.d.ts.map +1 -0
  122. package/build/esm/__tests__/helpers/baseClients.js +22 -0
  123. package/build/esm/__tests__/helpers/constants.d.ts +19 -0
  124. package/build/esm/__tests__/helpers/constants.d.ts.map +1 -0
  125. package/build/esm/__tests__/helpers/constants.js +104 -0
  126. package/build/esm/__tests__/lib/helpers.test.d.ts +2 -0
  127. package/build/esm/__tests__/lib/helpers.test.d.ts.map +1 -0
  128. package/build/esm/__tests__/lib/helpers.test.js +40 -0
  129. package/build/esm/__tests__/lib/util.test.d.ts +2 -0
  130. package/build/esm/__tests__/lib/util.test.d.ts.map +1 -0
  131. package/build/esm/__tests__/lib/util.test.js +65 -0
  132. package/build/esm/__tests__/lib/validation.test.d.ts +2 -0
  133. package/build/esm/__tests__/lib/validation.test.d.ts.map +1 -0
  134. package/build/esm/__tests__/lib/validation.test.js +249 -0
  135. package/build/esm/__tests__/modules/client/AccountEndpoints.test.d.ts +2 -0
  136. package/build/esm/__tests__/modules/client/AccountEndpoints.test.d.ts.map +1 -0
  137. package/build/esm/__tests__/modules/client/AccountEndpoints.test.js +169 -0
  138. package/build/esm/__tests__/modules/client/FaucetEndpoint.test.d.ts +2 -0
  139. package/build/esm/__tests__/modules/client/FaucetEndpoint.test.d.ts.map +1 -0
  140. package/build/esm/__tests__/modules/client/FaucetEndpoint.test.js +13 -0
  141. package/build/esm/__tests__/modules/client/MarketsEndpoints.test.d.ts +2 -0
  142. package/build/esm/__tests__/modules/client/MarketsEndpoints.test.d.ts.map +1 -0
  143. package/build/esm/__tests__/modules/client/MarketsEndpoints.test.js +66 -0
  144. package/build/esm/__tests__/modules/client/Transfers.test.d.ts +2 -0
  145. package/build/esm/__tests__/modules/client/Transfers.test.d.ts.map +1 -0
  146. package/build/esm/__tests__/modules/client/Transfers.test.js +39 -0
  147. package/build/esm/__tests__/modules/client/UtilityEndpoints.test.d.ts +2 -0
  148. package/build/esm/__tests__/modules/client/UtilityEndpoints.test.d.ts.map +1 -0
  149. package/build/esm/__tests__/modules/client/UtilityEndpoints.test.js +26 -0
  150. package/build/esm/__tests__/modules/client/ValidatorGetEndpoints.test.d.ts +2 -0
  151. package/build/esm/__tests__/modules/client/ValidatorGetEndpoints.test.d.ts.map +1 -0
  152. package/build/esm/__tests__/modules/client/ValidatorGetEndpoints.test.js +44 -0
  153. package/build/esm/__tests__/modules/client/ValidatorPostEndpoints.test.d.ts +2 -0
  154. package/build/esm/__tests__/modules/client/ValidatorPostEndpoints.test.d.ts.map +1 -0
  155. package/build/esm/__tests__/modules/client/ValidatorPostEndpoints.test.js +48 -0
  156. package/build/esm/__tests__/modules/client/constants.d.ts +4 -0
  157. package/build/esm/__tests__/modules/client/constants.d.ts.map +1 -0
  158. package/build/esm/__tests__/modules/client/constants.js +4 -0
  159. package/build/esm/__tests__/modules/onboarding.test.d.ts +2 -0
  160. package/build/esm/__tests__/modules/onboarding.test.d.ts.map +1 -0
  161. package/build/esm/__tests__/modules/onboarding.test.js +48 -0
  162. package/build/esm/examples/account_endpoints.d.ts +5 -0
  163. package/build/esm/examples/account_endpoints.d.ts.map +1 -0
  164. package/build/esm/examples/account_endpoints.js +127 -0
  165. package/build/esm/examples/batch_cancel_orders_example.d.ts +2 -0
  166. package/build/esm/examples/batch_cancel_orders_example.d.ts.map +1 -0
  167. package/build/esm/examples/batch_cancel_orders_example.js +88 -0
  168. package/build/esm/examples/composite_example.d.ts +2 -0
  169. package/build/esm/examples/composite_example.d.ts.map +1 -0
  170. package/build/esm/examples/composite_example.js +45 -0
  171. package/build/esm/examples/constants.d.ts +13 -0
  172. package/build/esm/examples/constants.d.ts.map +1 -0
  173. package/build/esm/examples/constants.js +29 -0
  174. package/build/esm/examples/faucet_endpoint.d.ts +5 -0
  175. package/build/esm/examples/faucet_endpoint.d.ts.map +1 -0
  176. package/build/esm/examples/faucet_endpoint.js +21 -0
  177. package/build/esm/examples/gov_add_new_market.d.ts +2 -0
  178. package/build/esm/examples/gov_add_new_market.d.ts.map +1 -0
  179. package/build/esm/examples/gov_add_new_market.js +72 -0
  180. package/build/esm/examples/human_readable_orders.json +86 -0
  181. package/build/esm/examples/human_readable_short_term_orders.json +42 -0
  182. package/build/esm/examples/json-encoding.d.ts +2 -0
  183. package/build/esm/examples/json-encoding.d.ts.map +1 -0
  184. package/build/esm/examples/json-encoding.js +27 -0
  185. package/build/esm/examples/long_term_order_cancel_example.d.ts +2 -0
  186. package/build/esm/examples/long_term_order_cancel_example.d.ts.map +1 -0
  187. package/build/esm/examples/long_term_order_cancel_example.js +58 -0
  188. package/build/esm/examples/markets_endpoints.d.ts +5 -0
  189. package/build/esm/examples/markets_endpoints.d.ts.map +1 -0
  190. package/build/esm/examples/markets_endpoints.js +131 -0
  191. package/build/esm/examples/native_examples.d.ts +2 -0
  192. package/build/esm/examples/native_examples.d.ts.map +1 -0
  193. package/build/esm/examples/native_examples.js +110 -0
  194. package/build/esm/examples/noble_example.d.ts +2 -0
  195. package/build/esm/examples/noble_example.d.ts.map +1 -0
  196. package/build/esm/examples/noble_example.js +83 -0
  197. package/build/esm/examples/optimal_node.d.ts +2 -0
  198. package/build/esm/examples/optimal_node.d.ts.map +1 -0
  199. package/build/esm/examples/optimal_node.js +68 -0
  200. package/build/esm/examples/permissioned_keys_example.d.ts +2 -0
  201. package/build/esm/examples/permissioned_keys_example.d.ts.map +1 -0
  202. package/build/esm/examples/permissioned_keys_example.js +99 -0
  203. package/build/esm/examples/raw_orders.json +130 -0
  204. package/build/esm/examples/short_term_order_cancel_example.d.ts +2 -0
  205. package/build/esm/examples/short_term_order_cancel_example.d.ts.map +1 -0
  206. package/build/esm/examples/short_term_order_cancel_example.js +49 -0
  207. package/build/esm/examples/short_term_order_composite_example.d.ts +2 -0
  208. package/build/esm/examples/short_term_order_composite_example.d.ts.map +1 -0
  209. package/build/esm/examples/short_term_order_composite_example.js +63 -0
  210. package/build/esm/examples/test.d.ts +2 -0
  211. package/build/esm/examples/test.d.ts.map +1 -0
  212. package/build/esm/examples/test.js +45 -0
  213. package/build/esm/examples/transfer_example_deposit.d.ts +2 -0
  214. package/build/esm/examples/transfer_example_deposit.d.ts.map +1 -0
  215. package/build/esm/examples/transfer_example_deposit.js +24 -0
  216. package/build/esm/examples/transfer_example_send.d.ts +2 -0
  217. package/build/esm/examples/transfer_example_send.d.ts.map +1 -0
  218. package/build/esm/examples/transfer_example_send.js +37 -0
  219. package/build/esm/examples/transfer_example_subaccount_transfer.d.ts +2 -0
  220. package/build/esm/examples/transfer_example_subaccount_transfer.d.ts.map +1 -0
  221. package/build/esm/examples/transfer_example_subaccount_transfer.js +24 -0
  222. package/build/esm/examples/transfer_example_withdraw.d.ts +2 -0
  223. package/build/esm/examples/transfer_example_withdraw.d.ts.map +1 -0
  224. package/build/esm/examples/transfer_example_withdraw.js +25 -0
  225. package/build/esm/examples/transfer_example_withdraw_other.d.ts +2 -0
  226. package/build/esm/examples/transfer_example_withdraw_other.d.ts.map +1 -0
  227. package/build/esm/examples/transfer_example_withdraw_other.js +37 -0
  228. package/build/esm/examples/utility_endpoints.d.ts +5 -0
  229. package/build/esm/examples/utility_endpoints.d.ts.map +1 -0
  230. package/build/esm/examples/utility_endpoints.js +40 -0
  231. package/build/esm/examples/validator_get_example.d.ts +2 -0
  232. package/build/esm/examples/validator_get_example.d.ts.map +1 -0
  233. package/build/esm/examples/validator_get_example.js +156 -0
  234. package/build/esm/examples/validator_post_example.d.ts +2 -0
  235. package/build/esm/examples/validator_post_example.d.ts.map +1 -0
  236. package/build/esm/examples/validator_post_example.js +71 -0
  237. package/build/esm/examples/wallet_address.d.ts +2 -0
  238. package/build/esm/examples/wallet_address.d.ts.map +1 -0
  239. package/build/esm/examples/wallet_address.js +17 -0
  240. package/build/esm/examples/websocket_example.d.ts +2 -0
  241. package/build/esm/examples/websocket_example.d.ts.map +1 -0
  242. package/build/esm/examples/websocket_example.js +34 -0
  243. package/build/esm/examples/websocket_orderbook_example.d.ts +2 -0
  244. package/build/esm/examples/websocket_orderbook_example.d.ts.map +1 -0
  245. package/build/esm/examples/websocket_orderbook_example.js +194 -0
  246. package/build/esm/src/clients/composite-client.d.ts +403 -0
  247. package/build/esm/src/clients/composite-client.d.ts.map +1 -0
  248. package/build/esm/src/clients/composite-client.js +781 -0
  249. package/build/esm/src/clients/constants.d.ts +172 -0
  250. package/build/esm/src/clients/constants.d.ts.map +1 -0
  251. package/build/esm/src/clients/constants.js +279 -0
  252. package/build/esm/src/clients/faucet-client.d.ts +18 -0
  253. package/build/esm/src/clients/faucet-client.d.ts.map +1 -0
  254. package/build/esm/src/clients/faucet-client.js +29 -0
  255. package/build/esm/src/clients/helpers/chain-helpers.d.ts +15 -0
  256. package/build/esm/src/clients/helpers/chain-helpers.d.ts.map +1 -0
  257. package/build/esm/src/clients/helpers/chain-helpers.js +163 -0
  258. package/build/esm/src/clients/helpers/request-helpers.d.ts +3 -0
  259. package/build/esm/src/clients/helpers/request-helpers.d.ts.map +1 -0
  260. package/build/esm/src/clients/helpers/request-helpers.js +58 -0
  261. package/build/esm/src/clients/indexer-client.d.ts +40 -0
  262. package/build/esm/src/clients/indexer-client.d.ts.map +1 -0
  263. package/build/esm/src/clients/indexer-client.js +49 -0
  264. package/build/esm/src/clients/lib/axios/axiosRequest.d.ts +9 -0
  265. package/build/esm/src/clients/lib/axios/axiosRequest.d.ts.map +1 -0
  266. package/build/esm/src/clients/lib/axios/axiosRequest.js +28 -0
  267. package/build/esm/src/clients/lib/axios/errors.d.ts +31 -0
  268. package/build/esm/src/clients/lib/axios/errors.d.ts.map +1 -0
  269. package/build/esm/src/clients/lib/axios/errors.js +23 -0
  270. package/build/esm/src/clients/lib/axios/index.d.ts +7 -0
  271. package/build/esm/src/clients/lib/axios/index.d.ts.map +1 -0
  272. package/build/esm/src/clients/lib/axios/index.js +7 -0
  273. package/build/esm/src/clients/lib/axios/types.d.ts +7 -0
  274. package/build/esm/src/clients/lib/axios/types.d.ts.map +1 -0
  275. package/build/esm/src/clients/lib/axios/types.js +8 -0
  276. package/build/esm/src/clients/lib/cctpProto.d.ts +670 -0
  277. package/build/esm/src/clients/lib/cctpProto.d.ts.map +1 -0
  278. package/build/esm/src/clients/lib/cctpProto.js +3234 -0
  279. package/build/esm/src/clients/lib/errors.d.ts +36 -0
  280. package/build/esm/src/clients/lib/errors.d.ts.map +1 -0
  281. package/build/esm/src/clients/lib/errors.js +50 -0
  282. package/build/esm/src/clients/lib/registry.d.ts +4 -0
  283. package/build/esm/src/clients/lib/registry.d.ts.map +1 -0
  284. package/build/esm/src/clients/lib/registry.js +47 -0
  285. package/build/esm/src/clients/modules/account.d.ts +30 -0
  286. package/build/esm/src/clients/modules/account.d.ts.map +1 -0
  287. package/build/esm/src/clients/modules/account.js +217 -0
  288. package/build/esm/src/clients/modules/composer.d.ts +37 -0
  289. package/build/esm/src/clients/modules/composer.d.ts.map +1 -0
  290. package/build/esm/src/clients/modules/composer.js +398 -0
  291. package/build/esm/src/clients/modules/get.d.ts +178 -0
  292. package/build/esm/src/clients/modules/get.d.ts.map +1 -0
  293. package/build/esm/src/clients/modules/get.js +363 -0
  294. package/build/esm/src/clients/modules/local-wallet.d.ts +19 -0
  295. package/build/esm/src/clients/modules/local-wallet.d.ts.map +1 -0
  296. package/build/esm/src/clients/modules/local-wallet.js +53 -0
  297. package/build/esm/src/clients/modules/markets.d.ts +14 -0
  298. package/build/esm/src/clients/modules/markets.d.ts.map +1 -0
  299. package/build/esm/src/clients/modules/markets.js +48 -0
  300. package/build/esm/src/clients/modules/post.d.ts +130 -0
  301. package/build/esm/src/clients/modules/post.d.ts.map +1 -0
  302. package/build/esm/src/clients/modules/post.js +384 -0
  303. package/build/esm/src/clients/modules/proto-includes.d.ts +30 -0
  304. package/build/esm/src/clients/modules/proto-includes.d.ts.map +1 -0
  305. package/build/esm/src/clients/modules/proto-includes.js +30 -0
  306. package/build/esm/src/clients/modules/rest.d.ts +12 -0
  307. package/build/esm/src/clients/modules/rest.d.ts.map +1 -0
  308. package/build/esm/src/clients/modules/rest.js +27 -0
  309. package/build/esm/src/clients/modules/signer.d.ts +19 -0
  310. package/build/esm/src/clients/modules/signer.d.ts.map +1 -0
  311. package/build/esm/src/clients/modules/signer.js +86 -0
  312. package/build/esm/src/clients/modules/tendermintClient.d.ts +52 -0
  313. package/build/esm/src/clients/modules/tendermintClient.d.ts.map +1 -0
  314. package/build/esm/src/clients/modules/tendermintClient.js +133 -0
  315. package/build/esm/src/clients/modules/utility.d.ts +27 -0
  316. package/build/esm/src/clients/modules/utility.d.ts.map +1 -0
  317. package/build/esm/src/clients/modules/utility.js +38 -0
  318. package/build/esm/src/clients/modules/vault.d.ts +12 -0
  319. package/build/esm/src/clients/modules/vault.d.ts.map +1 -0
  320. package/build/esm/src/clients/modules/vault.js +19 -0
  321. package/build/esm/src/clients/native.d.ts +72 -0
  322. package/build/esm/src/clients/native.d.ts.map +1 -0
  323. package/build/esm/src/clients/native.js +1190 -0
  324. package/build/esm/src/clients/noble-client.d.ts +18 -0
  325. package/build/esm/src/clients/noble-client.d.ts.map +1 -0
  326. package/build/esm/src/clients/noble-client.js +71 -0
  327. package/build/esm/src/clients/socket-client.d.ts +146 -0
  328. package/build/esm/src/clients/socket-client.d.ts.map +1 -0
  329. package/build/esm/src/clients/socket-client.js +294 -0
  330. package/build/esm/src/clients/subaccount.d.ts +14 -0
  331. package/build/esm/src/clients/subaccount.d.ts.map +1 -0
  332. package/build/esm/src/clients/subaccount.js +29 -0
  333. package/build/esm/src/clients/types.d.ts +137 -0
  334. package/build/esm/src/clients/types.d.ts.map +1 -0
  335. package/build/esm/src/clients/types.js +26 -0
  336. package/build/esm/src/clients/validator-client.d.ts +35 -0
  337. package/build/esm/src/clients/validator-client.d.ts.map +1 -0
  338. package/build/esm/src/clients/validator-client.js +74 -0
  339. package/build/esm/src/index.d.ts +17 -0
  340. package/build/esm/src/index.d.ts.map +1 -0
  341. package/build/esm/src/index.js +19 -0
  342. package/build/esm/src/lib/constants.d.ts +13 -0
  343. package/build/esm/src/lib/constants.d.ts.map +1 -0
  344. package/build/esm/src/lib/constants.js +20 -0
  345. package/build/esm/src/lib/errors.d.ts +23 -0
  346. package/build/esm/src/lib/errors.d.ts.map +1 -0
  347. package/build/esm/src/lib/errors.js +31 -0
  348. package/build/esm/src/lib/helpers.d.ts +22 -0
  349. package/build/esm/src/lib/helpers.d.ts.map +1 -0
  350. package/build/esm/src/lib/helpers.js +88 -0
  351. package/build/esm/src/lib/onboarding.d.ts +46 -0
  352. package/build/esm/src/lib/onboarding.d.ts.map +1 -0
  353. package/build/esm/src/lib/onboarding.js +69 -0
  354. package/build/esm/src/lib/trading-key-utils.d.ts +22 -0
  355. package/build/esm/src/lib/trading-key-utils.d.ts.map +1 -0
  356. package/build/esm/src/lib/trading-key-utils.js +99 -0
  357. package/build/esm/src/lib/utils.d.ts +39 -0
  358. package/build/esm/src/lib/utils.d.ts.map +1 -0
  359. package/build/esm/src/lib/utils.js +69 -0
  360. package/build/esm/src/lib/validation.d.ts +26 -0
  361. package/build/esm/src/lib/validation.d.ts.map +1 -0
  362. package/build/esm/src/lib/validation.js +138 -0
  363. package/build/esm/src/network_optimizer.d.ts +8 -0
  364. package/build/esm/src/network_optimizer.d.ts.map +1 -0
  365. package/build/esm/src/network_optimizer.js +91 -0
  366. package/build/esm/src/types.d.ts +26 -0
  367. package/build/esm/src/types.d.ts.map +1 -0
  368. package/build/esm/src/types.js +8 -0
  369. package/build/esm/tsconfig.esm.tsbuildinfo +1 -0
  370. package/commitlint.config.js +8 -0
  371. package/examples/account_endpoints.ts +129 -0
  372. package/examples/batch_cancel_orders_example.ts +130 -0
  373. package/examples/composite_example.ts +65 -0
  374. package/examples/constants.ts +42 -0
  375. package/examples/faucet_endpoint.ts +24 -0
  376. package/examples/gov_add_new_market.json +64 -0
  377. package/examples/gov_add_new_market.ts +95 -0
  378. package/examples/human_readable_orders.json +86 -0
  379. package/examples/human_readable_short_term_orders.json +42 -0
  380. package/examples/json-encoding.ts +33 -0
  381. package/examples/long_term_order_cancel_example.ts +87 -0
  382. package/examples/markets_endpoints.ts +134 -0
  383. package/examples/native_examples.ts +151 -0
  384. package/examples/noble_example.ts +107 -0
  385. package/examples/optimal_node.ts +70 -0
  386. package/examples/permissioned_keys_example.ts +162 -0
  387. package/examples/raw_orders.json +130 -0
  388. package/examples/short_term_order_cancel_example.ts +68 -0
  389. package/examples/short_term_order_composite_example.ts +80 -0
  390. package/examples/test.ts +65 -0
  391. package/examples/transfer_example_deposit.ts +28 -0
  392. package/examples/transfer_example_send.ts +60 -0
  393. package/examples/transfer_example_subaccount_transfer.ts +29 -0
  394. package/examples/transfer_example_withdraw.ts +31 -0
  395. package/examples/transfer_example_withdraw_other.ts +60 -0
  396. package/examples/utility_endpoints.ts +42 -0
  397. package/examples/validator_get_example.ts +160 -0
  398. package/examples/validator_post_example.ts +81 -0
  399. package/examples/wallet_address.ts +18 -0
  400. package/examples/websocket_example.ts +44 -0
  401. package/examples/websocket_orderbook_example.ts +239 -0
  402. package/jest.config.js +12 -0
  403. package/jest.globalSetup.js +5 -0
  404. package/jest.setup.js +1 -0
  405. package/package.json +108 -0
  406. package/scripts/bump_version.sh +16 -0
  407. package/scripts/generate-cctp-protos.sh +41 -0
  408. package/scripts/mobile_build_pack.sh +5 -0
  409. package/scripts/publish-if-not-exists.sh +21 -0
  410. package/src/clients/composite-client.ts +1432 -0
  411. package/src/clients/constants.ts +368 -0
  412. package/src/clients/faucet-client.ts +48 -0
  413. package/src/clients/helpers/chain-helpers.ts +231 -0
  414. package/src/clients/helpers/request-helpers.ts +71 -0
  415. package/src/clients/indexer-client.ts +61 -0
  416. package/src/clients/lib/axios/axiosRequest.ts +41 -0
  417. package/src/clients/lib/axios/errors.ts +41 -0
  418. package/src/clients/lib/axios/index.ts +7 -0
  419. package/src/clients/lib/axios/types.ts +6 -0
  420. package/src/clients/lib/cctpProto.ts +4197 -0
  421. package/src/clients/lib/errors.ts +61 -0
  422. package/src/clients/lib/registry.ts +88 -0
  423. package/src/clients/modules/account.ts +388 -0
  424. package/src/clients/modules/composer.ts +646 -0
  425. package/src/clients/modules/get.ts +637 -0
  426. package/src/clients/modules/local-wallet.ts +79 -0
  427. package/src/clients/modules/markets.ts +71 -0
  428. package/src/clients/modules/post.ts +1017 -0
  429. package/src/clients/modules/proto-includes.ts +31 -0
  430. package/src/clients/modules/rest.ts +40 -0
  431. package/src/clients/modules/signer.ts +139 -0
  432. package/src/clients/modules/tendermintClient.ts +164 -0
  433. package/src/clients/modules/utility.ts +47 -0
  434. package/src/clients/modules/vault.ts +23 -0
  435. package/src/clients/native.ts +1464 -0
  436. package/src/clients/noble-client.ts +108 -0
  437. package/src/clients/socket-client.ts +331 -0
  438. package/src/clients/subaccount.ts +57 -0
  439. package/src/clients/types.ts +191 -0
  440. package/src/clients/validator-client.ts +103 -0
  441. package/src/index.ts +20 -0
  442. package/src/lib/constants.ts +28 -0
  443. package/src/lib/errors.ts +38 -0
  444. package/src/lib/helpers.ts +99 -0
  445. package/src/lib/onboarding.ts +96 -0
  446. package/src/lib/trading-key-utils.ts +136 -0
  447. package/src/lib/utils.ts +84 -0
  448. package/src/lib/validation.ts +197 -0
  449. package/src/network_optimizer.ts +132 -0
  450. package/src/types.ts +44 -0
  451. package/tasks.json +16 -0
  452. package/tsconfig.base.json +16 -0
  453. package/tsconfig.cjs.json +9 -0
  454. package/tsconfig.eslint.json +14 -0
  455. package/tsconfig.esm.json +10 -0
  456. package/webpack.config.js +56 -0
@@ -0,0 +1,1432 @@
1
+ import { EncodeObject } from '@cosmjs/proto-signing';
2
+ import { Account, GasPrice, IndexedTx, StdFee } from '@cosmjs/stargate';
3
+ import { Method } from '@cosmjs/tendermint-rpc';
4
+ import {
5
+ BroadcastTxAsyncResponse,
6
+ BroadcastTxSyncResponse,
7
+ } from '@cosmjs/tendermint-rpc/build/tendermint37';
8
+ import { GetAuthenticatorsResponse } from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/accountplus/query';
9
+ import {
10
+ Order_ConditionType,
11
+ Order_TimeInForce,
12
+ } from '@dydxprotocol/v4-proto/src/codegen/dydxprotocol/clob/order';
13
+ import { parseUnits } from 'ethers';
14
+ import Long from 'long';
15
+ import protobuf from 'protobufjs';
16
+
17
+ import { bigIntToBytes } from '../lib/helpers';
18
+ import { isStatefulOrder, verifyOrderFlags } from '../lib/validation';
19
+ import { GovAddNewMarketParams, OrderFlags } from '../types';
20
+ import {
21
+ Authenticator,
22
+ AuthenticatorType,
23
+ Network,
24
+ OrderExecution,
25
+ OrderSide,
26
+ OrderTimeInForce,
27
+ OrderType,
28
+ SHORT_BLOCK_FORWARD,
29
+ SHORT_BLOCK_WINDOW,
30
+ SelectedGasDenom,
31
+ } from './constants';
32
+ import {
33
+ calculateQuantums,
34
+ calculateSubticks,
35
+ calculateSide,
36
+ calculateTimeInForce,
37
+ calculateOrderFlags,
38
+ calculateClientMetadata,
39
+ calculateConditionType,
40
+ calculateConditionalOrderTriggerSubticks,
41
+ calculateVaultQuantums,
42
+ } from './helpers/chain-helpers';
43
+ import { IndexerClient } from './indexer-client';
44
+ import { UserError } from './lib/errors';
45
+ import { generateRegistry } from './lib/registry';
46
+ import LocalWallet from './modules/local-wallet';
47
+ import { SubaccountInfo } from './subaccount';
48
+ import { BroadcastMode, OrderBatch } from './types';
49
+ import { ValidatorClient } from './validator-client';
50
+
51
+ // Required for encoding and decoding queries that are of type Long.
52
+ // Must be done once but since the individal modules should be usable
53
+ // - must be set in each module that encounters encoding/decoding Longs.
54
+ // Reference: https://github.com/protobufjs/protobuf.js/issues/921
55
+ protobuf.util.Long = Long;
56
+ protobuf.configure();
57
+
58
+ export interface MarketInfo {
59
+ clobPairId: number;
60
+ atomicResolution: number;
61
+ stepBaseQuantums: number;
62
+ quantumConversionExponent: number;
63
+ subticksPerTick: number;
64
+ }
65
+
66
+ export interface OrderBatchWithMarketId {
67
+ marketId: string;
68
+ clobPairId?: number;
69
+ clientIds: number[];
70
+ }
71
+
72
+ export type PlaceOrderPayload = {
73
+ subaccountNumber: number;
74
+ marketId: string;
75
+ type: OrderType;
76
+ side: OrderSide;
77
+ price: number;
78
+ size: number;
79
+ clientId: number;
80
+ timeInForce?: OrderTimeInForce;
81
+ goodTilTimeInSeconds?: number;
82
+ execution?: OrderExecution;
83
+ postOnly?: boolean;
84
+ reduceOnly?: boolean;
85
+ triggerPrice?: number;
86
+ marketInfo?: MarketInfo;
87
+ currentHeight?: number;
88
+ goodTilBlock?: number;
89
+ };
90
+
91
+ export type CancelRawOrderPayload = {
92
+ subaccountNumber: number;
93
+ clientId: number;
94
+ orderFlags: OrderFlags;
95
+ clobPairId: number;
96
+ goodTilBlock?: number;
97
+ goodTilBlockTime?: number;
98
+ };
99
+
100
+ export type TransferToSubaccountPayload = {
101
+ sourceSubaccountNumber: number;
102
+ recipientSubaccountNumber: number;
103
+ transferAmount: string;
104
+ };
105
+
106
+ export class CompositeClient {
107
+ public readonly network: Network;
108
+ public gasDenom: SelectedGasDenom = SelectedGasDenom.USDC;
109
+ private _indexerClient: IndexerClient;
110
+ private _validatorClient?: ValidatorClient;
111
+
112
+ static async connect(network: Network): Promise<CompositeClient> {
113
+ const client = new CompositeClient(network);
114
+ await client.initialize();
115
+ return client;
116
+ }
117
+
118
+ private constructor(network: Network, apiTimeout?: number) {
119
+ this.network = network;
120
+ this._indexerClient = new IndexerClient(network.indexerConfig, apiTimeout);
121
+ }
122
+
123
+ private async initialize(): Promise<void> {
124
+ this._validatorClient = await ValidatorClient.connect(this.network.validatorConfig);
125
+ }
126
+
127
+ get indexerClient(): IndexerClient {
128
+ /**
129
+ * Get the validator client
130
+ */
131
+ return this._indexerClient!;
132
+ }
133
+
134
+ get validatorClient(): ValidatorClient {
135
+ /**
136
+ * Get the validator client
137
+ */
138
+ return this._validatorClient!;
139
+ }
140
+
141
+ get selectedGasDenom(): SelectedGasDenom | undefined {
142
+ if (!this._validatorClient) return undefined;
143
+ return this._validatorClient.selectedGasDenom;
144
+ }
145
+
146
+ setSelectedGasDenom(gasDenom: SelectedGasDenom): void {
147
+ if (!this._validatorClient) throw new Error('Validator client not initialized');
148
+ this._validatorClient.setSelectedGasDenom(gasDenom);
149
+ }
150
+
151
+ async populateAccountNumberCache(address: string): Promise<void> {
152
+ if (!this._validatorClient) throw new Error('Validator client not initialized');
153
+ await this._validatorClient.populateAccountNumberCache(address);
154
+ }
155
+
156
+ /**
157
+ * @description Sign a list of messages with a wallet.
158
+ * the calling function is responsible for creating the messages.
159
+ *
160
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
161
+ * at any point.
162
+ * @returns The Signature.
163
+ */
164
+ async sign(
165
+ subaccount: SubaccountInfo,
166
+ messaging: () => Promise<EncodeObject[]>,
167
+ zeroFee: boolean,
168
+ gasPrice?: GasPrice,
169
+ memo?: string,
170
+ account?: () => Promise<Account>,
171
+ ): Promise<Uint8Array> {
172
+ return this.validatorClient.post.sign(subaccount, messaging, zeroFee, gasPrice, memo, account);
173
+ }
174
+
175
+ /**
176
+ * @description Send a list of messages with a wallet.
177
+ * the calling function is responsible for creating the messages.
178
+ *
179
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
180
+ * at any point.
181
+ * @returns The Transaction Hash.
182
+ */
183
+ async send(
184
+ subaccount: SubaccountInfo,
185
+ messaging: () => Promise<EncodeObject[]>,
186
+ zeroFee: boolean,
187
+ gasPrice?: GasPrice,
188
+ memo?: string,
189
+ broadcastMode?: BroadcastMode,
190
+ account?: () => Promise<Account>,
191
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
192
+ return this.validatorClient.post.send(
193
+ subaccount,
194
+ messaging,
195
+ zeroFee,
196
+ gasPrice,
197
+ memo,
198
+ broadcastMode,
199
+ account,
200
+ undefined,
201
+ );
202
+ }
203
+
204
+ /**
205
+ * @description Send a signed transaction.
206
+ *
207
+ * @param signedTransaction The signed transaction to send.
208
+ *
209
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
210
+ * at any point.
211
+ * @returns The Transaction Hash.
212
+ */
213
+ async sendSignedTransaction(
214
+ signedTransaction: Uint8Array,
215
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
216
+ return this.validatorClient.post.sendSignedTransaction(signedTransaction);
217
+ }
218
+
219
+ /**
220
+ * @description Simulate a list of messages with a wallet.
221
+ * the calling function is responsible for creating the messages.
222
+ *
223
+ * To send multiple messages with gas estimate:
224
+ * 1. Client is responsible for creating the messages.
225
+ * 2. Call simulate() to get the gas estimate.
226
+ * 3. Call send() to send the messages.
227
+ *
228
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
229
+ * at any point.
230
+ * @returns The gas estimate.
231
+ */
232
+ async simulate(
233
+ subaccount: SubaccountInfo,
234
+ messaging: () => Promise<EncodeObject[]>,
235
+ gasPrice?: GasPrice,
236
+ memo?: string,
237
+ account?: () => Promise<Account>,
238
+ ): Promise<StdFee> {
239
+ return this.validatorClient.post.simulate(subaccount, messaging, gasPrice, memo, account);
240
+ }
241
+
242
+ /**
243
+ * @description Calculate the goodTilBlock value for a SHORT_TERM order
244
+ *
245
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
246
+ * at any point.
247
+ * @returns The goodTilBlock value
248
+ */
249
+
250
+ private async calculateGoodTilBlock(
251
+ orderFlags: OrderFlags,
252
+ currentHeight?: number,
253
+ goodTilBlock?: number,
254
+ ): Promise<number> {
255
+ if (orderFlags === OrderFlags.SHORT_TERM) {
256
+ if (goodTilBlock !== undefined && goodTilBlock !== 0 && goodTilBlock !== null) {
257
+ return Promise.resolve(goodTilBlock);
258
+ } else {
259
+ const height = currentHeight ?? (await this.validatorClient.get.latestBlockHeight());
260
+ return height + SHORT_BLOCK_FORWARD;
261
+ }
262
+ } else {
263
+ return Promise.resolve(0);
264
+ }
265
+ }
266
+
267
+ /**
268
+ * @description Validate the goodTilBlock value for a SHORT_TERM order
269
+ *
270
+ * @param goodTilBlock Number of blocks from the current block height the order will
271
+ * be valid for.
272
+ *
273
+ * @throws UserError if the goodTilBlock value is not valid given latest block height and
274
+ * SHORT_BLOCK_WINDOW.
275
+ */
276
+ private async validateGoodTilBlock(goodTilBlock: number): Promise<void> {
277
+ const height = await this.validatorClient.get.latestBlockHeight();
278
+ const nextValidBlockHeight = height + 1;
279
+ const lowerBound = nextValidBlockHeight;
280
+ const upperBound = nextValidBlockHeight + SHORT_BLOCK_WINDOW;
281
+ if (goodTilBlock < lowerBound || goodTilBlock > upperBound) {
282
+ throw new UserError(`Invalid Short-Term order GoodTilBlock.
283
+ Should be greater-than-or-equal-to ${lowerBound} and less-than-or-equal-to ${upperBound}.
284
+ Provided good til block: ${goodTilBlock}`);
285
+ }
286
+ }
287
+
288
+ /**
289
+ * @description Calculate the goodTilBlockTime value for a LONG_TERM order
290
+ * the calling function is responsible for creating the messages.
291
+ *
292
+ * @param goodTilTimeInSeconds The goodTilTimeInSeconds of the order to place.
293
+ *
294
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
295
+ * at any point.
296
+ * @returns The goodTilBlockTime value
297
+ */
298
+ private calculateGoodTilBlockTime(goodTilTimeInSeconds: number): number {
299
+ const now = new Date();
300
+ const millisecondsPerSecond = 1000;
301
+ const interval = goodTilTimeInSeconds * millisecondsPerSecond;
302
+ const future = new Date(now.valueOf() + interval);
303
+ return Math.round(future.getTime() / 1000);
304
+ }
305
+
306
+ /**
307
+ * @description Place a short term order with human readable input.
308
+ *
309
+ * Use human readable form of input, including price and size
310
+ * The quantum and subticks are calculated and submitted
311
+ *
312
+ * @param subaccount The subaccount to place the order under
313
+ * @param marketId The market to place the order on
314
+ * @param side The side of the order to place
315
+ * @param price The price of the order to place
316
+ * @param size The size of the order to place
317
+ * @param clientId The client id of the order to place
318
+ * @param timeInForce The time in force of the order to place
319
+ * @param goodTilBlock The goodTilBlock of the order to place
320
+ * @param reduceOnly The reduceOnly of the order to place
321
+ *
322
+ *
323
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
324
+ * at any point.
325
+ * @returns The transaction hash.
326
+ */
327
+ async placeShortTermOrder(
328
+ subaccount: SubaccountInfo,
329
+ marketId: string,
330
+ side: OrderSide,
331
+ price: number,
332
+ size: number,
333
+ clientId: number,
334
+ goodTilBlock: number,
335
+ timeInForce: Order_TimeInForce,
336
+ reduceOnly: boolean,
337
+ memo?: string,
338
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
339
+ const msgs: Promise<EncodeObject[]> = new Promise((resolve, reject) => {
340
+ const msg = this.placeShortTermOrderMessage(
341
+ subaccount,
342
+ marketId,
343
+ side,
344
+ price,
345
+ size,
346
+ clientId,
347
+ goodTilBlock,
348
+ timeInForce,
349
+ reduceOnly,
350
+ );
351
+ msg
352
+ .then((it) => {
353
+ resolve([it]);
354
+ })
355
+ .catch((err) => {
356
+ console.log(err);
357
+ reject(err);
358
+ });
359
+ });
360
+ const account: Promise<Account> = this.validatorClient.post.account(
361
+ subaccount.address,
362
+ undefined,
363
+ );
364
+ return this.send(
365
+ subaccount,
366
+ () => msgs,
367
+ true,
368
+ undefined,
369
+ memo,
370
+ undefined,
371
+ () => account,
372
+ );
373
+ }
374
+
375
+ /**
376
+ * @description Place an order with human readable input.
377
+ *
378
+ * Only MARKET and LIMIT types are supported right now
379
+ * Use human readable form of input, including price and size
380
+ * The quantum and subticks are calculated and submitted
381
+ *
382
+ * @param subaccount The subaccount to place the order on.
383
+ * @param marketId The market to place the order on.
384
+ * @param type The type of order to place.
385
+ * @param side The side of the order to place.
386
+ * @param price The price of the order to place.
387
+ * @param size The size of the order to place.
388
+ * @param clientId The client id of the order to place.
389
+ * @param timeInForce The time in force of the order to place.
390
+ * @param goodTilTimeInSeconds The goodTilTimeInSeconds of the order to place.
391
+ * @param execution The execution of the order to place.
392
+ * @param postOnly The postOnly of the order to place.
393
+ * @param reduceOnly The reduceOnly of the order to place.
394
+ * @param triggerPrice The trigger price of conditional orders.
395
+ * @param marketInfo optional market information for calculating quantums and subticks.
396
+ * This can be constructed from Indexer API. If set to null, additional round
397
+ * trip to Indexer API will be made.
398
+ * @param currentHeight Current block height. This can be obtained from ValidatorClient.
399
+ * If set to null, additional round trip to ValidatorClient will be made.
400
+ *
401
+ *
402
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
403
+ * at any point.
404
+ * @returns The transaction hash.
405
+ */
406
+ async placeOrder(
407
+ subaccount: SubaccountInfo,
408
+ marketId: string,
409
+ type: OrderType,
410
+ side: OrderSide,
411
+ price: number,
412
+ size: number,
413
+ clientId: number,
414
+ timeInForce?: OrderTimeInForce,
415
+ goodTilTimeInSeconds?: number,
416
+ execution?: OrderExecution,
417
+ postOnly?: boolean,
418
+ reduceOnly?: boolean,
419
+ triggerPrice?: number,
420
+ marketInfo?: MarketInfo,
421
+ currentHeight?: number,
422
+ goodTilBlock?: number,
423
+ memo?: string,
424
+ broadcastMode?: BroadcastMode,
425
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
426
+ const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
427
+ const msg = this.placeOrderMessage(
428
+ subaccount,
429
+ marketId,
430
+ type,
431
+ side,
432
+ price,
433
+ size,
434
+ clientId,
435
+ timeInForce,
436
+ goodTilTimeInSeconds,
437
+ execution,
438
+ postOnly,
439
+ reduceOnly,
440
+ triggerPrice,
441
+ marketInfo,
442
+ currentHeight,
443
+ goodTilBlock,
444
+ );
445
+ msg
446
+ .then((it) => resolve([it]))
447
+ .catch((err) => {
448
+ throw err;
449
+ });
450
+ });
451
+ const orderFlags = calculateOrderFlags(type, timeInForce);
452
+ const account: Promise<Account> = this.validatorClient.post.account(
453
+ subaccount.address,
454
+ orderFlags,
455
+ );
456
+ return this.send(
457
+ subaccount,
458
+ () => msgs,
459
+ true,
460
+ undefined,
461
+ memo,
462
+ broadcastMode,
463
+ () => account,
464
+ );
465
+ }
466
+
467
+ /**
468
+ * @description Calculate and create the place order message
469
+ *
470
+ * Only MARKET and LIMIT types are supported right now
471
+ * Use human readable form of input, including price and size
472
+ * The quantum and subticks are calculated and submitted
473
+ *
474
+ * @param subaccount The subaccount to place the order under
475
+ * @param marketId The market to place the order on
476
+ * @param type The type of order to place
477
+ * @param side The side of the order to place
478
+ * @param price The price of the order to place
479
+ * @param size The size of the order to place
480
+ * @param clientId The client id of the order to place
481
+ * @param timeInForce The time in force of the order to place
482
+ * @param goodTilTimeInSeconds The goodTilTimeInSeconds of the order to place
483
+ * @param execution The execution of the order to place
484
+ * @param postOnly The postOnly of the order to place
485
+ * @param reduceOnly The reduceOnly of the order to place
486
+ *
487
+ *
488
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
489
+ * at any point.
490
+ * @returns The message to be passed into the protocol
491
+ */
492
+ private async placeOrderMessage(
493
+ subaccount: SubaccountInfo,
494
+ marketId: string,
495
+ type: OrderType,
496
+ side: OrderSide,
497
+ price: number,
498
+ size: number,
499
+ clientId: number,
500
+ timeInForce?: OrderTimeInForce,
501
+ goodTilTimeInSeconds?: number,
502
+ execution?: OrderExecution,
503
+ postOnly?: boolean,
504
+ reduceOnly?: boolean,
505
+ triggerPrice?: number,
506
+ marketInfo?: MarketInfo,
507
+ currentHeight?: number,
508
+ goodTilBlock?: number,
509
+ ): Promise<EncodeObject> {
510
+ const orderFlags = calculateOrderFlags(type, timeInForce);
511
+
512
+ const result = await Promise.all([
513
+ this.calculateGoodTilBlock(orderFlags, currentHeight, goodTilBlock),
514
+ this.retrieveMarketInfo(marketId, marketInfo),
515
+ ]);
516
+ const desiredGoodTilBlock = result[0];
517
+ const clobPairId = result[1].clobPairId;
518
+ const atomicResolution = result[1].atomicResolution;
519
+ const stepBaseQuantums = result[1].stepBaseQuantums;
520
+ const quantumConversionExponent = result[1].quantumConversionExponent;
521
+ const subticksPerTick = result[1].subticksPerTick;
522
+ const orderSide = calculateSide(side);
523
+ const quantums = calculateQuantums(size, atomicResolution, stepBaseQuantums);
524
+ const subticks = calculateSubticks(
525
+ price,
526
+ atomicResolution,
527
+ quantumConversionExponent,
528
+ subticksPerTick,
529
+ );
530
+ const orderTimeInForce = calculateTimeInForce(type, timeInForce, execution, postOnly);
531
+ let goodTilBlockTime = 0;
532
+ if (orderFlags === OrderFlags.LONG_TERM || orderFlags === OrderFlags.CONDITIONAL) {
533
+ if (goodTilTimeInSeconds == null) {
534
+ throw new Error('goodTilTimeInSeconds must be set for LONG_TERM or CONDITIONAL order');
535
+ } else {
536
+ goodTilBlockTime = this.calculateGoodTilBlockTime(goodTilTimeInSeconds);
537
+ }
538
+ }
539
+ const clientMetadata = calculateClientMetadata(type);
540
+ const conditionalType = calculateConditionType(type);
541
+ const conditionalOrderTriggerSubticks = calculateConditionalOrderTriggerSubticks(
542
+ type,
543
+ atomicResolution,
544
+ quantumConversionExponent,
545
+ subticksPerTick,
546
+ triggerPrice,
547
+ );
548
+ return this.validatorClient.post.composer.composeMsgPlaceOrder(
549
+ subaccount.address,
550
+ subaccount.subaccountNumber,
551
+ clientId,
552
+ clobPairId,
553
+ orderFlags,
554
+ desiredGoodTilBlock,
555
+ goodTilBlockTime,
556
+ orderSide,
557
+ quantums,
558
+ subticks,
559
+ orderTimeInForce,
560
+ reduceOnly ?? false,
561
+ clientMetadata,
562
+ conditionalType,
563
+ conditionalOrderTriggerSubticks,
564
+ );
565
+ }
566
+
567
+ private async retrieveMarketInfo(marketId: string, marketInfo?: MarketInfo): Promise<MarketInfo> {
568
+ if (marketInfo) {
569
+ return Promise.resolve(marketInfo);
570
+ } else {
571
+ const marketsResponse = await this.indexerClient.markets.getPerpetualMarkets(marketId);
572
+ const market = marketsResponse.markets[marketId];
573
+ const clobPairId = market.clobPairId;
574
+ const atomicResolution = market.atomicResolution;
575
+ const stepBaseQuantums = market.stepBaseQuantums;
576
+ const quantumConversionExponent = market.quantumConversionExponent;
577
+ const subticksPerTick = market.subticksPerTick;
578
+ return {
579
+ clobPairId,
580
+ atomicResolution,
581
+ stepBaseQuantums,
582
+ quantumConversionExponent,
583
+ subticksPerTick,
584
+ };
585
+ }
586
+ }
587
+
588
+ /**
589
+ * @description Calculate and create the short term place order message
590
+ *
591
+ * Use human readable form of input, including price and size
592
+ * The quantum and subticks are calculated and submitted
593
+ *
594
+ * @param subaccount The subaccount to place the order under
595
+ * @param marketId The market to place the order on
596
+ * @param side The side of the order to place
597
+ * @param price The price of the order to place
598
+ * @param size The size of the order to place
599
+ * @param clientId The client id of the order to place
600
+ * @param timeInForce The time in force of the order to place
601
+ * @param goodTilBlock The goodTilBlock of the order to place
602
+ * @param reduceOnly The reduceOnly of the order to place
603
+ *
604
+ *
605
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
606
+ * at any point.
607
+ * @returns The message to be passed into the protocol
608
+ */
609
+ private async placeShortTermOrderMessage(
610
+ subaccount: SubaccountInfo,
611
+ marketId: string,
612
+ side: OrderSide,
613
+ price: number,
614
+ size: number,
615
+ clientId: number,
616
+ goodTilBlock: number,
617
+ timeInForce: Order_TimeInForce,
618
+ reduceOnly: boolean,
619
+ ): Promise<EncodeObject> {
620
+ await this.validateGoodTilBlock(goodTilBlock);
621
+
622
+ const marketsResponse = await this.indexerClient.markets.getPerpetualMarkets(marketId);
623
+ const market = marketsResponse.markets[marketId];
624
+ const clobPairId = market.clobPairId;
625
+ const atomicResolution = market.atomicResolution;
626
+ const stepBaseQuantums = market.stepBaseQuantums;
627
+ const quantumConversionExponent = market.quantumConversionExponent;
628
+ const subticksPerTick = market.subticksPerTick;
629
+ const orderSide = calculateSide(side);
630
+ const quantums = calculateQuantums(size, atomicResolution, stepBaseQuantums);
631
+ const subticks = calculateSubticks(
632
+ price,
633
+ atomicResolution,
634
+ quantumConversionExponent,
635
+ subticksPerTick,
636
+ );
637
+ const orderFlags = OrderFlags.SHORT_TERM;
638
+ return this.validatorClient.post.composer.composeMsgPlaceOrder(
639
+ subaccount.address,
640
+ subaccount.subaccountNumber,
641
+ clientId,
642
+ clobPairId,
643
+ orderFlags,
644
+ goodTilBlock,
645
+ 0, // Short term orders use goodTilBlock.
646
+ orderSide,
647
+ quantums,
648
+ subticks,
649
+ timeInForce,
650
+ reduceOnly,
651
+ 0, // Client metadata is 0 for short term orders.
652
+ Order_ConditionType.CONDITION_TYPE_UNSPECIFIED, // Short term orders cannot be conditional.
653
+ Long.fromInt(0), // Short term orders cannot be conditional.
654
+ );
655
+ }
656
+
657
+ /**
658
+ * @description Cancel an order with order information from web socket or REST.
659
+ *
660
+ * @param subaccount The subaccount to cancel the order from
661
+ * @param clientId The client id of the order to cancel
662
+ * @param orderFlags The order flags of the order to cancel
663
+ * @param clobPairId The clob pair id of the order to cancel
664
+ * @param goodTilBlock The goodTilBlock of the order to cancel
665
+ * @param goodTilBlockTime The goodTilBlockTime of the order to cancel
666
+ *
667
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
668
+ * at any point.
669
+ * @returns The transaction hash.
670
+ */
671
+ async cancelRawOrder(
672
+ subaccount: SubaccountInfo,
673
+ clientId: number,
674
+ orderFlags: OrderFlags,
675
+ clobPairId: number,
676
+ goodTilBlock?: number,
677
+ goodTilBlockTime?: number,
678
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
679
+ return this.validatorClient.post.cancelOrder(
680
+ subaccount,
681
+ clientId,
682
+ orderFlags,
683
+ clobPairId,
684
+ goodTilBlock,
685
+ goodTilBlockTime,
686
+ );
687
+ }
688
+
689
+ /**
690
+ * @description Cancel an order with human readable input.
691
+ *
692
+ * @param subaccount The subaccount to cancel the order from
693
+ * @param clientId The client id of the order to cancel
694
+ * @param orderFlags The order flags of the order to cancel
695
+ * @param marketId The market to cancel the order on
696
+ * @param goodTilBlock The goodTilBlock of the order to cancel
697
+ * @param goodTilBlockTime The goodTilBlockTime of the order to cancel
698
+ *
699
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
700
+ * at any point.
701
+ * @returns The transaction hash.
702
+ */
703
+ async cancelOrder(
704
+ subaccount: SubaccountInfo,
705
+ clientId: number,
706
+ orderFlags: OrderFlags,
707
+ marketId: string,
708
+ goodTilBlock?: number,
709
+ goodTilTimeInSeconds?: number,
710
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
711
+ const marketsResponse = await this.indexerClient.markets.getPerpetualMarkets(marketId);
712
+ const market = marketsResponse.markets[marketId];
713
+ const clobPairId = market.clobPairId;
714
+
715
+ if (!verifyOrderFlags(orderFlags)) {
716
+ throw new Error(`Invalid order flags: ${orderFlags}`);
717
+ }
718
+
719
+ let goodTilBlockTime;
720
+ if (isStatefulOrder(orderFlags)) {
721
+ if (goodTilTimeInSeconds === undefined || goodTilTimeInSeconds === 0) {
722
+ throw new Error('goodTilTimeInSeconds must be set for LONG_TERM or CONDITIONAL order');
723
+ }
724
+ if (goodTilBlock !== 0) {
725
+ throw new Error(
726
+ 'goodTilBlock should be zero since LONG_TERM or CONDITIONAL orders ' +
727
+ 'use goodTilTimeInSeconds instead of goodTilBlock.',
728
+ );
729
+ }
730
+ goodTilBlockTime = this.calculateGoodTilBlockTime(goodTilTimeInSeconds);
731
+ } else {
732
+ if (goodTilBlock === undefined || goodTilBlock === 0) {
733
+ throw new Error('goodTilBlock must be non-zero for SHORT_TERM orders');
734
+ }
735
+ if (goodTilTimeInSeconds !== undefined && goodTilTimeInSeconds !== 0) {
736
+ throw new Error(
737
+ 'goodTilTimeInSeconds should be zero since SHORT_TERM orders use goodTilBlock instead of goodTilTimeInSeconds.',
738
+ );
739
+ }
740
+ }
741
+
742
+ return this.validatorClient.post.cancelOrder(
743
+ subaccount,
744
+ clientId,
745
+ orderFlags,
746
+ clobPairId,
747
+ goodTilBlock,
748
+ goodTilBlockTime,
749
+ );
750
+ }
751
+
752
+ /**
753
+ * @description Batch cancel short term orders using marketId to clobPairId translation.
754
+ *
755
+ * @param subaccount The subaccount to cancel the order from
756
+ * @param shortTermOrders The list of short term order batches to cancel with marketId
757
+ * @param goodTilBlock The goodTilBlock of the order to cancel
758
+ * @returns The transaction hash.
759
+ */
760
+ async batchCancelShortTermOrdersWithMarketId(
761
+ subaccount: SubaccountInfo,
762
+ shortTermOrders: OrderBatchWithMarketId[],
763
+ goodTilBlock: number,
764
+ broadcastMode?: BroadcastMode,
765
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
766
+ const orderBatches = await Promise.all(
767
+ shortTermOrders.map(async ({ marketId, clobPairId, clientIds }) => ({
768
+ clobPairId: (
769
+ clobPairId ??
770
+ (await this.indexerClient.markets.getPerpetualMarkets(marketId)).markets[marketId]
771
+ ).clobPairId,
772
+ clientIds,
773
+ })),
774
+ );
775
+
776
+ return this.validatorClient.post.batchCancelShortTermOrders(
777
+ subaccount,
778
+ orderBatches,
779
+ goodTilBlock,
780
+ broadcastMode,
781
+ );
782
+ }
783
+
784
+ /**
785
+ * @description Batch cancel short term orders using clobPairId.
786
+ *
787
+ * @param subaccount The subaccount to cancel the order from
788
+ * @param shortTermOrders The list of short term order batches to cancel with clobPairId
789
+ * @param goodTilBlock The goodTilBlock of the order to cancel
790
+ * @returns The transaction hash.
791
+ */
792
+ async batchCancelShortTermOrdersWithClobPairId(
793
+ subaccount: SubaccountInfo,
794
+ shortTermOrders: OrderBatch[],
795
+ goodTilBlock: number,
796
+ broadcastMode?: BroadcastMode,
797
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
798
+ return this.validatorClient.post.batchCancelShortTermOrders(
799
+ subaccount,
800
+ shortTermOrders,
801
+ goodTilBlock,
802
+ broadcastMode,
803
+ );
804
+ }
805
+
806
+ /**
807
+ * @description Transfer from a subaccount to another subaccount
808
+ *
809
+ * @param subaccount The subaccount to transfer from
810
+ * @param recipientAddress The recipient address
811
+ * @param recipientSubaccountNumber The recipient subaccount number
812
+ * @param amount The amount to transfer
813
+ *
814
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
815
+ * at any point.
816
+ * @returns The transaction hash.
817
+ */
818
+ async transferToSubaccount(
819
+ subaccount: SubaccountInfo,
820
+ recipientAddress: string,
821
+ recipientSubaccountNumber: number,
822
+ amount: string,
823
+ memo?: string,
824
+ broadcastMode?: BroadcastMode,
825
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
826
+ const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
827
+ const msg = this.transferToSubaccountMessage(
828
+ subaccount,
829
+ recipientAddress,
830
+ recipientSubaccountNumber,
831
+ amount,
832
+ );
833
+ resolve([msg]);
834
+ });
835
+ return this.send(
836
+ subaccount,
837
+ () => msgs,
838
+ false,
839
+ undefined,
840
+ memo,
841
+ broadcastMode ?? Method.BroadcastTxCommit,
842
+ );
843
+ }
844
+
845
+ /**
846
+ * @description Create message to transfer from a subaccount to another subaccount
847
+ *
848
+ * @param subaccount The subaccount to transfer from
849
+ * @param recipientAddress The recipient address
850
+ * @param recipientSubaccountNumber The recipient subaccount number
851
+ * @param amount The amount to transfer
852
+ *
853
+ *
854
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
855
+ * at any point.
856
+ * @returns The message
857
+ */
858
+ transferToSubaccountMessage(
859
+ subaccount: SubaccountInfo,
860
+ recipientAddress: string,
861
+ recipientSubaccountNumber: number,
862
+ amount: string,
863
+ ): EncodeObject {
864
+ const validatorClient = this._validatorClient;
865
+ if (validatorClient === undefined) {
866
+ throw new Error('validatorClient not set');
867
+ }
868
+ const quantums = parseUnits(amount, validatorClient.config.denoms.USDC_DECIMALS);
869
+ if (quantums > BigInt(Long.MAX_VALUE.toString())) {
870
+ throw new Error('amount to large');
871
+ }
872
+ if (quantums < 0) {
873
+ throw new Error('amount must be positive');
874
+ }
875
+
876
+ return this.validatorClient.post.composer.composeMsgTransfer(
877
+ subaccount.address,
878
+ subaccount.subaccountNumber,
879
+ recipientAddress,
880
+ recipientSubaccountNumber,
881
+ 0,
882
+ Long.fromString(quantums.toString()),
883
+ );
884
+ }
885
+
886
+ /**
887
+ * @description Deposit from wallet to subaccount
888
+ *
889
+ * @param subaccount The subaccount to deposit to
890
+ * @param amount The amount to deposit
891
+ *
892
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
893
+ * at any point.
894
+ * @returns The transaction hash.
895
+ */
896
+ async depositToSubaccount(
897
+ subaccount: SubaccountInfo,
898
+ amount: string,
899
+ memo?: string,
900
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
901
+ const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
902
+ const msg = this.depositToSubaccountMessage(subaccount, amount);
903
+ resolve([msg]);
904
+ });
905
+ return this.validatorClient.post.send(subaccount, () => msgs, false, undefined, memo);
906
+ }
907
+
908
+ /**
909
+ * @description Create message to deposit from wallet to subaccount
910
+ *
911
+ * @param subaccount The subaccount to deposit to
912
+ * @param amount The amount to deposit
913
+ *
914
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
915
+ * at any point.
916
+ * @returns The message
917
+ */
918
+ depositToSubaccountMessage(subaccount: SubaccountInfo, amount: string): EncodeObject {
919
+ const validatorClient = this._validatorClient;
920
+ if (validatorClient === undefined) {
921
+ throw new Error('validatorClient not set');
922
+ }
923
+ const quantums = parseUnits(amount, validatorClient.config.denoms.USDC_DECIMALS);
924
+ if (quantums > BigInt(Long.MAX_VALUE.toString())) {
925
+ throw new Error('amount to large');
926
+ }
927
+ if (quantums < 0) {
928
+ throw new Error('amount must be positive');
929
+ }
930
+
931
+ return this.validatorClient.post.composer.composeMsgDepositToSubaccount(
932
+ subaccount.address,
933
+ subaccount.subaccountNumber,
934
+ 0,
935
+ Long.fromString(quantums.toString()),
936
+ );
937
+ }
938
+
939
+ /**
940
+ * @description Withdraw from subaccount to wallet
941
+ *
942
+ * @param subaccount The subaccount to withdraw from
943
+ * @param amount The amount to withdraw
944
+ * @param recipient The recipient address, default to subaccount address
945
+ *
946
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
947
+ * at any point.
948
+ * @returns The transaction hash
949
+ */
950
+ async withdrawFromSubaccount(
951
+ subaccount: SubaccountInfo,
952
+ amount: string,
953
+ recipient?: string,
954
+ memo?: string,
955
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
956
+ const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
957
+ const msg = this.withdrawFromSubaccountMessage(subaccount, amount, recipient);
958
+ resolve([msg]);
959
+ });
960
+ return this.send(subaccount, () => msgs, false, undefined, memo);
961
+ }
962
+
963
+ /**
964
+ * @description Create message to withdraw from subaccount to wallet
965
+ * with human readable input.
966
+ *
967
+ * @param subaccount The subaccount to withdraw from
968
+ * @param amount The amount to withdraw
969
+ * @param recipient The recipient address
970
+ *
971
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
972
+ * at any point.
973
+ * @returns The message
974
+ */
975
+ withdrawFromSubaccountMessage(
976
+ subaccount: SubaccountInfo,
977
+ amount: string,
978
+ recipient?: string,
979
+ ): EncodeObject {
980
+ const validatorClient = this._validatorClient;
981
+ if (validatorClient === undefined) {
982
+ throw new Error('validatorClient not set');
983
+ }
984
+ const quantums = parseUnits(amount, validatorClient.config.denoms.USDC_DECIMALS);
985
+ if (quantums > BigInt(Long.MAX_VALUE.toString())) {
986
+ throw new Error('amount to large');
987
+ }
988
+ if (quantums < 0) {
989
+ throw new Error('amount must be positive');
990
+ }
991
+
992
+ return this.validatorClient.post.composer.composeMsgWithdrawFromSubaccount(
993
+ subaccount.address,
994
+ subaccount.subaccountNumber,
995
+ 0,
996
+ Long.fromString(quantums.toString()),
997
+ recipient,
998
+ );
999
+ }
1000
+
1001
+ /**
1002
+ * @description Create message to send chain token from subaccount to wallet
1003
+ * with human readable input.
1004
+ *
1005
+ * @param subaccount The subaccount to withdraw from
1006
+ * @param amount The amount to withdraw
1007
+ * @param recipient The recipient address
1008
+ *
1009
+ * @throws UnexpectedClientError if a malformed response is returned with no GRPC error
1010
+ * at any point.
1011
+ * @returns The message
1012
+ */
1013
+ sendTokenMessage(wallet: LocalWallet, amount: string, recipient: string): EncodeObject {
1014
+ const address = wallet.address;
1015
+ if (address === undefined) {
1016
+ throw new UserError('wallet address is not set. Call connectWallet() first');
1017
+ }
1018
+ const { CHAINTOKEN_DENOM: chainTokenDenom, CHAINTOKEN_DECIMALS: chainTokenDecimals } =
1019
+ this._validatorClient?.config.denoms || {};
1020
+
1021
+ if (chainTokenDenom === undefined || chainTokenDecimals === undefined) {
1022
+ throw new Error('Chain token denom not set in validator config');
1023
+ }
1024
+
1025
+ const quantums = parseUnits(amount, chainTokenDecimals);
1026
+
1027
+ return this.validatorClient.post.composer.composeMsgSendToken(
1028
+ address,
1029
+ recipient,
1030
+ chainTokenDenom,
1031
+ quantums.toString(),
1032
+ );
1033
+ }
1034
+
1035
+ async signPlaceOrder(
1036
+ subaccount: SubaccountInfo,
1037
+ marketId: string,
1038
+ type: OrderType,
1039
+ side: OrderSide,
1040
+ price: number,
1041
+ // trigger_price: number, // not used for MARKET and LIMIT
1042
+ size: number,
1043
+ clientId: number,
1044
+ timeInForce: OrderTimeInForce,
1045
+ goodTilTimeInSeconds: number,
1046
+ execution: OrderExecution,
1047
+ postOnly: boolean,
1048
+ reduceOnly: boolean,
1049
+ ): Promise<string> {
1050
+ const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
1051
+ const msg = this.placeOrderMessage(
1052
+ subaccount,
1053
+ marketId,
1054
+ type,
1055
+ side,
1056
+ price,
1057
+ // trigger_price: number, // not used for MARKET and LIMIT
1058
+ size,
1059
+ clientId,
1060
+ timeInForce,
1061
+ goodTilTimeInSeconds,
1062
+ execution,
1063
+ postOnly,
1064
+ reduceOnly,
1065
+ );
1066
+ msg
1067
+ .then((it) => resolve([it]))
1068
+ .catch((err) => {
1069
+ console.log(err);
1070
+ });
1071
+ });
1072
+ const signature = await this.sign(subaccount, () => msgs, true);
1073
+
1074
+ return Buffer.from(signature).toString('base64');
1075
+ }
1076
+
1077
+ async signCancelOrder(
1078
+ subaccount: SubaccountInfo,
1079
+ clientId: number,
1080
+ orderFlags: OrderFlags,
1081
+ clobPairId: number,
1082
+ goodTilBlock: number,
1083
+ goodTilBlockTime: number,
1084
+ ): Promise<string> {
1085
+ const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
1086
+ const msg = this.validatorClient.post.composer.composeMsgCancelOrder(
1087
+ subaccount.address,
1088
+ subaccount.subaccountNumber,
1089
+ clientId,
1090
+ clobPairId,
1091
+ orderFlags,
1092
+ goodTilBlock,
1093
+ goodTilBlockTime,
1094
+ );
1095
+ resolve([msg]);
1096
+ });
1097
+ const signature = await this.sign(subaccount, () => msgs, true);
1098
+
1099
+ return Buffer.from(signature).toString('base64');
1100
+ }
1101
+
1102
+ async bulkCancelAndTransferAndPlaceStatefulOrders(
1103
+ subaccount: SubaccountInfo,
1104
+ // these are executed in this order, all in one block, and all succeed or all fail
1105
+ cancelOrderPayloads: CancelRawOrderPayload[],
1106
+ transferToSubaccountPayload: TransferToSubaccountPayload | undefined,
1107
+ placeOrderPayloads: PlaceOrderPayload[],
1108
+ memo?: string,
1109
+ broadcastMode?: BroadcastMode,
1110
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
1111
+ if (cancelOrderPayloads.some((c) => c.orderFlags === OrderFlags.SHORT_TERM)) {
1112
+ throw new Error('SHORT_TERM cancels cannot be batched');
1113
+ }
1114
+
1115
+ if (
1116
+ placeOrderPayloads.some(
1117
+ (placePayload) =>
1118
+ calculateOrderFlags(placePayload.type, placePayload.timeInForce) ===
1119
+ OrderFlags.SHORT_TERM,
1120
+ )
1121
+ ) {
1122
+ throw new Error('SHORT_TERM orders cannot be batched');
1123
+ }
1124
+
1125
+ const account: Promise<Account> = this.validatorClient.post.account(
1126
+ subaccount.address,
1127
+ undefined,
1128
+ );
1129
+
1130
+ const msgs: Promise<EncodeObject[]> = (async () => {
1131
+ const cancelMsgPromises = cancelOrderPayloads.map(async (cancelPayload) => {
1132
+ const cancelSubaccount = subaccount.cloneWithSubaccount(cancelPayload.subaccountNumber);
1133
+ return this.validatorClient.post.cancelOrderMsg(
1134
+ cancelSubaccount.address,
1135
+ cancelSubaccount.subaccountNumber,
1136
+ cancelPayload.clientId,
1137
+ cancelPayload.orderFlags,
1138
+ cancelPayload.clobPairId,
1139
+ cancelPayload.goodTilBlock,
1140
+ cancelPayload.goodTilBlockTime,
1141
+ );
1142
+ });
1143
+
1144
+ const transferMsg = (() => {
1145
+ if (transferToSubaccountPayload == null) {
1146
+ return undefined;
1147
+ }
1148
+ const transferSubaccount = subaccount.cloneWithSubaccount(
1149
+ transferToSubaccountPayload.sourceSubaccountNumber,
1150
+ );
1151
+ return this.transferToSubaccountMessage(
1152
+ transferSubaccount,
1153
+ transferSubaccount.address,
1154
+ transferToSubaccountPayload.recipientSubaccountNumber,
1155
+ transferToSubaccountPayload.transferAmount,
1156
+ );
1157
+ })();
1158
+
1159
+ const placeOrderMsgPromises = placeOrderPayloads.map((placePayload) => {
1160
+ const placeSubaccount = subaccount.cloneWithSubaccount(placePayload.subaccountNumber);
1161
+ return this.placeOrderMessage(
1162
+ placeSubaccount,
1163
+ placePayload.marketId,
1164
+ placePayload.type,
1165
+ placePayload.side,
1166
+ placePayload.price,
1167
+ placePayload.size,
1168
+ placePayload.clientId,
1169
+ placePayload.timeInForce,
1170
+ placePayload.goodTilTimeInSeconds,
1171
+ placePayload.execution,
1172
+ placePayload.postOnly,
1173
+ placePayload.reduceOnly,
1174
+ placePayload.triggerPrice,
1175
+ placePayload.marketInfo,
1176
+ placePayload.currentHeight,
1177
+ placePayload.goodTilBlock,
1178
+ );
1179
+ });
1180
+
1181
+ return Promise.all([
1182
+ ...cancelMsgPromises,
1183
+ ...(transferMsg != null ? [transferMsg] : []),
1184
+ ...placeOrderMsgPromises,
1185
+ ]);
1186
+ })();
1187
+
1188
+ return this.send(
1189
+ subaccount,
1190
+ () => msgs,
1191
+ true,
1192
+ undefined,
1193
+ memo,
1194
+ broadcastMode ?? Method.BroadcastTxCommit,
1195
+ () => account,
1196
+ );
1197
+ }
1198
+
1199
+ // vaults
1200
+
1201
+ async depositToMegavault(
1202
+ subaccount: SubaccountInfo,
1203
+ amountUsdc: number,
1204
+ broadcastMode?: BroadcastMode,
1205
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
1206
+ return this.validatorClient.post.depositToMegavault(
1207
+ subaccount,
1208
+ bigIntToBytes(calculateVaultQuantums(amountUsdc)),
1209
+ broadcastMode,
1210
+ );
1211
+ }
1212
+
1213
+ depositToMegavaultMessage(subaccount: SubaccountInfo, amountUsdc: number): EncodeObject {
1214
+ return this.validatorClient.post.depositToMegavaultMsg(
1215
+ subaccount.address,
1216
+ subaccount.subaccountNumber,
1217
+ bigIntToBytes(calculateVaultQuantums(amountUsdc)),
1218
+ );
1219
+ }
1220
+
1221
+ async withdrawFromMegavault(
1222
+ subaccount: SubaccountInfo,
1223
+ shares: number,
1224
+ minAmount: number,
1225
+ broadcastMode?: BroadcastMode,
1226
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
1227
+ return this.validatorClient.post.withdrawFromMegavault(
1228
+ subaccount,
1229
+ bigIntToBytes(BigInt(Math.floor(shares))),
1230
+ bigIntToBytes(calculateVaultQuantums(minAmount)),
1231
+ broadcastMode,
1232
+ );
1233
+ }
1234
+
1235
+ withdrawFromMegavaultMessage(
1236
+ subaccount: SubaccountInfo,
1237
+ shares: number,
1238
+ minAmount: number,
1239
+ ): EncodeObject {
1240
+ return this.validatorClient.post.withdrawFromMegavaultMsg(
1241
+ subaccount.address,
1242
+ subaccount.subaccountNumber,
1243
+ bigIntToBytes(BigInt(Math.floor(shares))),
1244
+ bigIntToBytes(calculateVaultQuantums(minAmount)),
1245
+ );
1246
+ }
1247
+
1248
+ /**
1249
+ * @description Submit a governance proposal to add a new market.
1250
+ *
1251
+ * @param params Parameters neeeded to create a new market.
1252
+ * @param title Title of the gov proposal.
1253
+ * @param summary Summary of the gov proposal.
1254
+ * @param initialDepositAmount Initial deposit amount of the gov proposal.
1255
+ * @param proposer proposer of the gov proposal.
1256
+ *
1257
+ * @returns the transaction hash.
1258
+ */
1259
+ async submitGovAddNewMarketProposal(
1260
+ wallet: LocalWallet,
1261
+ params: GovAddNewMarketParams,
1262
+ title: string,
1263
+ summary: string,
1264
+ initialDepositAmount: string,
1265
+ memo?: string,
1266
+ metadata?: string,
1267
+ expedited?: boolean,
1268
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
1269
+ const msg: Promise<EncodeObject[]> = new Promise((resolve) => {
1270
+ const composer = this.validatorClient.post.composer;
1271
+ const registry = generateRegistry();
1272
+ const msgs: EncodeObject[] = [];
1273
+
1274
+ const isDydxUsd = params.ticker.toLowerCase() === 'dydx-usd';
1275
+
1276
+ // x/prices.MsgCreateOracleMarket
1277
+ const createOracleMarket = composer.composeMsgCreateOracleMarket(
1278
+ params.id,
1279
+ params.ticker,
1280
+ params.priceExponent,
1281
+ params.minExchanges,
1282
+ params.minPriceChange,
1283
+ params.exchangeConfigJson,
1284
+ );
1285
+
1286
+ // x/perpetuals.MsgCreatePerpetual
1287
+ const createPerpetual = composer.composeMsgCreatePerpetual(
1288
+ params.id,
1289
+ isDydxUsd ? 1000001 : params.id,
1290
+ params.ticker,
1291
+ params.atomicResolution,
1292
+ params.liquidityTier,
1293
+ params.marketType,
1294
+ );
1295
+
1296
+ // x/clob.MsgCreateClobPair
1297
+ const createClobPair = composer.composeMsgCreateClobPair(
1298
+ params.id,
1299
+ params.id,
1300
+ params.quantumConversionExponent,
1301
+ params.stepBaseQuantums,
1302
+ params.subticksPerTick,
1303
+ );
1304
+
1305
+ // x/clob.MsgUpdateClobPair
1306
+ const updateClobPair = composer.composeMsgUpdateClobPair(
1307
+ params.id,
1308
+ params.id,
1309
+ params.quantumConversionExponent,
1310
+ params.stepBaseQuantums,
1311
+ params.subticksPerTick,
1312
+ );
1313
+
1314
+ // x/delaymsg.MsgDelayMessage
1315
+ const delayMessage = composer.composeMsgDelayMessage(
1316
+ // IMPORTANT: must wrap messages in Any type to fit into delaymsg.
1317
+ composer.wrapMessageAsAny(registry, updateClobPair),
1318
+ params.delayBlocks,
1319
+ );
1320
+
1321
+ // The order matters.
1322
+ if (!isDydxUsd) {
1323
+ msgs.push(createOracleMarket);
1324
+ }
1325
+ msgs.push(createPerpetual);
1326
+ msgs.push(createClobPair);
1327
+ msgs.push(delayMessage);
1328
+
1329
+ // x/gov.v1.MsgSubmitProposal
1330
+ const submitProposal = composer.composeMsgSubmitProposal(
1331
+ title,
1332
+ initialDepositAmount,
1333
+ this.validatorClient.config.denoms, // use the client denom.
1334
+ summary,
1335
+ // IMPORTANT: must wrap messages in Any type for gov's submit proposal.
1336
+ composer.wrapMessageArrAsAny(registry, msgs),
1337
+ wallet.address!, // proposer
1338
+ metadata,
1339
+ expedited,
1340
+ );
1341
+
1342
+ resolve([submitProposal]);
1343
+ });
1344
+
1345
+ return this.send(SubaccountInfo.forLocalWallet(wallet), () => msg, false, undefined, memo);
1346
+ }
1347
+
1348
+ async createMarketPermissionless(
1349
+ subaccount: SubaccountInfo,
1350
+ ticker: string,
1351
+ broadcastMode?: BroadcastMode,
1352
+ gasAdjustment?: number,
1353
+ memo?: string,
1354
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
1355
+ return this.validatorClient.post.createMarketPermissionless(
1356
+ ticker,
1357
+ subaccount,
1358
+ broadcastMode,
1359
+ gasAdjustment,
1360
+ memo,
1361
+ );
1362
+ }
1363
+
1364
+ async addAuthenticator(
1365
+ subaccount: SubaccountInfo,
1366
+ authenticatorType: AuthenticatorType,
1367
+ data: Uint8Array,
1368
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
1369
+ // Validate the provided authenticators before sending to the validator
1370
+ const authenticator: Authenticator = {
1371
+ type: authenticatorType,
1372
+ config: JSON.parse(new TextDecoder().decode(data)),
1373
+ };
1374
+ if (!this.validateAuthenticator(authenticator)) {
1375
+ throw new Error(
1376
+ 'Invalid authenticator, please ensure the authenticator permissions are correct',
1377
+ );
1378
+ }
1379
+
1380
+ return this.validatorClient.post.addAuthenticator(subaccount, authenticatorType, data);
1381
+ }
1382
+
1383
+ async removeAuthenticator(
1384
+ subaccount: SubaccountInfo,
1385
+ id: string,
1386
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
1387
+ return this.validatorClient.post.removeAuthenticator(subaccount, Long.fromString(id));
1388
+ }
1389
+
1390
+ async getAuthenticators(address: string): Promise<GetAuthenticatorsResponse> {
1391
+ return this.validatorClient.get.getAuthenticators(address);
1392
+ }
1393
+
1394
+ validateAuthenticator(authenticator: Authenticator): boolean {
1395
+ const decodeCompositeConfig = (config: unknown): Authenticator[] | null => {
1396
+ if (Array.isArray(config)) {
1397
+ return config as Authenticator[];
1398
+ }
1399
+ if (typeof config === 'string') {
1400
+ try {
1401
+ const decoded = Buffer.from(config, 'base64').toString('utf8');
1402
+ const parsed = JSON.parse(decoded);
1403
+ return Array.isArray(parsed) ? (parsed as Authenticator[]) : null;
1404
+ } catch {
1405
+ return null;
1406
+ }
1407
+ }
1408
+ return null;
1409
+ };
1410
+
1411
+ const checkAuthenticator = (auth: Authenticator): boolean => {
1412
+ if (auth.type === AuthenticatorType.SIGNATURE_VERIFICATION) {
1413
+ return true;
1414
+ }
1415
+
1416
+ if (auth.type === AuthenticatorType.ANY_OF || auth.type === AuthenticatorType.ALL_OF) {
1417
+ const subAuthenticators = decodeCompositeConfig(auth.config);
1418
+ if (subAuthenticators == null) {
1419
+ return false;
1420
+ }
1421
+ if (auth.type === AuthenticatorType.ANY_OF) {
1422
+ return subAuthenticators.every((nested) => checkAuthenticator(nested));
1423
+ }
1424
+ return subAuthenticators.some((nested) => checkAuthenticator(nested));
1425
+ }
1426
+
1427
+ return false;
1428
+ };
1429
+
1430
+ return checkAuthenticator(authenticator);
1431
+ }
1432
+ }