@decibeltrade/sdk 0.1.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 (294) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-lint$colon$check.log +5 -0
  3. package/.turbo/turbo-lint.log +5 -0
  4. package/decibel_transactions.md +1049 -0
  5. package/dist/abi/abi-manager.d.ts +13 -0
  6. package/dist/abi/abi-manager.d.ts.map +1 -0
  7. package/dist/abi/abi-manager.js +21 -0
  8. package/dist/abi/abis.json +1322 -0
  9. package/dist/abi/bytecode-manager.d.ts +57 -0
  10. package/dist/abi/bytecode-manager.d.ts.map +1 -0
  11. package/dist/abi/bytecode-manager.js +62 -0
  12. package/dist/abi/bytecode.json +24 -0
  13. package/dist/abi/fetch-abis.d.ts +7 -0
  14. package/dist/abi/fetch-abis.d.ts.map +1 -0
  15. package/dist/abi/fetch-abis.js +132 -0
  16. package/dist/abi/fetch-bytecode.d.ts +24 -0
  17. package/dist/abi/fetch-bytecode.d.ts.map +1 -0
  18. package/dist/abi/fetch-bytecode.js +123 -0
  19. package/dist/abi/generate-abis.d.ts +6 -0
  20. package/dist/abi/generate-abis.d.ts.map +1 -0
  21. package/dist/abi/generate-abis.js +170 -0
  22. package/dist/abi/json/netna.json +1323 -0
  23. package/dist/abi/json/testnet.json +1315 -0
  24. package/dist/abi/types.d.ts +22 -0
  25. package/dist/abi/types.d.ts.map +1 -0
  26. package/dist/abi/types.js +2 -0
  27. package/dist/admin.d.ts +29 -0
  28. package/dist/admin.d.ts.map +1 -0
  29. package/dist/admin.js +203 -0
  30. package/dist/base.d.ts +42 -0
  31. package/dist/base.d.ts.map +1 -0
  32. package/dist/base.js +176 -0
  33. package/dist/constants.d.ts +41 -0
  34. package/dist/constants.d.ts.map +1 -0
  35. package/dist/constants.js +78 -0
  36. package/dist/fee-pay.d.ts +11 -0
  37. package/dist/fee-pay.d.ts.map +1 -0
  38. package/dist/fee-pay.js +30 -0
  39. package/dist/gas/gas-price-manager.d.ts +35 -0
  40. package/dist/gas/gas-price-manager.d.ts.map +1 -0
  41. package/dist/gas/gas-price-manager.js +93 -0
  42. package/dist/gas-price-manager.d.ts +31 -0
  43. package/dist/gas-price-manager.d.ts.map +1 -0
  44. package/dist/gas-price-manager.js +84 -0
  45. package/dist/index.d.ts +11 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +26 -0
  48. package/dist/order-event.types.d.ts +55 -0
  49. package/dist/order-event.types.d.ts.map +1 -0
  50. package/dist/order-event.types.js +3 -0
  51. package/dist/order-status.d.ts +43 -0
  52. package/dist/order-status.d.ts.map +1 -0
  53. package/dist/order-status.js +86 -0
  54. package/dist/read/account-overview/account-overview.reader.d.ts +37 -0
  55. package/dist/read/account-overview/account-overview.reader.d.ts.map +1 -0
  56. package/dist/read/account-overview/account-overview.reader.js +35 -0
  57. package/dist/read/account-overview/account-overview.types.d.ts +52 -0
  58. package/dist/read/account-overview/account-overview.types.d.ts.map +1 -0
  59. package/dist/read/account-overview/account-overview.types.js +36 -0
  60. package/dist/read/api-wallets/api-wallets.reader.d.ts +17 -0
  61. package/dist/read/api-wallets/api-wallets.reader.d.ts.map +1 -0
  62. package/dist/read/api-wallets/api-wallets.reader.js +27 -0
  63. package/dist/read/api-wallets/api-wallets.types.d.ts +17 -0
  64. package/dist/read/api-wallets/api-wallets.types.d.ts.map +1 -0
  65. package/dist/read/api-wallets/api-wallets.types.js +13 -0
  66. package/dist/read/base-reader.d.ts +22 -0
  67. package/dist/read/base-reader.d.ts.map +1 -0
  68. package/dist/read/base-reader.js +29 -0
  69. package/dist/read/candlesticks/candlesticks.reader.d.ts +31 -0
  70. package/dist/read/candlesticks/candlesticks.reader.d.ts.map +1 -0
  71. package/dist/read/candlesticks/candlesticks.reader.js +43 -0
  72. package/dist/read/candlesticks/candlesticks.types.d.ts +45 -0
  73. package/dist/read/candlesticks/candlesticks.types.d.ts.map +1 -0
  74. package/dist/read/candlesticks/candlesticks.types.js +36 -0
  75. package/dist/read/delegations/delegations.reader.d.ts +15 -0
  76. package/dist/read/delegations/delegations.reader.d.ts.map +1 -0
  77. package/dist/read/delegations/delegations.reader.js +23 -0
  78. package/dist/read/delegations/delegations.types.d.ts +17 -0
  79. package/dist/read/delegations/delegations.types.d.ts.map +1 -0
  80. package/dist/read/delegations/delegations.types.js +13 -0
  81. package/dist/read/index.d.ts +105 -0
  82. package/dist/read/index.d.ts.map +1 -0
  83. package/dist/read/index.js +244 -0
  84. package/dist/read/leaderboard/leaderboard.reader.d.ts +21 -0
  85. package/dist/read/leaderboard/leaderboard.reader.d.ts.map +1 -0
  86. package/dist/read/leaderboard/leaderboard.reader.js +22 -0
  87. package/dist/read/leaderboard/leaderboard.types.d.ts +27 -0
  88. package/dist/read/leaderboard/leaderboard.types.d.ts.map +1 -0
  89. package/dist/read/leaderboard/leaderboard.types.js +14 -0
  90. package/dist/read/market-contexts/market-contexts.reader.d.ts +22 -0
  91. package/dist/read/market-contexts/market-contexts.reader.d.ts.map +1 -0
  92. package/dist/read/market-contexts/market-contexts.reader.js +27 -0
  93. package/dist/read/market-contexts/market-contexts.types.d.ts +26 -0
  94. package/dist/read/market-contexts/market-contexts.types.d.ts.map +1 -0
  95. package/dist/read/market-contexts/market-contexts.types.js +19 -0
  96. package/dist/read/market-depth/market-depth.reader.d.ts +30 -0
  97. package/dist/read/market-depth/market-depth.reader.d.ts.map +1 -0
  98. package/dist/read/market-depth/market-depth.reader.js +46 -0
  99. package/dist/read/market-depth/market-depth.types.d.ts +20 -0
  100. package/dist/read/market-depth/market-depth.types.d.ts.map +1 -0
  101. package/dist/read/market-depth/market-depth.types.js +16 -0
  102. package/dist/read/market-prices/market-prices.reader.d.ts +44 -0
  103. package/dist/read/market-prices/market-prices.reader.d.ts.map +1 -0
  104. package/dist/read/market-prices/market-prices.reader.js +51 -0
  105. package/dist/read/market-prices/market-prices.types.d.ts +48 -0
  106. package/dist/read/market-prices/market-prices.types.d.ts.map +1 -0
  107. package/dist/read/market-prices/market-prices.types.js +26 -0
  108. package/dist/read/market-trades/market-trades.reader.d.ts +33 -0
  109. package/dist/read/market-trades/market-trades.reader.d.ts.map +1 -0
  110. package/dist/read/market-trades/market-trades.reader.js +39 -0
  111. package/dist/read/market-trades/market-trades.types.d.ts +52 -0
  112. package/dist/read/market-trades/market-trades.types.d.ts.map +1 -0
  113. package/dist/read/market-trades/market-trades.types.js +23 -0
  114. package/dist/read/markets/markets.reader.d.ts +38 -0
  115. package/dist/read/markets/markets.reader.d.ts.map +1 -0
  116. package/dist/read/markets/markets.reader.js +80 -0
  117. package/dist/read/markets/markets.types.d.ts +82 -0
  118. package/dist/read/markets/markets.types.d.ts.map +1 -0
  119. package/dist/read/markets/markets.types.js +46 -0
  120. package/dist/read/pagination.types.d.ts +14 -0
  121. package/dist/read/pagination.types.d.ts.map +1 -0
  122. package/dist/read/pagination.types.js +12 -0
  123. package/dist/read/portfolio-chart/portfolio-chart.reader.d.ts +14 -0
  124. package/dist/read/portfolio-chart/portfolio-chart.reader.d.ts.map +1 -0
  125. package/dist/read/portfolio-chart/portfolio-chart.reader.js +21 -0
  126. package/dist/read/portfolio-chart/portfolio-chart.types.d.ts +14 -0
  127. package/dist/read/portfolio-chart/portfolio-chart.types.d.ts.map +1 -0
  128. package/dist/read/portfolio-chart/portfolio-chart.types.js +12 -0
  129. package/dist/read/public-vaults/public-vaults.reader.d.ts +38 -0
  130. package/dist/read/public-vaults/public-vaults.reader.d.ts.map +1 -0
  131. package/dist/read/public-vaults/public-vaults.reader.js +31 -0
  132. package/dist/read/public-vaults/public-vaults.types.d.ts +62 -0
  133. package/dist/read/public-vaults/public-vaults.types.d.ts.map +1 -0
  134. package/dist/read/public-vaults/public-vaults.types.js +33 -0
  135. package/dist/read/types.d.ts +178 -0
  136. package/dist/read/types.d.ts.map +1 -0
  137. package/dist/read/types.js +87 -0
  138. package/dist/read/user-active-twaps/user-active-twaps.reader.d.ts +31 -0
  139. package/dist/read/user-active-twaps/user-active-twaps.reader.d.ts.map +1 -0
  140. package/dist/read/user-active-twaps/user-active-twaps.reader.js +31 -0
  141. package/dist/read/user-active-twaps/user-active-twaps.types.d.ts +49 -0
  142. package/dist/read/user-active-twaps/user-active-twaps.types.d.ts.map +1 -0
  143. package/dist/read/user-active-twaps/user-active-twaps.types.js +25 -0
  144. package/dist/read/user-bulk-orders/user-bulk-orders.reader.d.ts +31 -0
  145. package/dist/read/user-bulk-orders/user-bulk-orders.reader.d.ts.map +1 -0
  146. package/dist/read/user-bulk-orders/user-bulk-orders.reader.js +32 -0
  147. package/dist/read/user-bulk-orders/user-bulk-orders.types.d.ts +46 -0
  148. package/dist/read/user-bulk-orders/user-bulk-orders.types.d.ts.map +1 -0
  149. package/dist/read/user-bulk-orders/user-bulk-orders.types.js +24 -0
  150. package/dist/read/user-funding-history/user-funding-history.reader.d.ts +28 -0
  151. package/dist/read/user-funding-history/user-funding-history.reader.d.ts.map +1 -0
  152. package/dist/read/user-funding-history/user-funding-history.reader.js +32 -0
  153. package/dist/read/user-funding-history/user-funding-history.types.d.ts +37 -0
  154. package/dist/read/user-funding-history/user-funding-history.types.d.ts.map +1 -0
  155. package/dist/read/user-funding-history/user-funding-history.types.js +21 -0
  156. package/dist/read/user-notifications/user-notifications.reader.d.ts +13 -0
  157. package/dist/read/user-notifications/user-notifications.reader.d.ts.map +1 -0
  158. package/dist/read/user-notifications/user-notifications.reader.js +19 -0
  159. package/dist/read/user-notifications/user-notifications.types.d.ts +49 -0
  160. package/dist/read/user-notifications/user-notifications.types.d.ts.map +1 -0
  161. package/dist/read/user-notifications/user-notifications.types.js +18 -0
  162. package/dist/read/user-open-orders/user-open-orders.reader.d.ts +40 -0
  163. package/dist/read/user-open-orders/user-open-orders.reader.d.ts.map +1 -0
  164. package/dist/read/user-open-orders/user-open-orders.reader.js +31 -0
  165. package/dist/read/user-open-orders/user-open-orders.types.d.ts +76 -0
  166. package/dist/read/user-open-orders/user-open-orders.types.d.ts.map +1 -0
  167. package/dist/read/user-open-orders/user-open-orders.types.js +34 -0
  168. package/dist/read/user-order-history/user-order-history.reader.d.ts +40 -0
  169. package/dist/read/user-order-history/user-order-history.reader.d.ts.map +1 -0
  170. package/dist/read/user-order-history/user-order-history.reader.js +28 -0
  171. package/dist/read/user-order-history/user-order-history.types.d.ts +85 -0
  172. package/dist/read/user-order-history/user-order-history.types.d.ts.map +1 -0
  173. package/dist/read/user-order-history/user-order-history.types.js +37 -0
  174. package/dist/read/user-positions/user-positions.reader.d.ts +37 -0
  175. package/dist/read/user-positions/user-positions.reader.d.ts.map +1 -0
  176. package/dist/read/user-positions/user-positions.reader.js +41 -0
  177. package/dist/read/user-positions/user-positions.types.d.ts +2590 -0
  178. package/dist/read/user-positions/user-positions.types.d.ts.map +1 -0
  179. package/dist/read/user-positions/user-positions.types.js +31 -0
  180. package/dist/read/user-subaccounts/user-subaccounts.reader.d.ts +18 -0
  181. package/dist/read/user-subaccounts/user-subaccounts.reader.d.ts.map +1 -0
  182. package/dist/read/user-subaccounts/user-subaccounts.reader.js +28 -0
  183. package/dist/read/user-subaccounts/user-subaccounts.types.d.ts +21 -0
  184. package/dist/read/user-subaccounts/user-subaccounts.types.d.ts.map +1 -0
  185. package/dist/read/user-subaccounts/user-subaccounts.types.js +15 -0
  186. package/dist/read/user-trade-history/user-trade-history.reader.d.ts +33 -0
  187. package/dist/read/user-trade-history/user-trade-history.reader.d.ts.map +1 -0
  188. package/dist/read/user-trade-history/user-trade-history.reader.js +32 -0
  189. package/dist/read/user-trade-history/user-trade-history.types.d.ts +52 -0
  190. package/dist/read/user-trade-history/user-trade-history.types.d.ts.map +1 -0
  191. package/dist/read/user-trade-history/user-trade-history.types.js +26 -0
  192. package/dist/read/user-vaults/user-vaults.reader.d.ts +26 -0
  193. package/dist/read/user-vaults/user-vaults.reader.d.ts.map +1 -0
  194. package/dist/read/user-vaults/user-vaults.reader.js +32 -0
  195. package/dist/read/user-vaults/user-vaults.types.d.ts +39 -0
  196. package/dist/read/user-vaults/user-vaults.types.d.ts.map +1 -0
  197. package/dist/read/user-vaults/user-vaults.types.js +21 -0
  198. package/dist/read/vault/vault.reader.d.ts +95 -0
  199. package/dist/read/vault/vault.reader.d.ts.map +1 -0
  200. package/dist/read/vault/vault.reader.js +168 -0
  201. package/dist/read/vault/vault.types.d.ts +49 -0
  202. package/dist/read/vault/vault.types.d.ts.map +1 -0
  203. package/dist/read/vault/vault.types.js +45 -0
  204. package/dist/read/vaults/vaults.reader.d.ts +72 -0
  205. package/dist/read/vaults/vaults.reader.d.ts.map +1 -0
  206. package/dist/read/vaults/vaults.reader.js +63 -0
  207. package/dist/read/vaults/vaults.types.d.ts +140 -0
  208. package/dist/read/vaults/vaults.types.d.ts.map +1 -0
  209. package/dist/read/vaults/vaults.types.js +71 -0
  210. package/dist/read/ws-subscription.d.ts +21 -0
  211. package/dist/read/ws-subscription.d.ts.map +1 -0
  212. package/dist/read/ws-subscription.js +170 -0
  213. package/dist/subaccount-types.d.ts +24 -0
  214. package/dist/subaccount-types.d.ts.map +1 -0
  215. package/dist/subaccount-types.js +11 -0
  216. package/dist/transaction-builder.d.ts +14 -0
  217. package/dist/transaction-builder.d.ts.map +1 -0
  218. package/dist/transaction-builder.js +40 -0
  219. package/dist/tsconfig.tsbuildinfo +1 -0
  220. package/dist/utils.d.ts +56 -0
  221. package/dist/utils.d.ts.map +1 -0
  222. package/dist/utils.js +164 -0
  223. package/dist/vault-types.d.ts +43 -0
  224. package/dist/vault-types.d.ts.map +1 -0
  225. package/dist/vault-types.js +11 -0
  226. package/dist/write.d.ts +271 -0
  227. package/dist/write.d.ts.map +1 -0
  228. package/dist/write.js +485 -0
  229. package/eslint.config.mjs +25 -0
  230. package/package.json +39 -0
  231. package/readme.md +257 -0
  232. package/sdk_reference.md +876 -0
  233. package/src/abi/generate-abis.ts +164 -0
  234. package/src/abi/json/netna.json +1323 -0
  235. package/src/abi/json/testnet.json +1315 -0
  236. package/src/abi/types.ts +23 -0
  237. package/src/admin.ts +284 -0
  238. package/src/base.ts +218 -0
  239. package/src/constants.ts +118 -0
  240. package/src/fee-pay.ts +39 -0
  241. package/src/gas/gas-price-manager.ts +115 -0
  242. package/src/index.ts +10 -0
  243. package/src/order-event.types.ts +65 -0
  244. package/src/order-status.ts +89 -0
  245. package/src/read/account-overview/account-overview.reader.ts +43 -0
  246. package/src/read/account-overview/account-overview.types.ts +45 -0
  247. package/src/read/base-reader.ts +41 -0
  248. package/src/read/candlesticks/candlesticks.reader.ts +61 -0
  249. package/src/read/candlesticks/candlesticks.types.ts +46 -0
  250. package/src/read/delegations/delegations.reader.ts +22 -0
  251. package/src/read/delegations/delegations.types.ts +19 -0
  252. package/src/read/index.ts +271 -0
  253. package/src/read/leaderboard/leaderboard.reader.ts +21 -0
  254. package/src/read/leaderboard/leaderboard.types.ts +26 -0
  255. package/src/read/market-contexts/market-contexts.reader.ts +26 -0
  256. package/src/read/market-contexts/market-contexts.types.ts +18 -0
  257. package/src/read/market-depth/market-depth.reader.ts +60 -0
  258. package/src/read/market-depth/market-depth.types.ts +24 -0
  259. package/src/read/market-prices/market-prices.reader.ts +61 -0
  260. package/src/read/market-prices/market-prices.types.ts +38 -0
  261. package/src/read/market-trades/market-trades.reader.ts +46 -0
  262. package/src/read/market-trades/market-trades.types.ts +34 -0
  263. package/src/read/markets/markets.reader.ts +82 -0
  264. package/src/read/markets/markets.types.ts +54 -0
  265. package/src/read/pagination.types.ts +18 -0
  266. package/src/read/portfolio-chart/portfolio-chart.reader.ts +20 -0
  267. package/src/read/portfolio-chart/portfolio-chart.types.ts +21 -0
  268. package/src/read/types.ts +129 -0
  269. package/src/read/user-active-twaps/user-active-twaps.reader.ts +36 -0
  270. package/src/read/user-active-twaps/user-active-twaps.types.ts +33 -0
  271. package/src/read/user-bulk-orders/user-bulk-orders.reader.ts +37 -0
  272. package/src/read/user-bulk-orders/user-bulk-orders.types.ts +32 -0
  273. package/src/read/user-funding-history/user-funding-history.reader.ts +38 -0
  274. package/src/read/user-funding-history/user-funding-history.types.ts +29 -0
  275. package/src/read/user-notifications/user-notifications.reader.ts +17 -0
  276. package/src/read/user-notifications/user-notifications.types.ts +61 -0
  277. package/src/read/user-open-orders/user-open-orders.reader.ts +36 -0
  278. package/src/read/user-open-orders/user-open-orders.types.ts +42 -0
  279. package/src/read/user-order-history/user-order-history.reader.ts +34 -0
  280. package/src/read/user-order-history/user-order-history.types.ts +44 -0
  281. package/src/read/user-positions/user-positions.reader.ts +55 -0
  282. package/src/read/user-positions/user-positions.types.ts +43 -0
  283. package/src/read/user-subaccounts/user-subaccounts.reader.ts +30 -0
  284. package/src/read/user-subaccounts/user-subaccounts.types.ts +21 -0
  285. package/src/read/user-trade-history/user-trade-history.reader.ts +38 -0
  286. package/src/read/user-trade-history/user-trade-history.types.ts +33 -0
  287. package/src/read/vaults/vaults.reader.ts +79 -0
  288. package/src/read/vaults/vaults.types.ts +106 -0
  289. package/src/read/ws-subscription.ts +200 -0
  290. package/src/subaccount-types.ts +31 -0
  291. package/src/transaction-builder.ts +75 -0
  292. package/src/utils.ts +255 -0
  293. package/src/write.ts +965 -0
  294. package/tsconfig.json +8 -0
