@megatao/sdk 1.1.0

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 (228) hide show
  1. package/.env.example +37 -0
  2. package/CHANGELOG.md +19 -0
  3. package/README.md +199 -0
  4. package/bin/alf +4 -0
  5. package/cli/README.md +198 -0
  6. package/cli/TEST_MANUAL.md +577 -0
  7. package/cli/commands/account.ts +545 -0
  8. package/cli/commands/funding.ts +481 -0
  9. package/cli/commands/liquidation.ts +523 -0
  10. package/cli/commands/market.ts +590 -0
  11. package/cli/commands/orders.ts +395 -0
  12. package/cli/commands/position.ts +1085 -0
  13. package/cli/commands/shared/positionUtils.ts +239 -0
  14. package/cli/commands/trading.ts +483 -0
  15. package/cli/commands/utils.ts +281 -0
  16. package/cli/commands/vault.ts +522 -0
  17. package/cli/index.ts +169 -0
  18. package/cli/interactive.ts +530 -0
  19. package/cli/utils/client.ts +457 -0
  20. package/cli/utils/config.ts +226 -0
  21. package/cli/utils/display.ts +258 -0
  22. package/cli/utils/index.ts +10 -0
  23. package/cli/utils/prompts.ts +364 -0
  24. package/config.example.json +23 -0
  25. package/dist/AlphaFuturesClient.d.ts +36 -0
  26. package/dist/AlphaFuturesClient.d.ts.map +1 -0
  27. package/dist/AlphaFuturesClient.js +116 -0
  28. package/dist/AlphaFuturesClient.js.map +1 -0
  29. package/dist/abi/Alpha.json +5987 -0
  30. package/dist/abi/abis.d.ts +319 -0
  31. package/dist/abi/abis.d.ts.map +1 -0
  32. package/dist/abi/abis.js +128 -0
  33. package/dist/abi/abis.js.map +1 -0
  34. package/dist/abi/index.d.ts +11 -0
  35. package/dist/abi/index.d.ts.map +1 -0
  36. package/dist/abi/index.js +15 -0
  37. package/dist/abi/index.js.map +1 -0
  38. package/dist/config/contracts.config.d.ts +70 -0
  39. package/dist/config/contracts.config.d.ts.map +1 -0
  40. package/dist/config/contracts.config.js +137 -0
  41. package/dist/config/contracts.config.js.map +1 -0
  42. package/dist/config/environments/alpha.config.d.ts +17 -0
  43. package/dist/config/environments/alpha.config.d.ts.map +1 -0
  44. package/dist/config/environments/alpha.config.js +140 -0
  45. package/dist/config/environments/alpha.config.js.map +1 -0
  46. package/dist/config/environments/beta.config.d.ts +16 -0
  47. package/dist/config/environments/beta.config.d.ts.map +1 -0
  48. package/dist/config/environments/beta.config.js +131 -0
  49. package/dist/config/environments/beta.config.js.map +1 -0
  50. package/dist/config/environments/dev.config.d.ts +13 -0
  51. package/dist/config/environments/dev.config.d.ts.map +1 -0
  52. package/dist/config/environments/dev.config.js +123 -0
  53. package/dist/config/environments/dev.config.js.map +1 -0
  54. package/dist/config/environments/index.d.ts +48 -0
  55. package/dist/config/environments/index.d.ts.map +1 -0
  56. package/dist/config/environments/index.js +81 -0
  57. package/dist/config/environments/index.js.map +1 -0
  58. package/dist/config/environments/localhost.config.d.ts +16 -0
  59. package/dist/config/environments/localhost.config.d.ts.map +1 -0
  60. package/dist/config/environments/localhost.config.js +152 -0
  61. package/dist/config/environments/localhost.config.js.map +1 -0
  62. package/dist/config/environments/prod.config.d.ts +20 -0
  63. package/dist/config/environments/prod.config.d.ts.map +1 -0
  64. package/dist/config/environments/prod.config.js +143 -0
  65. package/dist/config/environments/prod.config.js.map +1 -0
  66. package/dist/config/index.d.ts +7 -0
  67. package/dist/config/index.d.ts.map +1 -0
  68. package/dist/config/index.js +41 -0
  69. package/dist/config/index.js.map +1 -0
  70. package/dist/constants/assets.d.ts +76 -0
  71. package/dist/constants/assets.d.ts.map +1 -0
  72. package/dist/constants/assets.js +277 -0
  73. package/dist/constants/assets.js.map +1 -0
  74. package/dist/constants/contracts.d.ts +41 -0
  75. package/dist/constants/contracts.d.ts.map +1 -0
  76. package/dist/constants/contracts.js +57 -0
  77. package/dist/constants/contracts.js.map +1 -0
  78. package/dist/constants/index.d.ts +36 -0
  79. package/dist/constants/index.d.ts.map +1 -0
  80. package/dist/constants/index.js +75 -0
  81. package/dist/constants/index.js.map +1 -0
  82. package/dist/constants/networks.d.ts +32 -0
  83. package/dist/constants/networks.d.ts.map +1 -0
  84. package/dist/constants/networks.js +174 -0
  85. package/dist/constants/networks.js.map +1 -0
  86. package/dist/contracts/index.d.ts +5 -0
  87. package/dist/contracts/index.d.ts.map +1 -0
  88. package/dist/contracts/index.js +21 -0
  89. package/dist/contracts/index.js.map +1 -0
  90. package/dist/contracts/viem/AlphaViem.d.ts +518 -0
  91. package/dist/contracts/viem/AlphaViem.d.ts.map +1 -0
  92. package/dist/contracts/viem/AlphaViem.js +1287 -0
  93. package/dist/contracts/viem/AlphaViem.js.map +1 -0
  94. package/dist/contracts/viem/PriceOracleViem.d.ts +71 -0
  95. package/dist/contracts/viem/PriceOracleViem.d.ts.map +1 -0
  96. package/dist/contracts/viem/PriceOracleViem.js +212 -0
  97. package/dist/contracts/viem/PriceOracleViem.js.map +1 -0
  98. package/dist/contracts/viem/index.d.ts +9 -0
  99. package/dist/contracts/viem/index.d.ts.map +1 -0
  100. package/dist/contracts/viem/index.js +17 -0
  101. package/dist/contracts/viem/index.js.map +1 -0
  102. package/dist/errors/index.d.ts +44 -0
  103. package/dist/errors/index.d.ts.map +1 -0
  104. package/dist/errors/index.js +83 -0
  105. package/dist/errors/index.js.map +1 -0
  106. package/dist/index.d.ts +19 -0
  107. package/dist/index.d.ts.map +1 -0
  108. package/dist/index.js +60 -0
  109. package/dist/index.js.map +1 -0
  110. package/dist/types/alpha.d.ts +299 -0
  111. package/dist/types/alpha.d.ts.map +1 -0
  112. package/dist/types/alpha.js +6 -0
  113. package/dist/types/alpha.js.map +1 -0
  114. package/dist/types/client.d.ts +24 -0
  115. package/dist/types/client.d.ts.map +1 -0
  116. package/dist/types/client.js +13 -0
  117. package/dist/types/client.js.map +1 -0
  118. package/dist/types/contracts.d.ts +48 -0
  119. package/dist/types/contracts.d.ts.map +1 -0
  120. package/dist/types/contracts.js +6 -0
  121. package/dist/types/contracts.js.map +1 -0
  122. package/dist/types/funding.d.ts +27 -0
  123. package/dist/types/funding.d.ts.map +1 -0
  124. package/dist/types/funding.js +6 -0
  125. package/dist/types/funding.js.map +1 -0
  126. package/dist/types/index.d.ts +92 -0
  127. package/dist/types/index.d.ts.map +1 -0
  128. package/dist/types/index.js +47 -0
  129. package/dist/types/index.js.map +1 -0
  130. package/dist/types/liquidation.d.ts +20 -0
  131. package/dist/types/liquidation.d.ts.map +1 -0
  132. package/dist/types/liquidation.js +6 -0
  133. package/dist/types/liquidation.js.map +1 -0
  134. package/dist/types/margin.d.ts +29 -0
  135. package/dist/types/margin.d.ts.map +1 -0
  136. package/dist/types/margin.js +6 -0
  137. package/dist/types/margin.js.map +1 -0
  138. package/dist/types/oracle.d.ts +21 -0
  139. package/dist/types/oracle.d.ts.map +1 -0
  140. package/dist/types/oracle.js +6 -0
  141. package/dist/types/oracle.js.map +1 -0
  142. package/dist/types/positions.d.ts +43 -0
  143. package/dist/types/positions.d.ts.map +1 -0
  144. package/dist/types/positions.js +13 -0
  145. package/dist/types/positions.js.map +1 -0
  146. package/dist/utils/calculations.d.ts +84 -0
  147. package/dist/utils/calculations.d.ts.map +1 -0
  148. package/dist/utils/calculations.js +155 -0
  149. package/dist/utils/calculations.js.map +1 -0
  150. package/dist/utils/errors.d.ts +24 -0
  151. package/dist/utils/errors.d.ts.map +1 -0
  152. package/dist/utils/errors.js +129 -0
  153. package/dist/utils/errors.js.map +1 -0
  154. package/dist/utils/events.d.ts +40 -0
  155. package/dist/utils/events.d.ts.map +1 -0
  156. package/dist/utils/events.js +73 -0
  157. package/dist/utils/events.js.map +1 -0
  158. package/dist/utils/format.d.ts +40 -0
  159. package/dist/utils/format.d.ts.map +1 -0
  160. package/dist/utils/format.js +86 -0
  161. package/dist/utils/format.js.map +1 -0
  162. package/dist/utils/index.d.ts +10 -0
  163. package/dist/utils/index.d.ts.map +1 -0
  164. package/dist/utils/index.js +26 -0
  165. package/dist/utils/index.js.map +1 -0
  166. package/dist/utils/network.d.ts +52 -0
  167. package/dist/utils/network.d.ts.map +1 -0
  168. package/dist/utils/network.js +192 -0
  169. package/dist/utils/network.js.map +1 -0
  170. package/dist/utils/positionCalculations.d.ts +145 -0
  171. package/dist/utils/positionCalculations.d.ts.map +1 -0
  172. package/dist/utils/positionCalculations.js +278 -0
  173. package/dist/utils/positionCalculations.js.map +1 -0
  174. package/dist/utils/validation.d.ts +28 -0
  175. package/dist/utils/validation.d.ts.map +1 -0
  176. package/dist/utils/validation.js +68 -0
  177. package/dist/utils/validation.js.map +1 -0
  178. package/docs/README.md +40 -0
  179. package/docs/api/API.md +831 -0
  180. package/docs/guides/GETTING_STARTED.md +316 -0
  181. package/docs/guides/TRADING_GUIDE.md +677 -0
  182. package/docs/integration/INTEGRATION_GUIDE.md +1679 -0
  183. package/docs/integration/VIEM_INTEGRATION.md +294 -0
  184. package/docs/reference/CLI_QUICK_REFERENCE.md +197 -0
  185. package/docs/reference/TROUBLESHOOTING.md +922 -0
  186. package/package.json +113 -0
  187. package/src/AlphaFuturesClient.ts +158 -0
  188. package/src/abi/.gitkeep +1 -0
  189. package/src/abi/Alpha.json +5987 -0
  190. package/src/abi/README.md +99 -0
  191. package/src/abi/abis.ts +131 -0
  192. package/src/abi/index.ts +13 -0
  193. package/src/config/contracts.config.ts +186 -0
  194. package/src/config/environments/alpha.config.ts +139 -0
  195. package/src/config/environments/beta.config.ts +130 -0
  196. package/src/config/environments/dev.config.ts +122 -0
  197. package/src/config/environments/index.ts +87 -0
  198. package/src/config/environments/localhost.config.ts +153 -0
  199. package/src/config/environments/prod.config.ts +142 -0
  200. package/src/config/index.ts +29 -0
  201. package/src/constants/assets.ts +299 -0
  202. package/src/constants/contracts.ts +64 -0
  203. package/src/constants/index.ts +69 -0
  204. package/src/constants/networks.ts +182 -0
  205. package/src/contracts/index.ts +5 -0
  206. package/src/contracts/viem/AlphaViem.ts +1615 -0
  207. package/src/contracts/viem/PriceOracleViem.ts +272 -0
  208. package/src/contracts/viem/index.ts +11 -0
  209. package/src/errors/index.ts +87 -0
  210. package/src/index.ts +59 -0
  211. package/src/types/VIEM_TYPES_README.md +70 -0
  212. package/src/types/alpha.ts +358 -0
  213. package/src/types/client.ts +27 -0
  214. package/src/types/contracts.ts +74 -0
  215. package/src/types/funding.ts +31 -0
  216. package/src/types/index.ts +108 -0
  217. package/src/types/liquidation.ts +23 -0
  218. package/src/types/margin.ts +34 -0
  219. package/src/types/oracle.ts +24 -0
  220. package/src/types/positions.ts +48 -0
  221. package/src/utils/calculations.ts +175 -0
  222. package/src/utils/errors.ts +147 -0
  223. package/src/utils/events.ts +98 -0
  224. package/src/utils/format.ts +84 -0
  225. package/src/utils/index.ts +10 -0
  226. package/src/utils/network.ts +212 -0
  227. package/src/utils/positionCalculations.ts +317 -0
  228. package/src/utils/validation.ts +76 -0
