@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.
- package/.env.example +37 -0
- package/CHANGELOG.md +19 -0
- package/README.md +199 -0
- package/bin/alf +4 -0
- package/cli/README.md +198 -0
- package/cli/TEST_MANUAL.md +577 -0
- package/cli/commands/account.ts +545 -0
- package/cli/commands/funding.ts +481 -0
- package/cli/commands/liquidation.ts +523 -0
- package/cli/commands/market.ts +590 -0
- package/cli/commands/orders.ts +395 -0
- package/cli/commands/position.ts +1085 -0
- package/cli/commands/shared/positionUtils.ts +239 -0
- package/cli/commands/trading.ts +483 -0
- package/cli/commands/utils.ts +281 -0
- package/cli/commands/vault.ts +522 -0
- package/cli/index.ts +169 -0
- package/cli/interactive.ts +530 -0
- package/cli/utils/client.ts +457 -0
- package/cli/utils/config.ts +226 -0
- package/cli/utils/display.ts +258 -0
- package/cli/utils/index.ts +10 -0
- package/cli/utils/prompts.ts +364 -0
- package/config.example.json +23 -0
- package/dist/AlphaFuturesClient.d.ts +36 -0
- package/dist/AlphaFuturesClient.d.ts.map +1 -0
- package/dist/AlphaFuturesClient.js +116 -0
- package/dist/AlphaFuturesClient.js.map +1 -0
- package/dist/abi/Alpha.json +5987 -0
- package/dist/abi/abis.d.ts +319 -0
- package/dist/abi/abis.d.ts.map +1 -0
- package/dist/abi/abis.js +128 -0
- package/dist/abi/abis.js.map +1 -0
- package/dist/abi/index.d.ts +11 -0
- package/dist/abi/index.d.ts.map +1 -0
- package/dist/abi/index.js +15 -0
- package/dist/abi/index.js.map +1 -0
- package/dist/config/contracts.config.d.ts +70 -0
- package/dist/config/contracts.config.d.ts.map +1 -0
- package/dist/config/contracts.config.js +137 -0
- package/dist/config/contracts.config.js.map +1 -0
- package/dist/config/environments/alpha.config.d.ts +17 -0
- package/dist/config/environments/alpha.config.d.ts.map +1 -0
- package/dist/config/environments/alpha.config.js +140 -0
- package/dist/config/environments/alpha.config.js.map +1 -0
- package/dist/config/environments/beta.config.d.ts +16 -0
- package/dist/config/environments/beta.config.d.ts.map +1 -0
- package/dist/config/environments/beta.config.js +131 -0
- package/dist/config/environments/beta.config.js.map +1 -0
- package/dist/config/environments/dev.config.d.ts +13 -0
- package/dist/config/environments/dev.config.d.ts.map +1 -0
- package/dist/config/environments/dev.config.js +123 -0
- package/dist/config/environments/dev.config.js.map +1 -0
- package/dist/config/environments/index.d.ts +48 -0
- package/dist/config/environments/index.d.ts.map +1 -0
- package/dist/config/environments/index.js +81 -0
- package/dist/config/environments/index.js.map +1 -0
- package/dist/config/environments/localhost.config.d.ts +16 -0
- package/dist/config/environments/localhost.config.d.ts.map +1 -0
- package/dist/config/environments/localhost.config.js +152 -0
- package/dist/config/environments/localhost.config.js.map +1 -0
- package/dist/config/environments/prod.config.d.ts +20 -0
- package/dist/config/environments/prod.config.d.ts.map +1 -0
- package/dist/config/environments/prod.config.js +143 -0
- package/dist/config/environments/prod.config.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +41 -0
- package/dist/config/index.js.map +1 -0
- package/dist/constants/assets.d.ts +76 -0
- package/dist/constants/assets.d.ts.map +1 -0
- package/dist/constants/assets.js +277 -0
- package/dist/constants/assets.js.map +1 -0
- package/dist/constants/contracts.d.ts +41 -0
- package/dist/constants/contracts.d.ts.map +1 -0
- package/dist/constants/contracts.js +57 -0
- package/dist/constants/contracts.js.map +1 -0
- package/dist/constants/index.d.ts +36 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +75 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/constants/networks.d.ts +32 -0
- package/dist/constants/networks.d.ts.map +1 -0
- package/dist/constants/networks.js +174 -0
- package/dist/constants/networks.js.map +1 -0
- package/dist/contracts/index.d.ts +5 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +21 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/viem/AlphaViem.d.ts +518 -0
- package/dist/contracts/viem/AlphaViem.d.ts.map +1 -0
- package/dist/contracts/viem/AlphaViem.js +1287 -0
- package/dist/contracts/viem/AlphaViem.js.map +1 -0
- package/dist/contracts/viem/PriceOracleViem.d.ts +71 -0
- package/dist/contracts/viem/PriceOracleViem.d.ts.map +1 -0
- package/dist/contracts/viem/PriceOracleViem.js +212 -0
- package/dist/contracts/viem/PriceOracleViem.js.map +1 -0
- package/dist/contracts/viem/index.d.ts +9 -0
- package/dist/contracts/viem/index.d.ts.map +1 -0
- package/dist/contracts/viem/index.js +17 -0
- package/dist/contracts/viem/index.js.map +1 -0
- package/dist/errors/index.d.ts +44 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +83 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/types/alpha.d.ts +299 -0
- package/dist/types/alpha.d.ts.map +1 -0
- package/dist/types/alpha.js +6 -0
- package/dist/types/alpha.js.map +1 -0
- package/dist/types/client.d.ts +24 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/client.js +13 -0
- package/dist/types/client.js.map +1 -0
- package/dist/types/contracts.d.ts +48 -0
- package/dist/types/contracts.d.ts.map +1 -0
- package/dist/types/contracts.js +6 -0
- package/dist/types/contracts.js.map +1 -0
- package/dist/types/funding.d.ts +27 -0
- package/dist/types/funding.d.ts.map +1 -0
- package/dist/types/funding.js +6 -0
- package/dist/types/funding.js.map +1 -0
- package/dist/types/index.d.ts +92 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +47 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/liquidation.d.ts +20 -0
- package/dist/types/liquidation.d.ts.map +1 -0
- package/dist/types/liquidation.js +6 -0
- package/dist/types/liquidation.js.map +1 -0
- package/dist/types/margin.d.ts +29 -0
- package/dist/types/margin.d.ts.map +1 -0
- package/dist/types/margin.js +6 -0
- package/dist/types/margin.js.map +1 -0
- package/dist/types/oracle.d.ts +21 -0
- package/dist/types/oracle.d.ts.map +1 -0
- package/dist/types/oracle.js +6 -0
- package/dist/types/oracle.js.map +1 -0
- package/dist/types/positions.d.ts +43 -0
- package/dist/types/positions.d.ts.map +1 -0
- package/dist/types/positions.js +13 -0
- package/dist/types/positions.js.map +1 -0
- package/dist/utils/calculations.d.ts +84 -0
- package/dist/utils/calculations.d.ts.map +1 -0
- package/dist/utils/calculations.js +155 -0
- package/dist/utils/calculations.js.map +1 -0
- package/dist/utils/errors.d.ts +24 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +129 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/events.d.ts +40 -0
- package/dist/utils/events.d.ts.map +1 -0
- package/dist/utils/events.js +73 -0
- package/dist/utils/events.js.map +1 -0
- package/dist/utils/format.d.ts +40 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +86 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +26 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/network.d.ts +52 -0
- package/dist/utils/network.d.ts.map +1 -0
- package/dist/utils/network.js +192 -0
- package/dist/utils/network.js.map +1 -0
- package/dist/utils/positionCalculations.d.ts +145 -0
- package/dist/utils/positionCalculations.d.ts.map +1 -0
- package/dist/utils/positionCalculations.js +278 -0
- package/dist/utils/positionCalculations.js.map +1 -0
- package/dist/utils/validation.d.ts +28 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +68 -0
- package/dist/utils/validation.js.map +1 -0
- package/docs/README.md +40 -0
- package/docs/api/API.md +831 -0
- package/docs/guides/GETTING_STARTED.md +316 -0
- package/docs/guides/TRADING_GUIDE.md +677 -0
- package/docs/integration/INTEGRATION_GUIDE.md +1679 -0
- package/docs/integration/VIEM_INTEGRATION.md +294 -0
- package/docs/reference/CLI_QUICK_REFERENCE.md +197 -0
- package/docs/reference/TROUBLESHOOTING.md +922 -0
- package/package.json +113 -0
- package/src/AlphaFuturesClient.ts +158 -0
- package/src/abi/.gitkeep +1 -0
- package/src/abi/Alpha.json +5987 -0
- package/src/abi/README.md +99 -0
- package/src/abi/abis.ts +131 -0
- package/src/abi/index.ts +13 -0
- package/src/config/contracts.config.ts +186 -0
- package/src/config/environments/alpha.config.ts +139 -0
- package/src/config/environments/beta.config.ts +130 -0
- package/src/config/environments/dev.config.ts +122 -0
- package/src/config/environments/index.ts +87 -0
- package/src/config/environments/localhost.config.ts +153 -0
- package/src/config/environments/prod.config.ts +142 -0
- package/src/config/index.ts +29 -0
- package/src/constants/assets.ts +299 -0
- package/src/constants/contracts.ts +64 -0
- package/src/constants/index.ts +69 -0
- package/src/constants/networks.ts +182 -0
- package/src/contracts/index.ts +5 -0
- package/src/contracts/viem/AlphaViem.ts +1615 -0
- package/src/contracts/viem/PriceOracleViem.ts +272 -0
- package/src/contracts/viem/index.ts +11 -0
- package/src/errors/index.ts +87 -0
- package/src/index.ts +59 -0
- package/src/types/VIEM_TYPES_README.md +70 -0
- package/src/types/alpha.ts +358 -0
- package/src/types/client.ts +27 -0
- package/src/types/contracts.ts +74 -0
- package/src/types/funding.ts +31 -0
- package/src/types/index.ts +108 -0
- package/src/types/liquidation.ts +23 -0
- package/src/types/margin.ts +34 -0
- package/src/types/oracle.ts +24 -0
- package/src/types/positions.ts +48 -0
- package/src/utils/calculations.ts +175 -0
- package/src/utils/errors.ts +147 -0
- package/src/utils/events.ts +98 -0
- package/src/utils/format.ts +84 -0
- package/src/utils/index.ts +10 -0
- package/src/utils/network.ts +212 -0
- package/src/utils/positionCalculations.ts +317 -0
- package/src/utils/validation.ts +76 -0
|
@@ -0,0 +1,922 @@
|
|
|
1
|
+
# Alpha Futures SDK Troubleshooting Guide
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Common Issues](#common-issues)
|
|
6
|
+
- [Installation Problems](#installation-problems)
|
|
7
|
+
- [Connection Issues](#connection-issues)
|
|
8
|
+
- [Transaction Errors](#transaction-errors)
|
|
9
|
+
- [Position Management Issues](#position-management-issues)
|
|
10
|
+
- [Gas and Fee Problems](#gas-and-fee-problems)
|
|
11
|
+
- [Event and WebSocket Issues](#event-and-websocket-issues)
|
|
12
|
+
- [Integration Specific Issues](#integration-specific-issues)
|
|
13
|
+
- [Performance Issues](#performance-issues)
|
|
14
|
+
- [Debugging Tools](#debugging-tools)
|
|
15
|
+
- [FAQ](#faq)
|
|
16
|
+
|
|
17
|
+
## Common Issues
|
|
18
|
+
|
|
19
|
+
### Issue: "Cannot read property 'x' of undefined"
|
|
20
|
+
|
|
21
|
+
**Symptoms:**
|
|
22
|
+
```
|
|
23
|
+
TypeError: Cannot read property 'openPosition' of undefined
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Causes:**
|
|
27
|
+
- Client not properly initialized
|
|
28
|
+
- Accessing property before async initialization completes
|
|
29
|
+
|
|
30
|
+
**Solutions:**
|
|
31
|
+
```typescript
|
|
32
|
+
// ❌ Wrong
|
|
33
|
+
const client = new AlphaFuturesClient(config);
|
|
34
|
+
client.positionManager.openPosition(...); // May fail
|
|
35
|
+
|
|
36
|
+
// ✅ Correct
|
|
37
|
+
const client = new AlphaFuturesClient(config);
|
|
38
|
+
// Wait for any async initialization if needed
|
|
39
|
+
await client.initialize?.();
|
|
40
|
+
await client.positionManager.openPosition(...);
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Issue: "Insufficient funds" or "Insufficient margin"
|
|
44
|
+
|
|
45
|
+
**Symptoms:**
|
|
46
|
+
- Transaction reverts with insufficient funds error
|
|
47
|
+
- Cannot open position despite having TAO balance
|
|
48
|
+
|
|
49
|
+
**Solutions:**
|
|
50
|
+
```typescript
|
|
51
|
+
// Check TAO balance
|
|
52
|
+
const taoBalance = await provider.getBalance(address);
|
|
53
|
+
console.log('TAO Balance:', ethers.formatEther(taoBalance));
|
|
54
|
+
|
|
55
|
+
// Check margin account
|
|
56
|
+
const marginAccount = await client.marginAccount.getMarginAccount(address);
|
|
57
|
+
console.log('Available Margin:', ethers.formatEther(marginAccount.availableMargin));
|
|
58
|
+
|
|
59
|
+
// Ensure you've deposited to margin account
|
|
60
|
+
if (marginAccount.availableMargin === 0n) {
|
|
61
|
+
const tx = await client.marginAccount.deposit(ethers.parseEther('1000'));
|
|
62
|
+
await tx.wait();
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Installation Problems
|
|
67
|
+
|
|
68
|
+
### Issue: Module Resolution Errors
|
|
69
|
+
|
|
70
|
+
**Symptoms:**
|
|
71
|
+
```
|
|
72
|
+
Error: Cannot find module '@alpha-futures/sdk'
|
|
73
|
+
Module not found: Can't resolve 'ethers'
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Solutions:**
|
|
77
|
+
|
|
78
|
+
1. **Verify installation:**
|
|
79
|
+
```bash
|
|
80
|
+
npm list @alpha-futures/sdk
|
|
81
|
+
npm list ethers
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
2. **Clean install:**
|
|
85
|
+
```bash
|
|
86
|
+
rm -rf node_modules package-lock.json
|
|
87
|
+
npm install
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
3. **Check TypeScript config:**
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"compilerOptions": {
|
|
94
|
+
"moduleResolution": "node",
|
|
95
|
+
"esModuleInterop": true,
|
|
96
|
+
"allowSyntheticDefaultImports": true
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Issue: Version Conflicts
|
|
102
|
+
|
|
103
|
+
**Symptoms:**
|
|
104
|
+
```
|
|
105
|
+
npm ERR! peer dep missing: ethers@^6.0.0
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Solutions:**
|
|
109
|
+
```bash
|
|
110
|
+
# Check ethers version
|
|
111
|
+
npm list ethers
|
|
112
|
+
|
|
113
|
+
# Install compatible version
|
|
114
|
+
npm install ethers@^6.0.0
|
|
115
|
+
|
|
116
|
+
# Or use --legacy-peer-deps
|
|
117
|
+
npm install @alpha-futures/sdk --legacy-peer-deps
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Connection Issues
|
|
121
|
+
|
|
122
|
+
### Issue: "Provider not connected"
|
|
123
|
+
|
|
124
|
+
**Symptoms:**
|
|
125
|
+
- Cannot connect to network
|
|
126
|
+
- Provider returns null/undefined
|
|
127
|
+
|
|
128
|
+
**Solutions:**
|
|
129
|
+
|
|
130
|
+
1. **Check RPC URL:**
|
|
131
|
+
```typescript
|
|
132
|
+
// Verify RPC is accessible
|
|
133
|
+
try {
|
|
134
|
+
const provider = new ethers.JsonRpcProvider(rpcUrl);
|
|
135
|
+
const network = await provider.getNetwork();
|
|
136
|
+
console.log('Connected to:', network.name);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error('RPC connection failed:', error);
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
2. **Use fallback providers:**
|
|
143
|
+
```typescript
|
|
144
|
+
const providers = [
|
|
145
|
+
'https://primary-rpc.com',
|
|
146
|
+
'https://backup-rpc.com',
|
|
147
|
+
'https://fallback-rpc.com'
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
let provider;
|
|
151
|
+
for (const url of providers) {
|
|
152
|
+
try {
|
|
153
|
+
provider = new ethers.JsonRpcProvider(url);
|
|
154
|
+
await provider.getNetwork();
|
|
155
|
+
console.log('Connected to:', url);
|
|
156
|
+
break;
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error(`Failed to connect to ${url}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Issue: MetaMask Connection Problems
|
|
164
|
+
|
|
165
|
+
**Symptoms:**
|
|
166
|
+
- "MetaMask not installed"
|
|
167
|
+
- Cannot get user accounts
|
|
168
|
+
- Chain ID mismatch
|
|
169
|
+
|
|
170
|
+
**Solutions:**
|
|
171
|
+
|
|
172
|
+
1. **Check MetaMask availability:**
|
|
173
|
+
```typescript
|
|
174
|
+
if (typeof window.ethereum === 'undefined') {
|
|
175
|
+
console.error('MetaMask not installed');
|
|
176
|
+
// Redirect to MetaMask install page
|
|
177
|
+
window.open('https://metamask.io/download/', '_blank');
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
2. **Handle chain switching:**
|
|
183
|
+
```typescript
|
|
184
|
+
async function switchChain(chainId: number) {
|
|
185
|
+
try {
|
|
186
|
+
await window.ethereum.request({
|
|
187
|
+
method: 'wallet_switchEthereumChain',
|
|
188
|
+
params: [{ chainId: `0x${chainId.toString(16)}` }],
|
|
189
|
+
});
|
|
190
|
+
} catch (error) {
|
|
191
|
+
if (error.code === 4902) {
|
|
192
|
+
// Chain not added to MetaMask
|
|
193
|
+
await addChain(chainId);
|
|
194
|
+
} else {
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async function addChain(chainId: number) {
|
|
201
|
+
const chainData = getChainData(chainId); // Your chain config
|
|
202
|
+
await window.ethereum.request({
|
|
203
|
+
method: 'wallet_addEthereumChain',
|
|
204
|
+
params: [chainData],
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Transaction Errors
|
|
210
|
+
|
|
211
|
+
### Issue: "Transaction reverted"
|
|
212
|
+
|
|
213
|
+
**Symptoms:**
|
|
214
|
+
- Transaction fails with generic revert
|
|
215
|
+
- No clear error message
|
|
216
|
+
|
|
217
|
+
**Solutions:**
|
|
218
|
+
|
|
219
|
+
1. **Simulate transaction first:**
|
|
220
|
+
```typescript
|
|
221
|
+
try {
|
|
222
|
+
// Simulate the transaction
|
|
223
|
+
await client.positionManager.callStatic.openPosition({
|
|
224
|
+
asset: 'ALPHA',
|
|
225
|
+
size: ethers.parseEther('1000'),
|
|
226
|
+
leverage: 3,
|
|
227
|
+
isLong: true
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// If simulation succeeds, send actual transaction
|
|
231
|
+
const tx = await client.positionManager.openPosition(...);
|
|
232
|
+
} catch (error) {
|
|
233
|
+
console.error('Transaction would fail:', error.reason);
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
2. **Decode revert reason:**
|
|
238
|
+
```typescript
|
|
239
|
+
async function decodeRevertReason(txHash: string) {
|
|
240
|
+
try {
|
|
241
|
+
const tx = await provider.getTransaction(txHash);
|
|
242
|
+
const code = await provider.call(tx, tx.blockNumber);
|
|
243
|
+
const reason = ethers.toUtf8String('0x' + code.substr(138));
|
|
244
|
+
console.log('Revert reason:', reason);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
console.error('Could not decode revert reason');
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Issue: "Nonce too low"
|
|
252
|
+
|
|
253
|
+
**Symptoms:**
|
|
254
|
+
- Transaction rejected with nonce error
|
|
255
|
+
- Transactions stuck in pending
|
|
256
|
+
|
|
257
|
+
**Solutions:**
|
|
258
|
+
|
|
259
|
+
1. **Get correct nonce:**
|
|
260
|
+
```typescript
|
|
261
|
+
const nonce = await provider.getTransactionCount(address, 'pending');
|
|
262
|
+
const tx = await client.positionManager.openPosition(params, { nonce });
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
2. **Reset nonce in MetaMask:**
|
|
266
|
+
- Settings → Advanced → Reset Account
|
|
267
|
+
- This clears pending transactions
|
|
268
|
+
|
|
269
|
+
### Issue: "Gas estimation failed"
|
|
270
|
+
|
|
271
|
+
**Solutions:**
|
|
272
|
+
|
|
273
|
+
1. **Manual gas estimation:**
|
|
274
|
+
```typescript
|
|
275
|
+
try {
|
|
276
|
+
const estimatedGas = await client.positionManager.estimateGas.openPosition(params);
|
|
277
|
+
const gasLimit = estimatedGas * 120n / 100n; // Add 20% buffer
|
|
278
|
+
|
|
279
|
+
const tx = await client.positionManager.openPosition(params, { gasLimit });
|
|
280
|
+
} catch (error) {
|
|
281
|
+
// Use fallback gas limit
|
|
282
|
+
const tx = await client.positionManager.openPosition(params, {
|
|
283
|
+
gasLimit: 500000n
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
2. **Check gas price:**
|
|
289
|
+
```typescript
|
|
290
|
+
const feeData = await provider.getFeeData();
|
|
291
|
+
console.log('Gas price:', ethers.formatUnits(feeData.gasPrice, 'gwei'));
|
|
292
|
+
|
|
293
|
+
// For EIP-1559
|
|
294
|
+
console.log('Max fee:', ethers.formatUnits(feeData.maxFeePerGas, 'gwei'));
|
|
295
|
+
console.log('Priority fee:', ethers.formatUnits(feeData.maxPriorityFeePerGas, 'gwei'));
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## Position Management Issues
|
|
299
|
+
|
|
300
|
+
### Issue: "Position not found"
|
|
301
|
+
|
|
302
|
+
**Symptoms:**
|
|
303
|
+
- getPosition returns error
|
|
304
|
+
- Position ID seems invalid
|
|
305
|
+
|
|
306
|
+
**Solutions:**
|
|
307
|
+
|
|
308
|
+
1. **Verify position exists:**
|
|
309
|
+
```typescript
|
|
310
|
+
// Get all positions for user
|
|
311
|
+
const positions = await client.positionManager.getAllPositions(address);
|
|
312
|
+
console.log('User positions:', positions);
|
|
313
|
+
|
|
314
|
+
// Check if position ID exists
|
|
315
|
+
const positionExists = positions.some(p => p.id === positionId);
|
|
316
|
+
if (!positionExists) {
|
|
317
|
+
console.error('Position does not exist');
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
2. **Extract position ID from transaction:**
|
|
322
|
+
```typescript
|
|
323
|
+
async function getPositionIdFromTx(txHash: string): Promise<bigint> {
|
|
324
|
+
const receipt = await provider.getTransactionReceipt(txHash);
|
|
325
|
+
|
|
326
|
+
// Find PositionOpened event
|
|
327
|
+
const iface = client.positionManager.interface;
|
|
328
|
+
const topic = iface.getEventTopic('PositionOpened');
|
|
329
|
+
|
|
330
|
+
const log = receipt.logs.find(log => log.topics[0] === topic);
|
|
331
|
+
if (!log) throw new Error('PositionOpened event not found');
|
|
332
|
+
|
|
333
|
+
// Decode event
|
|
334
|
+
const decoded = iface.decodeEventLog('PositionOpened', log.data, log.topics);
|
|
335
|
+
return decoded.positionId;
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Issue: "Cannot close position"
|
|
340
|
+
|
|
341
|
+
**Causes:**
|
|
342
|
+
- Position already closed
|
|
343
|
+
- Not position owner
|
|
344
|
+
- Position is being liquidated
|
|
345
|
+
|
|
346
|
+
**Solutions:**
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
// Check position status
|
|
350
|
+
const position = await client.positionManager.getPosition(positionId);
|
|
351
|
+
console.log('Position owner:', position.trader);
|
|
352
|
+
console.log('Current user:', await signer.getAddress());
|
|
353
|
+
|
|
354
|
+
// Verify ownership
|
|
355
|
+
if (position.trader.toLowerCase() !== (await signer.getAddress()).toLowerCase()) {
|
|
356
|
+
throw new Error('Not position owner');
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Check if position is liquidatable
|
|
360
|
+
const liquidationStatus = await client.liquidationEngine.checkLiquidationStatus(positionId);
|
|
361
|
+
if (liquidationStatus.canLiquidate) {
|
|
362
|
+
console.warn('Position is liquidatable, may fail to close normally');
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## Gas and Fee Problems
|
|
367
|
+
|
|
368
|
+
### Issue: "Gas price too high"
|
|
369
|
+
|
|
370
|
+
**Solutions:**
|
|
371
|
+
|
|
372
|
+
1. **Implement gas price limits:**
|
|
373
|
+
```typescript
|
|
374
|
+
class GasManager {
|
|
375
|
+
private maxGasPrice: bigint;
|
|
376
|
+
|
|
377
|
+
constructor(maxGweiPrice: number) {
|
|
378
|
+
this.maxGasPrice = ethers.parseUnits(maxGweiPrice.toString(), 'gwei');
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
async waitForAcceptableGas(provider: Provider): Promise<void> {
|
|
382
|
+
while (true) {
|
|
383
|
+
const feeData = await provider.getFeeData();
|
|
384
|
+
if (feeData.gasPrice <= this.maxGasPrice) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
console.log('Gas too high, waiting...');
|
|
389
|
+
await new Promise(resolve => setTimeout(resolve, 60000)); // Wait 1 minute
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
2. **Use gas price oracles:**
|
|
396
|
+
```typescript
|
|
397
|
+
async function getGasPriceRecommendation(): Promise<{
|
|
398
|
+
slow: bigint;
|
|
399
|
+
standard: bigint;
|
|
400
|
+
fast: bigint;
|
|
401
|
+
}> {
|
|
402
|
+
// Example using etherscan gas oracle
|
|
403
|
+
const response = await fetch(
|
|
404
|
+
`https://api.etherscan.io/api?module=gastracker&action=gasoracle&apikey=${API_KEY}`
|
|
405
|
+
);
|
|
406
|
+
const data = await response.json();
|
|
407
|
+
|
|
408
|
+
return {
|
|
409
|
+
slow: ethers.parseUnits(data.result.SafeGasPrice, 'gwei'),
|
|
410
|
+
standard: ethers.parseUnits(data.result.ProposeGasPrice, 'gwei'),
|
|
411
|
+
fast: ethers.parseUnits(data.result.FastGasPrice, 'gwei')
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Issue: "Trading fees unexpectedly high"
|
|
417
|
+
|
|
418
|
+
**Solutions:**
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
// Calculate fees before trading
|
|
422
|
+
const tradingFee = await client.positionManager.calculateTradingFee(positionSize);
|
|
423
|
+
const gasEstimate = await client.positionManager.estimateGas.openPosition(params);
|
|
424
|
+
const gasPrice = await provider.getGasPrice();
|
|
425
|
+
const gasCost = gasEstimate * gasPrice;
|
|
426
|
+
|
|
427
|
+
console.log('Trading fee:', ethers.formatEther(tradingFee));
|
|
428
|
+
console.log('Gas cost:', ethers.formatEther(gasCost));
|
|
429
|
+
console.log('Total cost:', ethers.formatEther(tradingFee + gasCost));
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## Event and WebSocket Issues
|
|
433
|
+
|
|
434
|
+
### Issue: "Missing events"
|
|
435
|
+
|
|
436
|
+
**Symptoms:**
|
|
437
|
+
- Events not firing
|
|
438
|
+
- WebSocket disconnects
|
|
439
|
+
|
|
440
|
+
**Solutions:**
|
|
441
|
+
|
|
442
|
+
1. **Implement event recovery:**
|
|
443
|
+
```typescript
|
|
444
|
+
class EventMonitor {
|
|
445
|
+
private lastBlockProcessed: number = 0;
|
|
446
|
+
|
|
447
|
+
async recoverMissedEvents(
|
|
448
|
+
contract: Contract,
|
|
449
|
+
eventName: string,
|
|
450
|
+
fromBlock: number
|
|
451
|
+
): Promise<Event[]> {
|
|
452
|
+
const currentBlock = await contract.provider.getBlockNumber();
|
|
453
|
+
const events = await contract.queryFilter(
|
|
454
|
+
contract.filters[eventName](),
|
|
455
|
+
fromBlock,
|
|
456
|
+
currentBlock
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
this.lastBlockProcessed = currentBlock;
|
|
460
|
+
return events;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
startMonitoring(contract: Contract, eventName: string) {
|
|
464
|
+
contract.on(eventName, (...args) => {
|
|
465
|
+
console.log(`${eventName} event:`, args);
|
|
466
|
+
this.lastBlockProcessed = args[args.length - 1].blockNumber;
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
// Periodic recovery check
|
|
470
|
+
setInterval(async () => {
|
|
471
|
+
const missed = await this.recoverMissedEvents(
|
|
472
|
+
contract,
|
|
473
|
+
eventName,
|
|
474
|
+
this.lastBlockProcessed + 1
|
|
475
|
+
);
|
|
476
|
+
|
|
477
|
+
if (missed.length > 0) {
|
|
478
|
+
console.log(`Recovered ${missed.length} missed events`);
|
|
479
|
+
}
|
|
480
|
+
}, 60000); // Check every minute
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
2. **WebSocket reconnection:**
|
|
486
|
+
```typescript
|
|
487
|
+
class ReconnectingWebSocket {
|
|
488
|
+
private ws: WebSocket | null = null;
|
|
489
|
+
private reconnectInterval: number = 5000;
|
|
490
|
+
private shouldReconnect: boolean = true;
|
|
491
|
+
|
|
492
|
+
connect(url: string) {
|
|
493
|
+
this.ws = new WebSocket(url);
|
|
494
|
+
|
|
495
|
+
this.ws.onopen = () => {
|
|
496
|
+
console.log('WebSocket connected');
|
|
497
|
+
this.reconnectInterval = 5000; // Reset interval
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
this.ws.onclose = () => {
|
|
501
|
+
if (this.shouldReconnect) {
|
|
502
|
+
console.log(`Reconnecting in ${this.reconnectInterval}ms...`);
|
|
503
|
+
setTimeout(() => this.connect(url), this.reconnectInterval);
|
|
504
|
+
this.reconnectInterval = Math.min(this.reconnectInterval * 2, 60000);
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
this.ws.onerror = (error) => {
|
|
509
|
+
console.error('WebSocket error:', error);
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
disconnect() {
|
|
514
|
+
this.shouldReconnect = false;
|
|
515
|
+
this.ws?.close();
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
## Integration Specific Issues
|
|
521
|
+
|
|
522
|
+
### React: "Invalid hook call"
|
|
523
|
+
|
|
524
|
+
**Solutions:**
|
|
525
|
+
|
|
526
|
+
1. **Check React versions:**
|
|
527
|
+
```bash
|
|
528
|
+
npm list react react-dom
|
|
529
|
+
# Ensure only one version of React is installed
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
2. **Fix hook usage:**
|
|
533
|
+
```typescript
|
|
534
|
+
// ❌ Wrong - Hook in conditional
|
|
535
|
+
function Component() {
|
|
536
|
+
if (someCondition) {
|
|
537
|
+
const { client } = useAlphaFutures(); // Error!
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// ✅ Correct
|
|
542
|
+
function Component() {
|
|
543
|
+
const { client } = useAlphaFutures();
|
|
544
|
+
|
|
545
|
+
if (someCondition && client) {
|
|
546
|
+
// Use client
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### Next.js: "Window is not defined"
|
|
552
|
+
|
|
553
|
+
**Solutions:**
|
|
554
|
+
|
|
555
|
+
```typescript
|
|
556
|
+
// Use dynamic imports for client-side only code
|
|
557
|
+
import dynamic from 'next/dynamic';
|
|
558
|
+
|
|
559
|
+
const TradingPanel = dynamic(
|
|
560
|
+
() => import('../components/TradingPanel'),
|
|
561
|
+
{ ssr: false }
|
|
562
|
+
);
|
|
563
|
+
|
|
564
|
+
// Or check for browser environment
|
|
565
|
+
if (typeof window !== 'undefined') {
|
|
566
|
+
// Browser-only code
|
|
567
|
+
}
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### Mobile: "WalletConnect issues"
|
|
571
|
+
|
|
572
|
+
**Solutions:**
|
|
573
|
+
|
|
574
|
+
```typescript
|
|
575
|
+
// Implement proper WalletConnect initialization
|
|
576
|
+
class WalletConnectManager {
|
|
577
|
+
private connector: WalletConnectProvider;
|
|
578
|
+
|
|
579
|
+
async initialize() {
|
|
580
|
+
this.connector = new WalletConnectProvider({
|
|
581
|
+
infuraId: process.env.INFURA_ID,
|
|
582
|
+
qrcode: true,
|
|
583
|
+
bridge: 'https://bridge.walletconnect.org',
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
// Subscribe to events
|
|
587
|
+
this.connector.on('connect', (error, payload) => {
|
|
588
|
+
if (error) {
|
|
589
|
+
console.error('WalletConnect error:', error);
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
console.log('Connected:', payload);
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
// Handle disconnect
|
|
596
|
+
this.connector.on('disconnect', (error, payload) => {
|
|
597
|
+
console.log('Disconnected');
|
|
598
|
+
// Clean up
|
|
599
|
+
this.connector = null;
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
## Performance Issues
|
|
606
|
+
|
|
607
|
+
### Issue: "Slow response times"
|
|
608
|
+
|
|
609
|
+
**Solutions:**
|
|
610
|
+
|
|
611
|
+
1. **Implement caching:**
|
|
612
|
+
```typescript
|
|
613
|
+
class CacheManager {
|
|
614
|
+
private cache = new Map<string, { data: any; timestamp: number }>();
|
|
615
|
+
private ttl: number = 5000; // 5 seconds
|
|
616
|
+
|
|
617
|
+
async getOrFetch<T>(
|
|
618
|
+
key: string,
|
|
619
|
+
fetcher: () => Promise<T>
|
|
620
|
+
): Promise<T> {
|
|
621
|
+
const cached = this.cache.get(key);
|
|
622
|
+
|
|
623
|
+
if (cached && Date.now() - cached.timestamp < this.ttl) {
|
|
624
|
+
return cached.data;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
const data = await fetcher();
|
|
628
|
+
this.cache.set(key, { data, timestamp: Date.now() });
|
|
629
|
+
|
|
630
|
+
return data;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// Usage
|
|
635
|
+
const cache = new CacheManager();
|
|
636
|
+
const price = await cache.getOrFetch(
|
|
637
|
+
`price:${asset}`,
|
|
638
|
+
() => client.priceOracle.getPrice(asset)
|
|
639
|
+
);
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
2. **Batch requests:**
|
|
643
|
+
```typescript
|
|
644
|
+
// Instead of multiple individual calls
|
|
645
|
+
const positions = [];
|
|
646
|
+
for (const id of positionIds) {
|
|
647
|
+
positions.push(await client.positionManager.getPosition(id));
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// Use multicall or batch requests
|
|
651
|
+
const multicall = new Multicall({ provider });
|
|
652
|
+
const calls = positionIds.map(id => ({
|
|
653
|
+
target: positionManagerAddress,
|
|
654
|
+
callData: positionManager.interface.encodeFunctionData('getPosition', [id])
|
|
655
|
+
}));
|
|
656
|
+
|
|
657
|
+
const results = await multicall.aggregate(calls);
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
### Issue: "Memory leaks"
|
|
661
|
+
|
|
662
|
+
**Solutions:**
|
|
663
|
+
|
|
664
|
+
```typescript
|
|
665
|
+
// Properly clean up event listeners
|
|
666
|
+
class ComponentWithCleanup {
|
|
667
|
+
private listeners: Array<() => void> = [];
|
|
668
|
+
|
|
669
|
+
initialize() {
|
|
670
|
+
const unsubscribe = client.positionManager.on('PositionOpened',
|
|
671
|
+
this.handlePositionOpened
|
|
672
|
+
);
|
|
673
|
+
this.listeners.push(unsubscribe);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
cleanup() {
|
|
677
|
+
// Remove all listeners
|
|
678
|
+
this.listeners.forEach(unsub => unsub());
|
|
679
|
+
this.listeners = [];
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
## Debugging Tools
|
|
685
|
+
|
|
686
|
+
### 1. Enable Debug Logging
|
|
687
|
+
|
|
688
|
+
```typescript
|
|
689
|
+
// Set debug environment variable
|
|
690
|
+
process.env.DEBUG = 'ethers:*,alpha-futures:*';
|
|
691
|
+
|
|
692
|
+
// Custom logger
|
|
693
|
+
class DebugLogger {
|
|
694
|
+
private enabled: boolean;
|
|
695
|
+
|
|
696
|
+
constructor() {
|
|
697
|
+
this.enabled = process.env.NODE_ENV === 'development';
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
log(category: string, message: string, data?: any) {
|
|
701
|
+
if (!this.enabled) return;
|
|
702
|
+
|
|
703
|
+
console.log(`[${new Date().toISOString()}] [${category}] ${message}`, data);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
error(category: string, error: Error) {
|
|
707
|
+
console.error(`[${new Date().toISOString()}] [${category}]`, error);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
### 2. Transaction Debugger
|
|
713
|
+
|
|
714
|
+
```typescript
|
|
715
|
+
class TransactionDebugger {
|
|
716
|
+
async debugTransaction(txHash: string) {
|
|
717
|
+
const tx = await provider.getTransaction(txHash);
|
|
718
|
+
const receipt = await provider.getTransactionReceipt(txHash);
|
|
719
|
+
|
|
720
|
+
console.log('Transaction:', {
|
|
721
|
+
hash: tx.hash,
|
|
722
|
+
from: tx.from,
|
|
723
|
+
to: tx.to,
|
|
724
|
+
value: ethers.formatEther(tx.value),
|
|
725
|
+
gasLimit: tx.gasLimit.toString(),
|
|
726
|
+
gasPrice: ethers.formatUnits(tx.gasPrice, 'gwei'),
|
|
727
|
+
nonce: tx.nonce,
|
|
728
|
+
data: tx.data
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
console.log('Receipt:', {
|
|
732
|
+
status: receipt.status,
|
|
733
|
+
gasUsed: receipt.gasUsed.toString(),
|
|
734
|
+
effectiveGasPrice: ethers.formatUnits(receipt.effectiveGasPrice, 'gwei'),
|
|
735
|
+
logs: receipt.logs.length,
|
|
736
|
+
blockNumber: receipt.blockNumber
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
// Decode logs
|
|
740
|
+
receipt.logs.forEach((log, i) => {
|
|
741
|
+
try {
|
|
742
|
+
const parsed = client.positionManager.interface.parseLog(log);
|
|
743
|
+
console.log(`Event ${i}:`, parsed.name, parsed.args);
|
|
744
|
+
} catch (e) {
|
|
745
|
+
// Not from this contract
|
|
746
|
+
}
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
### 3. Network Monitor
|
|
753
|
+
|
|
754
|
+
```typescript
|
|
755
|
+
class NetworkMonitor {
|
|
756
|
+
private provider: Provider;
|
|
757
|
+
private lastBlock: number = 0;
|
|
758
|
+
private lastResponseTime: number = 0;
|
|
759
|
+
|
|
760
|
+
constructor(provider: Provider) {
|
|
761
|
+
this.provider = provider;
|
|
762
|
+
this.startMonitoring();
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
private async startMonitoring() {
|
|
766
|
+
setInterval(async () => {
|
|
767
|
+
const start = Date.now();
|
|
768
|
+
|
|
769
|
+
try {
|
|
770
|
+
const block = await this.provider.getBlockNumber();
|
|
771
|
+
const responseTime = Date.now() - start;
|
|
772
|
+
|
|
773
|
+
if (block > this.lastBlock) {
|
|
774
|
+
console.log(`New block: ${block} (${responseTime}ms)`);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
if (responseTime > 5000) {
|
|
778
|
+
console.warn(`Slow network response: ${responseTime}ms`);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
this.lastBlock = block;
|
|
782
|
+
this.lastResponseTime = responseTime;
|
|
783
|
+
} catch (error) {
|
|
784
|
+
console.error('Network monitor error:', error);
|
|
785
|
+
}
|
|
786
|
+
}, 5000);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
## FAQ
|
|
792
|
+
|
|
793
|
+
### Q: How do I test on testnet?
|
|
794
|
+
|
|
795
|
+
```typescript
|
|
796
|
+
// Use testnet configuration
|
|
797
|
+
const client = new AlphaFuturesClient({
|
|
798
|
+
rpcUrl: 'https://testnet-rpc.bittensor.com',
|
|
799
|
+
privateKey: process.env.TESTNET_PRIVATE_KEY,
|
|
800
|
+
network: 'testnet'
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
// Get testnet TAO from faucet
|
|
804
|
+
async function requestTestnetFunds(address: string) {
|
|
805
|
+
const response = await fetch('https://faucet.bittensor.com', {
|
|
806
|
+
method: 'POST',
|
|
807
|
+
headers: { 'Content-Type': 'application/json' },
|
|
808
|
+
body: JSON.stringify({ address })
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
if (!response.ok) {
|
|
812
|
+
throw new Error('Faucet request failed');
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
### Q: How do I handle different error types?
|
|
818
|
+
|
|
819
|
+
```typescript
|
|
820
|
+
import {
|
|
821
|
+
ContractError,
|
|
822
|
+
NetworkError,
|
|
823
|
+
ValidationError
|
|
824
|
+
} from '@alpha-futures/sdk';
|
|
825
|
+
|
|
826
|
+
try {
|
|
827
|
+
await client.positionManager.openPosition(params);
|
|
828
|
+
} catch (error) {
|
|
829
|
+
if (error instanceof ValidationError) {
|
|
830
|
+
// Handle validation errors
|
|
831
|
+
alert(`Invalid input: ${error.field} - ${error.message}`);
|
|
832
|
+
} else if (error instanceof ContractError) {
|
|
833
|
+
// Handle contract errors
|
|
834
|
+
if (error.reason?.includes('Insufficient margin')) {
|
|
835
|
+
alert('Please deposit more margin');
|
|
836
|
+
} else {
|
|
837
|
+
alert(`Contract error: ${error.reason}`);
|
|
838
|
+
}
|
|
839
|
+
} else if (error instanceof NetworkError) {
|
|
840
|
+
// Handle network errors
|
|
841
|
+
alert('Network error. Please check your connection');
|
|
842
|
+
} else {
|
|
843
|
+
// Unknown error
|
|
844
|
+
console.error('Unknown error:', error);
|
|
845
|
+
alert('An unexpected error occurred');
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
### Q: How do I optimize for mobile?
|
|
851
|
+
|
|
852
|
+
```typescript
|
|
853
|
+
// Mobile-optimized client
|
|
854
|
+
class MobileOptimizedClient extends AlphaFuturesClient {
|
|
855
|
+
constructor(config: ClientConfig) {
|
|
856
|
+
super(config);
|
|
857
|
+
|
|
858
|
+
// Reduce polling frequency
|
|
859
|
+
this.pollingInterval = 10000; // 10 seconds
|
|
860
|
+
|
|
861
|
+
// Enable request batching
|
|
862
|
+
this.enableBatching = true;
|
|
863
|
+
|
|
864
|
+
// Limit concurrent requests
|
|
865
|
+
this.maxConcurrentRequests = 2;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
// Override methods to add mobile-specific optimizations
|
|
869
|
+
async getPrice(asset: string): Promise<bigint> {
|
|
870
|
+
// Cache prices more aggressively on mobile
|
|
871
|
+
return this.withCache(`price:${asset}`, 30000, () =>
|
|
872
|
+
super.priceOracle.getPrice(asset)
|
|
873
|
+
);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
```
|
|
877
|
+
|
|
878
|
+
### Q: How do I implement a kill switch?
|
|
879
|
+
|
|
880
|
+
```typescript
|
|
881
|
+
class EmergencyManager {
|
|
882
|
+
private killSwitch: boolean = false;
|
|
883
|
+
|
|
884
|
+
async checkKillSwitch(): Promise<void> {
|
|
885
|
+
// Check on-chain kill switch
|
|
886
|
+
const isEmergency = await client.protocolVault.isEmergencyMode();
|
|
887
|
+
|
|
888
|
+
if (isEmergency) {
|
|
889
|
+
this.killSwitch = true;
|
|
890
|
+
throw new Error('Protocol is in emergency mode');
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
wrapCall<T>(operation: () => Promise<T>): Promise<T> {
|
|
895
|
+
if (this.killSwitch) {
|
|
896
|
+
throw new Error('Operations disabled due to emergency');
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
return operation();
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
## Getting Help
|
|
905
|
+
|
|
906
|
+
If you're still experiencing issues:
|
|
907
|
+
|
|
908
|
+
1. **Check the documentation**: Review the [API Reference](./API.md) and [Integration Guide](./INTEGRATION_GUIDE.md)
|
|
909
|
+
|
|
910
|
+
2. **Search existing issues**: Check the [GitHub Issues](https://github.com/alpha-futures/sdk/issues)
|
|
911
|
+
|
|
912
|
+
3. **Join the community**:
|
|
913
|
+
- Discord: https://discord.gg/alphafutures
|
|
914
|
+
- Telegram: https://t.me/alphafutures
|
|
915
|
+
|
|
916
|
+
4. **Report a bug**: Open an issue with:
|
|
917
|
+
- SDK version
|
|
918
|
+
- Error message and stack trace
|
|
919
|
+
- Minimal reproduction code
|
|
920
|
+
- Network and environment details
|
|
921
|
+
|
|
922
|
+
5. **Contact support**: support@alphafutures.io
|