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.
- package/.claude/settings.local.json +11 -0
- package/CONTRACT_METHOD_FIXES.md +189 -0
- package/INTEGRATION_SUMMARY.md +219 -0
- package/OPTIMIZATION_GUIDE.md +238 -0
- package/README.md +384 -0
- package/SNAPSHOT_FIX_SUMMARY.md +161 -0
- package/SNAPSHOT_OPTIMIZATION_SUMMARY.md +199 -0
- package/dist/abis/Referral.d.ts +36 -0
- package/dist/abis/Referral.js +4 -0
- package/dist/abis/Trading.d.ts +57 -0
- package/dist/abis/Trading.js +742 -0
- package/dist/abis/erc20.d.ts +51 -0
- package/dist/abis/erc20.js +4 -0
- package/dist/abis/index.d.ts +8 -0
- package/dist/abis/index.js +24 -0
- package/dist/abis/multicall.d.ts +85 -0
- package/dist/abis/multicall.js +4 -0
- package/dist/abis/pairInfos.d.ts +77 -0
- package/dist/abis/pairInfos.js +4 -0
- package/dist/abis/pairStorage.d.ts +124 -0
- package/dist/abis/pairStorage.js +4 -0
- package/dist/abis/priceAggregator.d.ts +77 -0
- package/dist/abis/priceAggregator.js +4 -0
- package/dist/abis/tardingStorage.d.ts +97 -0
- package/dist/abis/tardingStorage.js +1295 -0
- package/dist/abis.d.ts +623 -0
- package/dist/abis.js +49 -0
- package/dist/client.d.ts +118 -0
- package/dist/client.js +224 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.js +42 -0
- package/dist/crypto/spki.d.ts +55 -0
- package/dist/crypto/spki.js +160 -0
- package/dist/feed/feed_client.d.ts +68 -0
- package/dist/feed/feed_client.js +239 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +87 -0
- package/dist/rpc/asset_parameters.d.ts +62 -0
- package/dist/rpc/asset_parameters.js +169 -0
- package/dist/rpc/blended.d.ts +23 -0
- package/dist/rpc/blended.js +55 -0
- package/dist/rpc/category_parameters.d.ts +34 -0
- package/dist/rpc/category_parameters.js +105 -0
- package/dist/rpc/delegation.d.ts +81 -0
- package/dist/rpc/delegation.js +180 -0
- package/dist/rpc/fee_parameters.d.ts +46 -0
- package/dist/rpc/fee_parameters.js +113 -0
- package/dist/rpc/multicall.d.ts +83 -0
- package/dist/rpc/multicall.js +117 -0
- package/dist/rpc/pair_info_queries.d.ts +101 -0
- package/dist/rpc/pair_info_queries.js +161 -0
- package/dist/rpc/pairs_cache.d.ts +62 -0
- package/dist/rpc/pairs_cache.js +240 -0
- package/dist/rpc/referral_operations.d.ts +67 -0
- package/dist/rpc/referral_operations.js +143 -0
- package/dist/rpc/snapshot.d.ts +49 -0
- package/dist/rpc/snapshot.js +162 -0
- package/dist/rpc/trade.d.ts +84 -0
- package/dist/rpc/trade.js +249 -0
- package/dist/rpc/trading_operations.d.ts +103 -0
- package/dist/rpc/trading_operations.js +295 -0
- package/dist/rpc/trading_parameters.d.ts +49 -0
- package/dist/rpc/trading_parameters.js +94 -0
- package/dist/signers/base.d.ts +24 -0
- package/dist/signers/base.js +10 -0
- package/dist/signers/kms.d.ts +47 -0
- package/dist/signers/kms.js +172 -0
- package/dist/signers/local.d.ts +43 -0
- package/dist/signers/local.js +64 -0
- package/dist/types.d.ts +1419 -0
- package/dist/types.js +245 -0
- package/dist/utils.d.ts +52 -0
- package/dist/utils.js +134 -0
- package/examples/advanced-queries.ts +181 -0
- package/examples/basic-usage.ts +78 -0
- package/examples/delegation-and-referrals.ts +130 -0
- package/examples/get-pyth-ids.ts +61 -0
- package/examples/kms-signer.ts +31 -0
- package/examples/optimized-snapshot.ts +153 -0
- package/examples/price-feed-with-sdk-ids.ts +97 -0
- package/examples/price-feed.ts +36 -0
- package/examples/trading-operations.ts +149 -0
- package/package.json +41 -0
- package/src/abis/Referral.ts +3 -0
- package/src/abis/Trading.ts +741 -0
- package/src/abis/erc20.ts +3 -0
- package/src/abis/index.ts +8 -0
- package/src/abis/multicall.ts +3 -0
- package/src/abis/pairInfos.ts +3 -0
- package/src/abis/pairStorage.ts +3 -0
- package/src/abis/priceAggregator.ts +3 -0
- package/src/abis/tardingStorage.ts +1294 -0
- package/src/abis.ts +56 -0
- package/src/client.ts +373 -0
- package/src/config.ts +62 -0
- package/src/crypto/spki.ts +197 -0
- package/src/feed/feed_client.ts +288 -0
- package/src/index.ts +114 -0
- package/src/rpc/asset_parameters.ts +217 -0
- package/src/rpc/blended.ts +77 -0
- package/src/rpc/category_parameters.ts +128 -0
- package/src/rpc/delegation.ts +225 -0
- package/src/rpc/fee_parameters.ts +150 -0
- package/src/rpc/multicall.ts +164 -0
- package/src/rpc/pair_info_queries.ts +208 -0
- package/src/rpc/pairs_cache.ts +268 -0
- package/src/rpc/referral_operations.ts +164 -0
- package/src/rpc/snapshot.ts +210 -0
- package/src/rpc/trade.ts +306 -0
- package/src/rpc/trading_operations.ts +378 -0
- package/src/rpc/trading_parameters.ts +127 -0
- package/src/signers/base.ts +27 -0
- package/src/signers/kms.ts +212 -0
- package/src/signers/local.ts +70 -0
- package/src/types.ts +410 -0
- package/src/utils.ts +155 -0
- 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
|
+
}
|
package/dist/utils.d.ts
ADDED
|
@@ -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);
|