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
@@ -0,0 +1,295 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TradingOperationsRPC = void 0;
4
+ const types_1 = require("../types");
5
+ /**
6
+ * Trading Operations RPC
7
+ * Handles all trading contract interactions including opening/closing trades,
8
+ * updating margins, and managing limit orders.
9
+ */
10
+ class TradingOperationsRPC {
11
+ constructor(tradingContract, tradingStorageContract, signer) {
12
+ this.tradingContract = tradingContract;
13
+ this.tradingStorageContract = tradingStorageContract;
14
+ this.signer = signer;
15
+ }
16
+ /**
17
+ * Get execution fee required for trading operations
18
+ * @returns Execution fee in ETH
19
+ */
20
+ async getExecutionFee() {
21
+ const fee = await this.tradingContract.getExecutionFee();
22
+ return (0, types_1.fromBlockchain18)(fee);
23
+ }
24
+ /**
25
+ * Open a new trade position
26
+ * @param trade - Trade parameters
27
+ * @param orderType - Order type (MARKET, LIMIT, etc.)
28
+ * @param slippageP - Slippage percentage (e.g., 1 for 1%)
29
+ * @param executionFeeEth - Execution fee in ETH (optional, will fetch if not provided)
30
+ * @returns Transaction receipt
31
+ */
32
+ async openTrade(trade, orderType, slippageP, executionFeeEth) {
33
+ if (!this.signer) {
34
+ throw new Error('Signer required for trading operations');
35
+ }
36
+ // Get execution fee if not provided
37
+ if (!executionFeeEth) {
38
+ executionFeeEth = await this.getExecutionFee();
39
+ }
40
+ // Convert order type to number
41
+ const orderTypeMap = {
42
+ [types_1.TradeInputOrderType.MARKET]: 0,
43
+ [types_1.TradeInputOrderType.STOP_LIMIT]: 1,
44
+ [types_1.TradeInputOrderType.LIMIT]: 2,
45
+ [types_1.TradeInputOrderType.MARKET_ZERO_FEE]: 3,
46
+ };
47
+ // Prepare trade struct with blockchain values
48
+ const tradeStruct = {
49
+ trader: trade.trader,
50
+ pairIndex: trade.pairIndex,
51
+ index: trade.index,
52
+ initialPosToken: (0, types_1.toBlockchain6)(trade.initialPosToken),
53
+ positionSizeUSDC: (0, types_1.toBlockchain6)(trade.positionSizeUSDC),
54
+ openPrice: (0, types_1.toBlockchain10)(trade.openPrice),
55
+ buy: trade.buy,
56
+ leverage: (0, types_1.toBlockchain10)(trade.leverage),
57
+ tp: (0, types_1.toBlockchain10)(trade.tp),
58
+ sl: (0, types_1.toBlockchain10)(trade.sl),
59
+ timestamp: Math.floor(Date.now() / 1000),
60
+ };
61
+ const slippageBlockchain = (0, types_1.toBlockchain10)(slippageP);
62
+ const executionFeeWei = (0, types_1.toBlockchain18)(executionFeeEth);
63
+ // Create transaction
64
+ const tx = {
65
+ to: await this.tradingContract.getAddress(),
66
+ data: this.tradingContract.interface.encodeFunctionData('openTrade', [
67
+ tradeStruct,
68
+ orderTypeMap[orderType],
69
+ slippageBlockchain,
70
+ ]),
71
+ value: executionFeeWei,
72
+ };
73
+ return await this.signAndSend(tx);
74
+ }
75
+ /**
76
+ * Close a trade position at market price
77
+ * @param pairIndex - Trading pair index
78
+ * @param index - Trade index
79
+ * @param closeAmount - Amount of collateral to close (USDC)
80
+ * @param executionFeeEth - Execution fee in ETH (optional)
81
+ * @returns Transaction receipt
82
+ */
83
+ async closeTradeMarket(pairIndex, index, closeAmount, executionFeeEth) {
84
+ if (!this.signer) {
85
+ throw new Error('Signer required for trading operations');
86
+ }
87
+ if (!executionFeeEth) {
88
+ executionFeeEth = await this.getExecutionFee();
89
+ }
90
+ const closeAmountBlockchain = (0, types_1.toBlockchain6)(closeAmount);
91
+ const executionFeeWei = (0, types_1.toBlockchain18)(executionFeeEth);
92
+ const tx = {
93
+ to: await this.tradingContract.getAddress(),
94
+ data: this.tradingContract.interface.encodeFunctionData('closeTradeMarket', [
95
+ pairIndex,
96
+ index,
97
+ closeAmountBlockchain,
98
+ ]),
99
+ value: executionFeeWei,
100
+ };
101
+ return await this.signAndSend(tx);
102
+ }
103
+ /**
104
+ * Update margin for an existing trade
105
+ * @param pairIndex - Trading pair index
106
+ * @param index - Trade index
107
+ * @param updateType - DEPOSIT or WITHDRAW
108
+ * @param amount - Amount to add/remove (USDC)
109
+ * @param priceUpdateData - Price oracle update data
110
+ * @returns Transaction receipt
111
+ */
112
+ async updateMargin(pairIndex, index, updateType, amount, priceUpdateData = []) {
113
+ if (!this.signer) {
114
+ throw new Error('Signer required for trading operations');
115
+ }
116
+ const amountBlockchain = (0, types_1.toBlockchain6)(amount);
117
+ const tx = {
118
+ to: await this.tradingContract.getAddress(),
119
+ data: this.tradingContract.interface.encodeFunctionData('updateMargin', [
120
+ pairIndex,
121
+ index,
122
+ updateType,
123
+ amountBlockchain,
124
+ priceUpdateData,
125
+ ]),
126
+ value: 1n, // 1 wei for price update
127
+ };
128
+ return await this.signAndSend(tx);
129
+ }
130
+ /**
131
+ * Update take profit and stop loss for a trade
132
+ * @param pairIndex - Trading pair index
133
+ * @param index - Trade index
134
+ * @param newSl - New stop loss price
135
+ * @param newTp - New take profit price
136
+ * @param priceUpdateData - Price oracle update data
137
+ * @returns Transaction receipt
138
+ */
139
+ async updateTpAndSl(pairIndex, index, newSl, newTp, priceUpdateData = []) {
140
+ if (!this.signer) {
141
+ throw new Error('Signer required for trading operations');
142
+ }
143
+ const slBlockchain = (0, types_1.toBlockchain10)(newSl);
144
+ const tpBlockchain = (0, types_1.toBlockchain10)(newTp);
145
+ const tx = {
146
+ to: await this.tradingContract.getAddress(),
147
+ data: this.tradingContract.interface.encodeFunctionData('updateTpAndSl', [
148
+ pairIndex,
149
+ index,
150
+ slBlockchain,
151
+ tpBlockchain,
152
+ priceUpdateData,
153
+ ]),
154
+ value: 1n, // 1 wei for price update
155
+ };
156
+ return await this.signAndSend(tx);
157
+ }
158
+ /**
159
+ * Cancel a pending limit order
160
+ * @param pairIndex - Trading pair index
161
+ * @param index - Order index
162
+ * @returns Transaction receipt
163
+ */
164
+ async cancelOpenLimitOrder(pairIndex, index) {
165
+ if (!this.signer) {
166
+ throw new Error('Signer required for trading operations');
167
+ }
168
+ const tx = {
169
+ to: await this.tradingContract.getAddress(),
170
+ data: this.tradingContract.interface.encodeFunctionData('cancelOpenLimitOrder', [
171
+ pairIndex,
172
+ index,
173
+ ]),
174
+ };
175
+ return await this.signAndSend(tx);
176
+ }
177
+ /**
178
+ * Get open trade information
179
+ * @param trader - Trader address
180
+ * @param pairIndex - Trading pair index
181
+ * @param index - Trade index
182
+ * @returns Trade information
183
+ */
184
+ async getOpenTrade(trader, pairIndex, index) {
185
+ const result = await this.tradingStorageContract.openTrades(trader, pairIndex, index);
186
+ return {
187
+ trader: result.trader,
188
+ pairIndex: Number(result.pairIndex),
189
+ index: Number(result.index),
190
+ initialPosToken: (0, types_1.fromBlockchain6)(result.initialPosToken),
191
+ positionSizeUSDC: (0, types_1.fromBlockchain6)(result.positionSizeUSDC),
192
+ openPrice: (0, types_1.fromBlockchain10)(result.openPrice),
193
+ buy: result.buy,
194
+ leverage: (0, types_1.fromBlockchain10)(result.leverage),
195
+ tp: (0, types_1.fromBlockchain10)(result.tp),
196
+ sl: (0, types_1.fromBlockchain10)(result.sl),
197
+ timestamp: Number(result.timestamp),
198
+ };
199
+ }
200
+ /**
201
+ * Get additional trade information
202
+ * @param trader - Trader address
203
+ * @param pairIndex - Trading pair index
204
+ * @param index - Trade index
205
+ * @returns Trade info
206
+ */
207
+ async getOpenTradeInfo(trader, pairIndex, index) {
208
+ const result = await this.tradingStorageContract.openTradesInfo(trader, pairIndex, index);
209
+ return {
210
+ openInterestUSDC: (0, types_1.fromBlockchain6)(result.openInterestUSDC),
211
+ tpLastUpdated: Number(result.tpLastUpdated),
212
+ slLastUpdated: Number(result.slLastUpdated),
213
+ beingMarketClosed: result.beingMarketClosed,
214
+ lossProtection: Number(result.lossProtection),
215
+ };
216
+ }
217
+ /**
218
+ * Get number of open trades for a trader on a pair
219
+ * @param trader - Trader address
220
+ * @param pairIndex - Trading pair index
221
+ * @returns Number of open trades
222
+ */
223
+ async getOpenTradesCount(trader, pairIndex) {
224
+ const count = await this.tradingStorageContract.openTradesCount(trader, pairIndex);
225
+ return Number(count);
226
+ }
227
+ /**
228
+ * Get limit order information
229
+ * @param trader - Trader address
230
+ * @param pairIndex - Trading pair index
231
+ * @param index - Order index
232
+ * @returns Limit order information
233
+ */
234
+ async getOpenLimitOrder(trader, pairIndex, index) {
235
+ const result = await this.tradingStorageContract.getOpenLimitOrder(trader, pairIndex, index);
236
+ return {
237
+ trader: result.trader,
238
+ pairIndex: Number(result.pairIndex),
239
+ index: Number(result.index),
240
+ positionSize: (0, types_1.fromBlockchain6)(result.positionSize),
241
+ buy: result.buy,
242
+ leverage: (0, types_1.fromBlockchain10)(result.leverage),
243
+ tp: (0, types_1.fromBlockchain10)(result.tp),
244
+ sl: (0, types_1.fromBlockchain10)(result.sl),
245
+ price: (0, types_1.fromBlockchain10)(result.price),
246
+ slippageP: (0, types_1.fromBlockchain10)(result.slippageP),
247
+ block: Number(result.block),
248
+ executionFee: (0, types_1.fromBlockchain18)(result.executionFee),
249
+ };
250
+ }
251
+ /**
252
+ * Helper method to sign and send transactions
253
+ */
254
+ async signAndSend(tx) {
255
+ if (!this.signer) {
256
+ throw new Error('Signer not set');
257
+ }
258
+ const address = await this.signer.getAddress();
259
+ tx.from = address;
260
+ const provider = this.tradingContract.runner?.provider;
261
+ if (!provider) {
262
+ throw new Error('Provider not available');
263
+ }
264
+ if (!tx.chainId) {
265
+ const network = await provider.getNetwork();
266
+ tx.chainId = network.chainId;
267
+ }
268
+ if (tx.nonce === undefined) {
269
+ tx.nonce = await provider.getTransactionCount(address);
270
+ }
271
+ if (!tx.gasLimit) {
272
+ tx.gasLimit = await provider.estimateGas(tx);
273
+ }
274
+ if (!tx.maxFeePerGas && !tx.gasPrice) {
275
+ const feeData = await provider.getFeeData();
276
+ if (feeData.maxFeePerGas) {
277
+ tx.maxFeePerGas = feeData.maxFeePerGas;
278
+ tx.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas || feeData.maxFeePerGas;
279
+ }
280
+ else {
281
+ tx.gasPrice = feeData.gasPrice || undefined;
282
+ }
283
+ }
284
+ const signedTx = await this.signer.signTransaction(tx);
285
+ const txResponse = await provider.broadcastTransaction(signedTx);
286
+ return await txResponse.wait();
287
+ }
288
+ /**
289
+ * Set signer for transactions
290
+ */
291
+ setSigner(signer) {
292
+ this.signer = signer;
293
+ }
294
+ }
295
+ exports.TradingOperationsRPC = TradingOperationsRPC;
@@ -0,0 +1,49 @@
1
+ import { Contract, Provider } from 'ethers';
2
+ import { TradeInput, LossProtectionInfo } from '../types';
3
+ import { PairsCache } from './pairs_cache';
4
+ /**
5
+ * RPC module for trading-related parameters
6
+ */
7
+ export declare class TradingParametersRPC {
8
+ private provider;
9
+ private pairInfosContract;
10
+ private pairsCache;
11
+ constructor(provider: Provider, pairInfosContract: Contract, pairsCache: PairsCache);
12
+ /**
13
+ * Get loss protection tier for a trade
14
+ * @param tradeInput - Trade input parameters
15
+ * @returns Loss protection tier
16
+ */
17
+ getLossProtectionTier(tradeInput: TradeInput): Promise<number>;
18
+ /**
19
+ * Get loss protection percentage for a tier
20
+ * @param tier - Loss protection tier
21
+ * @param pairIndex - Pair index
22
+ * @returns Loss protection percentage
23
+ */
24
+ getLossProtectionPercentage(tier: number, pairIndex: number): Promise<number>;
25
+ /**
26
+ * Calculate loss protection amount
27
+ * @param tier - Loss protection tier
28
+ * @param pairIndex - Pair index
29
+ * @param collateral - Collateral amount
30
+ * @param openingFee - Opening fee amount
31
+ * @returns Loss protection amount
32
+ */
33
+ getLossProtectionAmount(tier: number, pairIndex: number, collateral: number, openingFee: number): Promise<number>;
34
+ /**
35
+ * Get complete loss protection info for a trade
36
+ * @param tradeInput - Trade input parameters
37
+ * @param openingFee - Opening fee amount
38
+ * @returns Loss protection info
39
+ */
40
+ getLossProtectionInfo(tradeInput: TradeInput, openingFee: number): Promise<LossProtectionInfo>;
41
+ /**
42
+ * Get referral rebate for a trader
43
+ * @param trader - Trader address
44
+ * @param referrer - Referrer address
45
+ * @param openingFee - Opening fee amount
46
+ * @returns Rebate amount
47
+ */
48
+ getTradeReferralRebate(trader: string, referrer: string, openingFee: number): Promise<number>;
49
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TradingParametersRPC = void 0;
4
+ const types_1 = require("../types");
5
+ /**
6
+ * RPC module for trading-related parameters
7
+ */
8
+ class TradingParametersRPC {
9
+ constructor(provider, pairInfosContract, pairsCache) {
10
+ this.provider = provider;
11
+ this.pairInfosContract = pairInfosContract;
12
+ this.pairsCache = pairsCache;
13
+ }
14
+ /**
15
+ * Get loss protection tier for a trade
16
+ * @param tradeInput - Trade input parameters
17
+ * @returns Loss protection tier
18
+ */
19
+ async getLossProtectionTier(tradeInput) {
20
+ const pairIndex = await this.pairsCache.getPairIndex(tradeInput.pair);
21
+ if (pairIndex === undefined) {
22
+ throw new Error(`Pair ${tradeInput.pair} not found`);
23
+ }
24
+ try {
25
+ const tier = await this.pairInfosContract.getLossProtectionTier(pairIndex, (0, types_1.toBlockchain6)(tradeInput.collateralInTrade));
26
+ return Number(tier);
27
+ }
28
+ catch (error) {
29
+ console.error('Error getting loss protection tier:', error);
30
+ return 0;
31
+ }
32
+ }
33
+ /**
34
+ * Get loss protection percentage for a tier
35
+ * @param tier - Loss protection tier
36
+ * @param pairIndex - Pair index
37
+ * @returns Loss protection percentage
38
+ */
39
+ async getLossProtectionPercentage(tier, pairIndex) {
40
+ try {
41
+ const percentage = await this.pairInfosContract.getLossProtectionP(tier, pairIndex);
42
+ return (0, types_1.fromBlockchain10)(percentage);
43
+ }
44
+ catch (error) {
45
+ console.error('Error getting loss protection percentage:', error);
46
+ return 0;
47
+ }
48
+ }
49
+ /**
50
+ * Calculate loss protection amount
51
+ * @param tier - Loss protection tier
52
+ * @param pairIndex - Pair index
53
+ * @param collateral - Collateral amount
54
+ * @param openingFee - Opening fee amount
55
+ * @returns Loss protection amount
56
+ */
57
+ async getLossProtectionAmount(tier, pairIndex, collateral, openingFee) {
58
+ const percentage = await this.getLossProtectionPercentage(tier, pairIndex);
59
+ return openingFee * (percentage / 100);
60
+ }
61
+ /**
62
+ * Get complete loss protection info for a trade
63
+ * @param tradeInput - Trade input parameters
64
+ * @param openingFee - Opening fee amount
65
+ * @returns Loss protection info
66
+ */
67
+ async getLossProtectionInfo(tradeInput, openingFee) {
68
+ const pairIndex = await this.pairsCache.getPairIndex(tradeInput.pair);
69
+ if (pairIndex === undefined) {
70
+ throw new Error(`Pair ${tradeInput.pair} not found`);
71
+ }
72
+ const tier = await this.getLossProtectionTier(tradeInput);
73
+ const percentage = await this.getLossProtectionPercentage(tier, pairIndex);
74
+ const amount = await this.getLossProtectionAmount(tier, pairIndex, tradeInput.collateralInTrade, openingFee);
75
+ return {
76
+ tier,
77
+ percentage,
78
+ amount,
79
+ };
80
+ }
81
+ /**
82
+ * Get referral rebate for a trader
83
+ * @param trader - Trader address
84
+ * @param referrer - Referrer address
85
+ * @param openingFee - Opening fee amount
86
+ * @returns Rebate amount
87
+ */
88
+ async getTradeReferralRebate(trader, referrer, openingFee) {
89
+ // This would typically call the referral contract
90
+ // For now, return 0 as a placeholder
91
+ return 0;
92
+ }
93
+ }
94
+ exports.TradingParametersRPC = TradingParametersRPC;
@@ -0,0 +1,24 @@
1
+ import { TransactionRequest } from 'ethers';
2
+ /**
3
+ * Abstract base class for transaction signers
4
+ * Implementations can use local private keys, AWS KMS, or other signing methods
5
+ */
6
+ export declare abstract class BaseSigner {
7
+ /**
8
+ * Sign a transaction
9
+ * @param transaction - Transaction to sign
10
+ * @returns Signed transaction
11
+ */
12
+ abstract signTransaction(transaction: TransactionRequest): Promise<string>;
13
+ /**
14
+ * Get the Ethereum address associated with this signer
15
+ * @returns Ethereum address
16
+ */
17
+ abstract getAddress(): Promise<string>;
18
+ /**
19
+ * Sign a message
20
+ * @param message - Message to sign
21
+ * @returns Signature
22
+ */
23
+ abstract signMessage(message: string | Uint8Array): Promise<string>;
24
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseSigner = void 0;
4
+ /**
5
+ * Abstract base class for transaction signers
6
+ * Implementations can use local private keys, AWS KMS, or other signing methods
7
+ */
8
+ class BaseSigner {
9
+ }
10
+ exports.BaseSigner = BaseSigner;
@@ -0,0 +1,47 @@
1
+ import { Provider, TransactionRequest } from 'ethers';
2
+ import { BaseSigner } from './base';
3
+ /**
4
+ * AWS KMS signer for secure transaction signing without exposing private keys
5
+ * Private key never leaves AWS KMS hardware security modules
6
+ */
7
+ export declare class KMSSigner extends BaseSigner {
8
+ private kmsClient;
9
+ private kmsKeyId;
10
+ private provider;
11
+ private addressCache?;
12
+ /**
13
+ * Create a KMS signer
14
+ * @param kmsKeyId - AWS KMS key ID
15
+ * @param provider - Ethereum provider
16
+ * @param region - AWS region (default: us-east-1)
17
+ */
18
+ constructor(kmsKeyId: string, provider: Provider, region?: string);
19
+ /**
20
+ * Get the public key from KMS
21
+ * @returns DER-encoded public key
22
+ */
23
+ private getPublicKey;
24
+ /**
25
+ * Get the Ethereum address derived from the KMS key
26
+ * @returns Ethereum address
27
+ */
28
+ getAddress(): Promise<string>;
29
+ /**
30
+ * Sign a message hash using KMS
31
+ * @param msgHash - Message hash to sign
32
+ * @returns DER-encoded signature
33
+ */
34
+ private signMsgHash;
35
+ /**
36
+ * Sign a transaction using KMS
37
+ * @param transaction - Transaction to sign
38
+ * @returns Signed transaction as hex string
39
+ */
40
+ signTransaction(transaction: TransactionRequest): Promise<string>;
41
+ /**
42
+ * Sign a message using KMS
43
+ * @param message - Message to sign
44
+ * @returns Signature as hex string
45
+ */
46
+ signMessage(message: string | Uint8Array): Promise<string>;
47
+ }
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KMSSigner = void 0;
4
+ const client_kms_1 = require("@aws-sdk/client-kms");
5
+ const ethers_1 = require("ethers");
6
+ const base_1 = require("./base");
7
+ const spki_1 = require("../crypto/spki");
8
+ /**
9
+ * AWS KMS signer for secure transaction signing without exposing private keys
10
+ * Private key never leaves AWS KMS hardware security modules
11
+ */
12
+ class KMSSigner extends base_1.BaseSigner {
13
+ /**
14
+ * Create a KMS signer
15
+ * @param kmsKeyId - AWS KMS key ID
16
+ * @param provider - Ethereum provider
17
+ * @param region - AWS region (default: us-east-1)
18
+ */
19
+ constructor(kmsKeyId, provider, region = 'us-east-1') {
20
+ super();
21
+ this.kmsKeyId = kmsKeyId;
22
+ this.provider = provider;
23
+ this.kmsClient = new client_kms_1.KMSClient({ region });
24
+ }
25
+ /**
26
+ * Get the public key from KMS
27
+ * @returns DER-encoded public key
28
+ */
29
+ async getPublicKey() {
30
+ const command = new client_kms_1.GetPublicKeyCommand({
31
+ KeyId: this.kmsKeyId,
32
+ });
33
+ const response = await this.kmsClient.send(command);
34
+ if (!response.PublicKey) {
35
+ throw new Error('Failed to get public key from KMS');
36
+ }
37
+ return response.PublicKey;
38
+ }
39
+ /**
40
+ * Get the Ethereum address derived from the KMS key
41
+ * @returns Ethereum address
42
+ */
43
+ async getAddress() {
44
+ if (this.addressCache) {
45
+ return this.addressCache;
46
+ }
47
+ const publicKey = await this.getPublicKey();
48
+ this.addressCache = (0, spki_1.derEncodedPublicKeyToEthAddress)(publicKey);
49
+ return this.addressCache;
50
+ }
51
+ /**
52
+ * Sign a message hash using KMS
53
+ * @param msgHash - Message hash to sign
54
+ * @returns DER-encoded signature
55
+ */
56
+ async signMsgHash(msgHash) {
57
+ const command = new client_kms_1.SignCommand({
58
+ KeyId: this.kmsKeyId,
59
+ Message: msgHash,
60
+ MessageType: 'DIGEST',
61
+ SigningAlgorithm: 'ECDSA_SHA_256',
62
+ });
63
+ const response = await this.kmsClient.send(command);
64
+ if (!response.Signature) {
65
+ throw new Error('Failed to sign message with KMS');
66
+ }
67
+ return response.Signature;
68
+ }
69
+ /**
70
+ * Sign a transaction using KMS
71
+ * @param transaction - Transaction to sign
72
+ * @returns Signed transaction as hex string
73
+ */
74
+ async signTransaction(transaction) {
75
+ // Get the address to fill in the 'from' field if not set
76
+ const address = await this.getAddress();
77
+ // Fill in missing fields
78
+ const tx = {
79
+ ...transaction,
80
+ from: address,
81
+ };
82
+ // Get chain ID if not provided
83
+ if (!tx.chainId) {
84
+ const network = await this.provider.getNetwork();
85
+ tx.chainId = network.chainId;
86
+ }
87
+ // Get nonce if not provided
88
+ if (tx.nonce === undefined) {
89
+ tx.nonce = await this.provider.getTransactionCount(address);
90
+ }
91
+ // Estimate gas if not provided
92
+ if (!tx.gasLimit) {
93
+ tx.gasLimit = await this.provider.estimateGas(tx);
94
+ }
95
+ // Get gas price if not provided (for legacy transactions)
96
+ if (!tx.maxFeePerGas && !tx.gasPrice) {
97
+ const feeData = await this.provider.getFeeData();
98
+ if (feeData.maxFeePerGas) {
99
+ tx.maxFeePerGas = feeData.maxFeePerGas;
100
+ tx.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas || feeData.maxFeePerGas;
101
+ }
102
+ else {
103
+ tx.gasPrice = feeData.gasPrice || undefined;
104
+ }
105
+ }
106
+ // Resolve address fields to strings
107
+ const resolvedTo = tx.to ? await (0, ethers_1.resolveAddress)(tx.to, this.provider) : null;
108
+ const resolvedFrom = tx.from ? await (0, ethers_1.resolveAddress)(tx.from, this.provider) : address;
109
+ // Create a transaction object with resolved fields
110
+ const resolvedTx = {
111
+ type: tx.type,
112
+ to: resolvedTo,
113
+ from: resolvedFrom,
114
+ nonce: tx.nonce,
115
+ gasLimit: tx.gasLimit,
116
+ gasPrice: tx.gasPrice,
117
+ maxFeePerGas: tx.maxFeePerGas,
118
+ maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
119
+ data: tx.data,
120
+ value: tx.value,
121
+ chainId: tx.chainId,
122
+ accessList: tx.accessList,
123
+ };
124
+ // Create unsigned transaction
125
+ const unsignedTx = ethers_1.Transaction.from(resolvedTx);
126
+ const unsignedSerialized = unsignedTx.unsignedSerialized;
127
+ // Hash the unsigned transaction
128
+ const msgHash = (0, ethers_1.keccak256)(unsignedSerialized);
129
+ const msgHashBytes = (0, ethers_1.getBytes)(msgHash);
130
+ // Sign with KMS
131
+ const kmsSignature = await this.signMsgHash(msgHashBytes);
132
+ // Parse signature and recover v
133
+ const { r, s, v } = (0, spki_1.getSigRSV)(kmsSignature, msgHash, address);
134
+ // Create signed transaction
135
+ unsignedTx.signature = { r, s, v };
136
+ return unsignedTx.serialized;
137
+ }
138
+ /**
139
+ * Sign a message using KMS
140
+ * @param message - Message to sign
141
+ * @returns Signature as hex string
142
+ */
143
+ async signMessage(message) {
144
+ const address = await this.getAddress();
145
+ // Convert message to bytes
146
+ const messageBytes = typeof message === 'string' ? Buffer.from(message, 'utf8') : message;
147
+ // Create Ethereum signed message hash
148
+ const messageHash = (0, ethers_1.keccak256)(concat([
149
+ Buffer.from('\x19Ethereum Signed Message:\n', 'utf8'),
150
+ Buffer.from(String(messageBytes.length), 'utf8'),
151
+ messageBytes,
152
+ ]));
153
+ const msgHashBytes = (0, ethers_1.getBytes)(messageHash);
154
+ // Sign with KMS
155
+ const kmsSignature = await this.signMsgHash(msgHashBytes);
156
+ // Parse signature and recover v
157
+ const { r, s, v } = (0, spki_1.getSigRSV)(kmsSignature, messageHash, address);
158
+ return (0, spki_1.signatureToHex)(r, s, v);
159
+ }
160
+ }
161
+ exports.KMSSigner = KMSSigner;
162
+ // Helper function for concat
163
+ function concat(arrays) {
164
+ const totalLength = arrays.reduce((acc, arr) => acc + arr.length, 0);
165
+ const result = new Uint8Array(totalLength);
166
+ let offset = 0;
167
+ for (const arr of arrays) {
168
+ result.set(arr, offset);
169
+ offset += arr.length;
170
+ }
171
+ return result;
172
+ }