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
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Utilization, Skew } from '../types';
|
|
2
|
+
import { AssetParametersRPC } from './asset_parameters';
|
|
3
|
+
import { CategoryParametersRPC } from './category_parameters';
|
|
4
|
+
import { PairsCache } from './pairs_cache';
|
|
5
|
+
/**
|
|
6
|
+
* RPC module for blended calculations (25% asset + 75% category)
|
|
7
|
+
*/
|
|
8
|
+
export declare class BlendedRPC {
|
|
9
|
+
private assetParams;
|
|
10
|
+
private categoryParams;
|
|
11
|
+
private pairsCache;
|
|
12
|
+
constructor(assetParams: AssetParametersRPC, categoryParams: CategoryParametersRPC, pairsCache: PairsCache);
|
|
13
|
+
/**
|
|
14
|
+
* Calculate blended utilization (25% asset + 75% category)
|
|
15
|
+
* @returns Map of pair index to blended utilization
|
|
16
|
+
*/
|
|
17
|
+
getBlendedUtilization(): Promise<Map<number, Utilization>>;
|
|
18
|
+
/**
|
|
19
|
+
* Calculate blended skew (25% asset + 75% category)
|
|
20
|
+
* @returns Map of pair index to blended skew
|
|
21
|
+
*/
|
|
22
|
+
getBlendedSkew(): Promise<Map<number, Skew>>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BlendedRPC = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* RPC module for blended calculations (25% asset + 75% category)
|
|
6
|
+
*/
|
|
7
|
+
class BlendedRPC {
|
|
8
|
+
constructor(assetParams, categoryParams, pairsCache) {
|
|
9
|
+
this.assetParams = assetParams;
|
|
10
|
+
this.categoryParams = categoryParams;
|
|
11
|
+
this.pairsCache = pairsCache;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Calculate blended utilization (25% asset + 75% category)
|
|
15
|
+
* @returns Map of pair index to blended utilization
|
|
16
|
+
*/
|
|
17
|
+
async getBlendedUtilization() {
|
|
18
|
+
const assetUtilization = await this.assetParams.getUtilization();
|
|
19
|
+
const categoryUtilization = await this.categoryParams.getUtilization();
|
|
20
|
+
const pairs = await this.pairsCache.getPairsInfo();
|
|
21
|
+
const blended = new Map();
|
|
22
|
+
for (const [pairIndex, pairInfo] of pairs) {
|
|
23
|
+
const assetUtil = assetUtilization.get(pairIndex);
|
|
24
|
+
const catUtil = categoryUtilization.get(pairInfo.groupIndex);
|
|
25
|
+
if (assetUtil && catUtil) {
|
|
26
|
+
blended.set(pairIndex, {
|
|
27
|
+
utilizationLong: 0.25 * assetUtil.utilizationLong + 0.75 * catUtil.utilizationLong,
|
|
28
|
+
utilizationShort: 0.25 * assetUtil.utilizationShort + 0.75 * catUtil.utilizationShort,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return blended;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Calculate blended skew (25% asset + 75% category)
|
|
36
|
+
* @returns Map of pair index to blended skew
|
|
37
|
+
*/
|
|
38
|
+
async getBlendedSkew() {
|
|
39
|
+
const assetSkew = await this.assetParams.getAssetSkew();
|
|
40
|
+
const categorySkew = await this.categoryParams.getCategorySkew();
|
|
41
|
+
const pairs = await this.pairsCache.getPairsInfo();
|
|
42
|
+
const blended = new Map();
|
|
43
|
+
for (const [pairIndex, pairInfo] of pairs) {
|
|
44
|
+
const assetSk = assetSkew.get(pairIndex);
|
|
45
|
+
const catSk = categorySkew.get(pairInfo.groupIndex);
|
|
46
|
+
if (assetSk && catSk) {
|
|
47
|
+
blended.set(pairIndex, {
|
|
48
|
+
skew: 0.25 * assetSk.skew + 0.75 * catSk.skew,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return blended;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.BlendedRPC = BlendedRPC;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Contract, Provider } from 'ethers';
|
|
2
|
+
import { OpenInterest, Utilization, Skew } from '../types';
|
|
3
|
+
import { PairsCache } from './pairs_cache';
|
|
4
|
+
/**
|
|
5
|
+
* RPC module for retrieving category-level parameters
|
|
6
|
+
*/
|
|
7
|
+
export declare class CategoryParametersRPC {
|
|
8
|
+
private provider;
|
|
9
|
+
private pairStorageContract;
|
|
10
|
+
private pairsCache;
|
|
11
|
+
constructor(provider: Provider, pairStorageContract: Contract, pairsCache: PairsCache);
|
|
12
|
+
/**
|
|
13
|
+
* Get open interest limits per category
|
|
14
|
+
* Note: Group OI limits are calculated from pair backend data
|
|
15
|
+
* @returns Map of group index to OI limits
|
|
16
|
+
*/
|
|
17
|
+
getOILimits(): Promise<Map<number, OpenInterest>>;
|
|
18
|
+
/**
|
|
19
|
+
* Get current open interest per category
|
|
20
|
+
* Note: Calculated by summing pair OIs in each group
|
|
21
|
+
* @returns Map of group index to OI
|
|
22
|
+
*/
|
|
23
|
+
getOI(): Promise<Map<number, OpenInterest>>;
|
|
24
|
+
/**
|
|
25
|
+
* Get utilization per category
|
|
26
|
+
* @returns Map of group index to utilization
|
|
27
|
+
*/
|
|
28
|
+
getUtilization(): Promise<Map<number, Utilization>>;
|
|
29
|
+
/**
|
|
30
|
+
* Get category skew (long / total)
|
|
31
|
+
* @returns Map of group index to skew
|
|
32
|
+
*/
|
|
33
|
+
getCategorySkew(): Promise<Map<number, Skew>>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CategoryParametersRPC = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* RPC module for retrieving category-level parameters
|
|
6
|
+
*/
|
|
7
|
+
class CategoryParametersRPC {
|
|
8
|
+
constructor(provider, pairStorageContract, pairsCache) {
|
|
9
|
+
this.provider = provider;
|
|
10
|
+
this.pairStorageContract = pairStorageContract;
|
|
11
|
+
this.pairsCache = pairsCache;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Get open interest limits per category
|
|
15
|
+
* Note: Group OI limits are calculated from pair backend data
|
|
16
|
+
* @returns Map of group index to OI limits
|
|
17
|
+
*/
|
|
18
|
+
async getOILimits() {
|
|
19
|
+
const groupIndexes = await this.pairsCache.getGroupIndexes();
|
|
20
|
+
const limits = new Map();
|
|
21
|
+
// Get limits from pair backend data which includes group info
|
|
22
|
+
for (const groupIndex of groupIndexes) {
|
|
23
|
+
try {
|
|
24
|
+
// Get first pair in this group to get group max OI
|
|
25
|
+
const pairsInGroup = await this.pairsCache.getPairsInGroup(groupIndex);
|
|
26
|
+
if (pairsInGroup.length > 0) {
|
|
27
|
+
const backendData = await this.pairsCache.getPairBackend(pairsInGroup[0]);
|
|
28
|
+
const maxOI = Number(backendData.group.maxOpenInterestP) / 1e10; // Convert from 10 decimals to number
|
|
29
|
+
limits.set(groupIndex, {
|
|
30
|
+
long: maxOI,
|
|
31
|
+
short: maxOI,
|
|
32
|
+
max: maxOI,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error(`Error getting OI limits for group ${groupIndex}:`, error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return limits;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get current open interest per category
|
|
44
|
+
* Note: Calculated by summing pair OIs in each group
|
|
45
|
+
* @returns Map of group index to OI
|
|
46
|
+
*/
|
|
47
|
+
async getOI() {
|
|
48
|
+
const groupIndexes = await this.pairsCache.getGroupIndexes();
|
|
49
|
+
const oi = new Map();
|
|
50
|
+
const limits = await this.getOILimits();
|
|
51
|
+
for (const groupIndex of groupIndexes) {
|
|
52
|
+
try {
|
|
53
|
+
// Sum up OI from all pairs in this group
|
|
54
|
+
const pairsInGroup = await this.pairsCache.getPairsInGroup(groupIndex);
|
|
55
|
+
let totalLongOI = 0;
|
|
56
|
+
let totalShortOI = 0;
|
|
57
|
+
// This would require asset params to get individual pair OI
|
|
58
|
+
// For now, return default values
|
|
59
|
+
// TODO: Properly calculate by summing pair OIs
|
|
60
|
+
const maxOI = limits.get(groupIndex)?.max || 0;
|
|
61
|
+
oi.set(groupIndex, {
|
|
62
|
+
long: totalLongOI,
|
|
63
|
+
short: totalShortOI,
|
|
64
|
+
max: maxOI,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.error(`Error getting OI for group ${groupIndex}:`, error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return oi;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get utilization per category
|
|
75
|
+
* @returns Map of group index to utilization
|
|
76
|
+
*/
|
|
77
|
+
async getUtilization() {
|
|
78
|
+
const oi = await this.getOI();
|
|
79
|
+
const utilization = new Map();
|
|
80
|
+
for (const [groupIndex, oiData] of oi) {
|
|
81
|
+
const utilizationLong = oiData.max > 0 ? (oiData.long / oiData.max) * 100 : 0;
|
|
82
|
+
const utilizationShort = oiData.max > 0 ? (oiData.short / oiData.max) * 100 : 0;
|
|
83
|
+
utilization.set(groupIndex, {
|
|
84
|
+
utilizationLong,
|
|
85
|
+
utilizationShort,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return utilization;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get category skew (long / total)
|
|
92
|
+
* @returns Map of group index to skew
|
|
93
|
+
*/
|
|
94
|
+
async getCategorySkew() {
|
|
95
|
+
const oi = await this.getOI();
|
|
96
|
+
const skew = new Map();
|
|
97
|
+
for (const [groupIndex, oiData] of oi) {
|
|
98
|
+
const total = oiData.long + oiData.short;
|
|
99
|
+
const skewValue = total > 0 ? oiData.long / total : 0.5;
|
|
100
|
+
skew.set(groupIndex, { skew: skewValue });
|
|
101
|
+
}
|
|
102
|
+
return skew;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.CategoryParametersRPC = CategoryParametersRPC;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Contract, TransactionReceipt } from 'ethers';
|
|
2
|
+
import { BaseSigner } from '../signers/base';
|
|
3
|
+
/**
|
|
4
|
+
* Delegation RPC
|
|
5
|
+
* Handles delegation functionality for the Trading contract.
|
|
6
|
+
* Allows one address to execute trades on behalf of another.
|
|
7
|
+
*/
|
|
8
|
+
export declare class DelegationRPC {
|
|
9
|
+
private tradingContract;
|
|
10
|
+
private signer?;
|
|
11
|
+
constructor(tradingContract: Contract, signer?: BaseSigner | undefined);
|
|
12
|
+
/**
|
|
13
|
+
* Set a delegate wallet that can perform trade actions on behalf of caller
|
|
14
|
+
* @param delegate - Address to authorize as delegate (use 0x0 to revoke)
|
|
15
|
+
* @returns Transaction receipt
|
|
16
|
+
*/
|
|
17
|
+
setDelegate(delegate: string): Promise<TransactionReceipt | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Remove the current delegate for the caller
|
|
20
|
+
* @returns Transaction receipt
|
|
21
|
+
*/
|
|
22
|
+
removeDelegate(): Promise<TransactionReceipt | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Get the delegate wallet for a given owner
|
|
25
|
+
* @param owner - Owner address to check
|
|
26
|
+
* @returns Delegate address (0x0 if none set)
|
|
27
|
+
*/
|
|
28
|
+
getDelegateFor(owner: string): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Execute a delegated action on behalf of a trader
|
|
31
|
+
* @param trader - Address of the trader to act on behalf of
|
|
32
|
+
* @param callData - ABI-encoded function data for the action
|
|
33
|
+
* @param value - ETH value to send (for execution fees)
|
|
34
|
+
* @returns Transaction receipt
|
|
35
|
+
*/
|
|
36
|
+
delegatedAction(trader: string, callData: string, value?: bigint): Promise<TransactionReceipt | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Helper: Create call data for openTrade to be used with delegatedAction
|
|
39
|
+
* @param tradeStruct - Trade struct with blockchain values
|
|
40
|
+
* @param orderType - Order type (0-3)
|
|
41
|
+
* @param slippageP - Slippage percentage in blockchain units
|
|
42
|
+
* @returns Encoded call data
|
|
43
|
+
*/
|
|
44
|
+
encodeOpenTrade(tradeStruct: any, orderType: number, slippageP: bigint): string;
|
|
45
|
+
/**
|
|
46
|
+
* Helper: Create call data for closeTradeMarket to be used with delegatedAction
|
|
47
|
+
* @param pairIndex - Trading pair index
|
|
48
|
+
* @param index - Trade index
|
|
49
|
+
* @param amount - Amount to close in blockchain units
|
|
50
|
+
* @returns Encoded call data
|
|
51
|
+
*/
|
|
52
|
+
encodeCloseTradeMarket(pairIndex: number, index: number, amount: bigint): string;
|
|
53
|
+
/**
|
|
54
|
+
* Helper: Create call data for updateTpAndSl to be used with delegatedAction
|
|
55
|
+
* @param pairIndex - Trading pair index
|
|
56
|
+
* @param index - Trade index
|
|
57
|
+
* @param newSl - New stop loss in blockchain units
|
|
58
|
+
* @param newTp - New take profit in blockchain units
|
|
59
|
+
* @param priceUpdateData - Price update data
|
|
60
|
+
* @returns Encoded call data
|
|
61
|
+
*/
|
|
62
|
+
encodeUpdateTpAndSl(pairIndex: number, index: number, newSl: bigint, newTp: bigint, priceUpdateData: string[]): string;
|
|
63
|
+
/**
|
|
64
|
+
* Helper: Create call data for updateMargin to be used with delegatedAction
|
|
65
|
+
* @param pairIndex - Trading pair index
|
|
66
|
+
* @param index - Trade index
|
|
67
|
+
* @param updateType - 0 for DEPOSIT, 1 for WITHDRAW
|
|
68
|
+
* @param amount - Amount in blockchain units
|
|
69
|
+
* @param priceUpdateData - Price update data
|
|
70
|
+
* @returns Encoded call data
|
|
71
|
+
*/
|
|
72
|
+
encodeUpdateMargin(pairIndex: number, index: number, updateType: number, amount: bigint, priceUpdateData: string[]): string;
|
|
73
|
+
/**
|
|
74
|
+
* Helper method to sign and send transactions
|
|
75
|
+
*/
|
|
76
|
+
private signAndSend;
|
|
77
|
+
/**
|
|
78
|
+
* Set signer for transactions
|
|
79
|
+
*/
|
|
80
|
+
setSigner(signer: BaseSigner): void;
|
|
81
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DelegationRPC = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Delegation RPC
|
|
6
|
+
* Handles delegation functionality for the Trading contract.
|
|
7
|
+
* Allows one address to execute trades on behalf of another.
|
|
8
|
+
*/
|
|
9
|
+
class DelegationRPC {
|
|
10
|
+
constructor(tradingContract, signer) {
|
|
11
|
+
this.tradingContract = tradingContract;
|
|
12
|
+
this.signer = signer;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Set a delegate wallet that can perform trade actions on behalf of caller
|
|
16
|
+
* @param delegate - Address to authorize as delegate (use 0x0 to revoke)
|
|
17
|
+
* @returns Transaction receipt
|
|
18
|
+
*/
|
|
19
|
+
async setDelegate(delegate) {
|
|
20
|
+
if (!this.signer) {
|
|
21
|
+
throw new Error('Signer required for delegation operations');
|
|
22
|
+
}
|
|
23
|
+
const tx = {
|
|
24
|
+
to: await this.tradingContract.getAddress(),
|
|
25
|
+
data: this.tradingContract.interface.encodeFunctionData('setDelegate', [delegate]),
|
|
26
|
+
};
|
|
27
|
+
return await this.signAndSend(tx);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Remove the current delegate for the caller
|
|
31
|
+
* @returns Transaction receipt
|
|
32
|
+
*/
|
|
33
|
+
async removeDelegate() {
|
|
34
|
+
if (!this.signer) {
|
|
35
|
+
throw new Error('Signer required for delegation operations');
|
|
36
|
+
}
|
|
37
|
+
const tx = {
|
|
38
|
+
to: await this.tradingContract.getAddress(),
|
|
39
|
+
data: this.tradingContract.interface.encodeFunctionData('removeDelegate'),
|
|
40
|
+
};
|
|
41
|
+
return await this.signAndSend(tx);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get the delegate wallet for a given owner
|
|
45
|
+
* @param owner - Owner address to check
|
|
46
|
+
* @returns Delegate address (0x0 if none set)
|
|
47
|
+
*/
|
|
48
|
+
async getDelegateFor(owner) {
|
|
49
|
+
return await this.tradingContract.delegations(owner);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Execute a delegated action on behalf of a trader
|
|
53
|
+
* @param trader - Address of the trader to act on behalf of
|
|
54
|
+
* @param callData - ABI-encoded function data for the action
|
|
55
|
+
* @param value - ETH value to send (for execution fees)
|
|
56
|
+
* @returns Transaction receipt
|
|
57
|
+
*/
|
|
58
|
+
async delegatedAction(trader, callData, value = 0n) {
|
|
59
|
+
if (!this.signer) {
|
|
60
|
+
throw new Error('Signer required for delegation operations');
|
|
61
|
+
}
|
|
62
|
+
const tx = {
|
|
63
|
+
to: await this.tradingContract.getAddress(),
|
|
64
|
+
data: this.tradingContract.interface.encodeFunctionData('delegatedAction', [
|
|
65
|
+
trader,
|
|
66
|
+
callData,
|
|
67
|
+
]),
|
|
68
|
+
value,
|
|
69
|
+
};
|
|
70
|
+
return await this.signAndSend(tx);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Helper: Create call data for openTrade to be used with delegatedAction
|
|
74
|
+
* @param tradeStruct - Trade struct with blockchain values
|
|
75
|
+
* @param orderType - Order type (0-3)
|
|
76
|
+
* @param slippageP - Slippage percentage in blockchain units
|
|
77
|
+
* @returns Encoded call data
|
|
78
|
+
*/
|
|
79
|
+
encodeOpenTrade(tradeStruct, orderType, slippageP) {
|
|
80
|
+
return this.tradingContract.interface.encodeFunctionData('openTrade', [
|
|
81
|
+
tradeStruct,
|
|
82
|
+
orderType,
|
|
83
|
+
slippageP,
|
|
84
|
+
]);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Helper: Create call data for closeTradeMarket to be used with delegatedAction
|
|
88
|
+
* @param pairIndex - Trading pair index
|
|
89
|
+
* @param index - Trade index
|
|
90
|
+
* @param amount - Amount to close in blockchain units
|
|
91
|
+
* @returns Encoded call data
|
|
92
|
+
*/
|
|
93
|
+
encodeCloseTradeMarket(pairIndex, index, amount) {
|
|
94
|
+
return this.tradingContract.interface.encodeFunctionData('closeTradeMarket', [
|
|
95
|
+
pairIndex,
|
|
96
|
+
index,
|
|
97
|
+
amount,
|
|
98
|
+
]);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Helper: Create call data for updateTpAndSl to be used with delegatedAction
|
|
102
|
+
* @param pairIndex - Trading pair index
|
|
103
|
+
* @param index - Trade index
|
|
104
|
+
* @param newSl - New stop loss in blockchain units
|
|
105
|
+
* @param newTp - New take profit in blockchain units
|
|
106
|
+
* @param priceUpdateData - Price update data
|
|
107
|
+
* @returns Encoded call data
|
|
108
|
+
*/
|
|
109
|
+
encodeUpdateTpAndSl(pairIndex, index, newSl, newTp, priceUpdateData) {
|
|
110
|
+
return this.tradingContract.interface.encodeFunctionData('updateTpAndSl', [
|
|
111
|
+
pairIndex,
|
|
112
|
+
index,
|
|
113
|
+
newSl,
|
|
114
|
+
newTp,
|
|
115
|
+
priceUpdateData,
|
|
116
|
+
]);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Helper: Create call data for updateMargin to be used with delegatedAction
|
|
120
|
+
* @param pairIndex - Trading pair index
|
|
121
|
+
* @param index - Trade index
|
|
122
|
+
* @param updateType - 0 for DEPOSIT, 1 for WITHDRAW
|
|
123
|
+
* @param amount - Amount in blockchain units
|
|
124
|
+
* @param priceUpdateData - Price update data
|
|
125
|
+
* @returns Encoded call data
|
|
126
|
+
*/
|
|
127
|
+
encodeUpdateMargin(pairIndex, index, updateType, amount, priceUpdateData) {
|
|
128
|
+
return this.tradingContract.interface.encodeFunctionData('updateMargin', [
|
|
129
|
+
pairIndex,
|
|
130
|
+
index,
|
|
131
|
+
updateType,
|
|
132
|
+
amount,
|
|
133
|
+
priceUpdateData,
|
|
134
|
+
]);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Helper method to sign and send transactions
|
|
138
|
+
*/
|
|
139
|
+
async signAndSend(tx) {
|
|
140
|
+
if (!this.signer) {
|
|
141
|
+
throw new Error('Signer not set');
|
|
142
|
+
}
|
|
143
|
+
const address = await this.signer.getAddress();
|
|
144
|
+
tx.from = address;
|
|
145
|
+
const provider = this.tradingContract.runner?.provider;
|
|
146
|
+
if (!provider) {
|
|
147
|
+
throw new Error('Provider not available');
|
|
148
|
+
}
|
|
149
|
+
if (!tx.chainId) {
|
|
150
|
+
const network = await provider.getNetwork();
|
|
151
|
+
tx.chainId = network.chainId;
|
|
152
|
+
}
|
|
153
|
+
if (tx.nonce === undefined) {
|
|
154
|
+
tx.nonce = await provider.getTransactionCount(address);
|
|
155
|
+
}
|
|
156
|
+
if (!tx.gasLimit) {
|
|
157
|
+
tx.gasLimit = await provider.estimateGas(tx);
|
|
158
|
+
}
|
|
159
|
+
if (!tx.maxFeePerGas && !tx.gasPrice) {
|
|
160
|
+
const feeData = await provider.getFeeData();
|
|
161
|
+
if (feeData.maxFeePerGas) {
|
|
162
|
+
tx.maxFeePerGas = feeData.maxFeePerGas;
|
|
163
|
+
tx.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas || feeData.maxFeePerGas;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
tx.gasPrice = feeData.gasPrice || undefined;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const signedTx = await this.signer.signTransaction(tx);
|
|
170
|
+
const txResponse = await provider.broadcastTransaction(signedTx);
|
|
171
|
+
return await txResponse.wait();
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Set signer for transactions
|
|
175
|
+
*/
|
|
176
|
+
setSigner(signer) {
|
|
177
|
+
this.signer = signer;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
exports.DelegationRPC = DelegationRPC;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Contract, Provider } from 'ethers';
|
|
2
|
+
import { Fee, TradeInput } from '../types';
|
|
3
|
+
import { PairsCache } from './pairs_cache';
|
|
4
|
+
/**
|
|
5
|
+
* RPC module for fee calculations
|
|
6
|
+
*/
|
|
7
|
+
export declare class FeeParametersRPC {
|
|
8
|
+
private provider;
|
|
9
|
+
private pairInfosContract;
|
|
10
|
+
private referralContract?;
|
|
11
|
+
private pairsCache;
|
|
12
|
+
constructor(provider: Provider, pairInfosContract: Contract, pairsCache: PairsCache, referralContract?: Contract);
|
|
13
|
+
/**
|
|
14
|
+
* Get margin fee for all pairs (in basis points)
|
|
15
|
+
* @returns Map of pair index to fee
|
|
16
|
+
*/
|
|
17
|
+
getMarginFee(): Promise<Map<number, Fee>>;
|
|
18
|
+
/**
|
|
19
|
+
* Get constant spread parameter for each pair
|
|
20
|
+
* @returns Map of pair index to constant spread
|
|
21
|
+
*/
|
|
22
|
+
constantSpreadParameter(): Promise<Map<number, number>>;
|
|
23
|
+
/**
|
|
24
|
+
* Get opening fee for a position
|
|
25
|
+
* @param positionSize - Position size in USDC
|
|
26
|
+
* @param isLong - True for long, false for short
|
|
27
|
+
* @param pairIndex - Pair index
|
|
28
|
+
* @returns Opening fee in USDC
|
|
29
|
+
*/
|
|
30
|
+
getOpeningFee(positionSize: number, isLong: boolean, pairIndex: number): Promise<number>;
|
|
31
|
+
/**
|
|
32
|
+
* Get opening fee for a new trade with referral
|
|
33
|
+
* @param tradeInput - Trade input parameters
|
|
34
|
+
* @param referrer - Referrer address (optional)
|
|
35
|
+
* @returns Opening fee in USDC
|
|
36
|
+
*/
|
|
37
|
+
getNewTradeOpeningFee(tradeInput: TradeInput, referrer?: string): Promise<number>;
|
|
38
|
+
/**
|
|
39
|
+
* Get trade referral rebate
|
|
40
|
+
* @param trader - Trader address
|
|
41
|
+
* @param referrer - Referrer address
|
|
42
|
+
* @param openingFee - Opening fee amount
|
|
43
|
+
* @returns Rebate amount
|
|
44
|
+
*/
|
|
45
|
+
getTradeReferralRebate(trader: string, referrer: string, openingFee: number): Promise<number>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FeeParametersRPC = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
/**
|
|
6
|
+
* RPC module for fee calculations
|
|
7
|
+
*/
|
|
8
|
+
class FeeParametersRPC {
|
|
9
|
+
constructor(provider, pairInfosContract, pairsCache, referralContract) {
|
|
10
|
+
this.provider = provider;
|
|
11
|
+
this.pairInfosContract = pairInfosContract;
|
|
12
|
+
this.pairsCache = pairsCache;
|
|
13
|
+
this.referralContract = referralContract;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get margin fee for all pairs (in basis points)
|
|
17
|
+
* @returns Map of pair index to fee
|
|
18
|
+
*/
|
|
19
|
+
async getMarginFee() {
|
|
20
|
+
const pairs = await this.pairsCache.getPairsInfo();
|
|
21
|
+
const fees = new Map();
|
|
22
|
+
for (const [pairIndex] of pairs) {
|
|
23
|
+
try {
|
|
24
|
+
const feeP = await this.pairInfosContract.getPairMarginFeeP(pairIndex);
|
|
25
|
+
fees.set(pairIndex, {
|
|
26
|
+
feeP: (0, types_1.fromBlockchain10)(feeP),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error(`Error getting margin fee for pair ${pairIndex}:`, error);
|
|
31
|
+
fees.set(pairIndex, { feeP: 0 });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return fees;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get constant spread parameter for each pair
|
|
38
|
+
* @returns Map of pair index to constant spread
|
|
39
|
+
*/
|
|
40
|
+
async constantSpreadParameter() {
|
|
41
|
+
const pairs = await this.pairsCache.getPairsInfo();
|
|
42
|
+
const spreads = new Map();
|
|
43
|
+
for (const [pairIndex, pairInfo] of pairs) {
|
|
44
|
+
// Use the min spread as the constant spread
|
|
45
|
+
spreads.set(pairIndex, pairInfo.spread.min);
|
|
46
|
+
}
|
|
47
|
+
return spreads;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get opening fee for a position
|
|
51
|
+
* @param positionSize - Position size in USDC
|
|
52
|
+
* @param isLong - True for long, false for short
|
|
53
|
+
* @param pairIndex - Pair index
|
|
54
|
+
* @returns Opening fee in USDC
|
|
55
|
+
*/
|
|
56
|
+
async getOpeningFee(positionSize, isLong, pairIndex) {
|
|
57
|
+
try {
|
|
58
|
+
const feeUsdc = await this.pairInfosContract.getOpenFeeUsdc(pairIndex, (0, types_1.toBlockchain6)(positionSize), isLong);
|
|
59
|
+
return (0, types_1.fromBlockchain10)(feeUsdc);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
console.error('Error getting opening fee:', error);
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get opening fee for a new trade with referral
|
|
68
|
+
* @param tradeInput - Trade input parameters
|
|
69
|
+
* @param referrer - Referrer address (optional)
|
|
70
|
+
* @returns Opening fee in USDC
|
|
71
|
+
*/
|
|
72
|
+
async getNewTradeOpeningFee(tradeInput, referrer) {
|
|
73
|
+
const pairIndex = await this.pairsCache.getPairIndex(tradeInput.pair);
|
|
74
|
+
if (pairIndex === undefined) {
|
|
75
|
+
throw new Error(`Pair ${tradeInput.pair} not found`);
|
|
76
|
+
}
|
|
77
|
+
const positionSize = tradeInput.collateralInTrade * tradeInput.leverage;
|
|
78
|
+
let fee = await this.getOpeningFee(positionSize, tradeInput.isLong, pairIndex);
|
|
79
|
+
// Apply referral discount if applicable
|
|
80
|
+
if (referrer && this.referralContract) {
|
|
81
|
+
try {
|
|
82
|
+
const rebate = await this.getTradeReferralRebate(tradeInput.referrer || referrer, referrer, fee);
|
|
83
|
+
fee -= rebate;
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error('Error getting referral rebate:', error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return fee;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get trade referral rebate
|
|
93
|
+
* @param trader - Trader address
|
|
94
|
+
* @param referrer - Referrer address
|
|
95
|
+
* @param openingFee - Opening fee amount
|
|
96
|
+
* @returns Rebate amount
|
|
97
|
+
*/
|
|
98
|
+
async getTradeReferralRebate(trader, referrer, openingFee) {
|
|
99
|
+
if (!this.referralContract) {
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const rebateP = await this.referralContract.getReferralRebateP(trader, referrer);
|
|
104
|
+
const rebatePercentage = (0, types_1.fromBlockchain10)(rebateP);
|
|
105
|
+
return openingFee * (rebatePercentage / 100);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.error('Error getting referral rebate:', error);
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.FeeParametersRPC = FeeParametersRPC;
|