perps-sdk-ts 1.0.1

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 (117) hide show
  1. package/.claude/settings.local.json +11 -0
  2. package/CONTRACT_METHOD_FIXES.md +189 -0
  3. package/INTEGRATION_SUMMARY.md +219 -0
  4. package/OPTIMIZATION_GUIDE.md +238 -0
  5. package/README.md +384 -0
  6. package/SNAPSHOT_FIX_SUMMARY.md +161 -0
  7. package/SNAPSHOT_OPTIMIZATION_SUMMARY.md +199 -0
  8. package/dist/abis/Referral.d.ts +36 -0
  9. package/dist/abis/Referral.js +4 -0
  10. package/dist/abis/Trading.d.ts +57 -0
  11. package/dist/abis/Trading.js +742 -0
  12. package/dist/abis/erc20.d.ts +51 -0
  13. package/dist/abis/erc20.js +4 -0
  14. package/dist/abis/index.d.ts +8 -0
  15. package/dist/abis/index.js +24 -0
  16. package/dist/abis/multicall.d.ts +85 -0
  17. package/dist/abis/multicall.js +4 -0
  18. package/dist/abis/pairInfos.d.ts +77 -0
  19. package/dist/abis/pairInfos.js +4 -0
  20. package/dist/abis/pairStorage.d.ts +124 -0
  21. package/dist/abis/pairStorage.js +4 -0
  22. package/dist/abis/priceAggregator.d.ts +77 -0
  23. package/dist/abis/priceAggregator.js +4 -0
  24. package/dist/abis/tardingStorage.d.ts +97 -0
  25. package/dist/abis/tardingStorage.js +1295 -0
  26. package/dist/abis.d.ts +623 -0
  27. package/dist/abis.js +49 -0
  28. package/dist/client.d.ts +118 -0
  29. package/dist/client.js +224 -0
  30. package/dist/config.d.ts +43 -0
  31. package/dist/config.js +42 -0
  32. package/dist/crypto/spki.d.ts +55 -0
  33. package/dist/crypto/spki.js +160 -0
  34. package/dist/feed/feed_client.d.ts +68 -0
  35. package/dist/feed/feed_client.js +239 -0
  36. package/dist/index.d.ts +28 -0
  37. package/dist/index.js +87 -0
  38. package/dist/rpc/asset_parameters.d.ts +62 -0
  39. package/dist/rpc/asset_parameters.js +169 -0
  40. package/dist/rpc/blended.d.ts +23 -0
  41. package/dist/rpc/blended.js +55 -0
  42. package/dist/rpc/category_parameters.d.ts +34 -0
  43. package/dist/rpc/category_parameters.js +105 -0
  44. package/dist/rpc/delegation.d.ts +81 -0
  45. package/dist/rpc/delegation.js +180 -0
  46. package/dist/rpc/fee_parameters.d.ts +46 -0
  47. package/dist/rpc/fee_parameters.js +113 -0
  48. package/dist/rpc/multicall.d.ts +83 -0
  49. package/dist/rpc/multicall.js +117 -0
  50. package/dist/rpc/pair_info_queries.d.ts +101 -0
  51. package/dist/rpc/pair_info_queries.js +161 -0
  52. package/dist/rpc/pairs_cache.d.ts +62 -0
  53. package/dist/rpc/pairs_cache.js +240 -0
  54. package/dist/rpc/referral_operations.d.ts +67 -0
  55. package/dist/rpc/referral_operations.js +143 -0
  56. package/dist/rpc/snapshot.d.ts +49 -0
  57. package/dist/rpc/snapshot.js +162 -0
  58. package/dist/rpc/trade.d.ts +84 -0
  59. package/dist/rpc/trade.js +249 -0
  60. package/dist/rpc/trading_operations.d.ts +103 -0
  61. package/dist/rpc/trading_operations.js +295 -0
  62. package/dist/rpc/trading_parameters.d.ts +49 -0
  63. package/dist/rpc/trading_parameters.js +94 -0
  64. package/dist/signers/base.d.ts +24 -0
  65. package/dist/signers/base.js +10 -0
  66. package/dist/signers/kms.d.ts +47 -0
  67. package/dist/signers/kms.js +172 -0
  68. package/dist/signers/local.d.ts +43 -0
  69. package/dist/signers/local.js +64 -0
  70. package/dist/types.d.ts +1419 -0
  71. package/dist/types.js +245 -0
  72. package/dist/utils.d.ts +52 -0
  73. package/dist/utils.js +134 -0
  74. package/examples/advanced-queries.ts +181 -0
  75. package/examples/basic-usage.ts +78 -0
  76. package/examples/delegation-and-referrals.ts +130 -0
  77. package/examples/get-pyth-ids.ts +61 -0
  78. package/examples/kms-signer.ts +31 -0
  79. package/examples/optimized-snapshot.ts +153 -0
  80. package/examples/price-feed-with-sdk-ids.ts +97 -0
  81. package/examples/price-feed.ts +36 -0
  82. package/examples/trading-operations.ts +149 -0
  83. package/package.json +41 -0
  84. package/src/abis/Referral.ts +3 -0
  85. package/src/abis/Trading.ts +741 -0
  86. package/src/abis/erc20.ts +3 -0
  87. package/src/abis/index.ts +8 -0
  88. package/src/abis/multicall.ts +3 -0
  89. package/src/abis/pairInfos.ts +3 -0
  90. package/src/abis/pairStorage.ts +3 -0
  91. package/src/abis/priceAggregator.ts +3 -0
  92. package/src/abis/tardingStorage.ts +1294 -0
  93. package/src/abis.ts +56 -0
  94. package/src/client.ts +373 -0
  95. package/src/config.ts +62 -0
  96. package/src/crypto/spki.ts +197 -0
  97. package/src/feed/feed_client.ts +288 -0
  98. package/src/index.ts +114 -0
  99. package/src/rpc/asset_parameters.ts +217 -0
  100. package/src/rpc/blended.ts +77 -0
  101. package/src/rpc/category_parameters.ts +128 -0
  102. package/src/rpc/delegation.ts +225 -0
  103. package/src/rpc/fee_parameters.ts +150 -0
  104. package/src/rpc/multicall.ts +164 -0
  105. package/src/rpc/pair_info_queries.ts +208 -0
  106. package/src/rpc/pairs_cache.ts +268 -0
  107. package/src/rpc/referral_operations.ts +164 -0
  108. package/src/rpc/snapshot.ts +210 -0
  109. package/src/rpc/trade.ts +306 -0
  110. package/src/rpc/trading_operations.ts +378 -0
  111. package/src/rpc/trading_parameters.ts +127 -0
  112. package/src/signers/base.ts +27 -0
  113. package/src/signers/kms.ts +212 -0
  114. package/src/signers/local.ts +70 -0
  115. package/src/types.ts +410 -0
  116. package/src/utils.ts +155 -0
  117. package/tsconfig.json +18 -0