@@ -0,0 +1,200 @@
1
+ import WebSocket, { ErrorEvent } from "isomorphic-ws";
2
+ import { z } from "zod/v4";
3
+
4
+ import { DecibelConfig } from "../constants";
5
+ import { bigIntReviver, prettifyMaybeZodError } from "../utils";
6
+
7
+ export class DecibelWsSubscription {
8
+ constructor(
9
+ readonly config: DecibelConfig,
10
+ readonly onError?: (error: ErrorEvent) => void,
11
+ ) {}
12
+
13
+ #ws: WebSocket | null = null;
14
+ #subscriptions = new Map<string, Set<(data: unknown) => void | Promise<void>>>();
15
+ #reconnectAttempts = 0;
16
+
17
+ #getSubscribeMessage(topic: string) {
18
+ return JSON.stringify({ Subscribe: { topic } });
19
+ }
20
+
21
+ #getUnsubscribeMessage(topic: string) {
22
+ return JSON.stringify({ Unsubscribe: { topic } });
23
+ }
24
+
25
+ #parseMessageData(data: WebSocket.Data): { topic: string; data: unknown } | null {
26
+ if (typeof data !== "string") {
27
+ return null;
28
+ }
29
+ try {
30
+ const jsonData: unknown = JSON.parse(data, bigIntReviver);
31
+ if (
32
+ jsonData &&
33
+ typeof jsonData === "object" &&
34
+ "topic" in jsonData &&
35
+ typeof jsonData.topic === "string"
36
+ ) {
37
+ const { topic, ...rest } = jsonData;
38
+ return { topic, data: rest };
39
+ }
40
+ return null;
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+
46
+ #open() {
47
+ if (this.#ws) {
48
+ return;
49
+ }
50
+
51
+ const ws = new WebSocket(this.config.tradingWsUrl);
52
+
53
+ ws.addEventListener("open", () => {
54
+ this.#reconnectAttempts = 0;
55
+ this.#subscriptions.keys().forEach((topic) => {
56
+ ws.send(this.#getSubscribeMessage(topic));
57
+ });
58
+ });
59
+
60
+ ws.addEventListener("message", (event) => {
61
+ if (
62
+ typeof event.data === "string" &&
63
+ (event.data.includes("UnsubscribeResponse") || event.data.includes("SubscribeResponse"))
64
+ ) {
65
+ // Ignore response messages for now. Maybe we'll make use of them in the future.
66
+ return;
67
+ }
68
+
69
+ const parsedMessage = this.#parseMessageData(event.data);
70
+ if (!parsedMessage) {
71
+ throw new Error("Unhandled WebSocket message:", { cause: event.data });
72
+ }
73
+ const { topic, data } = parsedMessage;
74
+ const listeners = this.#subscriptions.get(topic);
75
+ if (listeners) {
76
+ listeners.forEach((listener) => {
77
+ try {
78
+ void listener(data);
79
+ } catch (e) {
80
+ // Log error but don't break other listeners
81
+ console.error(`Error in WebSocket listener for topic : `, topic, " with error : ", e);
82
+ }
83
+ });
84
+ }
85
+ });
86
+
87
+ ws.addEventListener("error", (event) => {
88
+ this.onError?.(event);
89
+ ws.close();
90
+ });
91
+
92
+ ws.addEventListener("close", () => {
93
+ this.#ws = null;
94
+
95
+ // If there are still subscriptions, reconnect.
96
+ if (this.#subscriptions.size > 0) {
97
+ setTimeout(() => this.#open(), Math.pow(1.5, this.#reconnectAttempts) * 1000);
98
+ this.#reconnectAttempts++;
99
+ }
100
+ });
101
+
102
+ this.#ws = ws;
103
+ }
104
+
105
+ subscribe<TMessageData>(
106
+ topic: string,
107
+ schema: z.ZodType<TMessageData>,
108
+ onData: (data: TMessageData) => void | Promise<void>,
109
+ ) {
110
+ const listeners = this.#subscriptions.get(topic) ?? new Set();
111
+
112
+ // If subscription arent found, subscribe to topic first
113
+ if (listeners.size === 0) {
114
+ if (this.#ws?.readyState === WebSocket.OPEN) {
115
+ this.#ws.send(this.#getSubscribeMessage(topic));
116
+ }
117
+ }
118
+
119
+ const listener = (data: unknown) => {
120
+ try {
121
+ const parsedData = schema.parse(data);
122
+ void onData(parsedData);
123
+ } catch (e) {
124
+ throw prettifyMaybeZodError(e);
125
+ }
126
+ };
127
+
128
+ listeners.add(listener);
129
+
130
+ this.#subscriptions.set(topic, listeners);
131
+
132
+ // Open the WebSocket. All subscription messages will be sent when the WebSocket is opened.
133
+ if (!this.#ws) {
134
+ this.#open();
135
+ }
136
+
137
+ return () => this.unsubscribeByListener(topic, listener);
138
+ }
139
+
140
+ private unsubscribe(topic: string) {
141
+ if (!this.#subscriptions.has(topic)) return;
142
+
143
+ this.#subscriptions.delete(topic);
144
+
145
+ if (this.#ws?.readyState === WebSocket.OPEN) {
146
+ this.#ws.send(this.#getUnsubscribeMessage(topic));
147
+ }
148
+
149
+ // Close the WebSocket if the last subscription was removed.
150
+ if (this.#subscriptions.size === 0) {
151
+ this.#ws?.close();
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Removes the specified listener from the set of listeners for the given topic.
157
+ * If no listeners remain for the topic after removal, unsubscribes from the topic.
158
+ * If all subscriptions are removed, closes the WebSocket connection.
159
+ */
160
+ private unsubscribeByListener(topic: string, listener: (data: unknown) => void | Promise<void>) {
161
+ if (this.#subscriptions.has(topic)) {
162
+ const listeners = this.#subscriptions.get(topic);
163
+
164
+ if (!listeners) return;
165
+
166
+ // Remove the specified listener
167
+ listeners.delete(listener);
168
+
169
+ // If no listeners remain for the topic, unsubscribe from the topic
170
+ if (listeners.size === 0) {
171
+ this.unsubscribe(topic);
172
+ }
173
+ // Otherwise, update the listeners set for the topic
174
+ else {
175
+ this.#subscriptions.set(topic, listeners);
176
+ }
177
+ }
178
+ }
179
+
180
+ reset(topic: string) {
181
+ if (!this.#subscriptions.has(topic)) {
182
+ return;
183
+ }
184
+
185
+ if (this.#ws?.readyState === WebSocket.OPEN) {
186
+ this.#ws.send(this.#getUnsubscribeMessage(topic));
187
+ this.#ws.send(this.#getSubscribeMessage(topic));
188
+ return;
189
+ }
190
+ }
191
+
192
+ close() {
193
+ this.#subscriptions.clear();
194
+ this.#ws?.close();
195
+ }
196
+
197
+ readyState() {
198
+ return this.#ws?.readyState ?? WebSocket.CLOSED;
199
+ }
200
+ }
@@ -0,0 +1,31 @@
1
+ import z from "zod/v4";
2
+
3
+ // TODO: put this in a separate folder and split up WRITE sdk
4
+
5
+ export interface SubaccountCreatedEvent {
6
+ is_primary: boolean;
7
+ owner: string;
8
+ subaccount: string;
9
+ }
10
+
11
+ export interface SubaccountActiveChangedEvent {
12
+ is_active: boolean;
13
+ owner: string;
14
+ subaccount: string;
15
+ }
16
+
17
+ export interface CreateSubaccountResponse {
18
+ subaccountAddress: string | null;
19
+ }
20
+
21
+ export interface RenameSubaccountArgs {
22
+ subaccountAddress: string;
23
+ newName: string;
24
+ }
25
+
26
+ export const RenameSubaccountSchema = z.object({
27
+ subaccount_address: z.string(),
28
+ new_name: z.string(),
29
+ });
30
+
31
+ export type RenameSubaccount = z.infer<typeof RenameSubaccountSchema>;
@@ -0,0 +1,75 @@
1
+ import {
2
+ AccountAddress,
3
+ AccountAddressInput,
4
+ AptosConfig,
5
+ ChainId,
6
+ convertPayloadToInnerPayload,
7
+ EntryFunctionABI,
8
+ findFirstNonSignerArg,
9
+ generateTransactionPayloadWithABI,
10
+ InputEntryFunctionData,
11
+ InputEntryFunctionDataWithABI,
12
+ MoveFunction,
13
+ parseTypeTag,
14
+ RawTransaction,
15
+ SimpleTransaction,
16
+ TypeTag,
17
+ } from "@aptos-labs/ts-sdk";
18
+
19
+ export function buildSimpleTransactionSync(args: {
20
+ aptosConfig: AptosConfig;
21
+ sender: AccountAddressInput;
22
+ data: InputEntryFunctionData;
23
+ chainId: number;
24
+ gasUnitPrice: number;
25
+ abi: MoveFunction;
26
+ withFeePayer: boolean;
27
+ replayProtectionNonce: bigint;
28
+ timeDeltaMs?: number;
29
+ }) {
30
+ const txnPayload = generateTransactionPayloadWithABI({
31
+ aptosConfig: args.aptosConfig,
32
+ function: args.data.function,
33
+ functionArguments: args.data.functionArguments,
34
+ typeArguments: args.data.typeArguments,
35
+ abi: parseMoveFnAbiToEntryFnABI(args.abi),
36
+ } as InputEntryFunctionDataWithABI);
37
+
38
+ const expireTimestamp = generateExpireTimestamp(args.aptosConfig, args.timeDeltaMs);
39
+
40
+ const rawTxn = new RawTransaction(
41
+ AccountAddress.from(args.sender),
42
+ // If replay nonce is provided, use it as the sequence number
43
+ // This is an unused value, so it's specifically to show that the sequence number is not used
44
+ BigInt("0xdeadbeef"),
45
+ convertPayloadToInnerPayload(txnPayload, args.replayProtectionNonce),
46
+ // @Todo: Use gasPriceManager to get the max gas amount [as defaultMaxGasAmount might be very high number]
47
+ BigInt(args.aptosConfig.getDefaultMaxGasAmount()),
48
+ BigInt(args.gasUnitPrice),
49
+ BigInt(expireTimestamp),
50
+ new ChainId(args.chainId),
51
+ );
52
+
53
+ return new SimpleTransaction(rawTxn, args.withFeePayer ? AccountAddress.ZERO : undefined);
54
+ }
55
+
56
+ const parseMoveFnAbiToEntryFnABI = (functionAbi: MoveFunction): EntryFunctionABI => {
57
+ // Remove the signer arguments
58
+ const numSigners = findFirstNonSignerArg(functionAbi);
59
+
60
+ const params: TypeTag[] = [];
61
+ for (let i = numSigners; i < functionAbi.params.length; i += 1) {
62
+ const param = functionAbi.params[i];
63
+ if (!param) continue;
64
+ params.push(parseTypeTag(param, { allowGenerics: true }));
65
+ }
66
+
67
+ return {
68
+ signers: numSigners,
69
+ typeParameters: functionAbi.generic_type_params,
70
+ parameters: params,
71
+ };
72
+ };
73
+
74
+ export const generateExpireTimestamp = (aptosConfig: AptosConfig, timeDeltaMs = 0) =>
75
+ Math.floor((Date.now() + timeDeltaMs) / 1000) + aptosConfig.getDefaultTxnExpirySecFromNow();
package/src/utils.ts ADDED
@@ -0,0 +1,255 @@
1
+ import {
2
+ AccountAddress,
3
+ CommittedTransactionResponse,
4
+ createObjectAddress,
5
+ MoveString,
6
+ } from "@aptos-labs/ts-sdk";
7
+ import { z, ZodError } from "zod/v4";
8
+
9
+ import { QUERY_PARAM_KEYS } from "./constants";
10
+ import { PageParams, SearchTermParams, SortParams } from "./read";
11
+
12
+ export function getMarketAddr(name: string, perpEngineGlobalAddr: string) {
13
+ const marketNameBytes = new MoveString(name).bcsToBytes();
14
+ return createObjectAddress(AccountAddress.fromString(perpEngineGlobalAddr), marketNameBytes);
15
+ }
16
+
17
+ export type FetchOptions = Omit<RequestInit, "method" | "body">;
18
+
19
+ export interface PostRequestArgs<TResponseData> {
20
+ schema: z.ZodType<TResponseData>;
21
+ url: string;
22
+ body?: unknown;
23
+ options?: FetchOptions;
24
+ apiKey?: string;
25
+ }
26
+
27
+ export async function postRequest<TResponseData>({
28
+ schema,
29
+ url,
30
+ body,
31
+ options = {},
32
+ apiKey,
33
+ }: PostRequestArgs<TResponseData>) {
34
+ return baseRequest({
35
+ schema,
36
+ url,
37
+ method: "POST",
38
+ body,
39
+ options,
40
+ setJsonContentType: true,
41
+ apiKey,
42
+ });
43
+ }
44
+
45
+ export interface PatchRequestArgs<TResponseData> {
46
+ schema: z.ZodType<TResponseData>;
47
+ url: string;
48
+ body?: unknown;
49
+ options?: FetchOptions;
50
+ apiKey?: string;
51
+ }
52
+
53
+ export async function patchRequest<TResponseData>({
54
+ schema,
55
+ url,
56
+ body,
57
+ options = {},
58
+ apiKey,
59
+ }: PatchRequestArgs<TResponseData>) {
60
+ return baseRequest({
61
+ schema,
62
+ url,
63
+ method: "PATCH",
64
+ body,
65
+ options,
66
+ setJsonContentType: true,
67
+ apiKey,
68
+ });
69
+ }
70
+
71
+ export interface GetRequestArgs<TResponseData> {
72
+ schema: z.ZodType<TResponseData>;
73
+ url: string;
74
+ queryParams?: ConstructorParameters<typeof URLSearchParams>[0];
75
+ options?: FetchOptions;
76
+ apiKey?: string;
77
+ }
78
+
79
+ export async function getRequest<TResponseData>({
80
+ schema,
81
+ url,
82
+ queryParams,
83
+ options = {},
84
+ apiKey,
85
+ }: GetRequestArgs<TResponseData>) {
86
+ return baseRequest({
87
+ schema,
88
+ url,
89
+ method: "GET",
90
+ queryParams,
91
+ options,
92
+ apiKey,
93
+ });
94
+ }
95
+
96
+ interface BaseRequestArgs<TResponseData> {
97
+ schema: z.ZodType<TResponseData>;
98
+ url: string;
99
+ method: "GET" | "POST" | "PATCH";
100
+ options?: FetchOptions;
101
+ body?: unknown;
102
+ queryParams?: ConstructorParameters<typeof URLSearchParams>[0];
103
+ setJsonContentType?: boolean;
104
+ apiKey?: string;
105
+ }
106
+
107
+ async function baseRequest<TResponseData>({
108
+ schema,
109
+ url,
110
+ method,
111
+ options = {},
112
+ body,
113
+ queryParams,
114
+ setJsonContentType = false,
115
+ apiKey,
116
+ }: BaseRequestArgs<TResponseData>) {
117
+ const { headers: argHeaders, credentials, ...restOptions } = options;
118
+
119
+ const headers = new Headers(argHeaders);
120
+ if (setJsonContentType) {
121
+ headers.set("Content-Type", "application/json");
122
+ }
123
+ if (apiKey) {
124
+ headers.set("Authorization", `Bearer ${apiKey}`);
125
+ }
126
+
127
+ const queryString = queryParams ? `?${new URLSearchParams(queryParams).toString()}` : "";
128
+ const fullUrl = `${url}${queryString}`;
129
+
130
+ const fetchInit: RequestInit = {
131
+ method,
132
+ headers,
133
+ credentials,
134
+ ...restOptions,
135
+ };
136
+
137
+ if (body !== undefined) {
138
+ fetchInit.body = JSON.stringify(body);
139
+ }
140
+
141
+ const response = await fetch(fullUrl, fetchInit);
142
+ const { status, statusText } = response;
143
+
144
+ if (!response.ok) {
145
+ const message = await response.text();
146
+ throw new Error(`HTTP Error ${status} (${statusText}): ${message}`);
147
+ }
148
+
149
+ const textData = await response.text();
150
+ try {
151
+ const data = schema.parse(JSON.parse(textData, bigIntReviver));
152
+ return { data, status, statusText };
153
+ } catch (e) {
154
+ throw prettifyMaybeZodError(e);
155
+ }
156
+ }
157
+
158
+ export function prettifyMaybeZodError(e: unknown) {
159
+ if (e instanceof ZodError) {
160
+ return new Error(z.prettifyError(e), { cause: e });
161
+ }
162
+ return e;
163
+ }
164
+
165
+ export function bigIntReviver(key: string, value: unknown) {
166
+ if (
167
+ value &&
168
+ typeof value === "object" &&
169
+ "$bigint" in value &&
170
+ typeof value.$bigint === "string"
171
+ ) {
172
+ return BigInt(value.$bigint);
173
+ }
174
+ return value;
175
+ }
176
+
177
+ export function getPrimarySubaccountAddr(addr: AccountAddress | string) {
178
+ const account = typeof addr === "string" ? AccountAddress.fromString(addr) : addr;
179
+ const seed = new TextEncoder().encode("decibel_dex_primary");
180
+ return createObjectAddress(account, seed).toString();
181
+ }
182
+
183
+ export function getVaultShareAddress(vaultAddress: string) {
184
+ const seed = new TextEncoder().encode("vault_share_asset");
185
+ return createObjectAddress(AccountAddress.fromString(vaultAddress), seed).toString();
186
+ }
187
+
188
+ type KnownQueryParams = Partial<PageParams & SearchTermParams & SortParams<string>>;
189
+
190
+ export const PARAM_MAP: Record<keyof KnownQueryParams, string> = {
191
+ limit: QUERY_PARAM_KEYS.limit,
192
+ offset: QUERY_PARAM_KEYS.offset,
193
+ sortKey: QUERY_PARAM_KEYS.sortKey,
194
+ sortDir: QUERY_PARAM_KEYS.sortDir,
195
+ searchTerm: QUERY_PARAM_KEYS.searchTerm,
196
+ };
197
+
198
+ /**
199
+ * Construct query params from an args object, supporting optional PageParams, SearchTermParams, and generic SortParams.
200
+ * @param args - The argument object, which may include page, search, and sort params.
201
+ * @returns URLSearchParams instance with the constructed query parameters.
202
+ */
203
+ export function constructKnownQueryParams(args: KnownQueryParams): URLSearchParams {
204
+ const queryParams = new URLSearchParams();
205
+
206
+ Object.keys(args).forEach((_argKey) => {
207
+ const argKey = _argKey as keyof KnownQueryParams;
208
+
209
+ const value = args[argKey];
210
+
211
+ const paramKey = PARAM_MAP[argKey];
212
+
213
+ if (paramKey && value !== undefined && !(typeof value === "string" && value.trim() === "")) {
214
+ queryParams.set(paramKey, String(value));
215
+ }
216
+ });
217
+
218
+ return queryParams;
219
+ }
220
+
221
+ export function generateRandomReplayProtectionNonce() {
222
+ const buf = new Uint32Array(2);
223
+
224
+ crypto.getRandomValues(buf);
225
+
226
+ const valueAtIndex0 = buf[0];
227
+
228
+ const valueAtIndex1 = buf[1];
229
+
230
+ if (!valueAtIndex0 || !valueAtIndex1) return null;
231
+
232
+ // combine two 32-bit parts into a single 64-bit bigint
233
+ return (BigInt(valueAtIndex0) << BigInt(32)) | BigInt(valueAtIndex1);
234
+ }
235
+
236
+ export const extractVaultAddressFromCreateTx = (createVaultTx: CommittedTransactionResponse) => {
237
+ // Extract vault address from transaction events
238
+ let vaultAddress: string | { inner: string } | null = null;
239
+ if ("events" in createVaultTx && Array.isArray(createVaultTx.events)) {
240
+ for (const event of createVaultTx.events) {
241
+ if (event.type.includes("::vault::VaultCreatedEvent")) {
242
+ const eventData = event.data as { vault: string | { inner: string } };
243
+ vaultAddress = eventData.vault;
244
+ break;
245
+ }
246
+ }
247
+ }
248
+
249
+ if (!vaultAddress) throw new Error("Unable to extract vault address from transaction");
250
+
251
+ vaultAddress =
252
+ typeof vaultAddress === "object" && "inner" in vaultAddress ? vaultAddress.inner : vaultAddress;
253
+
254
+ return vaultAddress;
255
+ };