sol-trade-sdk 0.1.0
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/README.md +390 -0
- package/dist/chunk-MMQAMIKR.mjs +3735 -0
- package/dist/chunk-NEZDFAYA.mjs +7744 -0
- package/dist/clients-VITWK7B6.mjs +1370 -0
- package/dist/index-1BK_FXsW.d.mts +2327 -0
- package/dist/index-1BK_FXsW.d.ts +2327 -0
- package/dist/index.d.mts +2659 -0
- package/dist/index.d.ts +2659 -0
- package/dist/index.js +13265 -0
- package/dist/index.mjs +562 -0
- package/dist/perf/index.d.mts +2 -0
- package/dist/perf/index.d.ts +2 -0
- package/dist/perf/index.js +3742 -0
- package/dist/perf/index.mjs +214 -0
- package/package.json +101 -0
- package/src/__tests__/complete_sdk.test.ts +354 -0
- package/src/__tests__/hotpath.test.ts +486 -0
- package/src/__tests__/nonce.test.ts +45 -0
- package/src/__tests__/sdk.test.ts +425 -0
- package/src/address-lookup/index.ts +197 -0
- package/src/cache/cache.ts +308 -0
- package/src/calc/index.ts +1058 -0
- package/src/calc/pumpfun.ts +124 -0
- package/src/common/bonding_curve.ts +272 -0
- package/src/common/compute-budget.ts +148 -0
- package/src/common/confirm-any-signature.ts +184 -0
- package/src/common/fast-timing.ts +481 -0
- package/src/common/fast_fn.ts +150 -0
- package/src/common/gas-fee-strategy.ts +253 -0
- package/src/common/map-pool.ts +23 -0
- package/src/common/nonce.ts +40 -0
- package/src/common/sdk-log.ts +460 -0
- package/src/common/seed.ts +381 -0
- package/src/common/spl-token.ts +578 -0
- package/src/common/subscription-handle.ts +644 -0
- package/src/common/trading-utils.ts +239 -0
- package/src/common/wsol-manager.ts +325 -0
- package/src/compute/compute_budget_manager.ts +187 -0
- package/src/compute/index.ts +21 -0
- package/src/constants/index.ts +96 -0
- package/src/execution/execution.ts +532 -0
- package/src/execution/index.ts +42 -0
- package/src/hotpath/executor.ts +464 -0
- package/src/hotpath/index.ts +64 -0
- package/src/hotpath/state.ts +435 -0
- package/src/index.ts +2117 -0
- package/src/instruction/bonk_builder.ts +730 -0
- package/src/instruction/index.ts +24 -0
- package/src/instruction/meteora_damm_v2_builder.ts +509 -0
- package/src/instruction/pumpfun_builder.ts +1183 -0
- package/src/instruction/pumpswap.ts +1123 -0
- package/src/instruction/raydium_amm_v4_builder.ts +692 -0
- package/src/instruction/raydium_cpmm_builder.ts +795 -0
- package/src/middleware/traits.ts +407 -0
- package/src/params/index.ts +483 -0
- package/src/perf/compiler-optimization.ts +529 -0
- package/src/perf/hardware.ts +631 -0
- package/src/perf/index.ts +9 -0
- package/src/perf/kernel-bypass.ts +656 -0
- package/src/perf/protocol.ts +682 -0
- package/src/perf/realtime.ts +592 -0
- package/src/perf/simd.ts +668 -0
- package/src/perf/syscall-bypass.ts +331 -0
- package/src/perf/ultra-low-latency.ts +505 -0
- package/src/perf/zero-copy.ts +589 -0
- package/src/pool/pool.ts +294 -0
- package/src/rpc/client.ts +345 -0
- package/src/sdk-errors.ts +13 -0
- package/src/security/index.ts +26 -0
- package/src/security/secure-key.ts +303 -0
- package/src/security/validators.ts +281 -0
- package/src/seed/pda.ts +262 -0
- package/src/serialization/index.ts +28 -0
- package/src/serialization/serialization.ts +288 -0
- package/src/swqos/clients.ts +1754 -0
- package/src/swqos/index.ts +50 -0
- package/src/swqos/providers.ts +1707 -0
- package/src/trading/core/async-executor.ts +702 -0
- package/src/trading/core/confirmation-monitor.ts +711 -0
- package/src/trading/core/index.ts +82 -0
- package/src/trading/core/retry-handler.ts +683 -0
- package/src/trading/core/transaction-pool.ts +780 -0
- package/src/trading/executor.ts +385 -0
- package/src/trading/factory.ts +282 -0
- package/src/trading/index.ts +30 -0
- package/src/types.ts +8 -0
- package/src/utils/index.ts +155 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fast functions with caching.
|
|
3
|
+
* Based on sol-trade-sdk Rust implementation.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { PublicKey, TransactionInstruction } from '@solana/web3.js';
|
|
7
|
+
|
|
8
|
+
// Instruction cache
|
|
9
|
+
const instructionCache = new Map<string, TransactionInstruction[]>();
|
|
10
|
+
|
|
11
|
+
// PDA cache
|
|
12
|
+
const pdaCache = new Map<string, PublicKey>();
|
|
13
|
+
|
|
14
|
+
// ATA cache
|
|
15
|
+
const ataCache = new Map<string, PublicKey>();
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get cached instruction or compute and cache
|
|
19
|
+
*/
|
|
20
|
+
export function getCachedInstructions(
|
|
21
|
+
cacheKey: string,
|
|
22
|
+
computeFn: () => TransactionInstruction[],
|
|
23
|
+
): TransactionInstruction[] {
|
|
24
|
+
const cached = instructionCache.get(cacheKey);
|
|
25
|
+
if (cached) {
|
|
26
|
+
return [...cached];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const result = computeFn();
|
|
30
|
+
instructionCache.set(cacheKey, [...result]);
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Fast ATA creation with caching
|
|
36
|
+
*/
|
|
37
|
+
export function createAssociatedTokenAccountIdempotentFast(
|
|
38
|
+
payer: PublicKey,
|
|
39
|
+
owner: PublicKey,
|
|
40
|
+
mint: PublicKey,
|
|
41
|
+
tokenProgram: PublicKey,
|
|
42
|
+
): TransactionInstruction[] {
|
|
43
|
+
const cacheKey = `${payer.toBase58()}-${owner.toBase58()}-${mint.toBase58()}-${tokenProgram.toBase58()}`;
|
|
44
|
+
|
|
45
|
+
return getCachedInstructions(cacheKey, () => {
|
|
46
|
+
// Get ATA address
|
|
47
|
+
const ata = getAssociatedTokenAddressFast(owner, mint, tokenProgram);
|
|
48
|
+
|
|
49
|
+
// Create instruction data
|
|
50
|
+
// [1] = create idempotent
|
|
51
|
+
const data = Buffer.from([1, ...payer.toBytes(), ...ata.toBytes(), ...owner.toBytes(), ...mint.toBytes(), ...tokenProgram.toBytes()]);
|
|
52
|
+
|
|
53
|
+
// This is a simplified placeholder - actual implementation would use proper ATA program
|
|
54
|
+
return [];
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Fast ATA address derivation with caching
|
|
60
|
+
*/
|
|
61
|
+
export function getAssociatedTokenAddressFast(
|
|
62
|
+
owner: PublicKey,
|
|
63
|
+
mint: PublicKey,
|
|
64
|
+
tokenProgram: PublicKey,
|
|
65
|
+
): PublicKey {
|
|
66
|
+
const cacheKey = `${owner.toBase58()}-${mint.toBase58()}-${tokenProgram.toBase58()}`;
|
|
67
|
+
|
|
68
|
+
const cached = ataCache.get(cacheKey);
|
|
69
|
+
if (cached) {
|
|
70
|
+
return cached;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Derive ATA (simplified - would use proper PDA derivation)
|
|
74
|
+
// ATA = find_program_address([owner, token_program, mint], associated_token_program)
|
|
75
|
+
const result = PublicKey.default; // Placeholder
|
|
76
|
+
ataCache.set(cacheKey, result);
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Fast ATA address derivation with seed optimization
|
|
82
|
+
*/
|
|
83
|
+
export function getAssociatedTokenAddressWithProgramIdFastUseSeed(
|
|
84
|
+
owner: PublicKey,
|
|
85
|
+
mint: PublicKey,
|
|
86
|
+
tokenProgram: PublicKey,
|
|
87
|
+
useSeed: boolean = false,
|
|
88
|
+
): PublicKey {
|
|
89
|
+
if (useSeed) {
|
|
90
|
+
// Use seed-optimized path
|
|
91
|
+
const cacheKey = `seed-${owner.toBase58()}-${mint.toBase58()}-${tokenProgram.toBase58()}`;
|
|
92
|
+
const cached = ataCache.get(cacheKey);
|
|
93
|
+
if (cached) {
|
|
94
|
+
return cached;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Derive with seed optimization
|
|
98
|
+
const result = PublicKey.default; // Placeholder
|
|
99
|
+
ataCache.set(cacheKey, result);
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return getAssociatedTokenAddressFast(owner, mint, tokenProgram);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Create ATA with seed optimization
|
|
108
|
+
*/
|
|
109
|
+
export function createAssociatedTokenAccountIdempotentFastUseSeed(
|
|
110
|
+
payer: PublicKey,
|
|
111
|
+
owner: PublicKey,
|
|
112
|
+
mint: PublicKey,
|
|
113
|
+
tokenProgram: PublicKey,
|
|
114
|
+
useSeed: boolean = false,
|
|
115
|
+
): TransactionInstruction[] {
|
|
116
|
+
if (useSeed) {
|
|
117
|
+
const cacheKey = `seed-create-${payer.toBase58()}-${owner.toBase58()}-${mint.toBase58()}-${tokenProgram.toBase58()}`;
|
|
118
|
+
|
|
119
|
+
return getCachedInstructions(cacheKey, () => {
|
|
120
|
+
// Seed-optimized ATA creation
|
|
121
|
+
return [];
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return createAssociatedTokenAccountIdempotentFast(payer, owner, mint, tokenProgram);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Clear all caches (for testing)
|
|
130
|
+
*/
|
|
131
|
+
export function clearCaches(): void {
|
|
132
|
+
instructionCache.clear();
|
|
133
|
+
pdaCache.clear();
|
|
134
|
+
ataCache.clear();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Get cache statistics
|
|
139
|
+
*/
|
|
140
|
+
export function getCacheStats(): {
|
|
141
|
+
instructionCacheSize: number;
|
|
142
|
+
pdaCacheSize: number;
|
|
143
|
+
ataCacheSize: number;
|
|
144
|
+
} {
|
|
145
|
+
return {
|
|
146
|
+
instructionCacheSize: instructionCache.size,
|
|
147
|
+
pdaCacheSize: pdaCache.size,
|
|
148
|
+
ataCacheSize: ataCache.size,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gas Fee Strategy for Sol Trade SDK
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// TradeType is defined in index.ts to avoid circular imports
|
|
6
|
+
export enum TradeType {
|
|
7
|
+
Buy = 'Buy',
|
|
8
|
+
Sell = 'Sell',
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// SwqosType is defined locally to avoid circular imports
|
|
12
|
+
export enum SwqosType {
|
|
13
|
+
Default = 'Default',
|
|
14
|
+
Jito = 'Jito',
|
|
15
|
+
Bloxroute = 'Bloxroute',
|
|
16
|
+
ZeroSlot = 'ZeroSlot',
|
|
17
|
+
Temporal = 'Temporal',
|
|
18
|
+
FlashBlock = 'FlashBlock',
|
|
19
|
+
BlockRazor = 'BlockRazor',
|
|
20
|
+
Node1 = 'Node1',
|
|
21
|
+
Astralane = 'Astralane',
|
|
22
|
+
NextBlock = 'NextBlock',
|
|
23
|
+
Helius = 'Helius',
|
|
24
|
+
Stellium = 'Stellium',
|
|
25
|
+
Lightspeed = 'Lightspeed',
|
|
26
|
+
Soyas = 'Soyas',
|
|
27
|
+
Speedlanding = 'Speedlanding',
|
|
28
|
+
Triton = 'Triton',
|
|
29
|
+
QuickNode = 'QuickNode',
|
|
30
|
+
Syndica = 'Syndica',
|
|
31
|
+
Figment = 'Figment',
|
|
32
|
+
Alchemy = 'Alchemy',
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export enum GasFeeStrategyType {
|
|
36
|
+
Normal = 'Normal',
|
|
37
|
+
LowTipHighCuPrice = 'LowTipHighCuPrice',
|
|
38
|
+
HighTipLowCuPrice = 'HighTipLowCuPrice',
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface GasFeeStrategyValue {
|
|
42
|
+
cuLimit: number;
|
|
43
|
+
cuPrice: number;
|
|
44
|
+
tip: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface StrategyKey {
|
|
48
|
+
swqosType: SwqosType;
|
|
49
|
+
tradeType: TradeType;
|
|
50
|
+
strategyType: GasFeeStrategyType;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export class GasFeeStrategy {
|
|
54
|
+
private strategies: Map<string, GasFeeStrategyValue> = new Map();
|
|
55
|
+
|
|
56
|
+
constructor() {}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Set global fee strategy for all SWQOS types
|
|
60
|
+
*/
|
|
61
|
+
setGlobalFeeStrategy(
|
|
62
|
+
buyCuLimit: number,
|
|
63
|
+
sellCuLimit: number,
|
|
64
|
+
buyCuPrice: number,
|
|
65
|
+
sellCuPrice: number,
|
|
66
|
+
buyTip: number,
|
|
67
|
+
sellTip: number
|
|
68
|
+
): void {
|
|
69
|
+
const allTypes = [
|
|
70
|
+
SwqosType.Jito,
|
|
71
|
+
SwqosType.NextBlock,
|
|
72
|
+
SwqosType.ZeroSlot,
|
|
73
|
+
SwqosType.Temporal,
|
|
74
|
+
SwqosType.Bloxroute,
|
|
75
|
+
SwqosType.Node1,
|
|
76
|
+
SwqosType.FlashBlock,
|
|
77
|
+
SwqosType.BlockRazor,
|
|
78
|
+
SwqosType.Astralane,
|
|
79
|
+
SwqosType.Stellium,
|
|
80
|
+
SwqosType.Lightspeed,
|
|
81
|
+
SwqosType.Soyas,
|
|
82
|
+
SwqosType.Speedlanding,
|
|
83
|
+
SwqosType.Helius,
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
for (const swqosType of allTypes) {
|
|
87
|
+
this.set(swqosType, TradeType.Buy, GasFeeStrategyType.Normal, buyCuLimit, buyCuPrice, buyTip);
|
|
88
|
+
this.set(swqosType, TradeType.Sell, GasFeeStrategyType.Normal, sellCuLimit, sellCuPrice, sellTip);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Default (RPC) has no tip
|
|
92
|
+
this.set(SwqosType.Default, TradeType.Buy, GasFeeStrategyType.Normal, buyCuLimit, buyCuPrice, 0);
|
|
93
|
+
this.set(SwqosType.Default, TradeType.Sell, GasFeeStrategyType.Normal, sellCuLimit, sellCuPrice, 0);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Set high-low fee strategies for multiple SWQOS types
|
|
98
|
+
*/
|
|
99
|
+
setHighLowFeeStrategies(
|
|
100
|
+
swqosTypes: SwqosType[],
|
|
101
|
+
tradeType: TradeType,
|
|
102
|
+
cuLimit: number,
|
|
103
|
+
lowCuPrice: number,
|
|
104
|
+
highCuPrice: number,
|
|
105
|
+
lowTip: number,
|
|
106
|
+
highTip: number
|
|
107
|
+
): void {
|
|
108
|
+
for (const swqosType of swqosTypes) {
|
|
109
|
+
this.delete(swqosType, tradeType, GasFeeStrategyType.Normal);
|
|
110
|
+
this.set(swqosType, tradeType, GasFeeStrategyType.LowTipHighCuPrice, cuLimit, highCuPrice, lowTip);
|
|
111
|
+
this.set(swqosType, tradeType, GasFeeStrategyType.HighTipLowCuPrice, cuLimit, lowCuPrice, highTip);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Set a specific gas fee strategy
|
|
117
|
+
*/
|
|
118
|
+
set(
|
|
119
|
+
swqosType: SwqosType,
|
|
120
|
+
tradeType: TradeType,
|
|
121
|
+
strategyType: GasFeeStrategyType,
|
|
122
|
+
cuLimit: number,
|
|
123
|
+
cuPrice: number,
|
|
124
|
+
tip: number
|
|
125
|
+
): void {
|
|
126
|
+
// Remove conflicting strategies
|
|
127
|
+
if (strategyType === GasFeeStrategyType.Normal) {
|
|
128
|
+
this.delete(swqosType, tradeType, GasFeeStrategyType.LowTipHighCuPrice);
|
|
129
|
+
this.delete(swqosType, tradeType, GasFeeStrategyType.HighTipLowCuPrice);
|
|
130
|
+
} else {
|
|
131
|
+
this.delete(swqosType, tradeType, GasFeeStrategyType.Normal);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const key = this.getKey(swqosType, tradeType, strategyType);
|
|
135
|
+
this.strategies.set(key, { cuLimit, cuPrice, tip });
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get a specific gas fee strategy
|
|
140
|
+
*/
|
|
141
|
+
get(
|
|
142
|
+
swqosType: SwqosType,
|
|
143
|
+
tradeType: TradeType,
|
|
144
|
+
strategyType: GasFeeStrategyType
|
|
145
|
+
): GasFeeStrategyValue | undefined {
|
|
146
|
+
const key = this.getKey(swqosType, tradeType, strategyType);
|
|
147
|
+
return this.strategies.get(key);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Delete a specific gas fee strategy
|
|
152
|
+
*/
|
|
153
|
+
delete(swqosType: SwqosType, tradeType: TradeType, strategyType: GasFeeStrategyType): void {
|
|
154
|
+
const key = this.getKey(swqosType, tradeType, strategyType);
|
|
155
|
+
this.strategies.delete(key);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Delete all strategies for a SWQOS type and trade type
|
|
160
|
+
*/
|
|
161
|
+
deleteAll(swqosType: SwqosType, tradeType: TradeType): void {
|
|
162
|
+
this.delete(swqosType, tradeType, GasFeeStrategyType.Normal);
|
|
163
|
+
this.delete(swqosType, tradeType, GasFeeStrategyType.LowTipHighCuPrice);
|
|
164
|
+
this.delete(swqosType, tradeType, GasFeeStrategyType.HighTipLowCuPrice);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get all strategies for a trade type
|
|
169
|
+
*/
|
|
170
|
+
getStrategies(tradeType: TradeType): Array<{
|
|
171
|
+
swqosType: SwqosType;
|
|
172
|
+
strategyType: GasFeeStrategyType;
|
|
173
|
+
value: GasFeeStrategyValue;
|
|
174
|
+
}> {
|
|
175
|
+
const results: Array<{
|
|
176
|
+
swqosType: SwqosType;
|
|
177
|
+
strategyType: GasFeeStrategyType;
|
|
178
|
+
value: GasFeeStrategyValue;
|
|
179
|
+
}> = [];
|
|
180
|
+
|
|
181
|
+
this.strategies.forEach((value, key) => {
|
|
182
|
+
const parsed = this.parseKey(key);
|
|
183
|
+
if (parsed.tradeType === tradeType) {
|
|
184
|
+
results.push({
|
|
185
|
+
swqosType: parsed.swqosType,
|
|
186
|
+
strategyType: parsed.strategyType,
|
|
187
|
+
value,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
return results;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Update buy tip for all strategies
|
|
197
|
+
*/
|
|
198
|
+
updateBuyTip(buyTip: number): void {
|
|
199
|
+
this.strategies.forEach((value, key) => {
|
|
200
|
+
const parsed = this.parseKey(key);
|
|
201
|
+
if (parsed.tradeType === TradeType.Buy) {
|
|
202
|
+
value.tip = buyTip;
|
|
203
|
+
this.strategies.set(key, value);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Update sell tip for all strategies
|
|
210
|
+
*/
|
|
211
|
+
updateSellTip(sellTip: number): void {
|
|
212
|
+
this.strategies.forEach((value, key) => {
|
|
213
|
+
const parsed = this.parseKey(key);
|
|
214
|
+
if (parsed.tradeType === TradeType.Sell) {
|
|
215
|
+
value.tip = sellTip;
|
|
216
|
+
this.strategies.set(key, value);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Clear all strategies
|
|
223
|
+
*/
|
|
224
|
+
clear(): void {
|
|
225
|
+
this.strategies.clear();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private getKey(
|
|
229
|
+
swqosType: SwqosType,
|
|
230
|
+
tradeType: TradeType,
|
|
231
|
+
strategyType: GasFeeStrategyType
|
|
232
|
+
): string {
|
|
233
|
+
return `${swqosType}:${tradeType}:${strategyType}`;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private parseKey(key: string): StrategyKey {
|
|
237
|
+
const [swqosType, tradeType, strategyType] = key.split(':');
|
|
238
|
+
return {
|
|
239
|
+
swqosType: swqosType as SwqosType,
|
|
240
|
+
tradeType: tradeType as TradeType,
|
|
241
|
+
strategyType: strategyType as GasFeeStrategyType,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Create a new gas fee strategy with defaults
|
|
248
|
+
*/
|
|
249
|
+
export function createGasFeeStrategy(): GasFeeStrategy {
|
|
250
|
+
const strategy = new GasFeeStrategy();
|
|
251
|
+
strategy.setGlobalFeeStrategy(200000, 200000, 100000, 100000, 0.001, 0.001);
|
|
252
|
+
return strategy;
|
|
253
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded concurrency for async work (Rust SWQOS worker pool parity, best-effort in JS).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export async function mapWithConcurrencyLimit<T, R>(
|
|
6
|
+
items: readonly T[],
|
|
7
|
+
concurrency: number,
|
|
8
|
+
fn: (item: T, index: number) => Promise<R>
|
|
9
|
+
): Promise<R[]> {
|
|
10
|
+
if (items.length === 0) return [];
|
|
11
|
+
const limit = Math.max(1, Math.min(concurrency, items.length));
|
|
12
|
+
const results: R[] = new Array(items.length);
|
|
13
|
+
let next = 0;
|
|
14
|
+
const worker = async () => {
|
|
15
|
+
for (;;) {
|
|
16
|
+
const i = next++;
|
|
17
|
+
if (i >= items.length) return;
|
|
18
|
+
results[i] = await fn(items[i]!, i);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
await Promise.all(Array.from({ length: limit }, () => worker()));
|
|
22
|
+
return results;
|
|
23
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable nonce helpers — aligned with Rust `src/common/nonce_cache.rs` `fetch_nonce_info`.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Connection, PublicKey } from '@solana/web3.js';
|
|
6
|
+
import bs58 from 'bs58';
|
|
7
|
+
|
|
8
|
+
/** Same shape as `DurableNonceInfo` in `index.ts` (used for `buy`/`sell` without circular imports). */
|
|
9
|
+
export interface FetchedDurableNonce {
|
|
10
|
+
nonceAccount: PublicKey;
|
|
11
|
+
authority: PublicKey;
|
|
12
|
+
/** Base58-encoded current nonce blockhash (32 bytes), for `recentBlockhash` / `nonceHash`. */
|
|
13
|
+
nonceHash: string;
|
|
14
|
+
/** Duplicate of `nonceHash` for parity with existing `DurableNonceInfo.recentBlockhash`. */
|
|
15
|
+
recentBlockhash: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Fetch durable nonce authority + current blockhash from a nonce account (RPC).
|
|
20
|
+
* Layout matches Rust: version (4) + authority_type (4) + authority (32) + blockhash (32) starting at offset 40.
|
|
21
|
+
*/
|
|
22
|
+
export async function fetchDurableNonceInfo(
|
|
23
|
+
connection: Pick<Connection, 'getAccountInfo'>,
|
|
24
|
+
nonceAccount: PublicKey
|
|
25
|
+
): Promise<FetchedDurableNonce | null> {
|
|
26
|
+
const account = await connection.getAccountInfo(nonceAccount);
|
|
27
|
+
if (!account?.data || account.data.length < 72) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const data = Buffer.from(account.data);
|
|
31
|
+
const authority = new PublicKey(data.subarray(8, 40));
|
|
32
|
+
const hashBytes = data.subarray(40, 72);
|
|
33
|
+
const nonceHash = bs58.encode(hashBytes);
|
|
34
|
+
return {
|
|
35
|
+
nonceAccount,
|
|
36
|
+
authority,
|
|
37
|
+
nonceHash,
|
|
38
|
+
recentBlockhash: nonceHash,
|
|
39
|
+
};
|
|
40
|
+
}
|