package/dist/types.js ADDED
@@ -0,0 +1,245 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ReferralDiscountSchema = exports.ReferralTierSchema = exports.OpenLimitOrderSchema = exports.TradeInfoSchema = exports.TradeSchema = exports.SnapshotSchema = exports.GroupSchema = exports.PairDataSchema = exports.LossProtectionInfoSchema = exports.DepthSchema = exports.FeeSchema = exports.SkewSchema = exports.UtilizationSchema = exports.OpenInterestLimitsSchema = exports.OpenInterestSchema = exports.PriceFeedResponseSchema = exports.EmaPriceSchema = exports.PriceSchema = exports.TradeResponseSchema = exports.TradeInputSchema = exports.PairInfoSchema = exports.SpreadSchema = exports.MarginUpdateType = exports.TradeInputOrderType = void 0;
4
+ exports.fromBlockchain10 = fromBlockchain10;
5
+ exports.fromBlockchain6 = fromBlockchain6;
6
+ exports.toBlockchain10 = toBlockchain10;
7
+ exports.toBlockchain6 = toBlockchain6;
8
+ exports.fromBlockchain12 = fromBlockchain12;
9
+ exports.toBlockchain12 = toBlockchain12;
10
+ exports.fromBlockchain18 = fromBlockchain18;
11
+ exports.toBlockchain18 = toBlockchain18;
12
+ const zod_1 = require("zod");
13
+ // ========== ENUMS ==========
14
+ var TradeInputOrderType;
15
+ (function (TradeInputOrderType) {
16
+ TradeInputOrderType["MARKET"] = "market";
17
+ TradeInputOrderType["STOP_LIMIT"] = "stop_limit";
18
+ TradeInputOrderType["LIMIT"] = "limit";
19
+ TradeInputOrderType["MARKET_ZERO_FEE"] = "market_zero_fee";
20
+ })(TradeInputOrderType || (exports.TradeInputOrderType = TradeInputOrderType = {}));
21
+ var MarginUpdateType;
22
+ (function (MarginUpdateType) {
23
+ MarginUpdateType[MarginUpdateType["DEPOSIT"] = 0] = "DEPOSIT";
24
+ MarginUpdateType[MarginUpdateType["WITHDRAW"] = 1] = "WITHDRAW";
25
+ })(MarginUpdateType || (exports.MarginUpdateType = MarginUpdateType = {}));
26
+ // ========== ZOD SCHEMAS ==========
27
+ // Address validation
28
+ const addressSchema = zod_1.z.string().regex(/^0x[a-fA-F0-9]{40}$/);
29
+ // Spread schema
30
+ exports.SpreadSchema = zod_1.z.object({
31
+ min: zod_1.z.number(),
32
+ max: zod_1.z.number(),
33
+ });
34
+ // PairInfo schema
35
+ exports.PairInfoSchema = zod_1.z.object({
36
+ from: zod_1.z.string(),
37
+ to: zod_1.z.string(),
38
+ spread: exports.SpreadSchema,
39
+ groupIndex: zod_1.z.number(),
40
+ feeIndex: zod_1.z.number(),
41
+ maxLeverage: zod_1.z.number(),
42
+ maxLongOiP: zod_1.z.number(),
43
+ maxShortOiP: zod_1.z.number(),
44
+ // maxOpenInterestUsdc: z.number(),
45
+ });
46
+ // TradeInput schema
47
+ exports.TradeInputSchema = zod_1.z.object({
48
+ pair: zod_1.z.string(),
49
+ isLong: zod_1.z.boolean(),
50
+ collateralInTrade: zod_1.z.number(),
51
+ leverage: zod_1.z.number(),
52
+ openPrice: zod_1.z.number(),
53
+ tp: zod_1.z.number(),
54
+ sl: zod_1.z.number(),
55
+ referrer: addressSchema.optional().default('0x0000000000000000000000000000000000000000'),
56
+ orderType: zod_1.z.nativeEnum(TradeInputOrderType),
57
+ maxSlippageP: zod_1.z.number(),
58
+ });
59
+ // TradeResponse schema
60
+ exports.TradeResponseSchema = zod_1.z.object({
61
+ trader: addressSchema,
62
+ pairIndex: zod_1.z.number(),
63
+ index: zod_1.z.number(),
64
+ initialPosUsdc: zod_1.z.number(),
65
+ openPrice: zod_1.z.number(),
66
+ buy: zod_1.z.boolean(),
67
+ leverage: zod_1.z.number(),
68
+ tp: zod_1.z.number(),
69
+ sl: zod_1.z.number(),
70
+ });
71
+ // Price schema (from Pyth)
72
+ exports.PriceSchema = zod_1.z.object({
73
+ price: zod_1.z.string(),
74
+ conf: zod_1.z.string(),
75
+ expo: zod_1.z.number(),
76
+ publishTime: zod_1.z.number(),
77
+ });
78
+ // EmaPrice schema
79
+ exports.EmaPriceSchema = zod_1.z.object({
80
+ price: zod_1.z.string(),
81
+ conf: zod_1.z.string(),
82
+ expo: zod_1.z.number(),
83
+ publishTime: zod_1.z.number(),
84
+ });
85
+ // PriceFeedResponse schema
86
+ exports.PriceFeedResponseSchema = zod_1.z.object({
87
+ id: zod_1.z.string(),
88
+ price: exports.PriceSchema,
89
+ emaPrice: exports.EmaPriceSchema,
90
+ });
91
+ // OpenInterest schema
92
+ exports.OpenInterestSchema = zod_1.z.object({
93
+ long: zod_1.z.number(),
94
+ short: zod_1.z.number(),
95
+ max: zod_1.z.number(),
96
+ });
97
+ // OpenInterestLimits schema
98
+ exports.OpenInterestLimitsSchema = zod_1.z.object({
99
+ pairIndex: zod_1.z.number(),
100
+ maxLong: zod_1.z.number(),
101
+ maxShort: zod_1.z.number(),
102
+ });
103
+ // Utilization schema
104
+ exports.UtilizationSchema = zod_1.z.object({
105
+ utilizationLong: zod_1.z.number(),
106
+ utilizationShort: zod_1.z.number(),
107
+ });
108
+ // Skew schema
109
+ exports.SkewSchema = zod_1.z.object({
110
+ skew: zod_1.z.number(),
111
+ });
112
+ // Fee schema
113
+ exports.FeeSchema = zod_1.z.object({
114
+ feeP: zod_1.z.number(),
115
+ });
116
+ // Depth schema
117
+ exports.DepthSchema = zod_1.z.object({
118
+ onePercentDepthAboveUsdc: zod_1.z.number(),
119
+ onePercentDepthBelowUsdc: zod_1.z.number(),
120
+ });
121
+ // LossProtectionInfo schema
122
+ exports.LossProtectionInfoSchema = zod_1.z.object({
123
+ tier: zod_1.z.number(),
124
+ percentage: zod_1.z.number(),
125
+ amount: zod_1.z.number(),
126
+ });
127
+ // PairData schema (for snapshot)
128
+ exports.PairDataSchema = zod_1.z.object({
129
+ pairInfo: exports.PairInfoSchema,
130
+ openInterest: exports.OpenInterestSchema.optional(),
131
+ utilization: exports.UtilizationSchema.optional(),
132
+ skew: exports.SkewSchema.optional(),
133
+ fee: exports.FeeSchema.optional(),
134
+ depth: exports.DepthSchema.optional(),
135
+ spread: zod_1.z.number().optional(),
136
+ });
137
+ // Group schema (for snapshot)
138
+ exports.GroupSchema = zod_1.z.object({
139
+ groupIndex: zod_1.z.number(),
140
+ pairs: zod_1.z.record(zod_1.z.string(), exports.PairDataSchema),
141
+ openInterest: exports.OpenInterestSchema.optional(),
142
+ utilization: exports.UtilizationSchema.optional(),
143
+ skew: exports.SkewSchema.optional(),
144
+ });
145
+ // Snapshot schema
146
+ exports.SnapshotSchema = zod_1.z.object({
147
+ groups: zod_1.z.record(zod_1.z.string(), exports.GroupSchema),
148
+ });
149
+ // Trade schema (from smart contract)
150
+ exports.TradeSchema = zod_1.z.object({
151
+ trader: addressSchema,
152
+ pairIndex: zod_1.z.number(),
153
+ index: zod_1.z.number(),
154
+ initialPosToken: zod_1.z.number(), // 6 decimals
155
+ positionSizeUSDC: zod_1.z.number(), // 6 decimals
156
+ openPrice: zod_1.z.number(), // 10 decimals
157
+ buy: zod_1.z.boolean(),
158
+ leverage: zod_1.z.number(), // 10 decimals
159
+ tp: zod_1.z.number(), // 10 decimals
160
+ sl: zod_1.z.number(), // 10 decimals
161
+ timestamp: zod_1.z.number(),
162
+ });
163
+ // TradeInfo schema (from smart contract)
164
+ exports.TradeInfoSchema = zod_1.z.object({
165
+ openInterestUSDC: zod_1.z.number(), // 6 decimals
166
+ tpLastUpdated: zod_1.z.number(),
167
+ slLastUpdated: zod_1.z.number(),
168
+ beingMarketClosed: zod_1.z.boolean(),
169
+ lossProtection: zod_1.z.number(),
170
+ });
171
+ // OpenLimitOrder schema (from smart contract)
172
+ exports.OpenLimitOrderSchema = zod_1.z.object({
173
+ trader: addressSchema,
174
+ pairIndex: zod_1.z.number(),
175
+ index: zod_1.z.number(),
176
+ positionSize: zod_1.z.number(), // 6 decimals
177
+ buy: zod_1.z.boolean(),
178
+ leverage: zod_1.z.number(), // 10 decimals
179
+ tp: zod_1.z.number(), // 10 decimals
180
+ sl: zod_1.z.number(), // 10 decimals
181
+ price: zod_1.z.number(), // 10 decimals
182
+ slippageP: zod_1.z.number(), // 10 decimals
183
+ block: zod_1.z.number(),
184
+ executionFee: zod_1.z.number(), // 18 decimals
185
+ });
186
+ // ReferralTier schema
187
+ exports.ReferralTierSchema = zod_1.z.object({
188
+ feeDiscountPct: zod_1.z.number(),
189
+ refRebatePct: zod_1.z.number(),
190
+ });
191
+ // ReferralDiscount schema
192
+ exports.ReferralDiscountSchema = zod_1.z.object({
193
+ traderDiscount: zod_1.z.number(),
194
+ referrer: addressSchema,
195
+ rebateShare: zod_1.z.number(),
196
+ });
197
+ // ========== CONVERSION HELPERS ==========
198
+ /**
199
+ * Convert blockchain integer to decimal (10^10 precision)
200
+ */
201
+ function fromBlockchain10(value) {
202
+ return Number(BigInt(value)) / 1e10;
203
+ }
204
+ /**
205
+ * Convert blockchain integer to decimal (10^6 precision for USDC)
206
+ */
207
+ function fromBlockchain6(value) {
208
+ return Number(BigInt(value)) / 1e6;
209
+ }
210
+ /**
211
+ * Convert decimal to blockchain integer (10^10 precision)
212
+ */
213
+ function toBlockchain10(value) {
214
+ return BigInt(Math.floor(value * 1e10));
215
+ }
216
+ /**
217
+ * Convert decimal to blockchain integer (10^6 precision for USDC)
218
+ */
219
+ function toBlockchain6(value) {
220
+ return BigInt(Math.floor(value * 1e6));
221
+ }
222
+ /**
223
+ * Convert blockchain integer to decimal (10^12 precision for fees)
224
+ */
225
+ function fromBlockchain12(value) {
226
+ return Number(BigInt(value)) / 1e12;
227
+ }
228
+ /**
229
+ * Convert decimal to blockchain integer (10^12 precision for fees)
230
+ */
231
+ function toBlockchain12(value) {
232
+ return BigInt(Math.floor(value * 1e12));
233
+ }
234
+ /**
235
+ * Convert blockchain integer to decimal (10^18 precision for ETH/execution fees)
236
+ */
237
+ function fromBlockchain18(value) {
238
+ return Number(BigInt(value)) / 1e18;
239
+ }
240
+ /**
241
+ * Convert decimal to blockchain integer (10^18 precision for ETH/execution fees)
242
+ */
243
+ function toBlockchain18(value) {
244
+ return BigInt(Math.floor(value * 1e18));
245
+ }
@@ -0,0 +1,52 @@
1
+ import { Result } from 'ethers';
2
+ /**
3
+ * Utility functions for Web3 decoding and data processing
4
+ */
5
+ /**
6
+ * Check if ABI type is a tuple
7
+ */
8
+ export declare function isTupleType(abiType: string): boolean;
9
+ /**
10
+ * Check if ABI type is an array
11
+ */
12
+ export declare function isArrayType(abiType: string): boolean;
13
+ /**
14
+ * Process ABI outputs and convert Result to object with named fields
15
+ */
16
+ export declare function processOutputTypes(outputs: readonly any[], decoded: Result): Record<string, any>;
17
+ /**
18
+ * Decode contract function output using ABI
19
+ * @param abi - Contract ABI
20
+ * @param functionName - Function name to decode
21
+ * @param output - Raw output data
22
+ * @returns Decoded output as object with named fields
23
+ */
24
+ export declare function decoder(abi: any[], functionName: string, output: any): Record<string, any> | null;
25
+ /**
26
+ * Convert hex string to number
27
+ */
28
+ export declare function hexToNumber(hex: string): number;
29
+ /**
30
+ * Convert number to hex string
31
+ */
32
+ export declare function numberToHex(num: number): string;
33
+ /**
34
+ * Validate Ethereum address
35
+ */
36
+ export declare function isValidAddress(address: string): boolean;
37
+ /**
38
+ * Format address to checksummed version
39
+ */
40
+ export declare function toChecksumAddress(address: string): string;
41
+ /**
42
+ * Sleep for specified milliseconds
43
+ */
44
+ export declare function sleep(ms: number): Promise<void>;
45
+ /**
46
+ * Retry function with exponential backoff
47
+ * @param fn - Async function to retry
48
+ * @param maxRetries - Maximum number of retries
49
+ * @param baseDelay - Base delay in milliseconds (default: 1000)
50
+ * @returns Result of the function
51
+ */
52
+ export declare function retryWithBackoff<T>(fn: () => Promise<T>, maxRetries?: number, baseDelay?: number): Promise<T>;
package/dist/utils.js ADDED
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTupleType = isTupleType;
4
+ exports.isArrayType = isArrayType;
5
+ exports.processOutputTypes = processOutputTypes;
6
+ exports.decoder = decoder;
7
+ exports.hexToNumber = hexToNumber;
8
+ exports.numberToHex = numberToHex;
9
+ exports.isValidAddress = isValidAddress;
10
+ exports.toChecksumAddress = toChecksumAddress;
11
+ exports.sleep = sleep;
12
+ exports.retryWithBackoff = retryWithBackoff;
13
+ const ethers_1 = require("ethers");
14
+ /**
15
+ * Utility functions for Web3 decoding and data processing
16
+ */
17
+ /**
18
+ * Check if ABI type is a tuple
19
+ */
20
+ function isTupleType(abiType) {
21
+ return abiType.startsWith('tuple');
22
+ }
23
+ /**
24
+ * Check if ABI type is an array
25
+ */
26
+ function isArrayType(abiType) {
27
+ return abiType.endsWith('[]');
28
+ }
29
+ /**
30
+ * Process ABI outputs and convert Result to object with named fields
31
+ */
32
+ function processOutputTypes(outputs, decoded) {
33
+ const result = {};
34
+ outputs.forEach((output, index) => {
35
+ const name = output.name || `output${index}`;
36
+ let value = decoded[index];
37
+ // Handle tuple types
38
+ if (isTupleType(output.type) && output.components) {
39
+ value = processOutputTypes(output.components, value);
40
+ }
41
+ // Handle array of tuples
42
+ else if (isArrayType(output.type) && output.baseType === 'tuple' && output.components) {
43
+ value = value.map((item) => processOutputTypes(output.components, item));
44
+ }
45
+ result[name] = value;
46
+ });
47
+ return result;
48
+ }
49
+ /**
50
+ * Decode contract function output using ABI
51
+ * @param abi - Contract ABI
52
+ * @param functionName - Function name to decode
53
+ * @param output - Raw output data
54
+ * @returns Decoded output as object with named fields
55
+ */
56
+ function decoder(abi, functionName, output) {
57
+ try {
58
+ const iface = new ethers_1.Interface(abi);
59
+ const fragment = iface.getFunction(functionName);
60
+ if (!fragment) {
61
+ throw new Error(`Function ${functionName} not found in ABI`);
62
+ }
63
+ // If output is already decoded (Result type), process it
64
+ if (typeof output === 'object' && !Array.isArray(output) && output.toArray) {
65
+ return processOutputTypes(fragment.outputs, output);
66
+ }
67
+ // Decode the output
68
+ const decoded = iface.decodeFunctionResult(fragment, output);
69
+ // Process and return with named fields
70
+ return processOutputTypes(fragment.outputs, decoded);
71
+ }
72
+ catch (error) {
73
+ console.error(`Error decoding function ${functionName}:`, error);
74
+ return null;
75
+ }
76
+ }
77
+ /**
78
+ * Convert hex string to number
79
+ */
80
+ function hexToNumber(hex) {
81
+ return parseInt(hex, 16);
82
+ }
83
+ /**
84
+ * Convert number to hex string
85
+ */
86
+ function numberToHex(num) {
87
+ return '0x' + num.toString(16);
88
+ }
89
+ /**
90
+ * Validate Ethereum address
91
+ */
92
+ function isValidAddress(address) {
93
+ return /^0x[a-fA-F0-9]{40}$/.test(address);
94
+ }
95
+ /**
96
+ * Format address to checksummed version
97
+ */
98
+ function toChecksumAddress(address) {
99
+ if (!isValidAddress(address)) {
100
+ throw new Error('Invalid Ethereum address');
101
+ }
102
+ // ethers.js getAddress() returns checksummed address
103
+ return address;
104
+ }
105
+ /**
106
+ * Sleep for specified milliseconds
107
+ */
108
+ function sleep(ms) {
109
+ return new Promise((resolve) => setTimeout(resolve, ms));
110
+ }
111
+ /**
112
+ * Retry function with exponential backoff
113
+ * @param fn - Async function to retry
114
+ * @param maxRetries - Maximum number of retries
115
+ * @param baseDelay - Base delay in milliseconds (default: 1000)
116
+ * @returns Result of the function
117
+ */
118
+ async function retryWithBackoff(fn, maxRetries = 3, baseDelay = 1000) {
119
+ let lastError;
120
+ for (let i = 0; i <= maxRetries; i++) {
121
+ try {
122
+ return await fn();
123
+ }
124
+ catch (error) {
125
+ lastError = error;
126
+ if (i < maxRetries) {
127
+ const delay = baseDelay * Math.pow(2, i);
128
+ console.log(`Retry ${i + 1}/${maxRetries} after ${delay}ms...`);
129
+ await sleep(delay);
130
+ }
131
+ }
132
+ }
133
+ throw lastError;
134
+ }
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Advanced Queries Example
3
+ * Demonstrates pair info queries and multicall functionality
4
+ */
5
+
6
+ import { TraderClient } from '../src';
7
+
8
+ async function main() {
9
+ // Initialize client
10
+ const client = new TraderClient('https://mainnet.base.org');
11
+
12
+ console.log('=== PAIR INFO QUERIES ===\n');
13
+
14
+ // ==================== PRICE IMPACT & SPREAD ====================
15
+
16
+ console.log('1. Calculating price impact and spread...');
17
+
18
+ const pairIndex = 0; // BTC/USD
19
+ const positionSize = 1000; // 1000 USDC
20
+ const isLong = true;
21
+
22
+ // Get price impact spread
23
+ const priceImpact = await client.pairInfoQueries.getPriceImpactSpread(
24
+ pairIndex,
25
+ isLong,
26
+ positionSize,
27
+ true // isOpen
28
+ );
29
+ console.log('Price impact spread:', priceImpact, '%');
30
+
31
+ // Get skew impact spread
32
+ const skewImpact = await client.pairInfoQueries.getSkewImpactSpread(
33
+ pairIndex,
34
+ isLong,
35
+ positionSize,
36
+ true
37
+ );
38
+ console.log('Skew impact spread:', skewImpact, '%');
39
+
40
+ // Get total price impact
41
+ const totalImpact = await client.pairInfoQueries.getPriceImpactP(pairIndex, isLong, positionSize);
42
+ console.log('Total price impact:', totalImpact, '%');
43
+
44
+ // ==================== FEES ====================
45
+
46
+ console.log('\n2. Calculating fees...');
47
+
48
+ // Get opening fee in USDC
49
+ const openFeeUsdc = await client.pairInfoQueries.getOpenFeeUsdc(pairIndex, positionSize, isLong);
50
+ console.log('Opening fee (USDC):', openFeeUsdc);
51
+
52
+ // Get opening fee percentage
53
+ const openFeeP = await client.pairInfoQueries.getOpenFeeP(pairIndex, positionSize, isLong);
54
+ console.log('Opening fee percentage:', openFeeP, '%');
55
+
56
+ // Get margin fee percentage
57
+ const marginFeeP = await client.pairInfoQueries.getPairMarginFeeP(pairIndex);
58
+ console.log('Margin fee percentage:', marginFeeP, '%');
59
+
60
+ // ==================== LOSS PROTECTION ====================
61
+
62
+ console.log('\n3. Checking loss protection...');
63
+
64
+ // Get loss protection tier for position size
65
+ const tier = await client.pairInfoQueries.getLossProtectionTierForSize(pairIndex, positionSize);
66
+ console.log('Loss protection tier:', tier);
67
+
68
+ // Get loss protection percentage
69
+ const protectionP = await client.pairInfoQueries.getLossProtectionP(pairIndex, tier);
70
+ console.log('Loss protection percentage:', protectionP, '%');
71
+
72
+ // ==================== LIQUIDITY DEPTH ====================
73
+
74
+ console.log('\n4. Checking liquidity depth...');
75
+
76
+ const depth = await client.pairInfoQueries.getDepth(pairIndex);
77
+ console.log('1% depth above (longs):', depth.above, 'USDC');
78
+ console.log('1% depth below (shorts):', depth.below, 'USDC');
79
+
80
+ // ==================== MULTICALL ====================
81
+
82
+ console.log('\n=== MULTICALL ===\n');
83
+
84
+ console.log('5. Batch reading multiple trades...');
85
+
86
+ const walletAddress = '0x...'; // Replace with actual address
87
+
88
+ // Get trading storage contract
89
+ const tradingStorage = client['contracts'].get('TradingStorage');
90
+
91
+ if (tradingStorage) {
92
+ // Batch read trades 0, 1, 2 for pair 0
93
+ const trades = await client.multicall.batchGetOpenTrades(
94
+ tradingStorage,
95
+ walletAddress,
96
+ 0, // pairIndex
97
+ [0, 1, 2] // trade indices
98
+ );
99
+
100
+ console.log('Fetched', trades.length, 'trades in a single call');
101
+ trades.forEach((trade, i) => {
102
+ console.log(`Trade ${i}:`, {
103
+ openPrice: trade.openPrice.toString(),
104
+ leverage: trade.leverage.toString(),
105
+ buy: trade.buy,
106
+ });
107
+ });
108
+
109
+ // Batch read trade infos
110
+ console.log('\n6. Batch reading trade infos...');
111
+ const tradeInfos = await client.multicall.batchGetOpenTradesInfo(
112
+ tradingStorage,
113
+ walletAddress,
114
+ 0,
115
+ [0, 1, 2]
116
+ );
117
+
118
+ console.log('Fetched', tradeInfos.length, 'trade infos');
119
+ tradeInfos.forEach((info, i) => {
120
+ console.log(`Trade ${i} info:`, {
121
+ openInterestUSDC: info.openInterestUSDC.toString(),
122
+ lossProtection: info.lossProtection.toString(),
123
+ });
124
+ });
125
+ }
126
+
127
+ // ==================== CUSTOM MULTICALL ====================
128
+
129
+ console.log('\n7. Custom multicall example...');
130
+
131
+ // Get pair storage contract
132
+ const pairStorage = client['contracts'].get('PairStorage');
133
+
134
+ if (pairStorage) {
135
+ // Read multiple pairs at once
136
+ const pairs = await client.multicall.batchGetPairs(pairStorage, [0, 1, 2, 3, 4]);
137
+
138
+ console.log('Fetched', pairs.length, 'pairs');
139
+ pairs.forEach((pair, i) => {
140
+ console.log(`Pair ${i}:`, {
141
+ from: pair.from,
142
+ to: pair.to,
143
+ maxLeverage: pair.maxLeverage.toString(),
144
+ });
145
+ });
146
+ }
147
+
148
+ // Advanced: Manual multicall with custom calls
149
+ console.log('\n8. Manual multicall with different contracts...');
150
+
151
+ const pairInfos = client['contracts'].get('PairInfos');
152
+ const referral = client['contracts'].get('Referral');
153
+
154
+ if (pairInfos && referral && tradingStorage) {
155
+ const result = await client.multicall.aggregateAndDecode([
156
+ {
157
+ contract: pairInfos,
158
+ functionName: 'onePercentDepthAboveUsdc',
159
+ args: [0],
160
+ },
161
+ {
162
+ contract: pairInfos,
163
+ functionName: 'onePercentDepthBelowUsdc',
164
+ args: [0],
165
+ },
166
+ {
167
+ contract: tradingStorage,
168
+ functionName: 'openInterestUsdc',
169
+ args: [0, 0],
170
+ },
171
+ ]);
172
+
173
+ console.log('Block number:', result.blockNumber);
174
+ console.log('Depth above:', result.results[0].toString());
175
+ console.log('Depth below:', result.results[1].toString());
176
+ console.log('Open interest:', result.results[2].toString());
177
+ }
178
+ }
179
+
180
+ // Run the example
181
+ main().catch(console.error);
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Basic usage example for Avantis Trader SDK
3
+ */
4
+
5
+ import { TraderClient, TradeInput, TradeInputOrderType } from '../src';
6
+
7
+ async function main() {
8
+ // Initialize client with your RPC endpoint
9
+ const providerUrl = 'https://base-rpc.publicnode.com';
10
+ const client = new TraderClient(providerUrl);
11
+
12
+ // Set up signer with your private key (for local development)
13
+ const privateKey = '';
14
+ client.setLocalSigner(privateKey);
15
+
16
+ // Get your address
17
+ const address = await client.signer?.getAddress();
18
+ console.log('Trading from address:', address);
19
+
20
+ // Check USDC balance
21
+ const usdcBalance = await client.getUsdcBalance(address!);
22
+ console.log('USDC Balance:', usdcBalance);
23
+
24
+ // Check USDC allowance
25
+ const allowance = await client.getUsdcAllowanceForTrading(address!);
26
+ console.log('USDC Allowance:', allowance);
27
+
28
+ // Approve USDC if needed
29
+ if (allowance < 1000) {
30
+ console.log('Approving USDC...');
31
+ const approvalReceipt = await client.approveUsdcForTrading(10000); // Approve 10,000 USDC
32
+ console.log('Approval transaction hash:', approvalReceipt?.hash);
33
+
34
+ // Check allowance again after approval
35
+ const newAllowance = await client.getUsdcAllowanceForTrading(address!);
36
+ console.log('New USDC Allowance after approval:', newAllowance);
37
+ }
38
+
39
+ // // Get market snapshot
40
+ // console.log('Fetching market snapshot...');
41
+ // const snapshot = await client.snapshotRPC.getSnapshot();
42
+ // console.log('Snapshot:', JSON.stringify(snapshot, null, 2));
43
+
44
+ // // Get pair data
45
+ // const btcPair = await client.snapshotRPC.getPairSnapshot('BTC/USD');
46
+ // console.log('BTC/USD data:', btcPair);
47
+
48
+ // Create a trade
49
+ const tradeInput: TradeInput = {
50
+ pair: 'BTC/USD',
51
+ isLong: true,
52
+ collateralInTrade: 2, // 3 USDC (leave room for fees)
53
+ leverage: 10, // 10x leverage
54
+ openPrice: 0, // 0 = market order
55
+ tp: 0, // Take profit (0 = none)
56
+ sl: 0, // Stop loss (0 = none)
57
+ orderType: TradeInputOrderType.MARKET,
58
+
59
+ maxSlippageP: 1, // 1% max slippage
60
+ referrer: "0xca4d3f16a1deef067875ec01a9f683f67a91d947"
61
+ };
62
+
63
+ // // Build trade transaction
64
+ // console.log('Building trade transaction...');
65
+ // const tradeTx = await client.tradeRPC.buildTradeOpenTx(tradeInput, address!);
66
+
67
+ // // Sign and send transaction
68
+ // console.log('Sending trade...');
69
+ // const receipt = await client.signAndGetReceipt(tradeTx);
70
+ // console.log('Trade executed! Transaction hash:', receipt?.hash);
71
+
72
+ // Get your open trades
73
+ const trades = await client.tradeRPC.getTrades(address!);
74
+ console.log('Open trades:', trades);
75
+ }
76
+
77
+ // Run the example
78
+ main().catch(console.error);