@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,1679 @@
1
+ # Alpha Futures SDK Integration Guide
2
+
3
+ ## Table of Contents
4
+
5
+ - [Overview](#overview)
6
+ - [Installation](#installation)
7
+ - [Basic Integration](#basic-integration)
8
+ - [Authentication & Security](#authentication--security)
9
+ - [Trading Bot Integration](#trading-bot-integration)
10
+ - [Web Application Integration](#web-application-integration)
11
+ - [API Server Integration](#api-server-integration)
12
+ - [Mobile Integration](#mobile-integration)
13
+ - [WebSocket & Real-time Data](#websocket--real-time-data)
14
+ - [Error Handling & Recovery](#error-handling--recovery)
15
+ - [Testing Your Integration](#testing-your-integration)
16
+ - [Performance Optimization](#performance-optimization)
17
+ - [Security Best Practices](#security-best-practices)
18
+
19
+ ## Overview
20
+
21
+ This guide covers how to integrate the Alpha Futures SDK into various types of applications, from simple scripts to complex trading systems.
22
+
23
+ ## Installation
24
+
25
+ ### NPM/Yarn
26
+
27
+ ```bash
28
+ # Using npm
29
+ npm install @alpha-futures/sdk ethers
30
+
31
+ # Using yarn
32
+ yarn add @alpha-futures/sdk ethers
33
+
34
+ # Using pnpm
35
+ pnpm add @alpha-futures/sdk ethers
36
+ ```
37
+
38
+ ### TypeScript Configuration
39
+
40
+ ```json
41
+ {
42
+ "compilerOptions": {
43
+ "target": "ES2020",
44
+ "module": "commonjs",
45
+ "lib": ["ES2020"],
46
+ "strict": true,
47
+ "esModuleInterop": true,
48
+ "skipLibCheck": true,
49
+ "forceConsistentCasingInFileNames": true,
50
+ "resolveJsonModule": true,
51
+ "moduleResolution": "node"
52
+ }
53
+ }
54
+ ```
55
+
56
+ ## Basic Integration
57
+
58
+ ### Simple Script
59
+
60
+ ```typescript
61
+ import { AlphaFuturesClient } from '@alpha-futures/sdk';
62
+ import { ethers } from 'ethers';
63
+ import dotenv from 'dotenv';
64
+
65
+ dotenv.config();
66
+
67
+ async function main() {
68
+ // Initialize client
69
+ const client = new AlphaFuturesClient({
70
+ rpcUrl: process.env.RPC_URL!,
71
+ privateKey: process.env.PRIVATE_KEY!,
72
+ network: 'mainnet'
73
+ });
74
+
75
+ // Get current price
76
+ const price = await client.priceOracle.getPrice('ALPHA');
77
+ console.log('ALPHA Price:', ethers.formatEther(price));
78
+
79
+ // Check account
80
+ const account = await client.marginAccount.getMarginAccount(
81
+ await client.signer.getAddress()
82
+ );
83
+ console.log('Available Margin:', ethers.formatEther(account.availableMargin));
84
+ }
85
+
86
+ main().catch(console.error);
87
+ ```
88
+
89
+ ### Environment Configuration
90
+
91
+ `.env` file:
92
+ ```bash
93
+ # Network Configuration
94
+ RPC_URL=https://bittensor-evm.alchemyapi.io/v2/your-key
95
+ NETWORK=mainnet
96
+
97
+ # Account Configuration
98
+ PRIVATE_KEY=0x...
99
+
100
+ # Optional: Custom Contract Addresses
101
+ MARGIN_ACCOUNT_ADDRESS=0x...
102
+ POSITION_MANAGER_ADDRESS=0x...
103
+ ```
104
+
105
+ ### Configuration Management
106
+
107
+ ```typescript
108
+ import { ClientConfig, NetworkConfig } from '@alpha-futures/sdk';
109
+
110
+ class ConfigManager {
111
+ static getConfig(): ClientConfig {
112
+ const network = process.env.NETWORK || 'mainnet';
113
+
114
+ // Custom network configuration
115
+ if (process.env.CUSTOM_NETWORK) {
116
+ const customNetwork: NetworkConfig = {
117
+ chainId: parseInt(process.env.CHAIN_ID!),
118
+ name: process.env.NETWORK_NAME!,
119
+ rpcUrl: process.env.RPC_URL!,
120
+ contracts: {
121
+ marginAccount: process.env.MARGIN_ACCOUNT_ADDRESS!,
122
+ positionManager: process.env.POSITION_MANAGER_ADDRESS!,
123
+ fundingRate: process.env.FUNDING_RATE_ADDRESS!,
124
+ liquidationEngine: process.env.LIQUIDATION_ENGINE_ADDRESS!,
125
+ protocolVault: process.env.PROTOCOL_VAULT_ADDRESS!,
126
+ priceOracle: process.env.PRICE_ORACLE_ADDRESS!,
127
+ taoToken: process.env.TAO_TOKEN_ADDRESS!
128
+ }
129
+ };
130
+
131
+ return {
132
+ rpcUrl: process.env.RPC_URL!,
133
+ privateKey: process.env.PRIVATE_KEY!,
134
+ networkConfig: customNetwork
135
+ };
136
+ }
137
+
138
+ // Standard network
139
+ return {
140
+ rpcUrl: process.env.RPC_URL!,
141
+ privateKey: process.env.PRIVATE_KEY!,
142
+ network
143
+ };
144
+ }
145
+ }
146
+ ```
147
+
148
+ ## Authentication & Security
149
+
150
+ ### Secure Key Management
151
+
152
+ ```typescript
153
+ import { Wallet } from 'ethers';
154
+ import * as crypto from 'crypto';
155
+
156
+ class SecureWalletManager {
157
+ private encryptedKey: string;
158
+ private salt: Buffer;
159
+
160
+ constructor() {
161
+ this.salt = crypto.randomBytes(32);
162
+ }
163
+
164
+ // Encrypt private key
165
+ encryptPrivateKey(privateKey: string, password: string): void {
166
+ const key = crypto.pbkdf2Sync(password, this.salt, 100000, 32, 'sha256');
167
+ const cipher = crypto.createCipheriv('aes-256-gcm', key, this.salt.slice(0, 16));
168
+
169
+ let encrypted = cipher.update(privateKey, 'utf8', 'hex');
170
+ encrypted += cipher.final('hex');
171
+
172
+ const authTag = cipher.getAuthTag();
173
+ this.encryptedKey = encrypted + authTag.toString('hex');
174
+ }
175
+
176
+ // Decrypt and create wallet
177
+ createWallet(password: string, provider: any): Wallet {
178
+ const key = crypto.pbkdf2Sync(password, this.salt, 100000, 32, 'sha256');
179
+ const decipher = crypto.createDecipheriv('aes-256-gcm', key, this.salt.slice(0, 16));
180
+
181
+ const encrypted = this.encryptedKey.slice(0, -32);
182
+ const authTag = Buffer.from(this.encryptedKey.slice(-32), 'hex');
183
+ decipher.setAuthTag(authTag);
184
+
185
+ let decrypted = decipher.update(encrypted, 'hex', 'utf8');
186
+ decrypted += decipher.final('utf8');
187
+
188
+ return new Wallet(decrypted, provider);
189
+ }
190
+ }
191
+ ```
192
+
193
+ ### Multi-Signature Integration
194
+
195
+ ```typescript
196
+ import { AlphaFuturesClient } from '@alpha-futures/sdk';
197
+
198
+ class MultiSigIntegration {
199
+ private client: AlphaFuturesClient;
200
+ private signers: string[];
201
+ private threshold: number;
202
+
203
+ constructor(client: AlphaFuturesClient, signers: string[], threshold: number) {
204
+ this.client = client;
205
+ this.signers = signers;
206
+ this.threshold = threshold;
207
+ }
208
+
209
+ async proposeTransaction(
210
+ target: string,
211
+ data: string,
212
+ value: bigint
213
+ ): Promise<number> {
214
+ // Implementation depends on your multisig contract
215
+ // This is a conceptual example
216
+ const proposalId = await this.submitToMultisig(target, data, value);
217
+ return proposalId;
218
+ }
219
+
220
+ async executeAfterApproval(proposalId: number): Promise<void> {
221
+ const approvals = await this.getApprovals(proposalId);
222
+ if (approvals >= this.threshold) {
223
+ await this.executeMultisigTransaction(proposalId);
224
+ }
225
+ }
226
+ }
227
+ ```
228
+
229
+ ## Trading Bot Integration
230
+
231
+ ### Basic Trading Bot Structure
232
+
233
+ ```typescript
234
+ import { AlphaFuturesClient } from '@alpha-futures/sdk';
235
+ import { EventEmitter } from 'events';
236
+
237
+ abstract class TradingBot extends EventEmitter {
238
+ protected client: AlphaFuturesClient;
239
+ protected isRunning: boolean = false;
240
+ protected config: BotConfig;
241
+
242
+ constructor(client: AlphaFuturesClient, config: BotConfig) {
243
+ super();
244
+ this.client = client;
245
+ this.config = config;
246
+ }
247
+
248
+ async start(): Promise<void> {
249
+ this.isRunning = true;
250
+ this.emit('started');
251
+
252
+ while (this.isRunning) {
253
+ try {
254
+ await this.executeStrategy();
255
+ await this.sleep(this.config.interval);
256
+ } catch (error) {
257
+ this.emit('error', error);
258
+ await this.handleError(error);
259
+ }
260
+ }
261
+ }
262
+
263
+ stop(): void {
264
+ this.isRunning = false;
265
+ this.emit('stopped');
266
+ }
267
+
268
+ abstract executeStrategy(): Promise<void>;
269
+ abstract handleError(error: any): Promise<void>;
270
+
271
+ protected sleep(ms: number): Promise<void> {
272
+ return new Promise(resolve => setTimeout(resolve, ms));
273
+ }
274
+ }
275
+
276
+ interface BotConfig {
277
+ interval: number;
278
+ maxPositions: number;
279
+ riskPerTrade: number;
280
+ stopLoss: number;
281
+ takeProfit: number;
282
+ }
283
+ ```
284
+
285
+ ### Grid Trading Bot Example
286
+
287
+ ```typescript
288
+ class GridTradingBot extends TradingBot {
289
+ private gridLevels: bigint[];
290
+ private positions: Map<string, GridPosition> = new Map();
291
+
292
+ constructor(
293
+ client: AlphaFuturesClient,
294
+ config: GridBotConfig
295
+ ) {
296
+ super(client, config);
297
+ this.gridLevels = this.calculateGridLevels();
298
+ }
299
+
300
+ private calculateGridLevels(): bigint[] {
301
+ const config = this.config as GridBotConfig;
302
+ const levels: bigint[] = [];
303
+
304
+ for (let i = 0; i <= config.gridCount; i++) {
305
+ const price = config.lowerBound +
306
+ (config.upperBound - config.lowerBound) * BigInt(i) / BigInt(config.gridCount);
307
+ levels.push(price);
308
+ }
309
+
310
+ return levels;
311
+ }
312
+
313
+ async executeStrategy(): Promise<void> {
314
+ const currentPrice = await this.client.priceOracle.getPrice('ALPHA');
315
+
316
+ // Check each grid level
317
+ for (let i = 0; i < this.gridLevels.length - 1; i++) {
318
+ const lowerLevel = this.gridLevels[i];
319
+ const upperLevel = this.gridLevels[i + 1];
320
+ const levelKey = `${i}`;
321
+
322
+ if (currentPrice >= lowerLevel && currentPrice <= upperLevel) {
323
+ if (!this.positions.has(levelKey)) {
324
+ // Open position at this level
325
+ await this.openGridPosition(levelKey, lowerLevel, upperLevel);
326
+ }
327
+ } else if (this.positions.has(levelKey)) {
328
+ // Close position if price moved out of range
329
+ await this.closeGridPosition(levelKey);
330
+ }
331
+ }
332
+ }
333
+
334
+ private async openGridPosition(
335
+ key: string,
336
+ buyPrice: bigint,
337
+ sellPrice: bigint
338
+ ): Promise<void> {
339
+ const size = this.calculatePositionSize();
340
+
341
+ const tx = await this.client.positionManager.openPosition({
342
+ asset: 'ALPHA',
343
+ size,
344
+ leverage: 2,
345
+ isLong: true
346
+ });
347
+
348
+ await tx.wait();
349
+
350
+ this.positions.set(key, {
351
+ positionId: await this.getPositionIdFromTx(tx),
352
+ buyPrice,
353
+ sellPrice,
354
+ size
355
+ });
356
+
357
+ this.emit('positionOpened', key);
358
+ }
359
+
360
+ private async closeGridPosition(key: string): Promise<void> {
361
+ const position = this.positions.get(key);
362
+ if (!position) return;
363
+
364
+ await this.client.positionManager.closePosition(position.positionId);
365
+ this.positions.delete(key);
366
+
367
+ this.emit('positionClosed', key);
368
+ }
369
+
370
+ async handleError(error: any): Promise<void> {
371
+ console.error('Grid bot error:', error);
372
+
373
+ // Retry logic
374
+ if (error.code === 'NETWORK_ERROR') {
375
+ await this.sleep(5000);
376
+ return;
377
+ }
378
+
379
+ // Critical error - stop bot
380
+ if (error.code === 'INSUFFICIENT_FUNDS') {
381
+ this.stop();
382
+ }
383
+ }
384
+ }
385
+
386
+ interface GridBotConfig extends BotConfig {
387
+ gridCount: number;
388
+ lowerBound: bigint;
389
+ upperBound: bigint;
390
+ amountPerGrid: bigint;
391
+ }
392
+
393
+ interface GridPosition {
394
+ positionId: bigint;
395
+ buyPrice: bigint;
396
+ sellPrice: bigint;
397
+ size: bigint;
398
+ }
399
+ ```
400
+
401
+ ## Web Application Integration
402
+
403
+ ### React Integration
404
+
405
+ ```typescript
406
+ // hooks/useAlphaFutures.ts
407
+ import { useState, useEffect, useCallback } from 'react';
408
+ import { AlphaFuturesClient } from '@alpha-futures/sdk';
409
+ import { ethers } from 'ethers';
410
+
411
+ export function useAlphaFutures() {
412
+ const [client, setClient] = useState<AlphaFuturesClient | null>(null);
413
+ const [account, setAccount] = useState<string | null>(null);
414
+ const [isConnected, setIsConnected] = useState(false);
415
+
416
+ const connect = useCallback(async () => {
417
+ if (typeof window.ethereum === 'undefined') {
418
+ throw new Error('MetaMask not installed');
419
+ }
420
+
421
+ // Request account access
422
+ const accounts = await window.ethereum.request({
423
+ method: 'eth_requestAccounts'
424
+ });
425
+
426
+ // Create provider and signer
427
+ const provider = new ethers.BrowserProvider(window.ethereum);
428
+ const signer = await provider.getSigner();
429
+
430
+ // Initialize client
431
+ const alphaClient = new AlphaFuturesClient({
432
+ provider,
433
+ signer,
434
+ network: 'mainnet'
435
+ });
436
+
437
+ setClient(alphaClient);
438
+ setAccount(accounts[0]);
439
+ setIsConnected(true);
440
+ }, []);
441
+
442
+ const disconnect = useCallback(() => {
443
+ setClient(null);
444
+ setAccount(null);
445
+ setIsConnected(false);
446
+ }, []);
447
+
448
+ // Auto-connect if previously connected
449
+ useEffect(() => {
450
+ const checkConnection = async () => {
451
+ if (typeof window.ethereum !== 'undefined') {
452
+ const accounts = await window.ethereum.request({
453
+ method: 'eth_accounts'
454
+ });
455
+
456
+ if (accounts.length > 0) {
457
+ await connect();
458
+ }
459
+ }
460
+ };
461
+
462
+ checkConnection();
463
+ }, [connect]);
464
+
465
+ // Listen for account changes
466
+ useEffect(() => {
467
+ if (typeof window.ethereum !== 'undefined') {
468
+ window.ethereum.on('accountsChanged', (accounts: string[]) => {
469
+ if (accounts.length === 0) {
470
+ disconnect();
471
+ } else {
472
+ setAccount(accounts[0]);
473
+ }
474
+ });
475
+
476
+ window.ethereum.on('chainChanged', () => {
477
+ window.location.reload();
478
+ });
479
+ }
480
+ }, [disconnect]);
481
+
482
+ return {
483
+ client,
484
+ account,
485
+ isConnected,
486
+ connect,
487
+ disconnect
488
+ };
489
+ }
490
+ ```
491
+
492
+ ### React Trading Component
493
+
494
+ ```tsx
495
+ // components/TradingPanel.tsx
496
+ import React, { useState, useEffect } from 'react';
497
+ import { useAlphaFutures } from '../hooks/useAlphaFutures';
498
+ import { ethers } from 'ethers';
499
+
500
+ export function TradingPanel() {
501
+ const { client, account, isConnected } = useAlphaFutures();
502
+ const [loading, setLoading] = useState(false);
503
+ const [position, setPosition] = useState({
504
+ asset: 'ALPHA',
505
+ size: '1000',
506
+ leverage: 3,
507
+ isLong: true
508
+ });
509
+ const [accountInfo, setAccountInfo] = useState(null);
510
+
511
+ useEffect(() => {
512
+ if (client && account) {
513
+ loadAccountInfo();
514
+ }
515
+ }, [client, account]);
516
+
517
+ const loadAccountInfo = async () => {
518
+ try {
519
+ const info = await client.marginAccount.getMarginAccount(account);
520
+ setAccountInfo(info);
521
+ } catch (error) {
522
+ console.error('Failed to load account info:', error);
523
+ }
524
+ };
525
+
526
+ const handleTrade = async () => {
527
+ if (!client) return;
528
+
529
+ setLoading(true);
530
+ try {
531
+ const tx = await client.positionManager.openPosition({
532
+ asset: position.asset,
533
+ size: ethers.parseEther(position.size),
534
+ leverage: position.leverage,
535
+ isLong: position.isLong
536
+ });
537
+
538
+ await tx.wait();
539
+ alert('Position opened successfully!');
540
+ await loadAccountInfo();
541
+ } catch (error) {
542
+ alert(`Error: ${error.message}`);
543
+ } finally {
544
+ setLoading(false);
545
+ }
546
+ };
547
+
548
+ if (!isConnected) {
549
+ return <div>Please connect your wallet</div>;
550
+ }
551
+
552
+ return (
553
+ <div className="trading-panel">
554
+ <h2>Open Position</h2>
555
+
556
+ {accountInfo && (
557
+ <div className="account-info">
558
+ <p>Available Margin: {ethers.formatEther(accountInfo.availableMargin)} TAO</p>
559
+ <p>Used Margin: {ethers.formatEther(accountInfo.usedMargin)} TAO</p>
560
+ </div>
561
+ )}
562
+
563
+ <div className="form-group">
564
+ <label>Asset</label>
565
+ <select
566
+ value={position.asset}
567
+ onChange={(e) => setPosition({...position, asset: e.target.value})}
568
+ >
569
+ <option value="ALPHA">ALPHA</option>
570
+ <option value="BETA">BETA</option>
571
+ </select>
572
+ </div>
573
+
574
+ <div className="form-group">
575
+ <label>Size (TAO)</label>
576
+ <input
577
+ type="number"
578
+ value={position.size}
579
+ onChange={(e) => setPosition({...position, size: e.target.value})}
580
+ />
581
+ </div>
582
+
583
+ <div className="form-group">
584
+ <label>Leverage</label>
585
+ <input
586
+ type="range"
587
+ min="1"
588
+ max="10"
589
+ value={position.leverage}
590
+ onChange={(e) => setPosition({...position, leverage: parseInt(e.target.value)})}
591
+ />
592
+ <span>{position.leverage}x</span>
593
+ </div>
594
+
595
+ <div className="form-group">
596
+ <label>Direction</label>
597
+ <button
598
+ className={position.isLong ? 'active' : ''}
599
+ onClick={() => setPosition({...position, isLong: true})}
600
+ >
601
+ Long
602
+ </button>
603
+ <button
604
+ className={!position.isLong ? 'active' : ''}
605
+ onClick={() => setPosition({...position, isLong: false})}
606
+ >
607
+ Short
608
+ </button>
609
+ </div>
610
+
611
+ <button
612
+ onClick={handleTrade}
613
+ disabled={loading}
614
+ >
615
+ {loading ? 'Opening Position...' : 'Open Position'}
616
+ </button>
617
+ </div>
618
+ );
619
+ }
620
+ ```
621
+
622
+ ### Vue.js Integration
623
+
624
+ ```typescript
625
+ // composables/useAlphaFutures.ts
626
+ import { ref, computed, onMounted, onUnmounted } from 'vue';
627
+ import { AlphaFuturesClient } from '@alpha-futures/sdk';
628
+ import { ethers } from 'ethers';
629
+
630
+ export function useAlphaFutures() {
631
+ const client = ref<AlphaFuturesClient | null>(null);
632
+ const account = ref<string | null>(null);
633
+ const isConnected = computed(() => !!client.value && !!account.value);
634
+
635
+ const connect = async () => {
636
+ if (!window.ethereum) {
637
+ throw new Error('MetaMask not installed');
638
+ }
639
+
640
+ const accounts = await window.ethereum.request({
641
+ method: 'eth_requestAccounts'
642
+ });
643
+
644
+ const provider = new ethers.BrowserProvider(window.ethereum);
645
+ const signer = await provider.getSigner();
646
+
647
+ client.value = new AlphaFuturesClient({
648
+ provider,
649
+ signer,
650
+ network: 'mainnet'
651
+ });
652
+
653
+ account.value = accounts[0];
654
+ };
655
+
656
+ const disconnect = () => {
657
+ client.value = null;
658
+ account.value = null;
659
+ };
660
+
661
+ onMounted(() => {
662
+ // Auto-connect logic
663
+ if (window.ethereum) {
664
+ window.ethereum.on('accountsChanged', handleAccountsChanged);
665
+ window.ethereum.on('chainChanged', handleChainChanged);
666
+ }
667
+ });
668
+
669
+ onUnmounted(() => {
670
+ if (window.ethereum) {
671
+ window.ethereum.removeListener('accountsChanged', handleAccountsChanged);
672
+ window.ethereum.removeListener('chainChanged', handleChainChanged);
673
+ }
674
+ });
675
+
676
+ return {
677
+ client: computed(() => client.value),
678
+ account: computed(() => account.value),
679
+ isConnected,
680
+ connect,
681
+ disconnect
682
+ };
683
+ }
684
+ ```
685
+
686
+ ## API Server Integration
687
+
688
+ ### Express.js API Server
689
+
690
+ ```typescript
691
+ // server.ts
692
+ import express from 'express';
693
+ import { AlphaFuturesClient } from '@alpha-futures/sdk';
694
+ import { ethers } from 'ethers';
695
+ import rateLimit from 'express-rate-limit';
696
+ import helmet from 'helmet';
697
+
698
+ const app = express();
699
+ app.use(helmet());
700
+ app.use(express.json());
701
+
702
+ // Rate limiting
703
+ const limiter = rateLimit({
704
+ windowMs: 15 * 60 * 1000, // 15 minutes
705
+ max: 100 // limit each IP to 100 requests per windowMs
706
+ });
707
+ app.use('/api/', limiter);
708
+
709
+ // Initialize client
710
+ const client = new AlphaFuturesClient({
711
+ rpcUrl: process.env.RPC_URL!,
712
+ privateKey: process.env.PRIVATE_KEY!,
713
+ network: 'mainnet'
714
+ });
715
+
716
+ // Middleware for API authentication
717
+ const authenticateAPI = (req: Request, res: Response, next: NextFunction) => {
718
+ const apiKey = req.headers['x-api-key'];
719
+
720
+ if (!apiKey || !isValidApiKey(apiKey)) {
721
+ return res.status(401).json({ error: 'Invalid API key' });
722
+ }
723
+
724
+ next();
725
+ };
726
+
727
+ // Price endpoint
728
+ app.get('/api/prices/:asset', authenticateAPI, async (req, res) => {
729
+ try {
730
+ const { asset } = req.params;
731
+ const price = await client.priceOracle.getPrice(asset);
732
+
733
+ res.json({
734
+ asset,
735
+ price: ethers.formatEther(price),
736
+ timestamp: Date.now()
737
+ });
738
+ } catch (error) {
739
+ res.status(500).json({ error: error.message });
740
+ }
741
+ });
742
+
743
+ // Position endpoints
744
+ app.post('/api/positions', authenticateAPI, async (req, res) => {
745
+ try {
746
+ const { asset, size, leverage, isLong, userAddress } = req.body;
747
+
748
+ // Validate inputs
749
+ if (!asset || !size || !leverage || isLong === undefined || !userAddress) {
750
+ return res.status(400).json({ error: 'Missing required fields' });
751
+ }
752
+
753
+ // Create position on behalf of user
754
+ // Note: This requires proper authorization setup
755
+ const tx = await client.positionManager.openPosition({
756
+ asset,
757
+ size: ethers.parseEther(size),
758
+ leverage,
759
+ isLong
760
+ });
761
+
762
+ res.json({
763
+ txHash: tx.hash,
764
+ status: 'pending'
765
+ });
766
+ } catch (error) {
767
+ res.status(500).json({ error: error.message });
768
+ }
769
+ });
770
+
771
+ // WebSocket for real-time updates
772
+ import { WebSocketServer } from 'ws';
773
+
774
+ const wss = new WebSocketServer({ port: 8080 });
775
+
776
+ wss.on('connection', (ws) => {
777
+ console.log('New WebSocket connection');
778
+
779
+ // Subscribe to position events
780
+ client.positionManager.on('PositionOpened', (positionId, trader, asset) => {
781
+ ws.send(JSON.stringify({
782
+ type: 'positionOpened',
783
+ data: { positionId: positionId.toString(), trader, asset }
784
+ }));
785
+ });
786
+
787
+ // Price updates
788
+ const priceInterval = setInterval(async () => {
789
+ try {
790
+ const prices = await client.priceOracle.getAllPrices();
791
+ ws.send(JSON.stringify({
792
+ type: 'priceUpdate',
793
+ data: prices.map(p => ({
794
+ asset: p.asset,
795
+ price: ethers.formatEther(p.price),
796
+ timestamp: p.timestamp
797
+ }))
798
+ }));
799
+ } catch (error) {
800
+ console.error('Price update error:', error);
801
+ }
802
+ }, 5000); // Every 5 seconds
803
+
804
+ ws.on('close', () => {
805
+ clearInterval(priceInterval);
806
+ });
807
+ });
808
+
809
+ app.listen(3000, () => {
810
+ console.log('API server running on port 3000');
811
+ });
812
+ ```
813
+
814
+ ### GraphQL Integration
815
+
816
+ ```typescript
817
+ // graphql/schema.ts
818
+ import { gql } from 'apollo-server-express';
819
+
820
+ export const typeDefs = gql`
821
+ type Position {
822
+ id: String!
823
+ trader: String!
824
+ asset: String!
825
+ size: String!
826
+ isLong: Boolean!
827
+ leverage: Int!
828
+ entryPrice: String!
829
+ margin: String!
830
+ unrealizedPnL: String
831
+ marginRatio: String
832
+ }
833
+
834
+ type MarginAccount {
835
+ user: String!
836
+ totalDeposited: String!
837
+ totalWithdrawn: String!
838
+ availableMargin: String!
839
+ usedMargin: String!
840
+ unrealizedPnL: String!
841
+ marginRatio: String!
842
+ }
843
+
844
+ type Price {
845
+ asset: String!
846
+ price: String!
847
+ timestamp: Int!
848
+ }
849
+
850
+ type FundingRate {
851
+ asset: String!
852
+ rate: String!
853
+ isPositive: Boolean!
854
+ nextUpdateTime: String!
855
+ }
856
+
857
+ type Query {
858
+ position(id: String!): Position
859
+ positions(trader: String!): [Position!]!
860
+ marginAccount(address: String!): MarginAccount
861
+ price(asset: String!): Price
862
+ prices: [Price!]!
863
+ fundingRate(asset: String!): FundingRate
864
+ fundingRates: [FundingRate!]!
865
+ }
866
+
867
+ type Mutation {
868
+ openPosition(
869
+ asset: String!
870
+ size: String!
871
+ leverage: Int!
872
+ isLong: Boolean!
873
+ ): TransactionResponse!
874
+
875
+ closePosition(id: String!): TransactionResponse!
876
+
877
+ deposit(amount: String!): TransactionResponse!
878
+
879
+ withdraw(amount: String!): TransactionResponse!
880
+ }
881
+
882
+ type TransactionResponse {
883
+ hash: String!
884
+ status: String!
885
+ }
886
+
887
+ type Subscription {
888
+ priceUpdates(asset: String): Price!
889
+ positionUpdates(trader: String!): Position!
890
+ fundingRateUpdates(asset: String): FundingRate!
891
+ }
892
+ `;
893
+
894
+ // graphql/resolvers.ts
895
+ export const resolvers = {
896
+ Query: {
897
+ position: async (_, { id }, { client }) => {
898
+ const position = await client.positionManager.getPosition(BigInt(id));
899
+ return formatPosition(position);
900
+ },
901
+
902
+ positions: async (_, { trader }, { client }) => {
903
+ const positions = await client.positionManager.getAllPositions(trader);
904
+ return positions.map(formatPosition);
905
+ },
906
+
907
+ marginAccount: async (_, { address }, { client }) => {
908
+ const account = await client.marginAccount.getMarginAccount(address);
909
+ return formatMarginAccount(account);
910
+ },
911
+
912
+ price: async (_, { asset }, { client }) => {
913
+ const price = await client.priceOracle.getPrice(asset);
914
+ return {
915
+ asset,
916
+ price: ethers.formatEther(price),
917
+ timestamp: Date.now()
918
+ };
919
+ },
920
+
921
+ prices: async (_, __, { client }) => {
922
+ const prices = await client.priceOracle.getAllPrices();
923
+ return prices.map(p => ({
924
+ asset: p.asset,
925
+ price: ethers.formatEther(p.price),
926
+ timestamp: p.timestamp
927
+ }));
928
+ }
929
+ },
930
+
931
+ Mutation: {
932
+ openPosition: async (_, args, { client }) => {
933
+ const tx = await client.positionManager.openPosition({
934
+ asset: args.asset,
935
+ size: ethers.parseEther(args.size),
936
+ leverage: args.leverage,
937
+ isLong: args.isLong
938
+ });
939
+
940
+ return {
941
+ hash: tx.hash,
942
+ status: 'pending'
943
+ };
944
+ },
945
+
946
+ closePosition: async (_, { id }, { client }) => {
947
+ const tx = await client.positionManager.closePosition(BigInt(id));
948
+ return {
949
+ hash: tx.hash,
950
+ status: 'pending'
951
+ };
952
+ }
953
+ },
954
+
955
+ Subscription: {
956
+ priceUpdates: {
957
+ subscribe: async function* (_, { asset }, { client }) {
958
+ while (true) {
959
+ const price = await client.priceOracle.getPrice(asset || 'ALPHA');
960
+ yield {
961
+ priceUpdates: {
962
+ asset: asset || 'ALPHA',
963
+ price: ethers.formatEther(price),
964
+ timestamp: Date.now()
965
+ }
966
+ };
967
+ await new Promise(resolve => setTimeout(resolve, 5000));
968
+ }
969
+ }
970
+ }
971
+ }
972
+ };
973
+ ```
974
+
975
+ ## Mobile Integration
976
+
977
+ ### React Native Integration
978
+
979
+ ```typescript
980
+ // services/AlphaFuturesService.ts
981
+ import { AlphaFuturesClient } from '@alpha-futures/sdk';
982
+ import { ethers } from 'ethers';
983
+ import AsyncStorage from '@react-native-async-storage/async-storage';
984
+ import { WalletConnectProvider } from '@walletconnect/react-native';
985
+
986
+ export class AlphaFuturesService {
987
+ private client: AlphaFuturesClient | null = null;
988
+ private walletConnector: WalletConnectProvider;
989
+
990
+ constructor() {
991
+ this.walletConnector = new WalletConnectProvider({
992
+ infuraId: process.env.INFURA_ID,
993
+ bridge: 'https://bridge.walletconnect.org',
994
+ });
995
+ }
996
+
997
+ async connect(): Promise<void> {
998
+ // Connect via WalletConnect
999
+ if (!this.walletConnector.connected) {
1000
+ await this.walletConnector.createSession();
1001
+ }
1002
+
1003
+ // Create provider
1004
+ const provider = new ethers.providers.Web3Provider(
1005
+ this.walletConnector as any
1006
+ );
1007
+
1008
+ const signer = provider.getSigner();
1009
+
1010
+ // Initialize client
1011
+ this.client = new AlphaFuturesClient({
1012
+ provider,
1013
+ signer,
1014
+ network: 'mainnet'
1015
+ });
1016
+
1017
+ // Save connection state
1018
+ await AsyncStorage.setItem('walletConnected', 'true');
1019
+ }
1020
+
1021
+ async disconnect(): Promise<void> {
1022
+ if (this.walletConnector.connected) {
1023
+ await this.walletConnector.killSession();
1024
+ }
1025
+
1026
+ this.client = null;
1027
+ await AsyncStorage.removeItem('walletConnected');
1028
+ }
1029
+
1030
+ getClient(): AlphaFuturesClient {
1031
+ if (!this.client) {
1032
+ throw new Error('Not connected');
1033
+ }
1034
+ return this.client;
1035
+ }
1036
+ }
1037
+
1038
+ // hooks/useAlphaFutures.ts (React Native)
1039
+ import { useState, useEffect } from 'react';
1040
+ import { AlphaFuturesService } from '../services/AlphaFuturesService';
1041
+
1042
+ const service = new AlphaFuturesService();
1043
+
1044
+ export function useAlphaFutures() {
1045
+ const [isConnected, setIsConnected] = useState(false);
1046
+ const [loading, setLoading] = useState(true);
1047
+
1048
+ useEffect(() => {
1049
+ checkConnection();
1050
+ }, []);
1051
+
1052
+ const checkConnection = async () => {
1053
+ try {
1054
+ const connected = await AsyncStorage.getItem('walletConnected');
1055
+ if (connected === 'true') {
1056
+ await service.connect();
1057
+ setIsConnected(true);
1058
+ }
1059
+ } catch (error) {
1060
+ console.error('Connection check failed:', error);
1061
+ } finally {
1062
+ setLoading(false);
1063
+ }
1064
+ };
1065
+
1066
+ const connect = async () => {
1067
+ try {
1068
+ setLoading(true);
1069
+ await service.connect();
1070
+ setIsConnected(true);
1071
+ } catch (error) {
1072
+ throw error;
1073
+ } finally {
1074
+ setLoading(false);
1075
+ }
1076
+ };
1077
+
1078
+ const disconnect = async () => {
1079
+ try {
1080
+ await service.disconnect();
1081
+ setIsConnected(false);
1082
+ } catch (error) {
1083
+ console.error('Disconnect failed:', error);
1084
+ }
1085
+ };
1086
+
1087
+ return {
1088
+ client: isConnected ? service.getClient() : null,
1089
+ isConnected,
1090
+ loading,
1091
+ connect,
1092
+ disconnect
1093
+ };
1094
+ }
1095
+ ```
1096
+
1097
+ ## WebSocket & Real-time Data
1098
+
1099
+ ### Real-time Price Feed
1100
+
1101
+ ```typescript
1102
+ import { AlphaFuturesClient } from '@alpha-futures/sdk';
1103
+ import WebSocket from 'ws';
1104
+
1105
+ class RealTimePriceFeed {
1106
+ private client: AlphaFuturesClient;
1107
+ private ws: WebSocket | null = null;
1108
+ private subscribers: Map<string, Set<(price: bigint) => void>> = new Map();
1109
+
1110
+ constructor(client: AlphaFuturesClient) {
1111
+ this.client = client;
1112
+ }
1113
+
1114
+ connect(wsUrl: string): void {
1115
+ this.ws = new WebSocket(wsUrl);
1116
+
1117
+ this.ws.on('open', () => {
1118
+ console.log('WebSocket connected');
1119
+ this.subscribeToAllAssets();
1120
+ });
1121
+
1122
+ this.ws.on('message', (data: string) => {
1123
+ const message = JSON.parse(data);
1124
+ if (message.type === 'price') {
1125
+ this.notifySubscribers(message.asset, BigInt(message.price));
1126
+ }
1127
+ });
1128
+
1129
+ this.ws.on('error', (error) => {
1130
+ console.error('WebSocket error:', error);
1131
+ this.reconnect(wsUrl);
1132
+ });
1133
+
1134
+ this.ws.on('close', () => {
1135
+ console.log('WebSocket closed');
1136
+ this.reconnect(wsUrl);
1137
+ });
1138
+ }
1139
+
1140
+ private reconnect(wsUrl: string): void {
1141
+ setTimeout(() => {
1142
+ console.log('Reconnecting...');
1143
+ this.connect(wsUrl);
1144
+ }, 5000);
1145
+ }
1146
+
1147
+ subscribeToPriceUpdates(
1148
+ asset: string,
1149
+ callback: (price: bigint) => void
1150
+ ): () => void {
1151
+ if (!this.subscribers.has(asset)) {
1152
+ this.subscribers.set(asset, new Set());
1153
+ }
1154
+
1155
+ this.subscribers.get(asset)!.add(callback);
1156
+
1157
+ // Return unsubscribe function
1158
+ return () => {
1159
+ this.subscribers.get(asset)?.delete(callback);
1160
+ };
1161
+ }
1162
+
1163
+ private notifySubscribers(asset: string, price: bigint): void {
1164
+ this.subscribers.get(asset)?.forEach(callback => {
1165
+ callback(price);
1166
+ });
1167
+ }
1168
+
1169
+ private subscribeToAllAssets(): void {
1170
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
1171
+ this.ws.send(JSON.stringify({
1172
+ type: 'subscribe',
1173
+ assets: ['ALPHA', 'BETA', 'GAMMA']
1174
+ }));
1175
+ }
1176
+ }
1177
+ }
1178
+ ```
1179
+
1180
+ ### Event Streaming
1181
+
1182
+ ```typescript
1183
+ class EventStreamer {
1184
+ private client: AlphaFuturesClient;
1185
+ private eventHandlers: Map<string, Function[]> = new Map();
1186
+
1187
+ constructor(client: AlphaFuturesClient) {
1188
+ this.client = client;
1189
+ this.setupEventListeners();
1190
+ }
1191
+
1192
+ private setupEventListeners(): void {
1193
+ // Position events
1194
+ this.client.positionManager.on('PositionOpened', (...args) => {
1195
+ this.emit('positionOpened', ...args);
1196
+ });
1197
+
1198
+ this.client.positionManager.on('PositionClosed', (...args) => {
1199
+ this.emit('positionClosed', ...args);
1200
+ });
1201
+
1202
+ // Liquidation events
1203
+ this.client.liquidationEngine.on('PositionLiquidated', (...args) => {
1204
+ this.emit('positionLiquidated', ...args);
1205
+ });
1206
+
1207
+ // Margin events
1208
+ this.client.marginAccount.on('MarginDeposited', (...args) => {
1209
+ this.emit('marginDeposited', ...args);
1210
+ });
1211
+
1212
+ this.client.marginAccount.on('MarginWithdrawn', (...args) => {
1213
+ this.emit('marginWithdrawn', ...args);
1214
+ });
1215
+ }
1216
+
1217
+ on(event: string, handler: Function): void {
1218
+ if (!this.eventHandlers.has(event)) {
1219
+ this.eventHandlers.set(event, []);
1220
+ }
1221
+ this.eventHandlers.get(event)!.push(handler);
1222
+ }
1223
+
1224
+ off(event: string, handler: Function): void {
1225
+ const handlers = this.eventHandlers.get(event);
1226
+ if (handlers) {
1227
+ const index = handlers.indexOf(handler);
1228
+ if (index > -1) {
1229
+ handlers.splice(index, 1);
1230
+ }
1231
+ }
1232
+ }
1233
+
1234
+ private emit(event: string, ...args: any[]): void {
1235
+ const handlers = this.eventHandlers.get(event);
1236
+ if (handlers) {
1237
+ handlers.forEach(handler => handler(...args));
1238
+ }
1239
+ }
1240
+ }
1241
+ ```
1242
+
1243
+ ## Error Handling & Recovery
1244
+
1245
+ ### Comprehensive Error Handler
1246
+
1247
+ ```typescript
1248
+ import { ContractError, NetworkError, ValidationError } from '@alpha-futures/sdk';
1249
+
1250
+ class ErrorHandler {
1251
+ private retryAttempts: Map<string, number> = new Map();
1252
+ private maxRetries: number = 3;
1253
+ private retryDelay: number = 1000;
1254
+
1255
+ async handleWithRetry<T>(
1256
+ operation: () => Promise<T>,
1257
+ context: string
1258
+ ): Promise<T> {
1259
+ const attempts = this.retryAttempts.get(context) || 0;
1260
+
1261
+ try {
1262
+ const result = await operation();
1263
+ this.retryAttempts.delete(context);
1264
+ return result;
1265
+ } catch (error) {
1266
+ return this.handleError(error, context, operation);
1267
+ }
1268
+ }
1269
+
1270
+ private async handleError<T>(
1271
+ error: any,
1272
+ context: string,
1273
+ operation: () => Promise<T>
1274
+ ): Promise<T> {
1275
+ const attempts = this.retryAttempts.get(context) || 0;
1276
+
1277
+ // Categorize error
1278
+ if (this.isRetryableError(error) && attempts < this.maxRetries) {
1279
+ this.retryAttempts.set(context, attempts + 1);
1280
+
1281
+ // Exponential backoff
1282
+ const delay = this.retryDelay * Math.pow(2, attempts);
1283
+ await this.sleep(delay);
1284
+
1285
+ console.log(`Retrying ${context} (attempt ${attempts + 1}/${this.maxRetries})`);
1286
+ return this.handleWithRetry(operation, context);
1287
+ }
1288
+
1289
+ // Non-retryable or max retries exceeded
1290
+ this.retryAttempts.delete(context);
1291
+ throw this.enhanceError(error, context);
1292
+ }
1293
+
1294
+ private isRetryableError(error: any): boolean {
1295
+ // Network errors
1296
+ if (error instanceof NetworkError) {
1297
+ return true;
1298
+ }
1299
+
1300
+ // Specific error codes
1301
+ const retryableCodes = [
1302
+ 'NETWORK_ERROR',
1303
+ 'TIMEOUT',
1304
+ 'SERVER_ERROR',
1305
+ 'ECONNRESET',
1306
+ 'ETIMEDOUT',
1307
+ 'ENOTFOUND'
1308
+ ];
1309
+
1310
+ return retryableCodes.includes(error.code);
1311
+ }
1312
+
1313
+ private enhanceError(error: any, context: string): Error {
1314
+ if (error instanceof ValidationError) {
1315
+ return new Error(`Validation failed in ${context}: ${error.message}`);
1316
+ }
1317
+
1318
+ if (error instanceof ContractError) {
1319
+ return new Error(`Contract error in ${context}: ${error.reason || error.message}`);
1320
+ }
1321
+
1322
+ if (error instanceof NetworkError) {
1323
+ return new Error(`Network error in ${context}: ${error.message}`);
1324
+ }
1325
+
1326
+ return new Error(`Unknown error in ${context}: ${error.message || error}`);
1327
+ }
1328
+
1329
+ private sleep(ms: number): Promise<void> {
1330
+ return new Promise(resolve => setTimeout(resolve, ms));
1331
+ }
1332
+ }
1333
+
1334
+ // Usage
1335
+ const errorHandler = new ErrorHandler();
1336
+
1337
+ async function safeOpenPosition(client: AlphaFuturesClient, params: any) {
1338
+ return errorHandler.handleWithRetry(
1339
+ () => client.positionManager.openPosition(params),
1340
+ 'openPosition'
1341
+ );
1342
+ }
1343
+ ```
1344
+
1345
+ ## Testing Your Integration
1346
+
1347
+ ### Unit Tests
1348
+
1349
+ ```typescript
1350
+ // __tests__/integration.test.ts
1351
+ import { AlphaFuturesClient } from '@alpha-futures/sdk';
1352
+ import { ethers } from 'ethers';
1353
+
1354
+ jest.mock('@alpha-futures/sdk');
1355
+
1356
+ describe('Alpha Futures Integration', () => {
1357
+ let client: AlphaFuturesClient;
1358
+ let mockProvider: any;
1359
+ let mockSigner: any;
1360
+
1361
+ beforeEach(() => {
1362
+ mockProvider = {
1363
+ getNetwork: jest.fn().mockResolvedValue({ chainId: 1 }),
1364
+ };
1365
+
1366
+ mockSigner = {
1367
+ getAddress: jest.fn().mockResolvedValue('0x123...'),
1368
+ };
1369
+
1370
+ client = new AlphaFuturesClient({
1371
+ provider: mockProvider,
1372
+ signer: mockSigner,
1373
+ network: 'mainnet'
1374
+ });
1375
+ });
1376
+
1377
+ describe('Position Management', () => {
1378
+ it('should open a position', async () => {
1379
+ const mockTx = { hash: '0xabc...', wait: jest.fn() };
1380
+ client.positionManager.openPosition = jest.fn().mockResolvedValue(mockTx);
1381
+
1382
+ const params = {
1383
+ asset: 'ALPHA',
1384
+ size: ethers.parseEther('1000'),
1385
+ leverage: 3,
1386
+ isLong: true
1387
+ };
1388
+
1389
+ const tx = await client.positionManager.openPosition(params);
1390
+
1391
+ expect(tx.hash).toBe('0xabc...');
1392
+ expect(client.positionManager.openPosition).toHaveBeenCalledWith(params);
1393
+ });
1394
+ });
1395
+ });
1396
+ ```
1397
+
1398
+ ### Integration Tests
1399
+
1400
+ ```typescript
1401
+ // __tests__/e2e.test.ts
1402
+ import { AlphaFuturesClient } from '@alpha-futures/sdk';
1403
+ import { ethers } from 'ethers';
1404
+
1405
+ describe('E2E Integration Tests', () => {
1406
+ let client: AlphaFuturesClient;
1407
+
1408
+ beforeAll(async () => {
1409
+ // Use test network
1410
+ client = new AlphaFuturesClient({
1411
+ rpcUrl: process.env.TEST_RPC_URL,
1412
+ privateKey: process.env.TEST_PRIVATE_KEY,
1413
+ network: 'testnet'
1414
+ });
1415
+ });
1416
+
1417
+ it('should complete full trading flow', async () => {
1418
+ // 1. Check initial balance
1419
+ const initialAccount = await client.marginAccount.getMarginAccount(
1420
+ await client.signer.getAddress()
1421
+ );
1422
+
1423
+ // 2. Deposit margin
1424
+ const depositTx = await client.marginAccount.deposit(
1425
+ ethers.parseEther('100')
1426
+ );
1427
+ await depositTx.wait();
1428
+
1429
+ // 3. Open position
1430
+ const openTx = await client.positionManager.openPosition({
1431
+ asset: 'ALPHA',
1432
+ size: ethers.parseEther('300'),
1433
+ leverage: 3,
1434
+ isLong: true
1435
+ });
1436
+ const receipt = await openTx.wait();
1437
+
1438
+ // Extract position ID from events
1439
+ const positionId = extractPositionId(receipt);
1440
+
1441
+ // 4. Check position
1442
+ const position = await client.positionManager.getPosition(positionId);
1443
+ expect(position.size).toBe(ethers.parseEther('300'));
1444
+
1445
+ // 5. Close position
1446
+ const closeTx = await client.positionManager.closePosition(positionId);
1447
+ await closeTx.wait();
1448
+
1449
+ // 6. Verify final state
1450
+ const finalAccount = await client.marginAccount.getMarginAccount(
1451
+ await client.signer.getAddress()
1452
+ );
1453
+
1454
+ expect(finalAccount.usedMargin).toBe(0n);
1455
+ }, 60000); // 60 second timeout
1456
+ });
1457
+ ```
1458
+
1459
+ ## Performance Optimization
1460
+
1461
+ ### Caching Layer
1462
+
1463
+ ```typescript
1464
+ class CachedAlphaFuturesClient extends AlphaFuturesClient {
1465
+ private cache: Map<string, { value: any; timestamp: number }> = new Map();
1466
+ private cacheTTL: number = 5000; // 5 seconds
1467
+
1468
+ async getPrice(asset: string): Promise<bigint> {
1469
+ const cacheKey = `price:${asset}`;
1470
+ const cached = this.getFromCache(cacheKey);
1471
+
1472
+ if (cached) {
1473
+ return cached;
1474
+ }
1475
+
1476
+ const price = await super.priceOracle.getPrice(asset);
1477
+ this.setCache(cacheKey, price);
1478
+
1479
+ return price;
1480
+ }
1481
+
1482
+ private getFromCache(key: string): any {
1483
+ const item = this.cache.get(key);
1484
+ if (!item) return null;
1485
+
1486
+ if (Date.now() - item.timestamp > this.cacheTTL) {
1487
+ this.cache.delete(key);
1488
+ return null;
1489
+ }
1490
+
1491
+ return item.value;
1492
+ }
1493
+
1494
+ private setCache(key: string, value: any): void {
1495
+ this.cache.set(key, {
1496
+ value,
1497
+ timestamp: Date.now()
1498
+ });
1499
+ }
1500
+
1501
+ clearCache(): void {
1502
+ this.cache.clear();
1503
+ }
1504
+ }
1505
+ ```
1506
+
1507
+ ### Batch Operations
1508
+
1509
+ ```typescript
1510
+ class BatchOperations {
1511
+ private client: AlphaFuturesClient;
1512
+ private queue: Array<{
1513
+ operation: () => Promise<any>;
1514
+ resolve: (value: any) => void;
1515
+ reject: (error: any) => void;
1516
+ }> = [];
1517
+ private processing: boolean = false;
1518
+
1519
+ constructor(client: AlphaFuturesClient) {
1520
+ this.client = client;
1521
+ }
1522
+
1523
+ async addToQueue<T>(operation: () => Promise<T>): Promise<T> {
1524
+ return new Promise((resolve, reject) => {
1525
+ this.queue.push({ operation, resolve, reject });
1526
+ this.processQueue();
1527
+ });
1528
+ }
1529
+
1530
+ private async processQueue(): Promise<void> {
1531
+ if (this.processing || this.queue.length === 0) {
1532
+ return;
1533
+ }
1534
+
1535
+ this.processing = true;
1536
+
1537
+ while (this.queue.length > 0) {
1538
+ const batch = this.queue.splice(0, 10); // Process 10 at a time
1539
+
1540
+ await Promise.all(
1541
+ batch.map(async ({ operation, resolve, reject }) => {
1542
+ try {
1543
+ const result = await operation();
1544
+ resolve(result);
1545
+ } catch (error) {
1546
+ reject(error);
1547
+ }
1548
+ })
1549
+ );
1550
+
1551
+ // Rate limiting
1552
+ await this.sleep(100);
1553
+ }
1554
+
1555
+ this.processing = false;
1556
+ }
1557
+
1558
+ private sleep(ms: number): Promise<void> {
1559
+ return new Promise(resolve => setTimeout(resolve, ms));
1560
+ }
1561
+ }
1562
+ ```
1563
+
1564
+ ## Security Best Practices
1565
+
1566
+ ### 1. Private Key Security
1567
+
1568
+ - Never expose private keys in code
1569
+ - Use environment variables or secure key management systems
1570
+ - Implement key rotation policies
1571
+
1572
+ ### 2. Input Validation
1573
+
1574
+ ```typescript
1575
+ class SecureIntegration {
1576
+ validatePositionParams(params: any): void {
1577
+ // Asset validation
1578
+ if (!this.isValidAsset(params.asset)) {
1579
+ throw new ValidationError('Invalid asset', 'asset');
1580
+ }
1581
+
1582
+ // Size validation
1583
+ const size = BigInt(params.size);
1584
+ if (size < MIN_POSITION_SIZE) {
1585
+ throw new ValidationError('Position size too small', 'size');
1586
+ }
1587
+
1588
+ // Leverage validation
1589
+ if (params.leverage < 1 || params.leverage > 10) {
1590
+ throw new ValidationError('Invalid leverage', 'leverage');
1591
+ }
1592
+ }
1593
+
1594
+ private isValidAsset(asset: string): boolean {
1595
+ const validAssets = ['ALPHA', 'BETA', 'GAMMA'];
1596
+ return validAssets.includes(asset);
1597
+ }
1598
+ }
1599
+ ```
1600
+
1601
+ ### 3. Rate Limiting
1602
+
1603
+ ```typescript
1604
+ class RateLimiter {
1605
+ private requests: Map<string, number[]> = new Map();
1606
+ private limit: number;
1607
+ private window: number;
1608
+
1609
+ constructor(limit: number = 100, windowMs: number = 60000) {
1610
+ this.limit = limit;
1611
+ this.window = windowMs;
1612
+ }
1613
+
1614
+ isAllowed(identifier: string): boolean {
1615
+ const now = Date.now();
1616
+ const requests = this.requests.get(identifier) || [];
1617
+
1618
+ // Remove old requests
1619
+ const validRequests = requests.filter(time => now - time < this.window);
1620
+
1621
+ if (validRequests.length >= this.limit) {
1622
+ return false;
1623
+ }
1624
+
1625
+ validRequests.push(now);
1626
+ this.requests.set(identifier, validRequests);
1627
+
1628
+ return true;
1629
+ }
1630
+ }
1631
+ ```
1632
+
1633
+ ### 4. Transaction Security
1634
+
1635
+ ```typescript
1636
+ class SecureTransactionManager {
1637
+ async sendTransaction(
1638
+ client: AlphaFuturesClient,
1639
+ operation: () => Promise<any>,
1640
+ options: {
1641
+ maxGasPrice?: bigint;
1642
+ requireConfirmations?: number;
1643
+ } = {}
1644
+ ): Promise<any> {
1645
+ // Check gas price
1646
+ if (options.maxGasPrice) {
1647
+ const gasPrice = await client.provider.getGasPrice();
1648
+ if (gasPrice > options.maxGasPrice) {
1649
+ throw new Error('Gas price too high');
1650
+ }
1651
+ }
1652
+
1653
+ // Execute transaction
1654
+ const tx = await operation();
1655
+
1656
+ // Wait for confirmations
1657
+ const receipt = await tx.wait(options.requireConfirmations || 1);
1658
+
1659
+ // Verify success
1660
+ if (receipt.status !== 1) {
1661
+ throw new Error('Transaction failed');
1662
+ }
1663
+
1664
+ return receipt;
1665
+ }
1666
+ }
1667
+ ```
1668
+
1669
+ ## Conclusion
1670
+
1671
+ Integrating the Alpha Futures SDK provides powerful capabilities for building trading applications. Key considerations:
1672
+
1673
+ 1. **Security First**: Always prioritize security in your implementation
1674
+ 2. **Error Handling**: Implement robust error handling and recovery
1675
+ 3. **Performance**: Use caching and batching for optimal performance
1676
+ 4. **Testing**: Thoroughly test all integration points
1677
+ 5. **Monitoring**: Implement logging and monitoring for production
1678
+
1679
+ For additional support and examples, visit the [GitHub repository](https://github.com/alpha-futures/sdk) or join our [Discord community](https://discord.gg/alphafutures).