@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,258 @@
1
+ /**
2
+ * Display Utilities
3
+ *
4
+ * Helper functions for formatting and displaying data in the CLI
5
+ */
6
+
7
+ import chalk from 'chalk';
8
+ import Table from 'cli-table3';
9
+ import { formatUSD, formatTAO, formatPercentage } from '../../src/utils';
10
+
11
+ // Asset name mapping for subnet market addresses
12
+ const ASSET_NAMES_DATA = [
13
+ { address: '0x0000000000000000000000000000000000000022', name: 'BITMIND' }, // Subnet 34
14
+ { address: '0x0000000000000000000000000000000000000040', name: 'CHUTES' }, // Subnet 64
15
+ { address: '0x0000000000000000000000000000000000000078', name: 'AFFINE' }, // Subnet 120
16
+ { address: '0x0000000000000000000000000000000000000003E', name: 'RIDGES' }, // Subnet 62
17
+ ];
18
+
19
+ const ASSET_NAMES: { [address: string]: string } = {};
20
+ ASSET_NAMES_DATA.forEach(({ address, name }) => {
21
+ ASSET_NAMES[address] = name;
22
+ ASSET_NAMES[address.toLowerCase()] = name;
23
+ });
24
+
25
+ /**
26
+ * Display detailed position information
27
+ */
28
+ export function displayPositionDetails(position: any, currentPrice: bigint) {
29
+ // Handle both old and new position structures
30
+ // Get asset name from mapping or fallback to UNKNOWN
31
+ let assetName = 'UNKNOWN';
32
+ if (position.asset) {
33
+ const assetAddress = position.asset.toLowerCase();
34
+ assetName = ASSET_NAMES[assetAddress] || ASSET_NAMES[position.asset] || 'UNKNOWN';
35
+ }
36
+ const status =
37
+ position.isActive !== undefined
38
+ ? position.isActive
39
+ ? chalk.green('Active')
40
+ : chalk.gray('Closed')
41
+ : position.notionalValue > 0n
42
+ ? chalk.green('Active')
43
+ : chalk.gray('Closed');
44
+
45
+ console.log(` Asset: ${chalk.cyan(assetName)}`);
46
+ console.log(` Direction: ${position.isLong ? chalk.green('LONG ↗') : chalk.red('SHORT ↘')}`);
47
+ console.log(` Size: ${formatUSD(position.notionalValue)}`);
48
+ console.log(` Margin: ${formatTAO(position.margin)} TAO`);
49
+
50
+ // Calculate leverage from position size and margin
51
+ if (position.notionalValue && position.margin && position.margin !== 0n) {
52
+ // Both size and margin are in 18-decimal format (wei)
53
+ // Leverage = position.notionalValue / position.margin
54
+ const leverageRaw = BigInt(position.notionalValue) / BigInt(position.margin);
55
+
56
+ // Convert to number for display (leverage is typically a small number like 3x)
57
+ const leverageValue = Number(leverageRaw);
58
+
59
+ // If the calculated leverage seems too high, it might be in different format
60
+ const displayLeverage =
61
+ leverageValue > 1000
62
+ ? (leverageValue / 1e18).toFixed(2) // Handle if still in wei format
63
+ : leverageValue.toFixed(2);
64
+
65
+ console.log(` Leverage: ${displayLeverage}x`);
66
+ } else if (position.leverage !== undefined) {
67
+ // Handle leverage field - could be in basis points or regular number
68
+ const leverageRaw = Number(position.leverage);
69
+ let leverageValue: number;
70
+
71
+ if (leverageRaw > 100) {
72
+ // Leverage is in basis points (e.g., 3000 = 30x, 10000 = 100%, so 30000 = 3x)
73
+ // Actually, if it's basis points for leverage calculation: 3x = 30000 basis points
74
+ // But the contract seems to multiply by 10000, so 3x = 30000
75
+ leverageValue = leverageRaw / 10000;
76
+ } else {
77
+ // Leverage is in regular format (e.g., 3 = 3x)
78
+ leverageValue = leverageRaw;
79
+ }
80
+
81
+ console.log(` Leverage: ${leverageValue.toFixed(2)}x`);
82
+ }
83
+
84
+ console.log(` Entry Price: ${formatUSD(position.entryPrice)}`);
85
+ console.log(` Current Price: ${formatUSD(currentPrice)}`);
86
+ console.log(` Status: ${status}`);
87
+
88
+ // Handle timestamps - could be lastUpdated (monolith) or timestamp (old)
89
+ const timestamp = position.lastUpdated || position.timestamp;
90
+ if (timestamp) {
91
+ console.log(` Last Updated: ${new Date(Number(timestamp) * 1000).toLocaleString()}`);
92
+ }
93
+
94
+ // Only show liquidation price if available
95
+ if (position.liquidationPrice !== undefined) {
96
+ console.log(` Liquidation Price: ${formatUSD(position.liquidationPrice)}`);
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Calculate position P&L
102
+ */
103
+ export function calculatePnL(position: any, currentPrice: bigint, size: bigint): bigint {
104
+ // Ensure all values are BigInt
105
+ const entryPrice = BigInt(position.entryPrice);
106
+ const currPrice = BigInt(currentPrice);
107
+ const posSize = BigInt(size);
108
+
109
+ const priceDiff = position.isLong ? currPrice - entryPrice : entryPrice - currPrice;
110
+
111
+ // Avoid division by zero
112
+ if (entryPrice === 0n) {
113
+ return 0n;
114
+ }
115
+
116
+ return (priceDiff * posSize) / entryPrice;
117
+ }
118
+
119
+ /**
120
+ * Display market summary
121
+ */
122
+ export function displayMarketSummary(marketData: any) {
123
+ const table = new Table({
124
+ head: ['Metric', 'Value'],
125
+ colWidths: [20, 30],
126
+ });
127
+
128
+ table.push(
129
+ ['Price', formatUSD(marketData.price)],
130
+ [
131
+ '24h Change',
132
+ marketData.change24h ? formatPercentage(marketData.change24h) : chalk.gray('N/A'),
133
+ ],
134
+ ['24h Volume', marketData.volume24h ? formatUSD(marketData.volume24h) : chalk.gray('N/A')],
135
+ ['Funding Rate', formatPercentage(marketData.fundingRate) + ' per 8h'],
136
+ [
137
+ 'Open Interest',
138
+ marketData.openInterest ? formatUSD(marketData.openInterest) : chalk.gray('N/A'),
139
+ ],
140
+ );
141
+
142
+ console.log(table.toString());
143
+ }
144
+
145
+ /**
146
+ * Create a simple ASCII price chart (placeholder)
147
+ */
148
+ export function createPriceChart(): string {
149
+ // This is a placeholder for ASCII chart generation
150
+ const chart = `
151
+ $110 | ╱╲
152
+ $108 | ╱ ╲
153
+ $106 | ╱ ╲
154
+ $104 | ╱ ╲
155
+ $102 | ╱ ╲
156
+ $100 |╱
157
+ └──────────
158
+ 1h 2h 3h`;
159
+
160
+ return chalk.gray(chart);
161
+ }
162
+
163
+ /**
164
+ * Create a volume chart (placeholder)
165
+ */
166
+ export function createVolumeChart(): string {
167
+ const chart = `
168
+ 10M | ▐▌
169
+ 8M | ▐▌ ▐▌
170
+ 6M | ▐▌ ▐▌
171
+ 4M |▐▌▐▌ ▐▌▐▌
172
+ 2M |▐▌▐▌▐▌▐▌▐▌
173
+ └──────────
174
+ 1h 2h 3h`;
175
+
176
+ return chalk.gray(chart);
177
+ }
178
+
179
+ /**
180
+ * Format a large number with K/M/B suffixes
181
+ */
182
+ export function formatLargeNumber(value: bigint): string {
183
+ const num = Number(value);
184
+
185
+ if (num >= 1e9) {
186
+ return (num / 1e9).toFixed(2) + 'B';
187
+ } else if (num >= 1e6) {
188
+ return (num / 1e6).toFixed(2) + 'M';
189
+ } else if (num >= 1e3) {
190
+ return (num / 1e3).toFixed(2) + 'K';
191
+ }
192
+
193
+ return num.toFixed(2);
194
+ }
195
+
196
+ /**
197
+ * Display a progress bar
198
+ */
199
+ export function progressBar(current: number, total: number, width: number = 20): string {
200
+ const percentage = current / total;
201
+ const filled = Math.round(width * percentage);
202
+ const empty = width - filled;
203
+
204
+ const bar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));
205
+ const percentStr = (percentage * 100).toFixed(1) + '%';
206
+
207
+ return `${bar} ${percentStr}`;
208
+ }
209
+
210
+ /**
211
+ * Display risk indicator
212
+ */
213
+ export function riskIndicator(riskLevel: number): string {
214
+ if (riskLevel < 20) {
215
+ return chalk.green('●●●●●') + ' Low Risk';
216
+ } else if (riskLevel < 40) {
217
+ return chalk.green('●●●') + chalk.gray('●●') + ' Low-Medium Risk';
218
+ } else if (riskLevel < 60) {
219
+ return chalk.yellow('●●●') + chalk.gray('●●') + ' Medium Risk';
220
+ } else if (riskLevel < 80) {
221
+ return chalk.red('●●') + chalk.gray('●●●') + ' High Risk';
222
+ } else {
223
+ return chalk.red('●') + chalk.gray('●●●●') + ' Very High Risk';
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Format time remaining
229
+ */
230
+ export function formatTimeRemaining(seconds: number): string {
231
+ const hours = Math.floor(seconds / 3600);
232
+ const minutes = Math.floor((seconds % 3600) / 60);
233
+ const secs = seconds % 60;
234
+
235
+ if (hours > 0) {
236
+ return `${hours}h ${minutes}m`;
237
+ } else if (minutes > 0) {
238
+ return `${minutes}m ${secs}s`;
239
+ } else {
240
+ return `${secs}s`;
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Display a summary card
246
+ */
247
+ export function displaySummaryCard(title: string, data: Array<[string, string]>) {
248
+ const maxKeyLength = Math.max(...data.map(([key]) => key.length));
249
+
250
+ console.log(chalk.bold(`\n╔══ ${title} ${'═'.repeat(40 - title.length)}`));
251
+
252
+ data.forEach(([key, value]) => {
253
+ const padding = ' '.repeat(maxKeyLength - key.length);
254
+ console.log(`║ ${key}:${padding} ${value}`);
255
+ });
256
+
257
+ console.log('╚' + '═'.repeat(44));
258
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * CLI Utilities Index
3
+ *
4
+ * Export all utility functions
5
+ */
6
+
7
+ export * from './client';
8
+ export * from './config';
9
+ export * from './display';
10
+ export * from './prompts';
@@ -0,0 +1,364 @@
1
+ /**
2
+ * Prompt Utilities
3
+ *
4
+ * Helper functions for user input and confirmation
5
+ */
6
+
7
+ import inquirer from 'inquirer';
8
+ import chalk from 'chalk';
9
+ import { privateKeyToAccount } from 'viem/accounts';
10
+ import { parseEther, formatEther, getAddress as viemGetAddress } from 'viem';
11
+
12
+ /**
13
+ * Confirm an action with the user
14
+ */
15
+ export async function confirmAction(
16
+ message: string,
17
+ defaultValue: boolean = false,
18
+ ): Promise<boolean> {
19
+ const { confirmed } = await inquirer.prompt([
20
+ {
21
+ type: 'confirm',
22
+ name: 'confirmed',
23
+ message,
24
+ default: defaultValue,
25
+ },
26
+ ]);
27
+
28
+ return confirmed;
29
+ }
30
+
31
+ /**
32
+ * Select from a list of options
33
+ */
34
+ export async function selectFromList<T>(
35
+ message: string,
36
+ choices: Array<{ name: string; value: T }>,
37
+ defaultValue?: T,
38
+ ): Promise<T> {
39
+ const { selected } = await inquirer.prompt([
40
+ {
41
+ type: 'list',
42
+ name: 'selected',
43
+ message,
44
+ choices,
45
+ default: defaultValue,
46
+ },
47
+ ]);
48
+
49
+ return selected;
50
+ }
51
+
52
+ /**
53
+ * Get a numeric input with validation
54
+ */
55
+ export async function getNumericInput(
56
+ message: string,
57
+ options: {
58
+ min?: number;
59
+ max?: number;
60
+ decimals?: number;
61
+ default?: number;
62
+ } = {},
63
+ ): Promise<number> {
64
+ const { value } = await inquirer.prompt([
65
+ {
66
+ type: 'input',
67
+ name: 'value',
68
+ message,
69
+ default: options.default?.toString(),
70
+ validate: (input) => {
71
+ const num = parseFloat(input);
72
+
73
+ if (isNaN(num)) {
74
+ return 'Please enter a valid number';
75
+ }
76
+
77
+ if (options.min !== undefined && num < options.min) {
78
+ return `Value must be at least ${options.min}`;
79
+ }
80
+
81
+ if (options.max !== undefined && num > options.max) {
82
+ return `Value must be at most ${options.max}`;
83
+ }
84
+
85
+ return true;
86
+ },
87
+ filter: (input) => {
88
+ const num = parseFloat(input);
89
+ if (options.decimals !== undefined) {
90
+ return parseFloat(num.toFixed(options.decimals));
91
+ }
92
+ return num;
93
+ },
94
+ },
95
+ ]);
96
+
97
+ return value;
98
+ }
99
+
100
+ /**
101
+ * Get an Ethereum address with validation
102
+ */
103
+ export async function getAddress(message: string, defaultValue?: string): Promise<string> {
104
+ const { address } = await inquirer.prompt([
105
+ {
106
+ type: 'input',
107
+ name: 'address',
108
+ message,
109
+ default: defaultValue,
110
+ validate: (input) => {
111
+ try {
112
+ viemGetAddress(input);
113
+ return true;
114
+ } catch {
115
+ return 'Please enter a valid Ethereum address';
116
+ }
117
+ },
118
+ filter: (input) => {
119
+ try {
120
+ return viemGetAddress(input);
121
+ } catch {
122
+ return input;
123
+ }
124
+ },
125
+ },
126
+ ]);
127
+
128
+ return address;
129
+ }
130
+
131
+ /**
132
+ * Get a private key with validation (masked input)
133
+ */
134
+ export async function getPrivateKey(message: string = 'Enter private key:'): Promise<string> {
135
+ const { key } = await inquirer.prompt([
136
+ {
137
+ type: 'password',
138
+ name: 'key',
139
+ message,
140
+ mask: '*',
141
+ validate: (input) => {
142
+ if (!input || input.length === 0) {
143
+ return 'Private key is required';
144
+ }
145
+
146
+ try {
147
+ // Validate it's a valid private key format
148
+ const cleanKey = input.startsWith('0x') ? input : '0x' + input;
149
+ if (cleanKey.length !== 66) {
150
+ return 'Invalid private key length';
151
+ }
152
+
153
+ // Try to create an account to validate
154
+ privateKeyToAccount(cleanKey as `0x${string}`);
155
+ return true;
156
+ } catch {
157
+ return 'Invalid private key format';
158
+ }
159
+ },
160
+ filter: (input) => {
161
+ return input.startsWith('0x') ? input : '0x' + input;
162
+ },
163
+ },
164
+ ]);
165
+
166
+ return key;
167
+ }
168
+
169
+ /**
170
+ * Get TAO amount with validation
171
+ */
172
+ export async function getTaoAmount(
173
+ message: string,
174
+ options: {
175
+ maxAmount?: bigint;
176
+ minAmount?: bigint;
177
+ default?: string;
178
+ } = {},
179
+ ): Promise<bigint> {
180
+ const { amount } = await inquirer.prompt([
181
+ {
182
+ type: 'input',
183
+ name: 'amount',
184
+ message,
185
+ default: options.default,
186
+ validate: (input) => {
187
+ try {
188
+ const value = parseEther(input);
189
+
190
+ if (options.minAmount && value < options.minAmount) {
191
+ return `Minimum amount is ${formatEther(options.minAmount)} TAO`;
192
+ }
193
+
194
+ if (options.maxAmount && value > options.maxAmount) {
195
+ return `Maximum amount is ${formatEther(options.maxAmount)} TAO`;
196
+ }
197
+
198
+ return true;
199
+ } catch {
200
+ return 'Please enter a valid amount';
201
+ }
202
+ },
203
+ },
204
+ ]);
205
+
206
+ return parseEther(amount);
207
+ }
208
+
209
+ /**
210
+ * Multi-select from a list
211
+ */
212
+ export async function multiSelect<T>(
213
+ message: string,
214
+ choices: Array<{ name: string; value: T; checked?: boolean }>,
215
+ ): Promise<T[]> {
216
+ const { selected } = await inquirer.prompt([
217
+ {
218
+ type: 'checkbox',
219
+ name: 'selected',
220
+ message,
221
+ choices,
222
+ },
223
+ ]);
224
+
225
+ return selected;
226
+ }
227
+
228
+ /**
229
+ * Validates direction input
230
+ */
231
+ export function validateDirection(direction: string): 'long' | 'short' {
232
+ const normalizedDirection = direction.toLowerCase().trim();
233
+
234
+ if (['long', 'buy'].includes(normalizedDirection)) {
235
+ return 'long';
236
+ } else if (['short', 'sell'].includes(normalizedDirection)) {
237
+ return 'short';
238
+ } else {
239
+ throw new Error(`Invalid direction: "${direction}". Must be one of: long, short, buy, sell`);
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Get asset symbol with validation
245
+ */
246
+ export async function getAssetSymbol(
247
+ message: string = 'Enter asset symbol:',
248
+ defaultValue: string = 'ALPHA',
249
+ ): Promise<string> {
250
+ const { asset } = await inquirer.prompt([
251
+ {
252
+ type: 'input',
253
+ name: 'asset',
254
+ message,
255
+ default: defaultValue,
256
+ transformer: (input) => input.toUpperCase(),
257
+ filter: (input) => input.toUpperCase(),
258
+ validate: (input) => {
259
+ if (!input || input.length === 0) {
260
+ return 'Asset symbol is required';
261
+ }
262
+
263
+ if (!/^[A-Z0-9]+$/.test(input.toUpperCase())) {
264
+ return 'Asset symbol must contain only letters and numbers';
265
+ }
266
+
267
+ return true;
268
+ },
269
+ },
270
+ ]);
271
+
272
+ return asset;
273
+ }
274
+
275
+ /**
276
+ * Display a warning and get confirmation
277
+ */
278
+ export async function confirmWarning(
279
+ warning: string,
280
+ confirmMessage: string = 'Do you want to proceed?',
281
+ ): Promise<boolean> {
282
+ console.log(chalk.yellow.bold('\n⚠️ Warning:'));
283
+ console.log(chalk.yellow(warning));
284
+
285
+ return confirmAction(confirmMessage, false);
286
+ }
287
+
288
+ /**
289
+ * Get leverage selection
290
+ */
291
+ export async function selectLeverage(
292
+ message: string = 'Select leverage:',
293
+ defaultValue: number = 3,
294
+ ): Promise<number> {
295
+ const leverageOptions = [
296
+ { name: '1x (No leverage)', value: 1 },
297
+ { name: '2x', value: 2 },
298
+ { name: '3x (Recommended)', value: 3 },
299
+ { name: '5x', value: 5 },
300
+ { name: '10x (High risk)', value: 10 },
301
+ ];
302
+
303
+ return selectFromList(message, leverageOptions, defaultValue);
304
+ }
305
+
306
+ /**
307
+ * Get position size with smart defaults
308
+ */
309
+ export async function getPositionSize(
310
+ availableBalance: bigint,
311
+ leverage: number = 3,
312
+ ): Promise<{ size: bigint; margin: bigint }> {
313
+ console.log(chalk.cyan(`Available balance: ${formatEther(availableBalance)} TAO`));
314
+
315
+ const { sizeType } = await inquirer.prompt([
316
+ {
317
+ type: 'list',
318
+ name: 'sizeType',
319
+ message: 'How would you like to specify position size?',
320
+ choices: [
321
+ { name: 'By margin amount (TAO)', value: 'margin' },
322
+ { name: 'By position size (USD)', value: 'size' },
323
+ { name: 'By percentage of balance', value: 'percentage' },
324
+ ],
325
+ },
326
+ ]);
327
+
328
+ let margin: bigint;
329
+ let size: bigint;
330
+
331
+ switch (sizeType) {
332
+ case 'margin':
333
+ margin = await getTaoAmount('Enter margin amount:', {
334
+ maxAmount: availableBalance,
335
+ minAmount: parseEther('10'), // Minimum 10 TAO
336
+ });
337
+ size = margin * BigInt(leverage);
338
+ break;
339
+
340
+ case 'size':
341
+ const sizeUsd = await getNumericInput('Enter position size (USD):', {
342
+ min: 100,
343
+ max: Number(formatEther(availableBalance)) * leverage * 100, // Rough USD estimate
344
+ });
345
+ size = parseEther(sizeUsd.toString());
346
+ margin = size / BigInt(leverage);
347
+ break;
348
+
349
+ case 'percentage':
350
+ const percentage = await getNumericInput('Enter percentage of balance:', {
351
+ min: 1,
352
+ max: 100,
353
+ decimals: 1,
354
+ });
355
+ margin = (availableBalance * BigInt(Math.floor(percentage * 10))) / 1000n;
356
+ size = margin * BigInt(leverage);
357
+ break;
358
+
359
+ default:
360
+ throw new Error('Invalid size type');
361
+ }
362
+
363
+ return { size, margin };
364
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "network": "mainnet",
3
+ "rpcUrl": "https://your-rpc-endpoint.com",
4
+ "contracts": {
5
+ "positionManager": "0x0000000000000000000000000000000000000000",
6
+ "marginAccount": "0x0000000000000000000000000000000000000000",
7
+ "fundingRate": "0x0000000000000000000000000000000000000000",
8
+ "liquidationEngine": "0x0000000000000000000000000000000000000000",
9
+ "protocolVault": "0x0000000000000000000000000000000000000000",
10
+ "priceOracle": "0x0000000000000000000000000000000000000000"
11
+ },
12
+ "defaultSettings": {
13
+ "leverage": 3,
14
+ "slippage": 0.5,
15
+ "gasLimit": 500000,
16
+ "confirmations": 2
17
+ },
18
+ "display": {
19
+ "currency": "USD",
20
+ "decimals": 2,
21
+ "timezone": "UTC"
22
+ }
23
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Alpha Futures Client
3
+ * Main client class that provides access to all protocol contracts
4
+ */
5
+ import { PriceOracleViem } from './contracts/viem/PriceOracleViem';
6
+ import { AlphaViem } from './contracts/viem/AlphaViem';
7
+ import { type Environment } from './config/environments';
8
+ import { type PublicClient, type WalletClient, type Address } from 'viem';
9
+ export interface AlphaClientConfig {
10
+ rpcUrl?: string;
11
+ privateKey?: `0x${string}`;
12
+ walletClient?: WalletClient;
13
+ }
14
+ export declare class AlphaFuturesClient {
15
+ private alphaContract;
16
+ private oracleContract;
17
+ private publicClient;
18
+ private walletClient?;
19
+ private environment?;
20
+ readonly oracle: PriceOracleViem;
21
+ constructor(environment: Environment, config?: AlphaClientConfig);
22
+ getAlpha(): AlphaViem;
23
+ getPublicClient(): PublicClient;
24
+ getWalletClient(): WalletClient | undefined;
25
+ getEnvironment(): Environment | undefined;
26
+ get isInitialized(): boolean;
27
+ get isConnected(): boolean;
28
+ getSignerAddress(): Promise<Address | undefined>;
29
+ /**
30
+ * Get the collateral token address (TAO/USDC) for the current environment
31
+ * @returns The collateral token contract address
32
+ */
33
+ getCollateralTokenAddress(): Address | undefined;
34
+ static forEnvironment(environment: Environment, config?: AlphaClientConfig): AlphaFuturesClient;
35
+ }
36
+ //# sourceMappingURL=AlphaFuturesClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlphaFuturesClient.d.ts","sourceRoot":"","sources":["../src/AlphaFuturesClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAwB,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,OAAO,EACb,MAAM,MAAM,CAAC;AAGd,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,SAAgB,MAAM,EAAE,eAAe,CAAC;gBAE5B,WAAW,EAAE,WAAW,EAAE,MAAM,GAAE,iBAAsB;IAiFpE,QAAQ,IAAI,SAAS;IAIrB,eAAe,IAAI,YAAY;IAI/B,eAAe,IAAI,YAAY,GAAG,SAAS;IAI3C,cAAc,IAAI,WAAW,GAAG,SAAS;IAIzC,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAEK,gBAAgB,IAAI,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAItD;;;OAGG;IACH,yBAAyB,IAAI,OAAO,GAAG,SAAS;IAMhD,MAAM,CAAC,cAAc,CACnB,WAAW,EAAE,WAAW,EACxB,MAAM,GAAE,iBAAsB,GAC7B,kBAAkB;CAGtB"}