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,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delegation and Referrals Example
|
|
3
|
+
* Demonstrates delegation functionality and referral program
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { TraderClient, toBlockchain10, toBlockchain6, toBlockchain18 } from '../src';
|
|
7
|
+
|
|
8
|
+
async function main() {
|
|
9
|
+
// Initialize client
|
|
10
|
+
const client = new TraderClient('https://mainnet.base.org');
|
|
11
|
+
const privateKey = process.env.PRIVATE_KEY || '0x...';
|
|
12
|
+
client.setLocalSigner(privateKey);
|
|
13
|
+
|
|
14
|
+
const walletAddress = await client.signer?.getAddress();
|
|
15
|
+
console.log('Wallet address:', walletAddress);
|
|
16
|
+
|
|
17
|
+
// ==================== DELEGATION ====================
|
|
18
|
+
|
|
19
|
+
console.log('\n=== DELEGATION ===\n');
|
|
20
|
+
|
|
21
|
+
// 1. Set a delegate
|
|
22
|
+
console.log('1. Setting delegate...');
|
|
23
|
+
const delegateAddress = '0x...'; // Replace with actual delegate address
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const receipt = await client.delegation.setDelegate(delegateAddress);
|
|
27
|
+
console.log('Delegate set! Transaction hash:', receipt?.hash);
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.error('Error setting delegate:', error);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 2. Check current delegate
|
|
33
|
+
console.log('\n2. Checking current delegate...');
|
|
34
|
+
const currentDelegate = await client.delegation.getDelegateFor(walletAddress!);
|
|
35
|
+
console.log('Current delegate:', currentDelegate);
|
|
36
|
+
|
|
37
|
+
// 3. Execute delegated action (as delegate)
|
|
38
|
+
console.log('\n3. Executing delegated action...');
|
|
39
|
+
|
|
40
|
+
// Example: Update TP/SL as delegate
|
|
41
|
+
const traderAddress = '0x...'; // Address you're delegating for
|
|
42
|
+
const newSl = toBlockchain10(47000);
|
|
43
|
+
const newTp = toBlockchain10(56000);
|
|
44
|
+
|
|
45
|
+
const callData = client.delegation.encodeUpdateTpAndSl(
|
|
46
|
+
0, // pairIndex
|
|
47
|
+
0, // tradeIndex
|
|
48
|
+
newSl,
|
|
49
|
+
newTp,
|
|
50
|
+
[]
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const receipt = await client.delegation.delegatedAction(
|
|
55
|
+
traderAddress,
|
|
56
|
+
callData,
|
|
57
|
+
1n // 1 wei for price update
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
console.log('Delegated action executed! Transaction hash:', receipt?.hash);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.error('Error executing delegated action:', error);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 4. Remove delegate
|
|
66
|
+
console.log('\n4. Removing delegate...');
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const receipt = await client.delegation.removeDelegate();
|
|
70
|
+
console.log('Delegate removed! Transaction hash:', receipt?.hash);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error('Error removing delegate:', error);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ==================== REFERRALS ====================
|
|
76
|
+
|
|
77
|
+
console.log('\n=== REFERRALS ===\n');
|
|
78
|
+
|
|
79
|
+
// 1. Set referral code
|
|
80
|
+
console.log('1. Setting referral code...');
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
const receipt = await client.referral.setReferralCode('AVANTIS2024');
|
|
84
|
+
console.log('Referral code set! Transaction hash:', receipt?.hash);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error('Error setting referral code:', error);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 2. Get referral info
|
|
90
|
+
console.log('\n2. Getting referral info...');
|
|
91
|
+
const referralInfo = await client.referral.getTraderReferralInfo(walletAddress!);
|
|
92
|
+
console.log('Referral code:', referralInfo.code);
|
|
93
|
+
console.log('Referrer address:', referralInfo.referrer);
|
|
94
|
+
|
|
95
|
+
// 3. Check if user has referral code
|
|
96
|
+
const hasCode = await client.referral.hasReferralCode(walletAddress!);
|
|
97
|
+
console.log('Has referral code:', hasCode);
|
|
98
|
+
|
|
99
|
+
// 4. Get referrer tier
|
|
100
|
+
if (referralInfo.referrer !== '0x0000000000000000000000000000000000000000') {
|
|
101
|
+
const tier = await client.referral.getReferrerTier(referralInfo.referrer);
|
|
102
|
+
console.log('Referrer tier:', tier);
|
|
103
|
+
|
|
104
|
+
// Get tier details
|
|
105
|
+
const tierInfo = await client.referral.getTierInfo(tier);
|
|
106
|
+
console.log('Tier info:', {
|
|
107
|
+
feeDiscountPct: tierInfo.feeDiscountPct,
|
|
108
|
+
refRebatePct: tierInfo.refRebatePct,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 5. Calculate referral discount
|
|
113
|
+
console.log('\n5. Calculating referral discount...');
|
|
114
|
+
const baseFee = 1000000; // 1 USDC in 6 decimals
|
|
115
|
+
const discount = await client.referral.getTraderReferralDiscount(walletAddress!, baseFee);
|
|
116
|
+
|
|
117
|
+
console.log('Discount info:', {
|
|
118
|
+
traderDiscount: discount.traderDiscount,
|
|
119
|
+
referrer: discount.referrer,
|
|
120
|
+
rebateShare: discount.rebateShare,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// 6. Get effective fee after discount
|
|
124
|
+
const effectiveFee = await client.referral.getEffectiveFee(walletAddress!, baseFee);
|
|
125
|
+
console.log('Original fee:', baseFee);
|
|
126
|
+
console.log('Effective fee after discount:', effectiveFee);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Run the example
|
|
130
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple example - Get Pyth feed IDs from the SDK
|
|
3
|
+
*
|
|
4
|
+
* This shows how to retrieve Pyth feed IDs that are stored
|
|
5
|
+
* in the trading pair storage contract.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { TraderClient } from '../src';
|
|
9
|
+
|
|
10
|
+
async function main() {
|
|
11
|
+
// Initialize the trading client
|
|
12
|
+
const providerUrl = 'https://base-rpc.publicnode.com';
|
|
13
|
+
const client = new TraderClient(providerUrl);
|
|
14
|
+
|
|
15
|
+
console.log('Fetching Pyth feed IDs from pair storage contract...\n');
|
|
16
|
+
|
|
17
|
+
// Method 1: Get Pyth ID for a specific pair
|
|
18
|
+
console.log('=== Method 1: Get Pyth ID for a specific pair ===');
|
|
19
|
+
|
|
20
|
+
const btcPairIndex = await client.pairsCache.getPairIndex('BTC/USD');
|
|
21
|
+
|
|
22
|
+
if (btcPairIndex !== undefined) {
|
|
23
|
+
const btcPairData = await client.pairsCache.getPairBackend(btcPairIndex);
|
|
24
|
+
|
|
25
|
+
console.log('Pair: BTC/USD');
|
|
26
|
+
console.log('Pair Index:', btcPairIndex);
|
|
27
|
+
console.log('Pyth Feed ID:', btcPairData.pair.feed.feedId);
|
|
28
|
+
console.log('Backup Feed (Chainlink):', btcPairData.pair.backupFeed.feedId);
|
|
29
|
+
console.log('');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Method 2: Get ALL Pyth IDs as a map
|
|
33
|
+
console.log('=== Method 2: Get all Pyth IDs ===');
|
|
34
|
+
|
|
35
|
+
const allPairs = await client.pairsCache.getPairsInfo();
|
|
36
|
+
const pythIds: Record<string, string> = {};
|
|
37
|
+
|
|
38
|
+
for (const [pairIndex, pairInfo] of allPairs) {
|
|
39
|
+
const pairData = await client.pairsCache.getPairBackend(pairIndex);
|
|
40
|
+
const pairName = `${pairInfo.from}/${pairInfo.to}`;
|
|
41
|
+
pythIds[pairName] = pairData.pair.feed.feedId;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.log('All Pyth Feed IDs:');
|
|
45
|
+
console.log(JSON.stringify(pythIds, null, 2));
|
|
46
|
+
|
|
47
|
+
// Method 3: Export as CSV format (useful for documentation)
|
|
48
|
+
console.log('\n=== Method 3: Export as CSV ===');
|
|
49
|
+
console.log('Pair,PairIndex,PythFeedID,BackupFeedID');
|
|
50
|
+
|
|
51
|
+
for (const [pairIndex, pairInfo] of allPairs) {
|
|
52
|
+
const pairData = await client.pairsCache.getPairBackend(pairIndex);
|
|
53
|
+
const pairName = `${pairInfo.from}/${pairInfo.to}`;
|
|
54
|
+
console.log(
|
|
55
|
+
`${pairName},${pairIndex},${pairData.pair.feed.feedId},${pairData.pair.backupFeed.feedId}`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Run the example
|
|
61
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example using AWS KMS for secure transaction signing
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { TraderClient } from '../src';
|
|
6
|
+
|
|
7
|
+
async function main() {
|
|
8
|
+
// Initialize client
|
|
9
|
+
const providerUrl = 'https://your-rpc-endpoint.com';
|
|
10
|
+
const client = new TraderClient(providerUrl);
|
|
11
|
+
|
|
12
|
+
// Set up AWS KMS signer
|
|
13
|
+
const kmsKeyId = 'your-kms-key-id';
|
|
14
|
+
const region = 'us-east-1';
|
|
15
|
+
client.setAwsKmsSigner(kmsKeyId, region);
|
|
16
|
+
|
|
17
|
+
// Get address from KMS key
|
|
18
|
+
const address = await client.signer?.getAddress();
|
|
19
|
+
console.log('Trading from KMS-secured address:', address);
|
|
20
|
+
|
|
21
|
+
// Now you can use the client normally
|
|
22
|
+
// All transactions will be signed by AWS KMS
|
|
23
|
+
const balance = await client.getUsdcBalance(address!);
|
|
24
|
+
console.log('USDC Balance:', balance);
|
|
25
|
+
|
|
26
|
+
// The private key never leaves AWS KMS hardware security modules
|
|
27
|
+
console.log('Secure signing enabled via AWS KMS');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Run the example
|
|
31
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optimized Snapshot Example
|
|
3
|
+
* Demonstrates the optimized snapshot that uses getPairBackend() to reduce contract calls
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { TraderClient, fromBlockchain10, fromBlockchain12 } from '../src';
|
|
7
|
+
|
|
8
|
+
async function main() {
|
|
9
|
+
// Initialize client
|
|
10
|
+
const client = new TraderClient('https://mainnet.base.org');
|
|
11
|
+
|
|
12
|
+
console.log('=== OPTIMIZED SNAPSHOT DEMO ===\n');
|
|
13
|
+
|
|
14
|
+
// ==================== STANDARD SNAPSHOT ====================
|
|
15
|
+
|
|
16
|
+
console.log('1. Getting market snapshot (optimized)...');
|
|
17
|
+
const snapshot = await client.snapshotRPC.getSnapshot();
|
|
18
|
+
|
|
19
|
+
console.log('\nSnapshot groups:', Object.keys(snapshot.groups));
|
|
20
|
+
|
|
21
|
+
// Display first group
|
|
22
|
+
const firstGroupKey = Object.keys(snapshot.groups)[0];
|
|
23
|
+
if (firstGroupKey) {
|
|
24
|
+
const group = snapshot.groups[firstGroupKey];
|
|
25
|
+
console.log(`\n${firstGroupKey} details:`);
|
|
26
|
+
console.log(' Pairs in group:', Object.keys(group.pairs).length);
|
|
27
|
+
console.log(' Group OI:', group.openInterest);
|
|
28
|
+
console.log(' Group Utilization:', group.utilization);
|
|
29
|
+
console.log(' Group Skew:', group.skew);
|
|
30
|
+
|
|
31
|
+
// Display first pair in group
|
|
32
|
+
const firstPairName = Object.keys(group.pairs)[0];
|
|
33
|
+
if (firstPairName) {
|
|
34
|
+
const pair = group.pairs[firstPairName];
|
|
35
|
+
console.log(`\n ${firstPairName} details:`);
|
|
36
|
+
console.log(' Max Leverage:', pair.pairInfo.maxLeverage);
|
|
37
|
+
console.log(' Spread:', pair.spread);
|
|
38
|
+
console.log(' Fee:', pair.fee?.feeP);
|
|
39
|
+
console.log(' OI:', pair.openInterest);
|
|
40
|
+
console.log(' Utilization:', pair.utilization);
|
|
41
|
+
console.log(' Depth Above:', pair.depth?.onePercentDepthAboveUsdc);
|
|
42
|
+
console.log(' Depth Below:', pair.depth?.onePercentDepthBelowUsdc);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ==================== FULL BACKEND DATA ====================
|
|
47
|
+
|
|
48
|
+
console.log('\n\n2. Getting full backend data for a pair...');
|
|
49
|
+
|
|
50
|
+
// Get full backend data for BTC/USD (usually pair index 0)
|
|
51
|
+
const pairIndex = 0;
|
|
52
|
+
const fullData = await client.snapshotRPC.getPairFullData(pairIndex);
|
|
53
|
+
|
|
54
|
+
console.log('\nFull pair data structure:');
|
|
55
|
+
console.log(' Pair Config:');
|
|
56
|
+
console.log(' Feed ID:', fullData.pair.feed.feedId);
|
|
57
|
+
console.log(' Max Open Deviation:', fromBlockchain10(fullData.pair.feed.maxOpenDeviationP), '%');
|
|
58
|
+
console.log(' Max Close Deviation:', fromBlockchain10(fullData.pair.feed.maxCloseDeviationP), '%');
|
|
59
|
+
console.log(' Spread:', fromBlockchain10(fullData.pair.spreadP), '%');
|
|
60
|
+
console.log(' PnL Spread:', fromBlockchain10(fullData.pair.pnlSpreadP), '%');
|
|
61
|
+
|
|
62
|
+
console.log('\n Leverage Config:');
|
|
63
|
+
console.log(' Min Leverage:', fromBlockchain10(fullData.pair.leverages.minLeverage), 'x');
|
|
64
|
+
console.log(' Max Leverage:', fromBlockchain10(fullData.pair.leverages.maxLeverage), 'x');
|
|
65
|
+
console.log(' PnL Min Leverage:', fromBlockchain10(fullData.pair.leverages.pnlMinLeverage), 'x');
|
|
66
|
+
console.log(' PnL Max Leverage:', fromBlockchain10(fullData.pair.leverages.pnlMaxLeverage), 'x');
|
|
67
|
+
|
|
68
|
+
console.log('\n OI & Risk Config:');
|
|
69
|
+
console.log(' Max Long OI:', fromBlockchain10(fullData.pair.values.maxLongOiP), '%');
|
|
70
|
+
console.log(' Max Short OI:', fromBlockchain10(fullData.pair.values.maxShortOiP), '%');
|
|
71
|
+
console.log(' Group OI %:', fromBlockchain10(fullData.pair.values.groupOpenInterestPercentageP), '%');
|
|
72
|
+
console.log(' Max Wallet OI:', fromBlockchain10(fullData.pair.values.maxWalletOIP), '%');
|
|
73
|
+
console.log(' Max Gain:', fromBlockchain10(fullData.pair.values.maxGainP), '%');
|
|
74
|
+
console.log(' Max SL:', fromBlockchain10(fullData.pair.values.maxSlP), '%');
|
|
75
|
+
console.log(' Is USDC Aligned:', fullData.pair.values.isUSDCAligned);
|
|
76
|
+
|
|
77
|
+
console.log('\n Group Info:');
|
|
78
|
+
console.log(' Name:', fullData.group.name);
|
|
79
|
+
console.log(' Max OI:', fromBlockchain10(fullData.group.maxOpenInterestP), '%');
|
|
80
|
+
console.log(' Dynamic Spread:', fullData.group.isSpreadDynamic);
|
|
81
|
+
|
|
82
|
+
console.log('\n Fee Structure:');
|
|
83
|
+
console.log(' Open Fee:', fromBlockchain12(fullData.fee.openFeeP), '%');
|
|
84
|
+
console.log(' Close Fee:', fromBlockchain12(fullData.fee.closeFeeP), '%');
|
|
85
|
+
console.log(' Limit Order Fee:', fromBlockchain12(fullData.fee.limitOrderFeeP), '%');
|
|
86
|
+
console.log(' Min Lev Position:', fromBlockchain10(fullData.fee.minLevPosUSDC), 'USDC');
|
|
87
|
+
|
|
88
|
+
console.log('\n PnL Fees:');
|
|
89
|
+
console.log(' Number of Tiers:', fullData.fee.pnlFees.numTiers.toString());
|
|
90
|
+
if (fullData.fee.pnlFees.tierP.length > 0) {
|
|
91
|
+
fullData.fee.pnlFees.tierP.forEach((tier, i) => {
|
|
92
|
+
console.log(` Tier ${i}: ${fromBlockchain10(tier)}% -> Fee: ${fromBlockchain12(fullData.fee.pnlFees.feesP[i])}%`);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ==================== ALL PAIRS FULL DATA ====================
|
|
97
|
+
|
|
98
|
+
console.log('\n\n3. Getting full backend data for all pairs...');
|
|
99
|
+
|
|
100
|
+
const allPairsData = await client.snapshotRPC.getAllPairsFullData();
|
|
101
|
+
|
|
102
|
+
console.log(`\nLoaded full data for ${allPairsData.size} pairs`);
|
|
103
|
+
|
|
104
|
+
// Get pair names
|
|
105
|
+
const pairs = await client.pairsCache.getPairsInfo();
|
|
106
|
+
|
|
107
|
+
// Display summary of all pairs
|
|
108
|
+
console.log('\nAll pairs summary:');
|
|
109
|
+
for (const [pairIdx, backendData] of allPairsData) {
|
|
110
|
+
const pairInfo = pairs.get(pairIdx);
|
|
111
|
+
if (pairInfo) {
|
|
112
|
+
const maxLev = fromBlockchain10(backendData.pair.leverages.maxLeverage);
|
|
113
|
+
const spreadP = fromBlockchain10(backendData.pair.spreadP);
|
|
114
|
+
const openFeeP = fromBlockchain12(backendData.fee.openFeeP);
|
|
115
|
+
|
|
116
|
+
console.log(` ${pairInfo.from}/${pairInfo.to}:`);
|
|
117
|
+
console.log(` Max Leverage: ${maxLev}x`);
|
|
118
|
+
console.log(` Spread: ${spreadP}%`);
|
|
119
|
+
console.log(` Open Fee: ${openFeeP}%`);
|
|
120
|
+
console.log(` Group: ${backendData.group.name}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ==================== PERFORMANCE COMPARISON ====================
|
|
125
|
+
|
|
126
|
+
console.log('\n\n4. Performance comparison...');
|
|
127
|
+
console.log('\nOld approach (multiple calls):');
|
|
128
|
+
console.log(' - getPairsInfo() - 1 call');
|
|
129
|
+
console.log(' - getGroupIndexes() - 1 call');
|
|
130
|
+
console.log(' - getOI() (asset) - N calls per pair');
|
|
131
|
+
console.log(' - getOI() (category) - N calls per group');
|
|
132
|
+
console.log(' - getMarginFee() - N calls per pair');
|
|
133
|
+
console.log(' - And many more...');
|
|
134
|
+
console.log(' TOTAL: ~10+ separate RPC calls');
|
|
135
|
+
|
|
136
|
+
console.log('\nNew optimized approach:');
|
|
137
|
+
console.log(' - getPairsInfo() - 1 call (to get count)');
|
|
138
|
+
console.log(' - getPairBackend() - N calls (but includes pair + group + fee)');
|
|
139
|
+
console.log(' - getOI() (dynamic data) - still needed');
|
|
140
|
+
console.log(' - getUtilization() (dynamic data) - still needed');
|
|
141
|
+
console.log(' - getSkew() (dynamic data) - still needed');
|
|
142
|
+
console.log(' TOTAL: Reduced by eliminating separate group and fee calls');
|
|
143
|
+
|
|
144
|
+
console.log('\nBenefits:');
|
|
145
|
+
console.log(' ✓ Fewer total RPC calls');
|
|
146
|
+
console.log(' ✓ All static config data in one call');
|
|
147
|
+
console.log(' ✓ Access to complete pair configuration');
|
|
148
|
+
console.log(' ✓ Better for batch operations');
|
|
149
|
+
console.log(' ✓ More efficient caching opportunities');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Run the example
|
|
153
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Price feed example - Get Pyth IDs from SDK and use with FeedClient
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to:
|
|
5
|
+
* 1. Fetch Pyth feed IDs from the trading pair storage contract
|
|
6
|
+
* 2. Use those IDs with the FeedClient to get real-time price updates
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { TraderClient, FeedClient, PriceFeedResponse } from '../src';
|
|
10
|
+
|
|
11
|
+
async function main() {
|
|
12
|
+
// Initialize the trading client
|
|
13
|
+
const providerUrl = 'https://base-rpc.publicnode.com';
|
|
14
|
+
const client = new TraderClient(providerUrl);
|
|
15
|
+
|
|
16
|
+
// Example 1: Get Pyth feed ID for a specific pair
|
|
17
|
+
console.log('=== Example 1: Get Pyth ID for BTC/USD ===');
|
|
18
|
+
|
|
19
|
+
// Get BTC/USD pair index
|
|
20
|
+
const btcPairIndex = await client.pairsCache.getPairIndex('BTC/USD');
|
|
21
|
+
console.log('BTC/USD pair index:', btcPairIndex);
|
|
22
|
+
|
|
23
|
+
if (btcPairIndex !== undefined) {
|
|
24
|
+
// Get the full pair backend data (includes feed IDs)
|
|
25
|
+
const pairData = await client.pairsCache.getPairBackend(btcPairIndex);
|
|
26
|
+
|
|
27
|
+
console.log('Primary Pyth Feed ID:', pairData.pair.feed.feedId);
|
|
28
|
+
console.log('Backup Feed ID (Chainlink):', pairData.pair.backupFeed.feedId);
|
|
29
|
+
console.log('Max Open Deviation:', pairData.pair.feed.maxOpenDeviationP);
|
|
30
|
+
console.log('Max Close Deviation:', pairData.pair.feed.maxCloseDeviationP);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Example 2: Get Pyth IDs for ALL trading pairs
|
|
34
|
+
console.log('\n=== Example 2: Get Pyth IDs for all pairs ===');
|
|
35
|
+
|
|
36
|
+
const allPairs = await client.pairsCache.getPairsInfo();
|
|
37
|
+
const pairFeedsMap = new Map<string, string>();
|
|
38
|
+
|
|
39
|
+
for (const [pairIndex, pairInfo] of allPairs) {
|
|
40
|
+
// Get the full backend data for this pair
|
|
41
|
+
const pairData = await client.pairsCache.getPairBackend(pairIndex);
|
|
42
|
+
const pairName = `${pairInfo.from}/${pairInfo.to}`;
|
|
43
|
+
const feedId = pairData.pair.feed.feedId;
|
|
44
|
+
|
|
45
|
+
pairFeedsMap.set(pairName, feedId);
|
|
46
|
+
console.log(`${pairName}: ${feedId}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Example 3: Use the Pyth IDs with FeedClient for real-time prices
|
|
50
|
+
console.log('\n=== Example 3: Connect to Pyth for real-time prices ===');
|
|
51
|
+
|
|
52
|
+
const feedClient = new FeedClient();
|
|
53
|
+
|
|
54
|
+
// Load the pair-to-feed mapping into FeedClient
|
|
55
|
+
feedClient.loadPairFeeds(pairFeedsMap);
|
|
56
|
+
|
|
57
|
+
// Register callbacks for specific pairs
|
|
58
|
+
const btcFeedId = feedClient.getFeedIdForPair('BTC/USD');
|
|
59
|
+
const ethFeedId = feedClient.getFeedIdForPair('ETH/USD');
|
|
60
|
+
|
|
61
|
+
if (btcFeedId) {
|
|
62
|
+
console.log('Registering callback for BTC/USD feed:', btcFeedId);
|
|
63
|
+
feedClient.registerPriceFeedCallback(btcFeedId, (priceData: PriceFeedResponse) => {
|
|
64
|
+
const price = Number(priceData.price.price) * Math.pow(10, priceData.price.expo);
|
|
65
|
+
console.log('BTC/USD Price Update:', {
|
|
66
|
+
price: price.toFixed(2),
|
|
67
|
+
confidence: priceData.price.conf,
|
|
68
|
+
timestamp: new Date(priceData.price.publishTime * 1000).toISOString(),
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (ethFeedId) {
|
|
74
|
+
console.log('Registering callback for ETH/USD feed:', ethFeedId);
|
|
75
|
+
feedClient.registerPriceFeedCallback(ethFeedId, (priceData: PriceFeedResponse) => {
|
|
76
|
+
const price = Number(priceData.price.price) * Math.pow(10, priceData.price.expo);
|
|
77
|
+
console.log('ETH/USD Price Update:', {
|
|
78
|
+
price: price.toFixed(2),
|
|
79
|
+
confidence: priceData.price.conf,
|
|
80
|
+
timestamp: new Date(priceData.price.publishTime * 1000).toISOString(),
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Connect to Pyth WebSocket and start receiving updates
|
|
86
|
+
console.log('\nConnecting to Pyth Network WebSocket...');
|
|
87
|
+
await feedClient.listenForPriceUpdates();
|
|
88
|
+
|
|
89
|
+
console.log('Connected! Listening for price updates...');
|
|
90
|
+
console.log('Press Ctrl+C to exit');
|
|
91
|
+
|
|
92
|
+
// Keep the process running
|
|
93
|
+
process.stdin.resume();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Run the example
|
|
97
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Price feed example using WebSocket
|
|
3
|
+
*
|
|
4
|
+
* NOTE: For a complete example showing how to get Pyth feed IDs from the SDK,
|
|
5
|
+
* see: price-feed-with-sdk-ids.ts
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { FeedClient, PriceFeedResponse } from '../src';
|
|
9
|
+
|
|
10
|
+
async function main() {
|
|
11
|
+
// Create feed client
|
|
12
|
+
const feedClient = new FeedClient();
|
|
13
|
+
|
|
14
|
+
// Register callback for BTC/USD price feed
|
|
15
|
+
// You can get this ID from the SDK - see price-feed-with-sdk-ids.ts example
|
|
16
|
+
const btcFeedId = 'your-btc-feed-id-here'; // Or use client.pairsCache.getPairBackend()
|
|
17
|
+
|
|
18
|
+
feedClient.registerPriceFeedCallback(btcFeedId, (priceData: PriceFeedResponse) => {
|
|
19
|
+
const price = Number(priceData.price.price) * Math.pow(10, priceData.price.expo);
|
|
20
|
+
console.log('BTC/USD Price Update:', {
|
|
21
|
+
price: price,
|
|
22
|
+
confidence: priceData.price.conf,
|
|
23
|
+
timestamp: new Date(priceData.price.publishTime * 1000).toISOString(),
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Connect and listen for updates
|
|
28
|
+
console.log('Connecting to price feed...');
|
|
29
|
+
await feedClient.listenForPriceUpdates();
|
|
30
|
+
|
|
31
|
+
// Keep the process running
|
|
32
|
+
process.stdin.resume();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Run the example
|
|
36
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trading Operations Example
|
|
3
|
+
* Demonstrates opening trades, closing trades, and updating positions
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { TraderClient, TradeInputOrderType, MarginUpdateType } from '../src';
|
|
7
|
+
|
|
8
|
+
async function main() {
|
|
9
|
+
// Initialize client (Base network)
|
|
10
|
+
const client = new TraderClient('https://mainnet.base.org');
|
|
11
|
+
|
|
12
|
+
// Set signer with private key
|
|
13
|
+
const privateKey = process.env.PRIVATE_KEY || '0x...';
|
|
14
|
+
client.setLocalSigner(privateKey);
|
|
15
|
+
|
|
16
|
+
const walletAddress = await client.signer?.getAddress();
|
|
17
|
+
console.log('Wallet address:', walletAddress);
|
|
18
|
+
|
|
19
|
+
// ==================== OPEN A TRADE ====================
|
|
20
|
+
|
|
21
|
+
console.log('\n1. Opening a trade...');
|
|
22
|
+
|
|
23
|
+
// Get execution fee
|
|
24
|
+
const executionFee = await client.tradingOps.getExecutionFee();
|
|
25
|
+
console.log('Execution fee:', executionFee, 'ETH');
|
|
26
|
+
|
|
27
|
+
// Define trade parameters
|
|
28
|
+
const trade = {
|
|
29
|
+
trader: walletAddress!,
|
|
30
|
+
pairIndex: 0, // BTC/USD
|
|
31
|
+
index: 0, // Will be assigned by contract
|
|
32
|
+
initialPosToken: 100, // 100 USDC collateral
|
|
33
|
+
positionSizeUSDC: 100,
|
|
34
|
+
openPrice: 50000, // $50,000 BTC price
|
|
35
|
+
buy: true, // Long position
|
|
36
|
+
leverage: 10, // 10x leverage
|
|
37
|
+
tp: 55000, // Take profit at $55,000
|
|
38
|
+
sl: 48000, // Stop loss at $48,000
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const slippagePercent = 1; // 1% slippage tolerance
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const receipt = await client.tradingOps.openTrade(
|
|
45
|
+
trade,
|
|
46
|
+
TradeInputOrderType.MARKET,
|
|
47
|
+
slippagePercent,
|
|
48
|
+
executionFee
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
console.log('Trade opened! Transaction hash:', receipt?.hash);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('Error opening trade:', error);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ==================== QUERY OPEN TRADES ====================
|
|
57
|
+
|
|
58
|
+
console.log('\n2. Querying open trades...');
|
|
59
|
+
|
|
60
|
+
const tradeCount = await client.tradingOps.getOpenTradesCount(walletAddress!, 0);
|
|
61
|
+
console.log('Number of open trades:', tradeCount);
|
|
62
|
+
|
|
63
|
+
if (tradeCount > 0) {
|
|
64
|
+
// Get first trade
|
|
65
|
+
const openTrade = await client.tradingOps.getOpenTrade(walletAddress!, 0, 0);
|
|
66
|
+
console.log('Open trade:', {
|
|
67
|
+
leverage: openTrade.leverage,
|
|
68
|
+
openPrice: openTrade.openPrice,
|
|
69
|
+
tp: openTrade.tp,
|
|
70
|
+
sl: openTrade.sl,
|
|
71
|
+
isLong: openTrade.buy,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Get additional trade info
|
|
75
|
+
const tradeInfo = await client.tradingOps.getOpenTradeInfo(walletAddress!, 0, 0);
|
|
76
|
+
console.log('Trade info:', {
|
|
77
|
+
openInterestUSDC: tradeInfo.openInterestUSDC,
|
|
78
|
+
lossProtection: tradeInfo.lossProtection,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ==================== UPDATE TP/SL ====================
|
|
83
|
+
|
|
84
|
+
console.log('\n3. Updating take profit and stop loss...');
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
const receipt = await client.tradingOps.updateTpAndSl(
|
|
88
|
+
0, // pairIndex
|
|
89
|
+
0, // tradeIndex
|
|
90
|
+
47000, // New SL: $47,000
|
|
91
|
+
56000, // New TP: $56,000
|
|
92
|
+
[] // Price update data (can be empty for now)
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
console.log('TP/SL updated! Transaction hash:', receipt?.hash);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
console.error('Error updating TP/SL:', error);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ==================== UPDATE MARGIN ====================
|
|
101
|
+
|
|
102
|
+
console.log('\n4. Adding margin to position...');
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
const receipt = await client.tradingOps.updateMargin(
|
|
106
|
+
0, // pairIndex
|
|
107
|
+
0, // tradeIndex
|
|
108
|
+
MarginUpdateType.DEPOSIT,
|
|
109
|
+
50, // Add 50 USDC
|
|
110
|
+
[]
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
console.log('Margin updated! Transaction hash:', receipt?.hash);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error('Error updating margin:', error);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ==================== CLOSE TRADE ====================
|
|
119
|
+
|
|
120
|
+
console.log('\n5. Closing trade...');
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const receipt = await client.tradingOps.closeTradeMarket(
|
|
124
|
+
0, // pairIndex
|
|
125
|
+
0, // tradeIndex
|
|
126
|
+
150, // Close 150 USDC worth (full position if that's the total)
|
|
127
|
+
executionFee
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
console.log('Trade closed! Transaction hash:', receipt?.hash);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.error('Error closing trade:', error);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// ==================== LIMIT ORDERS ====================
|
|
136
|
+
|
|
137
|
+
console.log('\n6. Checking limit orders...');
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
const limitOrder = await client.tradingOps.getOpenLimitOrder(walletAddress!, 0, 0);
|
|
141
|
+
console.log('Limit order:', limitOrder);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
// No limit order exists
|
|
144
|
+
console.log('No limit order found');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Run the example
|
|
149
|
+
main().catch(console.error);
|