@@ -0,0 +1,1287 @@
1
+ "use strict";
2
+ /**
3
+ * Alpha contract wrapper using Viem
4
+ * Main implementation of ALPHA perpetual futures protocol
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.AlphaViem = void 0;
11
+ const viem_1 = require("viem");
12
+ const Alpha_json_1 = __importDefault(require("../../abi/Alpha.json"));
13
+ class AlphaViem {
14
+ constructor(contractAddress, publicClient, walletClient, collateralTokenAddress) {
15
+ this.contractAddress = contractAddress;
16
+ this.publicClient = publicClient;
17
+ this.walletClient = walletClient;
18
+ this.collateralTokenAddress = collateralTokenAddress;
19
+ }
20
+ get isNativeCollateral() {
21
+ return (!this.collateralTokenAddress ||
22
+ this.collateralTokenAddress === '0x0000000000000000000000000000000000000000');
23
+ }
24
+ // ============ Utility Functions ============
25
+ /**
26
+ * Convert bytes32 (padded by ABI encoding) to bytes16
27
+ * Takes first 16 bytes from the 32 byte value
28
+ */
29
+ bytes32ToBytes16(bytes32) {
30
+ // Remove 0x prefix if present
31
+ const hex = bytes32.startsWith('0x') ? bytes32.slice(2) : bytes32;
32
+ // Take first 32 characters (16 bytes)
33
+ const bytes16Hex = hex.slice(0, 32);
34
+ return `0x${bytes16Hex}`;
35
+ }
36
+ /**
37
+ * Simulate a contract transaction before writing to catch errors early
38
+ * This prevents sending failed transactions to the wallet
39
+ */
40
+ async simulateAndWriteContract(writeParams) {
41
+ if (!this.walletClient) {
42
+ throw new Error('Wallet client required for write operations');
43
+ }
44
+ if (!this.walletClient.account) {
45
+ throw new Error('Wallet client must have an account for transactions');
46
+ }
47
+ // Simulate the transaction first to catch errors early
48
+ try {
49
+ await this.publicClient.simulateContract({
50
+ address: writeParams.address,
51
+ abi: writeParams.abi,
52
+ functionName: writeParams.functionName,
53
+ args: writeParams.args,
54
+ account: this.walletClient.account.address,
55
+ value: writeParams.value,
56
+ });
57
+ }
58
+ catch (simulationError) {
59
+ console.error('[simulateContract] Raw viem error:', simulationError);
60
+ let errorMessage = 'Transaction simulation failed';
61
+ let errorName;
62
+ let errorArgs;
63
+ // Walk the viem error chain to find decoded custom error data
64
+ for (let cur = simulationError; cur; cur = cur.cause) {
65
+ if (cur.data?.errorName) {
66
+ errorName = cur.data.errorName;
67
+ errorArgs = cur.data.args ? [...cur.data.args] : undefined;
68
+ errorMessage = errorName;
69
+ if (errorArgs && errorArgs.length > 0) {
70
+ errorMessage += `: ${errorArgs
71
+ .map((arg) => (typeof arg === 'bigint' ? arg.toString() : String(arg)))
72
+ .join(', ')}`;
73
+ }
74
+ break;
75
+ }
76
+ }
77
+ // If no decoded error found, fall back to message extraction
78
+ if (!errorName) {
79
+ if (simulationError.cause?.shortMessage) {
80
+ errorMessage = simulationError.cause.shortMessage;
81
+ }
82
+ else if (simulationError.shortMessage) {
83
+ errorMessage = simulationError.shortMessage;
84
+ }
85
+ else if (simulationError.cause?.message) {
86
+ errorMessage = simulationError.cause.message;
87
+ }
88
+ else if (simulationError.message) {
89
+ errorMessage = simulationError.message;
90
+ }
91
+ }
92
+ const error = new Error(errorMessage);
93
+ error.code = 'SIMULATION_FAILED';
94
+ error.cause = simulationError;
95
+ error.simulationError = true;
96
+ error.contractErrorName = errorName;
97
+ error.contractErrorArgs = errorArgs;
98
+ throw error;
99
+ }
100
+ // If simulation succeeds, proceed with the actual write
101
+ // Note: writeContract needs the full account object, not just the address
102
+ return await this.walletClient.writeContract({
103
+ ...writeParams,
104
+ account: this.walletClient.account,
105
+ });
106
+ }
107
+ // ============ Admin Functions ============
108
+ async initializeMarket(market, maxLeverage, maintenanceMargin, liquidationFee, options) {
109
+ if (!this.walletClient)
110
+ throw new Error('Wallet client required for write operations');
111
+ const { waitForConfirmation, ...txOptions } = options || {};
112
+ if (!this.walletClient.account) {
113
+ throw new Error('Wallet client must have an account for transactions');
114
+ }
115
+ const hash = await this.walletClient.writeContract({
116
+ address: this.contractAddress,
117
+ abi: Alpha_json_1.default,
118
+ functionName: 'initializeMarket',
119
+ args: [market, maxLeverage, maintenanceMargin, liquidationFee],
120
+ account: this.walletClient.account,
121
+ ...txOptions,
122
+ });
123
+ if (waitForConfirmation) {
124
+ await this.publicClient.waitForTransactionReceipt({ hash });
125
+ return hash;
126
+ }
127
+ return hash;
128
+ }
129
+ async addMarket(market, symbol, options) {
130
+ if (!this.walletClient)
131
+ throw new Error('Wallet client required for write operations');
132
+ const { waitForConfirmation, ...txOptions } = options || {};
133
+ if (!this.walletClient.account) {
134
+ throw new Error('Wallet client must have an account for transactions');
135
+ }
136
+ const hash = await this.walletClient.writeContract({
137
+ address: this.contractAddress,
138
+ abi: Alpha_json_1.default,
139
+ functionName: 'addMarket',
140
+ args: [market, symbol],
141
+ account: this.walletClient.account,
142
+ ...txOptions,
143
+ });
144
+ if (waitForConfirmation) {
145
+ await this.publicClient.waitForTransactionReceipt({ hash });
146
+ return hash;
147
+ }
148
+ return hash;
149
+ }
150
+ async seedVault(amount, options) {
151
+ if (!this.walletClient)
152
+ throw new Error('Wallet client required for write operations');
153
+ const { waitForConfirmation, ...txOptions } = options || {};
154
+ if (!this.walletClient.account) {
155
+ throw new Error('Wallet client must have an account for transactions');
156
+ }
157
+ const hash = await this.walletClient.writeContract({
158
+ address: this.contractAddress,
159
+ abi: Alpha_json_1.default,
160
+ functionName: 'seedVault',
161
+ args: [amount],
162
+ account: this.walletClient.account,
163
+ ...txOptions,
164
+ });
165
+ if (waitForConfirmation) {
166
+ await this.publicClient.waitForTransactionReceipt({ hash });
167
+ return hash;
168
+ }
169
+ return hash;
170
+ }
171
+ // ============ Margin Management ============
172
+ async deposit(amount, options) {
173
+ const { waitForConfirmation, ...txOptions } = options || {};
174
+ if (!this.walletClient?.account) {
175
+ throw new Error('Wallet client must have an account for transactions');
176
+ }
177
+ const hash = await this.simulateAndWriteContract({
178
+ address: this.contractAddress,
179
+ abi: Alpha_json_1.default,
180
+ functionName: 'deposit',
181
+ args: [amount],
182
+ account: this.walletClient.account.address,
183
+ ...(this.isNativeCollateral ? { value: amount } : {}),
184
+ ...txOptions,
185
+ });
186
+ if (waitForConfirmation) {
187
+ await this.publicClient.waitForTransactionReceipt({ hash });
188
+ return hash;
189
+ }
190
+ return hash;
191
+ }
192
+ async withdraw(amount, options) {
193
+ const { waitForConfirmation, ...txOptions } = options || {};
194
+ if (!this.walletClient?.account) {
195
+ throw new Error('Wallet client must have an account for transactions');
196
+ }
197
+ const hash = await this.simulateAndWriteContract({
198
+ address: this.contractAddress,
199
+ abi: Alpha_json_1.default,
200
+ functionName: 'withdraw',
201
+ args: [amount],
202
+ account: this.walletClient.account.address,
203
+ ...txOptions,
204
+ });
205
+ if (waitForConfirmation) {
206
+ await this.publicClient.waitForTransactionReceipt({ hash });
207
+ return hash;
208
+ }
209
+ return hash;
210
+ }
211
+ // ============ Position Management ============
212
+ /**
213
+ * Opens a market position with specified margin, leverage, and slippage tolerance
214
+ * @param market - Market address
215
+ * @param isLong - True for long position, false for short
216
+ * @param margin - Collateral amount to risk (in wei)
217
+ * @param leverage - Leverage multiplier in 1e18 format (e.g., 3e18 for 3x)
218
+ * @param maxSlippage - Maximum allowed slippage in basis points
219
+ * @param options - Transaction options
220
+ * @returns Transaction hash
221
+ */
222
+ async openMarketPosition(market, isLong, margin, leverage, maxSlippage, options) {
223
+ const { waitForConfirmation, ...txOptions } = options || {};
224
+ if (!this.walletClient?.account) {
225
+ throw new Error('Wallet client must have an account for transactions');
226
+ }
227
+ // Contract expects a single struct parameter: MarketPositionParams
228
+ const params = {
229
+ market,
230
+ isLong,
231
+ margin,
232
+ leverage,
233
+ maxSlippage,
234
+ };
235
+ const hash = await this.simulateAndWriteContract({
236
+ address: this.contractAddress,
237
+ abi: Alpha_json_1.default,
238
+ functionName: 'openMarketPosition',
239
+ args: [params],
240
+ account: this.walletClient.account.address,
241
+ ...txOptions,
242
+ });
243
+ if (waitForConfirmation) {
244
+ await this.publicClient.waitForTransactionReceipt({ hash });
245
+ return hash;
246
+ }
247
+ return hash;
248
+ }
249
+ async openMarketPositionWithStruct(params, options) {
250
+ if (!this.walletClient)
251
+ throw new Error('Wallet client required for write operations');
252
+ const { waitForConfirmation, ...txOptions } = options || {};
253
+ if (!this.walletClient.account) {
254
+ throw new Error('Wallet client must have an account for transactions');
255
+ }
256
+ const hash = await this.walletClient.writeContract({
257
+ address: this.contractAddress,
258
+ abi: Alpha_json_1.default,
259
+ functionName: 'openMarketPositionWithStruct',
260
+ args: [params],
261
+ account: this.walletClient.account,
262
+ ...txOptions,
263
+ });
264
+ if (waitForConfirmation) {
265
+ await this.publicClient.waitForTransactionReceipt({ hash });
266
+ return hash;
267
+ }
268
+ return hash;
269
+ }
270
+ async closePosition(positionId, sizeToClose, options) {
271
+ const { waitForConfirmation, ...txOptions } = options || {};
272
+ if (!this.walletClient?.account) {
273
+ throw new Error('Wallet client must have an account for transactions');
274
+ }
275
+ const hash = await this.simulateAndWriteContract({
276
+ address: this.contractAddress,
277
+ abi: Alpha_json_1.default,
278
+ functionName: 'closePosition',
279
+ args: [positionId, sizeToClose],
280
+ account: this.walletClient.account.address,
281
+ ...txOptions,
282
+ });
283
+ if (waitForConfirmation) {
284
+ await this.publicClient.waitForTransactionReceipt({ hash });
285
+ return hash;
286
+ }
287
+ return hash;
288
+ }
289
+ /**
290
+ * Batch multiple contract calls into a single transaction using multicall.
291
+ * Handles ABI encoding internally.
292
+ *
293
+ * @param calls - Array of { functionName, args } to batch
294
+ * @param options - Optional transaction options
295
+ * @returns Transaction hash
296
+ *
297
+ * @example
298
+ * // Close multiple positions in one tx
299
+ * await alpha.multicall([
300
+ * { functionName: 'closePosition', args: [posId1, 0n] },
301
+ * { functionName: 'closePosition', args: [posId2, 0n] },
302
+ * ]);
303
+ */
304
+ async multicall(calls, options) {
305
+ const { waitForConfirmation, ...txOptions } = options || {};
306
+ if (!this.walletClient?.account) {
307
+ throw new Error('Wallet client must have an account for transactions');
308
+ }
309
+ if (calls.length === 0) {
310
+ throw new Error('No calls provided');
311
+ }
312
+ const calldata = calls.map((call) => (0, viem_1.encodeFunctionData)({
313
+ abi: Alpha_json_1.default,
314
+ functionName: call.functionName,
315
+ args: call.args ?? [],
316
+ }));
317
+ const hash = await this.simulateAndWriteContract({
318
+ address: this.contractAddress,
319
+ abi: Alpha_json_1.default,
320
+ functionName: 'multicall',
321
+ args: [calldata],
322
+ account: this.walletClient.account.address,
323
+ ...txOptions,
324
+ });
325
+ if (waitForConfirmation) {
326
+ await this.publicClient.waitForTransactionReceipt({ hash });
327
+ }
328
+ return hash;
329
+ }
330
+ /**
331
+ * Close multiple positions in a single transaction using multicall
332
+ * @param positionIds - Array of position IDs to close (bytes16 format)
333
+ * @param options - Optional transaction options
334
+ * @returns Transaction hash
335
+ */
336
+ async closeAllPositions(positionIds, options) {
337
+ if (positionIds.length === 0) {
338
+ throw new Error('No position IDs provided');
339
+ }
340
+ return this.multicall(positionIds.map((positionId) => ({
341
+ functionName: 'closePosition',
342
+ args: [positionId, 0n],
343
+ })), options);
344
+ }
345
+ // ============ Order Management ============
346
+ /**
347
+ * Places a limit order with specified margin and leverage
348
+ * @param market - Market address
349
+ * @param isBuy - True for buy order, false for sell
350
+ * @param margin - Collateral amount to risk
351
+ * @param leverage - Leverage multiplier in 1e18 format (e.g., 3e18 for 3x)
352
+ * @param price - Limit price in wei
353
+ * @param reduceOnlyType - 0=Normal, 1=TakeProfit (natural side), 2=StopLoss (opposite side)
354
+ * @param options - Transaction options
355
+ * @returns Transaction hash
356
+ */
357
+ async placeLimitOrder(market, isBuy, margin, leverage, price, reduceOnlyType = 0, options) {
358
+ const { waitForConfirmation, ...txOptions } = options || {};
359
+ if (!this.walletClient?.account) {
360
+ throw new Error('Wallet client must have an account for transactions');
361
+ }
362
+ const params = {
363
+ market,
364
+ isBuy,
365
+ margin,
366
+ leverage,
367
+ price,
368
+ reduceOnlyType,
369
+ };
370
+ const hash = await this.simulateAndWriteContract({
371
+ address: this.contractAddress,
372
+ abi: Alpha_json_1.default,
373
+ functionName: 'placeLimitOrder',
374
+ args: [params],
375
+ account: this.walletClient.account.address,
376
+ ...txOptions,
377
+ });
378
+ if (waitForConfirmation) {
379
+ await this.publicClient.waitForTransactionReceipt({ hash });
380
+ return hash;
381
+ }
382
+ return hash;
383
+ }
384
+ /**
385
+ * Places a limit order using a params struct
386
+ * @param params - LimitOrderParams struct containing all order parameters
387
+ * @param options - Transaction options
388
+ * @returns Transaction hash
389
+ */
390
+ async placeLimitOrderWithStruct(params, options) {
391
+ return this.placeLimitOrder(params.market, params.isBuy, params.margin, params.leverage, params.price, params.reduceOnlyType, options);
392
+ }
393
+ async cancelOrder(market, orderId, options) {
394
+ if (!this.walletClient)
395
+ throw new Error('Wallet client required for write operations');
396
+ const { waitForConfirmation, ...txOptions } = options || {};
397
+ if (!this.walletClient.account) {
398
+ throw new Error('Wallet client must have an account for transactions');
399
+ }
400
+ const hash = await this.walletClient.writeContract({
401
+ address: this.contractAddress,
402
+ abi: Alpha_json_1.default,
403
+ functionName: 'cancelOrder',
404
+ args: [market, orderId],
405
+ account: this.walletClient.account,
406
+ ...txOptions,
407
+ });
408
+ if (waitForConfirmation) {
409
+ await this.publicClient.waitForTransactionReceipt({ hash });
410
+ return hash;
411
+ }
412
+ return hash;
413
+ }
414
+ async cancelAllOrders(market, options) {
415
+ if (!this.walletClient)
416
+ throw new Error('Wallet client required for write operations');
417
+ const { waitForConfirmation, ...txOptions } = options || {};
418
+ if (!this.walletClient.account) {
419
+ throw new Error('Wallet client must have an account for transactions');
420
+ }
421
+ const hash = await this.walletClient.writeContract({
422
+ address: this.contractAddress,
423
+ abi: Alpha_json_1.default,
424
+ functionName: 'cancelAllOrders',
425
+ args: [market],
426
+ account: this.walletClient.account,
427
+ ...txOptions,
428
+ });
429
+ if (waitForConfirmation) {
430
+ await this.publicClient.waitForTransactionReceipt({ hash });
431
+ return hash;
432
+ }
433
+ return hash;
434
+ }
435
+ // ============ Liquidation Functions ============
436
+ async liquidatePosition(positionId, options) {
437
+ if (!this.walletClient)
438
+ throw new Error('Wallet client required for write operations');
439
+ const { waitForConfirmation, ...txOptions } = options || {};
440
+ if (!this.walletClient.account) {
441
+ throw new Error('Wallet client must have an account for transactions');
442
+ }
443
+ const hash = await this.walletClient.writeContract({
444
+ address: this.contractAddress,
445
+ abi: Alpha_json_1.default,
446
+ functionName: 'liquidatePosition',
447
+ args: [positionId],
448
+ account: this.walletClient.account,
449
+ ...txOptions,
450
+ });
451
+ if (waitForConfirmation) {
452
+ await this.publicClient.waitForTransactionReceipt({ hash });
453
+ return hash;
454
+ }
455
+ return hash;
456
+ }
457
+ async claimKeeperRewards(options) {
458
+ if (!this.walletClient)
459
+ throw new Error('Wallet client required for write operations');
460
+ const { waitForConfirmation, ...txOptions } = options || {};
461
+ if (!this.walletClient.account) {
462
+ throw new Error('Wallet client must have an account for transactions');
463
+ }
464
+ const hash = await this.walletClient.writeContract({
465
+ address: this.contractAddress,
466
+ abi: Alpha_json_1.default,
467
+ functionName: 'claimKeeperRewards',
468
+ args: [],
469
+ account: this.walletClient.account,
470
+ ...txOptions,
471
+ });
472
+ if (waitForConfirmation) {
473
+ await this.publicClient.waitForTransactionReceipt({ hash });
474
+ return hash;
475
+ }
476
+ return hash;
477
+ }
478
+ // ============ View Functions - Positions ============
479
+ async getPositionId(trader, market) {
480
+ const result = await this.publicClient.readContract({
481
+ address: this.contractAddress,
482
+ abi: Alpha_json_1.default,
483
+ functionName: 'getPositionId',
484
+ args: [trader, market],
485
+ });
486
+ // Convert bytes32 (padded) to bytes16
487
+ return this.bytes32ToBytes16(result);
488
+ }
489
+ async hasPosition(trader, market) {
490
+ return (await this.publicClient.readContract({
491
+ address: this.contractAddress,
492
+ abi: Alpha_json_1.default,
493
+ functionName: 'hasPosition',
494
+ args: [trader, market],
495
+ }));
496
+ }
497
+ async getPosition(positionId) {
498
+ const result = (await this.publicClient.readContract({
499
+ address: this.contractAddress,
500
+ abi: Alpha_json_1.default,
501
+ functionName: 'getPosition',
502
+ args: [positionId],
503
+ }));
504
+ // Ensure values are BigInt for calculations
505
+ const notionalValue = BigInt(result[3]);
506
+ const margin = BigInt(result[4]);
507
+ return {
508
+ // Based on ABI: [0] owner, [1] market, [2] isLong, [3] notionalValue, [4] margin, [5] entryPrice, [6] fundingIndex, [7] lastUpdateTime
509
+ notionalValue: result[3],
510
+ margin: result[4],
511
+ entryPrice: result[5],
512
+ isLong: result[2],
513
+ lastUpdated: result[7], // Maps from contract's lastUpdateTime
514
+ fundingIndex: result[6],
515
+ leverage: margin > 0n ? (notionalValue * 1000000000000000000n) / margin : 0n, // Calculate leverage in 1e18 format (notionalValue/margin * 1e18)
516
+ liquidationPrice: 0n, // Not returned by ABI - would need separate calculation
517
+ };
518
+ }
519
+ async getPositionDetails(positionId) {
520
+ return (await this.publicClient.readContract({
521
+ address: this.contractAddress,
522
+ abi: Alpha_json_1.default,
523
+ functionName: 'getPositionDetails',
524
+ args: [positionId],
525
+ }));
526
+ }
527
+ async getUserPositions(trader) {
528
+ const result = (await this.publicClient.readContract({
529
+ address: this.contractAddress,
530
+ abi: Alpha_json_1.default,
531
+ functionName: 'getUserPositions',
532
+ args: [trader],
533
+ }));
534
+ // Convert each bytes32 (padded) to bytes16
535
+ return result.map((id) => this.bytes32ToBytes16(id));
536
+ }
537
+ async getUserPositionsSummary(trader) {
538
+ const result = (await this.publicClient.readContract({
539
+ address: this.contractAddress,
540
+ abi: Alpha_json_1.default,
541
+ functionName: 'getUserPositionsSummary',
542
+ args: [trader],
543
+ }));
544
+ return {
545
+ totalPositions: result[0],
546
+ totalMargin: result[1],
547
+ totalUnrealizedPnl: result[2],
548
+ totalSize: result[3],
549
+ };
550
+ }
551
+ async calculateUnrealizedPnl(positionId) {
552
+ return (await this.publicClient.readContract({
553
+ address: this.contractAddress,
554
+ abi: Alpha_json_1.default,
555
+ functionName: 'calculateUnrealizedPnl',
556
+ args: [positionId],
557
+ }));
558
+ }
559
+ async getMarginRatio(positionId) {
560
+ return (await this.publicClient.readContract({
561
+ address: this.contractAddress,
562
+ abi: Alpha_json_1.default,
563
+ functionName: 'getMarginRatio',
564
+ args: [positionId],
565
+ }));
566
+ }
567
+ async isLiquidatable(positionId) {
568
+ return (await this.publicClient.readContract({
569
+ address: this.contractAddress,
570
+ abi: Alpha_json_1.default,
571
+ functionName: 'isLiquidatable',
572
+ args: [positionId],
573
+ }));
574
+ }
575
+ async getLiquidationStatus(positionId) {
576
+ const result = (await this.publicClient.readContract({
577
+ address: this.contractAddress,
578
+ abi: Alpha_json_1.default,
579
+ functionName: 'getLiquidationStatus',
580
+ args: [positionId],
581
+ }));
582
+ return {
583
+ isLiquidatable: result[0],
584
+ marginRatio: result[1],
585
+ requiredMargin: result[2],
586
+ liquidationPrice: result[3],
587
+ };
588
+ }
589
+ /**
590
+ * Get account-level liquidation status (cross-margin)
591
+ * When account equity < total maintenance, ALL positions are liquidatable (Hyperliquid-style)
592
+ */
593
+ async getAccountLiquidationStatus(trader) {
594
+ const result = (await this.publicClient.readContract({
595
+ address: this.contractAddress,
596
+ abi: Alpha_json_1.default,
597
+ functionName: 'getAccountLiquidationStatus',
598
+ args: [trader],
599
+ }));
600
+ return {
601
+ liquidatable: result[0],
602
+ worstPositionId: result[1],
603
+ accountEquity: result[2],
604
+ totalMaintenanceRequired: result[3],
605
+ };
606
+ }
607
+ /**
608
+ * Get cross-margin liquidation price for a position
609
+ * Uses Hyperliquid formula: accounts for all positions' PnL in the account
610
+ */
611
+ async getAccountLiquidationPrice(positionId) {
612
+ return (await this.publicClient.readContract({
613
+ address: this.contractAddress,
614
+ abi: Alpha_json_1.default,
615
+ functionName: 'getAccountLiquidationPrice',
616
+ args: [positionId],
617
+ }));
618
+ }
619
+ // ============ View Functions - Margin ============
620
+ /**
621
+ * Get raw deposited margin balance (excludes unrealized PnL).
622
+ * For account equity (balance + PnL), use getAccountSummary().
623
+ */
624
+ async getMarginBalance(trader) {
625
+ return (await this.publicClient.readContract({
626
+ address: this.contractAddress,
627
+ abi: Alpha_json_1.default,
628
+ functionName: 'getMarginBalance',
629
+ args: [trader],
630
+ }));
631
+ }
632
+ /**
633
+ * Get comprehensive account summary in a single RPC call.
634
+ * Returns deposited balance, account equity, unrealized PnL, locked margin, and available margin.
635
+ */
636
+ async getAccountSummary(trader) {
637
+ const result = (await this.publicClient.readContract({
638
+ address: this.contractAddress,
639
+ abi: Alpha_json_1.default,
640
+ functionName: 'getAccountSummary',
641
+ args: [trader],
642
+ }));
643
+ return {
644
+ depositedBalance: result.depositedBalance ?? result[0],
645
+ accountEquity: result.accountEquity ?? result[1],
646
+ unrealizedPnl: result.unrealizedPnl ?? result[2],
647
+ lockedMargin: result.lockedMargin ?? result[3],
648
+ availableMargin: result.availableMargin ?? result[4],
649
+ };
650
+ }
651
+ async getLockedMargin(trader) {
652
+ return (await this.publicClient.readContract({
653
+ address: this.contractAddress,
654
+ abi: Alpha_json_1.default,
655
+ functionName: 'getLockedMargin',
656
+ args: [trader],
657
+ }));
658
+ }
659
+ async getAvailableMargin(trader) {
660
+ return (await this.publicClient.readContract({
661
+ address: this.contractAddress,
662
+ abi: Alpha_json_1.default,
663
+ functionName: 'getAvailableMargin',
664
+ args: [trader],
665
+ }));
666
+ }
667
+ async getMaxUserDeposit() {
668
+ return (await this.publicClient.readContract({
669
+ address: this.contractAddress,
670
+ abi: Alpha_json_1.default,
671
+ functionName: 'getMaxUserDeposit',
672
+ args: [],
673
+ }));
674
+ }
675
+ async getMaxGlobalDeposits() {
676
+ return (await this.publicClient.readContract({
677
+ address: this.contractAddress,
678
+ abi: Alpha_json_1.default,
679
+ functionName: 'getMaxGlobalDeposits',
680
+ args: [],
681
+ }));
682
+ }
683
+ async getTotalDeposits() {
684
+ return (await this.publicClient.readContract({
685
+ address: this.contractAddress,
686
+ abi: Alpha_json_1.default,
687
+ functionName: 'getTotalDeposits',
688
+ args: [],
689
+ }));
690
+ }
691
+ // ============ View Functions - Markets ============
692
+ async getMarketInfo(market) {
693
+ const result = (await this.publicClient.readContract({
694
+ address: this.contractAddress,
695
+ abi: Alpha_json_1.default,
696
+ functionName: 'getMarketInfo',
697
+ args: [market],
698
+ }));
699
+ if (!result || !Array.isArray(result) || result.length < 8) {
700
+ throw new Error(`Invalid market info response for market ${market}. ` +
701
+ `Expected array with 8 elements, got: ${JSON.stringify(result)}`);
702
+ }
703
+ return {
704
+ longOpenInterest: result[0],
705
+ shortOpenInterest: result[1],
706
+ fundingRate: result[2],
707
+ lastFundingUpdate: result[3],
708
+ isActive: result[4],
709
+ maxLeverage: result[5],
710
+ maintenanceMargin: result[6],
711
+ liquidationFee: result[7],
712
+ };
713
+ }
714
+ async getMarketOpenInterest(market) {
715
+ const result = (await this.publicClient.readContract({
716
+ address: this.contractAddress,
717
+ abi: Alpha_json_1.default,
718
+ functionName: 'getMarketOpenInterest',
719
+ args: [market],
720
+ }));
721
+ return {
722
+ longOI: result[0],
723
+ shortOI: result[1],
724
+ };
725
+ }
726
+ async getFundingRate(market) {
727
+ return (await this.publicClient.readContract({
728
+ address: this.contractAddress,
729
+ abi: Alpha_json_1.default,
730
+ functionName: 'getFundingRate',
731
+ args: [market],
732
+ }));
733
+ }
734
+ async getFundingState(market) {
735
+ const result = (await this.publicClient.readContract({
736
+ address: this.contractAddress,
737
+ abi: Alpha_json_1.default,
738
+ functionName: 'getFundingState',
739
+ args: [market],
740
+ }));
741
+ // Based on ABI, getFundingState returns:
742
+ // [0] currentRate (int256), [1] cumulativeIndex (int256), [2] lastUpdate (uint256)
743
+ const lastUpdateTime = result[2] !== undefined ? BigInt(result[2]) : 0n;
744
+ return {
745
+ fundingRate: result[0] || 0n,
746
+ fundingIndex: result[1] || 0n,
747
+ lastUpdateTime: result[2] || 0n,
748
+ nextFundingTime: lastUpdateTime + 8n * 3600n, // Add 8 hours to lastUpdate
749
+ };
750
+ }
751
+ // ============ Funding Rate Updates (Keeper Function) ============
752
+ async updateFundingRates(markets, options) {
753
+ if (!this.walletClient)
754
+ throw new Error('Wallet client required for write operations');
755
+ const { waitForConfirmation: _waitForConfirmation, ...txOptions } = options || {};
756
+ if (!this.walletClient.account) {
757
+ throw new Error('Wallet client must have an account for transactions');
758
+ }
759
+ const hash = await this.walletClient.writeContract({
760
+ address: this.contractAddress,
761
+ abi: Alpha_json_1.default,
762
+ functionName: 'updateFundingRates',
763
+ args: [markets],
764
+ account: this.walletClient.account,
765
+ ...txOptions,
766
+ });
767
+ return {
768
+ hash,
769
+ wait: async () => {
770
+ const receipt = await this.publicClient.waitForTransactionReceipt({ hash });
771
+ return receipt;
772
+ },
773
+ };
774
+ }
775
+ // ============ View Functions - Orders ============
776
+ async getBestBid(market) {
777
+ return (await this.publicClient.readContract({
778
+ address: this.contractAddress,
779
+ abi: Alpha_json_1.default,
780
+ functionName: 'getBestBid',
781
+ args: [market],
782
+ }));
783
+ }
784
+ async getBestAsk(market) {
785
+ return (await this.publicClient.readContract({
786
+ address: this.contractAddress,
787
+ abi: Alpha_json_1.default,
788
+ functionName: 'getBestAsk',
789
+ args: [market],
790
+ }));
791
+ }
792
+ /**
793
+ * Get all open order IDs for a trader in a specific market
794
+ * @param trader - Trader address
795
+ * @param market - Market address
796
+ * @returns Array of order IDs (bytes16)
797
+ */
798
+ async getUserOrders(trader, market) {
799
+ const result = (await this.publicClient.readContract({
800
+ address: this.contractAddress,
801
+ abi: Alpha_json_1.default,
802
+ functionName: 'getUserOrders',
803
+ args: [trader, market],
804
+ }));
805
+ // Convert each bytes32 (padded) to bytes16
806
+ return result.map((id) => this.bytes32ToBytes16(id));
807
+ }
808
+ /**
809
+ * Get details of a specific order
810
+ * @param market - The market address
811
+ * @param orderId - The order ID (bytes16)
812
+ * @returns Order details including trader, direction, size, price, reduceOnly
813
+ */
814
+ async getOrderDetails(market, orderId) {
815
+ const result = (await this.publicClient.readContract({
816
+ address: this.contractAddress,
817
+ abi: Alpha_json_1.default,
818
+ functionName: 'getOrderDetails',
819
+ args: [market, orderId],
820
+ }));
821
+ // Contract returns a struct with: trader, isLong, notionalValue, price, reduceOnly, next, prev
822
+ return {
823
+ trader: result.trader,
824
+ isLong: result.isLong,
825
+ notionalValue: result.notionalValue,
826
+ price: result.price,
827
+ reduceOnly: result.reduceOnly,
828
+ next: result.next,
829
+ prev: result.prev,
830
+ };
831
+ }
832
+ // ============ View Functions - Vault ============
833
+ async getVaultStats() {
834
+ const result = (await this.publicClient.readContract({
835
+ address: this.contractAddress,
836
+ abi: Alpha_json_1.default,
837
+ functionName: 'getVaultStats',
838
+ args: [],
839
+ }));
840
+ return {
841
+ totalReserves: result[0],
842
+ availableReserves: result[1],
843
+ totalExposure: result[2],
844
+ unrealizedPnl: result[3],
845
+ };
846
+ }
847
+ async getVaultBalance() {
848
+ return (await this.publicClient.readContract({
849
+ address: this.contractAddress,
850
+ abi: Alpha_json_1.default,
851
+ functionName: 'getVaultBalance',
852
+ args: [],
853
+ }));
854
+ }
855
+ async getVaultState() {
856
+ return (await this.publicClient.readContract({
857
+ address: this.contractAddress,
858
+ abi: Alpha_json_1.default,
859
+ functionName: 'getVaultState',
860
+ args: [],
861
+ }));
862
+ }
863
+ async getVaultExposure(market) {
864
+ const result = (await this.publicClient.readContract({
865
+ address: this.contractAddress,
866
+ abi: Alpha_json_1.default,
867
+ functionName: 'getVaultExposure',
868
+ args: [market],
869
+ }));
870
+ return {
871
+ longExposure: result[0],
872
+ shortExposure: result[1],
873
+ netExposure: result[2],
874
+ utilizationRate: result[3],
875
+ };
876
+ }
877
+ // ============ View Functions - Protocol Limits ============
878
+ async getMaxPositionSize(market) {
879
+ return (await this.publicClient.readContract({
880
+ address: this.contractAddress,
881
+ abi: Alpha_json_1.default,
882
+ functionName: 'getMaxPositionSize',
883
+ args: [market],
884
+ }));
885
+ }
886
+ // ============ View Functions - Execution Analysis ============
887
+ async calculateVaultSlippage(market, size, isBuy) {
888
+ return (await this.publicClient.readContract({
889
+ address: this.contractAddress,
890
+ abi: Alpha_json_1.default,
891
+ functionName: 'calculateVaultSlippage',
892
+ args: [market, size, isBuy],
893
+ }));
894
+ }
895
+ async getOptimalExecutionPlan(market, size, isLong, maxSlippage) {
896
+ return (await this.publicClient.readContract({
897
+ address: this.contractAddress,
898
+ abi: Alpha_json_1.default,
899
+ functionName: 'getOptimalExecutionPlan',
900
+ args: [market, size, isLong, maxSlippage],
901
+ }));
902
+ }
903
+ async getExecutionStrategyAnalysis(market, size, isLong, maxSlippage) {
904
+ return (await this.publicClient.readContract({
905
+ address: this.contractAddress,
906
+ abi: Alpha_json_1.default,
907
+ functionName: 'getExecutionStrategyAnalysisStruct',
908
+ args: [market, size, isLong, maxSlippage],
909
+ }));
910
+ }
911
+ // ============ View Functions - Market Depth ============
912
+ async getMarketDepth(market, isBuy, levels) {
913
+ const result = (await this.publicClient.readContract({
914
+ address: this.contractAddress,
915
+ abi: Alpha_json_1.default,
916
+ functionName: 'getMarketDepth',
917
+ args: [market, isBuy, levels],
918
+ }));
919
+ return {
920
+ depth: result[0],
921
+ totalLiquidity: result[1],
922
+ };
923
+ }
924
+ async getOrderbookDepth(market, levels) {
925
+ const result = (await this.publicClient.readContract({
926
+ address: this.contractAddress,
927
+ abi: Alpha_json_1.default,
928
+ functionName: 'getOrderbookDepth',
929
+ args: [market, levels],
930
+ }));
931
+ return {
932
+ bidPrices: result[0],
933
+ bidNotionals: result[1],
934
+ askPrices: result[2],
935
+ askNotionals: result[3],
936
+ };
937
+ }
938
+ async getVWAP(market, size, isBuy) {
939
+ return (await this.publicClient.readContract({
940
+ address: this.contractAddress,
941
+ abi: Alpha_json_1.default,
942
+ functionName: 'getVWAP',
943
+ args: [market, size, isBuy],
944
+ }));
945
+ }
946
+ async getBidAskSpread(market) {
947
+ return (await this.publicClient.readContract({
948
+ address: this.contractAddress,
949
+ abi: Alpha_json_1.default,
950
+ functionName: 'getBidAskSpread',
951
+ args: [market],
952
+ }));
953
+ }
954
+ async estimateMarketImpact(market, size, isBuy) {
955
+ const result = (await this.publicClient.readContract({
956
+ address: this.contractAddress,
957
+ abi: Alpha_json_1.default,
958
+ functionName: 'estimateMarketImpact',
959
+ args: [market, size, isBuy],
960
+ }));
961
+ return {
962
+ averagePrice: result[0],
963
+ worstPrice: result[1],
964
+ priceImpact: result[2],
965
+ filledFromOrderbook: result[3],
966
+ };
967
+ }
968
+ async getMarketLiquidityAnalysis(market) {
969
+ return (await this.publicClient.readContract({
970
+ address: this.contractAddress,
971
+ abi: Alpha_json_1.default,
972
+ functionName: 'getMarketLiquidityAnalysisStruct',
973
+ args: [market],
974
+ }));
975
+ }
976
+ // ============ Event Parsing ============
977
+ parsePositionOpenedEvent(receipt) {
978
+ const logs = (0, viem_1.parseEventLogs)({
979
+ abi: Alpha_json_1.default,
980
+ logs: receipt.logs,
981
+ eventName: 'PositionOpened',
982
+ });
983
+ if (logs.length > 0) {
984
+ const event = logs[0];
985
+ // Convert bytes32 (padded) back to bytes16
986
+ const positionId = this.bytes32ToBytes16(event.args.positionId);
987
+ return {
988
+ positionId: positionId,
989
+ trader: event.args.trader,
990
+ market: event.args.market,
991
+ isLong: event.args.isLong,
992
+ notionalValue: event.args.notionalValue,
993
+ margin: event.args.margin,
994
+ };
995
+ }
996
+ return undefined;
997
+ }
998
+ parsePositionClosedEvent(receipt) {
999
+ const logs = (0, viem_1.parseEventLogs)({
1000
+ abi: Alpha_json_1.default,
1001
+ logs: receipt.logs,
1002
+ eventName: 'PositionClosed',
1003
+ });
1004
+ if (logs.length > 0) {
1005
+ const event = logs[0];
1006
+ // Convert bytes32 (padded) back to bytes16
1007
+ const positionId = this.bytes32ToBytes16(event.args.positionId);
1008
+ return {
1009
+ positionId: positionId,
1010
+ trader: event.args.trader,
1011
+ pnl: event.args.pnl,
1012
+ };
1013
+ }
1014
+ return undefined;
1015
+ }
1016
+ parseOrderPlacedEvent(receipt) {
1017
+ const logs = (0, viem_1.parseEventLogs)({
1018
+ abi: Alpha_json_1.default,
1019
+ logs: receipt.logs,
1020
+ eventName: 'OrderPlaced',
1021
+ });
1022
+ if (logs.length > 0) {
1023
+ const event = logs[0];
1024
+ return {
1025
+ orderId: event.args.orderId,
1026
+ trader: event.args.trader,
1027
+ market: event.args.market,
1028
+ isBuy: event.args.isBuy,
1029
+ notionalValue: event.args.notionalValue,
1030
+ price: event.args.price,
1031
+ };
1032
+ }
1033
+ return undefined;
1034
+ }
1035
+ parseHybridOrderExecutedEvent(receipt) {
1036
+ const logs = (0, viem_1.parseEventLogs)({
1037
+ abi: Alpha_json_1.default,
1038
+ logs: receipt.logs,
1039
+ eventName: 'HybridOrderExecuted',
1040
+ });
1041
+ if (logs.length > 0) {
1042
+ const event = logs[0];
1043
+ return {
1044
+ trader: event.args.trader,
1045
+ market: event.args.market,
1046
+ orderbookFilled: event.args.orderbookFilled,
1047
+ vaultFilled: event.args.vaultFilled,
1048
+ avgPrice: event.args.avgPrice,
1049
+ };
1050
+ }
1051
+ return undefined;
1052
+ }
1053
+ // ============ Helper Functions ============
1054
+ async waitForTransaction(hash) {
1055
+ return this.publicClient.waitForTransactionReceipt({ hash });
1056
+ }
1057
+ getContractAddress() {
1058
+ return this.contractAddress;
1059
+ }
1060
+ // Generic readContract method for custom function calls
1061
+ async readContract({ functionName, args }) {
1062
+ return await this.publicClient.readContract({
1063
+ address: this.contractAddress,
1064
+ abi: Alpha_json_1.default,
1065
+ functionName,
1066
+ args,
1067
+ });
1068
+ }
1069
+ async getConstants() {
1070
+ const [precision, basisPoints, maxLeverage, defaultLeverage, minPositionSize, liquidationThreshold, partialLiquidationThreshold, liquidationFee, fundingInterval, maxFundingRate, maxExposurePerAsset, maxTotalUtilization, criticalUtilizationBps, maxLossRateBps, maxLiquidationsPerBlock,] = await Promise.all([
1071
+ this.publicClient.readContract({
1072
+ address: this.contractAddress,
1073
+ abi: Alpha_json_1.default,
1074
+ functionName: 'PRECISION',
1075
+ args: [],
1076
+ }),
1077
+ this.publicClient.readContract({
1078
+ address: this.contractAddress,
1079
+ abi: Alpha_json_1.default,
1080
+ functionName: 'BASIS_POINTS',
1081
+ args: [],
1082
+ }),
1083
+ this.publicClient.readContract({
1084
+ address: this.contractAddress,
1085
+ abi: Alpha_json_1.default,
1086
+ functionName: 'MAX_LEVERAGE',
1087
+ args: [],
1088
+ }),
1089
+ this.publicClient.readContract({
1090
+ address: this.contractAddress,
1091
+ abi: Alpha_json_1.default,
1092
+ functionName: 'DEFAULT_LEVERAGE',
1093
+ args: [],
1094
+ }),
1095
+ this.publicClient.readContract({
1096
+ address: this.contractAddress,
1097
+ abi: Alpha_json_1.default,
1098
+ functionName: 'MIN_POSITION_SIZE',
1099
+ args: [],
1100
+ }),
1101
+ this.publicClient.readContract({
1102
+ address: this.contractAddress,
1103
+ abi: Alpha_json_1.default,
1104
+ functionName: 'LIQUIDATION_THRESHOLD',
1105
+ args: [],
1106
+ }),
1107
+ this.publicClient.readContract({
1108
+ address: this.contractAddress,
1109
+ abi: Alpha_json_1.default,
1110
+ functionName: 'PARTIAL_LIQUIDATION_THRESHOLD',
1111
+ args: [],
1112
+ }),
1113
+ this.publicClient.readContract({
1114
+ address: this.contractAddress,
1115
+ abi: Alpha_json_1.default,
1116
+ functionName: 'LIQUIDATION_FEE',
1117
+ args: [],
1118
+ }),
1119
+ this.publicClient.readContract({
1120
+ address: this.contractAddress,
1121
+ abi: Alpha_json_1.default,
1122
+ functionName: 'FUNDING_INTERVAL',
1123
+ args: [],
1124
+ }),
1125
+ this.publicClient.readContract({
1126
+ address: this.contractAddress,
1127
+ abi: Alpha_json_1.default,
1128
+ functionName: 'MAX_FUNDING_RATE',
1129
+ args: [],
1130
+ }),
1131
+ this.publicClient.readContract({
1132
+ address: this.contractAddress,
1133
+ abi: Alpha_json_1.default,
1134
+ functionName: 'MAX_EXPOSURE_PER_ASSET',
1135
+ args: [],
1136
+ }),
1137
+ this.publicClient.readContract({
1138
+ address: this.contractAddress,
1139
+ abi: Alpha_json_1.default,
1140
+ functionName: 'MAX_TOTAL_UTILIZATION',
1141
+ args: [],
1142
+ }),
1143
+ this.publicClient.readContract({
1144
+ address: this.contractAddress,
1145
+ abi: Alpha_json_1.default,
1146
+ functionName: 'CRITICAL_UTILIZATION_BPS',
1147
+ args: [],
1148
+ }),
1149
+ this.publicClient.readContract({
1150
+ address: this.contractAddress,
1151
+ abi: Alpha_json_1.default,
1152
+ functionName: 'MAX_LOSS_RATE_BPS',
1153
+ args: [],
1154
+ }),
1155
+ this.publicClient.readContract({
1156
+ address: this.contractAddress,
1157
+ abi: Alpha_json_1.default,
1158
+ functionName: 'MAX_LIQUIDATIONS_PER_BLOCK',
1159
+ args: [],
1160
+ }),
1161
+ ]);
1162
+ return {
1163
+ precision,
1164
+ basisPoints,
1165
+ maxLeverage,
1166
+ defaultLeverage,
1167
+ minPositionSize,
1168
+ liquidationThreshold,
1169
+ partialLiquidationThreshold,
1170
+ liquidationFee,
1171
+ fundingInterval,
1172
+ maxFundingRate,
1173
+ maxExposurePerAsset,
1174
+ maxTotalUtilization,
1175
+ criticalUtilizationBps,
1176
+ maxLossRateBps,
1177
+ maxLiquidationsPerBlock,
1178
+ };
1179
+ }
1180
+ // Event watching methods
1181
+ /**
1182
+ * Watch for MarginDeposited events
1183
+ */
1184
+ watchMarginDepositedEvent(callback) {
1185
+ return this.publicClient.watchContractEvent({
1186
+ address: this.contractAddress,
1187
+ abi: Alpha_json_1.default,
1188
+ eventName: 'MarginDeposited',
1189
+ onLogs: (logs) => {
1190
+ for (const log of logs) {
1191
+ const { trader, amount } = log.args;
1192
+ callback(trader, amount);
1193
+ }
1194
+ },
1195
+ });
1196
+ }
1197
+ /**
1198
+ * Watch for MarginWithdrawn events
1199
+ */
1200
+ watchMarginWithdrawnEvent(callback) {
1201
+ return this.publicClient.watchContractEvent({
1202
+ address: this.contractAddress,
1203
+ abi: Alpha_json_1.default,
1204
+ eventName: 'MarginWithdrawn',
1205
+ onLogs: (logs) => {
1206
+ for (const log of logs) {
1207
+ const { trader, amount } = log.args;
1208
+ callback(trader, amount);
1209
+ }
1210
+ },
1211
+ });
1212
+ }
1213
+ /**
1214
+ * Watch for PositionOpened events
1215
+ */
1216
+ watchPositionOpenedEvent(callback) {
1217
+ return this.publicClient.watchContractEvent({
1218
+ address: this.contractAddress,
1219
+ abi: Alpha_json_1.default,
1220
+ eventName: 'PositionOpened',
1221
+ onLogs: (logs) => {
1222
+ for (const log of logs) {
1223
+ const { positionId, trader, market, isLong, notionalValue, entryPrice, margin } = log.args;
1224
+ callback(positionId, trader, market, isLong, notionalValue, entryPrice, margin);
1225
+ }
1226
+ },
1227
+ });
1228
+ }
1229
+ /**
1230
+ * Get past MarginDeposited events
1231
+ */
1232
+ async getMarginDepositedEvents(fromBlock, toBlock, trader) {
1233
+ return await this.publicClient.getContractEvents({
1234
+ address: this.contractAddress,
1235
+ abi: Alpha_json_1.default,
1236
+ eventName: 'MarginDeposited',
1237
+ fromBlock: fromBlock || 'earliest',
1238
+ toBlock: toBlock || 'latest',
1239
+ args: trader ? { trader } : undefined,
1240
+ });
1241
+ }
1242
+ /**
1243
+ * Get past MarginWithdrawn events
1244
+ */
1245
+ async getMarginWithdrawnEvents(fromBlock, toBlock, trader) {
1246
+ return await this.publicClient.getContractEvents({
1247
+ address: this.contractAddress,
1248
+ abi: Alpha_json_1.default,
1249
+ eventName: 'MarginWithdrawn',
1250
+ fromBlock: fromBlock || 'earliest',
1251
+ toBlock: toBlock || 'latest',
1252
+ args: trader ? { trader } : undefined,
1253
+ });
1254
+ }
1255
+ /**
1256
+ * Get past PositionOpened events
1257
+ */
1258
+ async getPositionOpenedEvents(fromBlock, toBlock, trader) {
1259
+ return await this.publicClient.getContractEvents({
1260
+ address: this.contractAddress,
1261
+ abi: Alpha_json_1.default,
1262
+ eventName: 'PositionOpened',
1263
+ fromBlock: fromBlock || 'earliest',
1264
+ toBlock: toBlock || 'latest',
1265
+ args: trader ? { trader } : undefined,
1266
+ });
1267
+ }
1268
+ /**
1269
+ * Estimate gas for a transaction
1270
+ */
1271
+ async estimateGas(functionName, args, options) {
1272
+ if (!this.walletClient) {
1273
+ throw new Error('Wallet client is required for gas estimation');
1274
+ }
1275
+ const { gasPrice: _gasPrice, waitForConfirmation: _waitForConfirmation, ...estimateOptions } = options || {};
1276
+ return await this.publicClient.estimateContractGas({
1277
+ address: this.contractAddress,
1278
+ abi: Alpha_json_1.default,
1279
+ functionName,
1280
+ args,
1281
+ account: this.walletClient.account,
1282
+ ...estimateOptions,
1283
+ });
1284
+ }
1285
+ }
1286
+ exports.AlphaViem = AlphaViem;
1287
+ //# sourceMappingURL=AlphaViem.js.map