@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,545 @@
1
+ /**
2
+ * Account Commands - Manage margin accounts and balances
3
+ */
4
+
5
+ import { Command } from 'commander';
6
+ import { parseEther, formatEther, Address } from 'viem';
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+ import Table from 'cli-table3';
10
+ import { formatTAO, formatUSD } from '../../src/utils';
11
+ import { getClient, handleError } from '../utils/client';
12
+ import { confirmAction } from '../utils/prompts';
13
+
14
+ export function accountCommands(program: Command) {
15
+ const account = program.command('account').alias('acc').description('Manage margin accounts');
16
+
17
+ // Deposit command
18
+ account
19
+ .command('deposit <amount>')
20
+ .description('Deposit TAO to your margin account')
21
+ .option('-y, --yes', 'Skip confirmation')
22
+ .action(async (amount, options) => {
23
+ const spinner = ora('Processing deposit...').start();
24
+
25
+ try {
26
+ const client = await getClient(program.opts());
27
+ const alpha = client.getAlpha();
28
+ const walletClient = client.getWalletClient();
29
+
30
+ if (!walletClient) {
31
+ throw new Error('Wallet client not initialized. Please provide a private key.');
32
+ }
33
+
34
+ const depositAmount = parseEther(amount);
35
+
36
+ spinner.stop();
37
+
38
+ // Show deposit details
39
+ console.log(chalk.bold('\nšŸ’° Deposit Details:'));
40
+ console.log(` Amount: ${chalk.green(amount + ' TAO')}`);
41
+ console.log(` To: Margin Account`);
42
+
43
+ // Confirm action
44
+ if (!options.yes) {
45
+ const confirmed = await confirmAction('Proceed with deposit?');
46
+ if (!confirmed) {
47
+ console.log(chalk.yellow('Deposit cancelled'));
48
+ return;
49
+ }
50
+ }
51
+
52
+ // Check and approve TAO token spending if needed
53
+ spinner.start('Checking TAO allowance...');
54
+ const publicClient = client.getPublicClient();
55
+ const alphaAddress = alpha.getContractAddress();
56
+ const userAddress = walletClient.account!.address;
57
+
58
+ // Get TAO token contract
59
+ const taoTokenAddress = client.getCollateralTokenAddress();
60
+ if (!taoTokenAddress) {
61
+ throw new Error('TAO token address not configured');
62
+ }
63
+
64
+ // Check current allowance
65
+ const currentAllowance = (await publicClient.readContract({
66
+ address: taoTokenAddress,
67
+ abi: [
68
+ {
69
+ name: 'allowance',
70
+ type: 'function',
71
+ stateMutability: 'view',
72
+ inputs: [
73
+ { name: 'owner', type: 'address' },
74
+ { name: 'spender', type: 'address' },
75
+ ],
76
+ outputs: [{ name: '', type: 'uint256' }],
77
+ },
78
+ ],
79
+ functionName: 'allowance',
80
+ args: [userAddress, alphaAddress],
81
+ })) as bigint;
82
+
83
+ if (currentAllowance < depositAmount) {
84
+ spinner.text = 'Approving TAO spending...';
85
+ const approveHash = await walletClient.writeContract({
86
+ address: taoTokenAddress,
87
+ abi: [
88
+ {
89
+ name: 'approve',
90
+ type: 'function',
91
+ stateMutability: 'nonpayable',
92
+ inputs: [
93
+ { name: 'spender', type: 'address' },
94
+ { name: 'amount', type: 'uint256' },
95
+ ],
96
+ outputs: [{ name: '', type: 'bool' }],
97
+ },
98
+ ],
99
+ functionName: 'approve',
100
+ args: [alphaAddress, depositAmount],
101
+ });
102
+
103
+ await publicClient.waitForTransactionReceipt({ hash: approveHash });
104
+ }
105
+
106
+ spinner.text = 'Depositing TAO...';
107
+ const hash = await alpha.deposit(depositAmount);
108
+
109
+ spinner.text = 'Waiting for confirmation...';
110
+ const receipt = await publicClient.waitForTransactionReceipt({ hash });
111
+
112
+ spinner.succeed('Deposit successful!');
113
+ console.log(chalk.gray(` Transaction: ${receipt.transactionHash}`));
114
+ console.log(chalk.gray(` Gas used: ${receipt.gasUsed.toString()}`));
115
+
116
+ // Show updated balance
117
+ const balance = await alpha.getMarginBalance(walletClient.account!.address);
118
+ console.log(chalk.cyan(`\n New balance: ${formatTAO(balance)} TAO`));
119
+ } catch (error) {
120
+ spinner.fail('Deposit failed');
121
+ handleError(error, program.opts());
122
+ }
123
+ });
124
+
125
+ // Withdraw command
126
+ account
127
+ .command('withdraw <amount>')
128
+ .description('Withdraw TAO from your margin account')
129
+ .option('-y, --yes', 'Skip confirmation')
130
+ .option('-a, --all', 'Withdraw all available balance')
131
+ .action(async (amount, options) => {
132
+ const spinner = ora('Processing withdrawal...').start();
133
+
134
+ try {
135
+ const client = await getClient(program.opts());
136
+ const alpha = client.getAlpha();
137
+ const walletClient = client.getWalletClient();
138
+
139
+ if (!walletClient) {
140
+ throw new Error('Wallet client not initialized. Please provide a private key.');
141
+ }
142
+
143
+ const userAddress = walletClient.account!.address;
144
+
145
+ let withdrawAmount: bigint;
146
+ if (options.all) {
147
+ withdrawAmount = await alpha.getAvailableMargin(userAddress);
148
+ amount = formatEther(withdrawAmount);
149
+ } else {
150
+ withdrawAmount = parseEther(amount);
151
+ }
152
+
153
+ spinner.stop();
154
+
155
+ // Check available balance
156
+ const available = await alpha.getAvailableMargin(userAddress);
157
+ if (withdrawAmount > available) {
158
+ spinner.fail('Insufficient available balance');
159
+ console.log(` Available: ${formatTAO(available)} TAO`);
160
+ console.log(` Requested: ${formatTAO(withdrawAmount)} TAO`);
161
+ process.exit(1);
162
+ }
163
+
164
+ // Show withdrawal details
165
+ console.log(chalk.bold('\nšŸ’ø Withdrawal Details:'));
166
+ console.log(` Amount: ${chalk.red(amount + ' TAO')}`);
167
+ console.log(` From: Margin Account`);
168
+ console.log(` Available: ${formatTAO(available)} TAO`);
169
+
170
+ // Confirm action
171
+ if (!options.yes) {
172
+ const confirmed = await confirmAction('Proceed with withdrawal?');
173
+ if (!confirmed) {
174
+ console.log(chalk.yellow('Withdrawal cancelled'));
175
+ return;
176
+ }
177
+ }
178
+
179
+ spinner.start('Withdrawing TAO...');
180
+ const hash = await alpha.withdraw(withdrawAmount);
181
+
182
+ spinner.text = 'Waiting for confirmation...';
183
+ const publicClient = client.getPublicClient();
184
+ const receipt = await publicClient.waitForTransactionReceipt({ hash });
185
+
186
+ spinner.succeed('Withdrawal successful!');
187
+ console.log(chalk.gray(` Transaction: ${receipt.transactionHash}`));
188
+ console.log(chalk.gray(` Gas used: ${receipt.gasUsed.toString()}`));
189
+
190
+ // Show updated balance
191
+ const balance = await alpha.getMarginBalance(userAddress);
192
+ console.log(chalk.cyan(`\n Remaining balance: ${formatTAO(balance)} TAO`));
193
+ } catch (error) {
194
+ spinner.fail('Withdrawal failed');
195
+ handleError(error, program.opts());
196
+ }
197
+ });
198
+
199
+ // Enhanced balance command
200
+ account
201
+ .command('balance [address]')
202
+ .alias('bal')
203
+ .description('Check balances (TAO wallet where P&L settles + margin account for trading)')
204
+ .option('-d, --detailed', 'Show detailed breakdown')
205
+ .option('-w, --wallet-only', 'Show only TAO wallet balance')
206
+ .option('-m, --margin-only', 'Show only margin account balance')
207
+ .action(async (address, options) => {
208
+ const spinner = ora('Fetching balance...').start();
209
+
210
+ try {
211
+ const client = await getClient(program.opts());
212
+ const alpha = client.getAlpha();
213
+ const walletClient = client.getWalletClient();
214
+
215
+ // Use provided address or wallet address
216
+ const userAddress = address || walletClient?.account?.address;
217
+
218
+ if (!userAddress) {
219
+ spinner.fail('No address provided and no wallet client available');
220
+ return;
221
+ }
222
+
223
+ // Fetch balance data using alpha - use direct methods for better compatibility
224
+ const balance = await alpha.getMarginBalance(userAddress as Address);
225
+ const available = await alpha.getAvailableMargin(userAddress as Address);
226
+ const locked = await alpha.getLockedMargin(userAddress as Address);
227
+
228
+ // For margin ratio, we'll need to calculate it based on positions
229
+ const userPositions = await alpha.getUserPositions(userAddress as Address);
230
+ let marginRatio = 0n;
231
+ if (userPositions.length > 0) {
232
+ // Get first position's margin ratio as proxy (in real app, would aggregate)
233
+ try {
234
+ marginRatio = await alpha.getMarginRatio(userPositions[0]);
235
+ } catch {
236
+ marginRatio = 0n;
237
+ }
238
+ }
239
+
240
+ spinner.stop();
241
+
242
+ // Get TAO wallet balance if requested
243
+ let taoWalletBalance = 0n;
244
+ if (!options.marginOnly) {
245
+ try {
246
+ const publicClient = client.getPublicClient();
247
+ const taoTokenAddress = client.getCollateralTokenAddress();
248
+ if (taoTokenAddress) {
249
+ taoWalletBalance = (await publicClient.readContract({
250
+ address: taoTokenAddress,
251
+ abi: [
252
+ {
253
+ name: 'balanceOf',
254
+ type: 'function',
255
+ stateMutability: 'view',
256
+ inputs: [{ name: 'account', type: 'address' }],
257
+ outputs: [{ name: '', type: 'uint256' }],
258
+ },
259
+ ],
260
+ functionName: 'balanceOf',
261
+ args: [userAddress as Address],
262
+ })) as bigint;
263
+ }
264
+ } catch (error) {
265
+ // TAO token not available or error reading balance
266
+ }
267
+ }
268
+
269
+ spinner.stop();
270
+
271
+ // Display balance summary
272
+ if (options.walletOnly) {
273
+ console.log(chalk.bold(`\nšŸ’³ TAO Wallet (P&L Settlement): ${chalk.cyan(userAddress)}`));
274
+ console.log(` TAO Balance: ${chalk.green(formatTAO(taoWalletBalance) + ' TAO')}`);
275
+ console.log(chalk.gray(' šŸ’” All position profits and losses are settled here'));
276
+ } else if (options.marginOnly) {
277
+ console.log(chalk.bold(`\nšŸ’° Margin Account: ${chalk.cyan(userAddress)}`));
278
+ console.log(` Balance: ${chalk.green(formatTAO(balance) + ' TAO')}`);
279
+ console.log(` Available: ${chalk.cyan(formatTAO(available) + ' TAO')}`);
280
+ console.log(` Locked: ${chalk.yellow(formatTAO(locked) + ' TAO')}`);
281
+ console.log(
282
+ chalk.gray(
283
+ ' šŸ’” Tip: Use "alpha-futures account balance" to see TAO wallet where P&L settles',
284
+ ),
285
+ );
286
+ } else {
287
+ console.log(chalk.bold(`\nšŸ’° Account Overview: ${chalk.cyan(userAddress)}`));
288
+ console.log(chalk.bold('\nšŸ’³ TAO Wallet (P&L Settlement):'));
289
+ console.log(` Balance: ${chalk.green(formatTAO(taoWalletBalance) + ' TAO')}`);
290
+ console.log(chalk.gray(' šŸ’” All position P&L is credited/debited here'));
291
+ console.log(chalk.bold('\nšŸ¦ Margin Account (Trading Collateral):'));
292
+ console.log(` Total: ${chalk.green(formatTAO(balance) + ' TAO')}`);
293
+ console.log(` Available: ${chalk.cyan(formatTAO(available) + ' TAO')}`);
294
+ console.log(` Locked: ${chalk.yellow(formatTAO(locked) + ' TAO')}`);
295
+ }
296
+
297
+ if (options.detailed && !options.walletOnly) {
298
+ // Detailed table view
299
+ const table = new Table({
300
+ head: ['Type', 'Amount (TAO)', 'USD Value'],
301
+ colWidths: [20, 20, 20],
302
+ });
303
+
304
+ // For now, we'll use a placeholder TAO price
305
+ // In production, this would come from an oracle
306
+ const taoPrice = parseEther('100'); // $100 placeholder
307
+
308
+ table.push(
309
+ [
310
+ 'Total Balance',
311
+ formatTAO(balance),
312
+ formatUSD((balance * taoPrice) / parseEther('1')),
313
+ ],
314
+ [
315
+ 'Available',
316
+ chalk.green(formatTAO(available)),
317
+ chalk.green(formatUSD((available * taoPrice) / parseEther('1'))),
318
+ ],
319
+ [
320
+ 'Locked',
321
+ chalk.yellow(formatTAO(locked)),
322
+ chalk.yellow(formatUSD((locked * taoPrice) / parseEther('1'))),
323
+ ],
324
+ );
325
+
326
+ console.log(table.toString());
327
+
328
+ // Margin ratio display
329
+ if (marginRatio > 0n) {
330
+ const marginRatioPercent = Number(marginRatio) / 100;
331
+ let marginColor = chalk.green;
332
+ if (marginRatioPercent < 50) marginColor = chalk.yellow;
333
+ if (marginRatioPercent < 30) marginColor = chalk.red;
334
+
335
+ console.log(`\nšŸ“Š Margin Ratio: ${marginColor(marginRatioPercent.toFixed(2) + '%')}`);
336
+ }
337
+ }
338
+ } catch (error) {
339
+ spinner.fail('Failed to fetch balance');
340
+ handleError(error, program.opts());
341
+ }
342
+ });
343
+
344
+ // Token transfer command
345
+ account
346
+ .command('transfer <recipient> <amount>')
347
+ .description('Transfer TAO tokens to another address')
348
+ .option('-y, --yes', 'Skip confirmation')
349
+ .action(async (recipient, amount, options) => {
350
+ const spinner = ora('Processing TAO transfer...').start();
351
+
352
+ try {
353
+ const client = await getClient(program.opts());
354
+ const walletClient = client.getWalletClient();
355
+
356
+ if (!walletClient) {
357
+ throw new Error('Wallet client not initialized. Please provide a private key.');
358
+ }
359
+
360
+ const transferAmount = parseEther(amount);
361
+ const publicClient = client.getPublicClient();
362
+ const userAddress = walletClient.account!.address;
363
+
364
+ // Get TAO token contract address
365
+ const taoTokenAddress = client.getCollateralTokenAddress();
366
+ if (!taoTokenAddress) {
367
+ throw new Error('TAO token address not configured. Set TAO_TOKEN environment variable.');
368
+ }
369
+
370
+ // Check sender's TAO balance
371
+ const senderBalance = (await publicClient.readContract({
372
+ address: taoTokenAddress,
373
+ abi: [
374
+ {
375
+ name: 'balanceOf',
376
+ type: 'function',
377
+ stateMutability: 'view',
378
+ inputs: [{ name: 'account', type: 'address' }],
379
+ outputs: [{ name: '', type: 'uint256' }],
380
+ },
381
+ ],
382
+ functionName: 'balanceOf',
383
+ args: [userAddress],
384
+ })) as bigint;
385
+
386
+ if (senderBalance < transferAmount) {
387
+ spinner.fail('Insufficient TAO balance');
388
+ console.log(` Balance: ${formatTAO(senderBalance)} TAO`);
389
+ console.log(` Required: ${formatTAO(transferAmount)} TAO`);
390
+ return;
391
+ }
392
+
393
+ spinner.stop();
394
+
395
+ // Show transfer details
396
+ console.log(chalk.bold('\nšŸ’ø TAO Transfer Details:'));
397
+ console.log(` From: ${chalk.cyan(userAddress)}`);
398
+ console.log(` To: ${chalk.cyan(recipient)}`);
399
+ console.log(` Amount: ${chalk.green(amount + ' TAO')}`);
400
+ console.log(` Available: ${formatTAO(senderBalance)} TAO`);
401
+
402
+ // Confirm action
403
+ if (!options.yes) {
404
+ const confirmed = await confirmAction('Proceed with transfer?');
405
+ if (!confirmed) {
406
+ console.log(chalk.yellow('Transfer cancelled'));
407
+ return;
408
+ }
409
+ }
410
+
411
+ spinner.start('Transferring TAO...');
412
+ const hash = await walletClient.writeContract({
413
+ address: taoTokenAddress,
414
+ abi: [
415
+ {
416
+ name: 'transfer',
417
+ type: 'function',
418
+ stateMutability: 'nonpayable',
419
+ inputs: [
420
+ { name: 'to', type: 'address' },
421
+ { name: 'amount', type: 'uint256' },
422
+ ],
423
+ outputs: [{ name: '', type: 'bool' }],
424
+ },
425
+ ],
426
+ functionName: 'transfer',
427
+ args: [recipient as Address, transferAmount],
428
+ });
429
+
430
+ spinner.text = 'Waiting for confirmation...';
431
+ const receipt = await publicClient.waitForTransactionReceipt({ hash });
432
+
433
+ spinner.succeed('TAO transfer successful!');
434
+ console.log(chalk.gray(` Transaction: ${receipt.transactionHash}`));
435
+ console.log(chalk.gray(` Gas used: ${receipt.gasUsed.toString()}`));
436
+
437
+ // Show updated balances
438
+ const newSenderBalance = (await publicClient.readContract({
439
+ address: taoTokenAddress,
440
+ abi: [
441
+ {
442
+ name: 'balanceOf',
443
+ type: 'function',
444
+ stateMutability: 'view',
445
+ inputs: [{ name: 'account', type: 'address' }],
446
+ outputs: [{ name: '', type: 'uint256' }],
447
+ },
448
+ ],
449
+ functionName: 'balanceOf',
450
+ args: [userAddress],
451
+ })) as bigint;
452
+
453
+ console.log(chalk.cyan(`\n Your new balance: ${formatTAO(newSenderBalance)} TAO`));
454
+ } catch (error) {
455
+ spinner.fail('TAO transfer failed');
456
+ handleError(error, program.opts());
457
+ }
458
+ });
459
+
460
+ // Account info command
461
+ account
462
+ .command('info [address]')
463
+ .description('Get detailed account information (use "balance" for quick balance check)')
464
+ .action(async (address) => {
465
+ const spinner = ora('Fetching account info...').start();
466
+
467
+ try {
468
+ const client = await getClient(program.opts());
469
+ const alpha = client.getAlpha();
470
+ const walletClient = client.getWalletClient();
471
+
472
+ const userAddress = address || walletClient?.account?.address;
473
+
474
+ if (!userAddress) {
475
+ spinner.fail('No address provided and no wallet client available');
476
+ return;
477
+ }
478
+
479
+ // Fetch comprehensive account data via single RPC call
480
+ const [summary, positionIds] = await Promise.all([
481
+ alpha.getAccountSummary(userAddress as Address),
482
+ alpha.getUserPositions(userAddress as Address),
483
+ ]);
484
+ const balance = summary.accountEquity;
485
+ const available = summary.availableMargin;
486
+ const locked = summary.lockedMargin;
487
+
488
+ // Calculate margin ratio from positions
489
+ let marginRatio = 0n;
490
+ if (positionIds.length > 0) {
491
+ try {
492
+ marginRatio = await alpha.getMarginRatio(positionIds[0]);
493
+ } catch {
494
+ marginRatio = 0n;
495
+ }
496
+ }
497
+
498
+ spinner.stop();
499
+
500
+ // Display account summary
501
+ console.log(chalk.bold(`\nšŸ“‹ Account Information`));
502
+ console.log(chalk.gray(`Address: ${userAddress}`));
503
+
504
+ // Balance info
505
+ console.log(chalk.bold('\nšŸ’° Balances:'));
506
+ console.log(` Total: ${formatTAO(balance)} TAO`);
507
+ console.log(` Available: ${chalk.green(formatTAO(available) + ' TAO')}`);
508
+ console.log(` Locked: ${chalk.yellow(formatTAO(locked) + ' TAO')}`);
509
+
510
+ // Margin info
511
+ if (marginRatio > 0n) {
512
+ const marginRatioPercent = Number(marginRatio) / 100;
513
+ let marginColor = chalk.green;
514
+ if (marginRatioPercent < 50) marginColor = chalk.yellow;
515
+ if (marginRatioPercent < 30) marginColor = chalk.red;
516
+
517
+ console.log(chalk.bold('\nšŸ“Š Margin Status:'));
518
+ console.log(` Ratio: ${marginColor(marginRatioPercent.toFixed(2) + '%')}`);
519
+ console.log(
520
+ ` Health: ${marginRatioPercent >= 50 ? 'āœ… Healthy' : marginRatioPercent >= 30 ? 'āš ļø Warning' : '🚨 Critical'}`,
521
+ );
522
+ }
523
+
524
+ // Position summary
525
+ console.log(chalk.bold('\nšŸ“ˆ Positions:'));
526
+ console.log(` Active: ${positionIds.length}`);
527
+ if (positionIds.length > 0) {
528
+ // Fetch full position details for summary
529
+ const positions = await Promise.all(positionIds.map((id) => alpha.getPosition(id)));
530
+
531
+ let totalNotionalValue = 0n;
532
+ let totalMargin = 0n;
533
+ for (const pos of positions) {
534
+ totalNotionalValue += pos.notionalValue;
535
+ totalMargin += pos.margin;
536
+ }
537
+ console.log(` Total Notional: ${formatTAO(totalNotionalValue)} TAO`);
538
+ console.log(` Total Margin: ${formatTAO(totalMargin)} TAO`);
539
+ }
540
+ } catch (error) {
541
+ spinner.fail('Failed to fetch account info');
542
+ handleError(error, program.opts());
543
+ }
544
+ });
545
+ }