four-flap-meme-sdk 1.5.55 → 1.5.56
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/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/sol/constants.d.ts +150 -0
- package/dist/sol/constants.js +188 -0
- package/dist/sol/dex/blockrazor/client.d.ts +51 -0
- package/dist/sol/dex/blockrazor/client.js +96 -0
- package/dist/sol/dex/blockrazor/constants.d.ts +34 -0
- package/dist/sol/dex/blockrazor/constants.js +55 -0
- package/dist/sol/dex/blockrazor/geyser.d.ts +128 -0
- package/dist/sol/dex/blockrazor/geyser.js +530 -0
- package/dist/sol/dex/blockrazor/index.d.ts +18 -0
- package/dist/sol/dex/blockrazor/index.js +23 -0
- package/dist/sol/dex/blockrazor/send.d.ts +135 -0
- package/dist/sol/dex/blockrazor/send.js +254 -0
- package/dist/sol/dex/blockrazor/types.d.ts +191 -0
- package/dist/sol/dex/blockrazor/types.js +5 -0
- package/dist/sol/dex/index.d.ts +10 -0
- package/dist/sol/dex/index.js +16 -0
- package/dist/sol/dex/jup/client.d.ts +33 -0
- package/dist/sol/dex/jup/client.js +110 -0
- package/dist/sol/dex/jup/index.d.ts +16 -0
- package/dist/sol/dex/jup/index.js +148 -0
- package/dist/sol/dex/jup/legacy.d.ts +623 -0
- package/dist/sol/dex/jup/legacy.js +416 -0
- package/dist/sol/dex/jup/lend.d.ts +640 -0
- package/dist/sol/dex/jup/lend.js +603 -0
- package/dist/sol/dex/jup/portfolio.d.ts +362 -0
- package/dist/sol/dex/jup/portfolio.js +367 -0
- package/dist/sol/dex/jup/price.d.ts +173 -0
- package/dist/sol/dex/jup/price.js +220 -0
- package/dist/sol/dex/jup/recurring.d.ts +437 -0
- package/dist/sol/dex/jup/recurring.js +320 -0
- package/dist/sol/dex/jup/send.d.ts +282 -0
- package/dist/sol/dex/jup/send.js +295 -0
- package/dist/sol/dex/jup/studio.d.ts +457 -0
- package/dist/sol/dex/jup/studio.js +488 -0
- package/dist/sol/dex/jup/tokens.d.ts +767 -0
- package/dist/sol/dex/jup/tokens.js +697 -0
- package/dist/sol/dex/jup/trigger.d.ts +511 -0
- package/dist/sol/dex/jup/trigger.js +397 -0
- package/dist/sol/dex/jup/types.d.ts +433 -0
- package/dist/sol/dex/jup/types.js +5 -0
- package/dist/sol/dex/jup/ultra.d.ts +646 -0
- package/dist/sol/dex/jup/ultra.js +853 -0
- package/dist/sol/dex/meteora/client.d.ts +76 -0
- package/dist/sol/dex/meteora/client.js +219 -0
- package/dist/sol/dex/meteora/damm-v1-bundle.d.ts +61 -0
- package/dist/sol/dex/meteora/damm-v1-bundle.js +112 -0
- package/dist/sol/dex/meteora/damm-v1.d.ts +118 -0
- package/dist/sol/dex/meteora/damm-v1.js +315 -0
- package/dist/sol/dex/meteora/damm-v2-bundle.d.ts +82 -0
- package/dist/sol/dex/meteora/damm-v2-bundle.js +242 -0
- package/dist/sol/dex/meteora/damm-v2.d.ts +172 -0
- package/dist/sol/dex/meteora/damm-v2.js +632 -0
- package/dist/sol/dex/meteora/dbc-bundle.d.ts +123 -0
- package/dist/sol/dex/meteora/dbc-bundle.js +304 -0
- package/dist/sol/dex/meteora/dbc.d.ts +192 -0
- package/dist/sol/dex/meteora/dbc.js +619 -0
- package/dist/sol/dex/meteora/dlmm-bundle.d.ts +39 -0
- package/dist/sol/dex/meteora/dlmm-bundle.js +189 -0
- package/dist/sol/dex/meteora/dlmm.d.ts +157 -0
- package/dist/sol/dex/meteora/dlmm.js +671 -0
- package/dist/sol/dex/meteora/index.d.ts +25 -0
- package/dist/sol/dex/meteora/index.js +65 -0
- package/dist/sol/dex/meteora/types.d.ts +787 -0
- package/dist/sol/dex/meteora/types.js +110 -0
- package/dist/sol/dex/orca/index.d.ts +10 -0
- package/dist/sol/dex/orca/index.js +16 -0
- package/dist/sol/dex/orca/orca-bundle.d.ts +41 -0
- package/dist/sol/dex/orca/orca-bundle.js +173 -0
- package/dist/sol/dex/orca/orca.d.ts +65 -0
- package/dist/sol/dex/orca/orca.js +474 -0
- package/dist/sol/dex/orca/types.d.ts +263 -0
- package/dist/sol/dex/orca/types.js +38 -0
- package/dist/sol/dex/orca/wavebreak-bundle.d.ts +34 -0
- package/dist/sol/dex/orca/wavebreak-bundle.js +198 -0
- package/dist/sol/dex/orca/wavebreak-types.d.ts +227 -0
- package/dist/sol/dex/orca/wavebreak-types.js +23 -0
- package/dist/sol/dex/orca/wavebreak.d.ts +78 -0
- package/dist/sol/dex/orca/wavebreak.js +497 -0
- package/dist/sol/dex/pump/index.d.ts +9 -0
- package/dist/sol/dex/pump/index.js +14 -0
- package/dist/sol/dex/pump/pump-bundle.d.ts +92 -0
- package/dist/sol/dex/pump/pump-bundle.js +383 -0
- package/dist/sol/dex/pump/pump-swap-bundle.d.ts +103 -0
- package/dist/sol/dex/pump/pump-swap-bundle.js +380 -0
- package/dist/sol/dex/pump/pump-swap.d.ts +46 -0
- package/dist/sol/dex/pump/pump-swap.js +199 -0
- package/dist/sol/dex/pump/pump.d.ts +35 -0
- package/dist/sol/dex/pump/pump.js +352 -0
- package/dist/sol/dex/pump/types.d.ts +215 -0
- package/dist/sol/dex/pump/types.js +5 -0
- package/dist/sol/dex/raydium/index.d.ts +8 -0
- package/dist/sol/dex/raydium/index.js +12 -0
- package/dist/sol/dex/raydium/launchlab.d.ts +68 -0
- package/dist/sol/dex/raydium/launchlab.js +210 -0
- package/dist/sol/dex/raydium/raydium-bundle.d.ts +64 -0
- package/dist/sol/dex/raydium/raydium-bundle.js +324 -0
- package/dist/sol/dex/raydium/raydium.d.ts +40 -0
- package/dist/sol/dex/raydium/raydium.js +366 -0
- package/dist/sol/dex/raydium/types.d.ts +240 -0
- package/dist/sol/dex/raydium/types.js +5 -0
- package/dist/sol/index.d.ts +11 -0
- package/dist/sol/index.js +18 -0
- package/dist/sol/jito/bundle.d.ts +90 -0
- package/dist/sol/jito/bundle.js +263 -0
- package/dist/sol/jito/index.d.ts +7 -0
- package/dist/sol/jito/index.js +7 -0
- package/dist/sol/jito/tip.d.ts +51 -0
- package/dist/sol/jito/tip.js +83 -0
- package/dist/sol/jito/types.d.ts +100 -0
- package/dist/sol/jito/types.js +5 -0
- package/dist/sol/nozomi/client.d.ts +63 -0
- package/dist/sol/nozomi/client.js +222 -0
- package/dist/sol/nozomi/index.d.ts +8 -0
- package/dist/sol/nozomi/index.js +8 -0
- package/dist/sol/nozomi/tip.d.ts +50 -0
- package/dist/sol/nozomi/tip.js +80 -0
- package/dist/sol/nozomi/types.d.ts +96 -0
- package/dist/sol/nozomi/types.js +5 -0
- package/dist/sol/token/create-complete.d.ts +115 -0
- package/dist/sol/token/create-complete.js +235 -0
- package/dist/sol/token/create-token.d.ts +57 -0
- package/dist/sol/token/create-token.js +230 -0
- package/dist/sol/token/index.d.ts +9 -0
- package/dist/sol/token/index.js +14 -0
- package/dist/sol/token/metadata-upload.d.ts +86 -0
- package/dist/sol/token/metadata-upload.js +173 -0
- package/dist/sol/token/metadata.d.ts +92 -0
- package/dist/sol/token/metadata.js +274 -0
- package/dist/sol/token/types.d.ts +153 -0
- package/dist/sol/token/types.js +5 -0
- package/dist/sol/types.d.ts +176 -0
- package/dist/sol/types.js +7 -0
- package/dist/sol/utils/balance.d.ts +160 -0
- package/dist/sol/utils/balance.js +638 -0
- package/dist/sol/utils/connection.d.ts +78 -0
- package/dist/sol/utils/connection.js +168 -0
- package/dist/sol/utils/index.d.ts +9 -0
- package/dist/sol/utils/index.js +9 -0
- package/dist/sol/utils/lp-inspect.d.ts +75 -0
- package/dist/sol/utils/lp-inspect.js +235 -0
- package/dist/sol/utils/transfer.d.ts +196 -0
- package/dist/sol/utils/transfer.js +307 -0
- package/dist/sol/utils/wallet.d.ts +107 -0
- package/dist/sol/utils/wallet.js +210 -0
- package/package.json +44 -5
- package/README.zh-CN.pdf +0 -0
- package/dist/flap/portal-bundle-merkle/encryption.d.ts +0 -16
- package/dist/flap/portal-bundle-merkle/encryption.js +0 -146
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jupiter Legacy Swap API
|
|
3
|
+
* @module sol/dex/jup/legacy
|
|
4
|
+
*
|
|
5
|
+
* Legacy Swap API 提供更多自定义选项的交易路由
|
|
6
|
+
* 文档: https://docs.jup.ag/docs/apis/swap-api
|
|
7
|
+
*/
|
|
8
|
+
import { jupGet, jupPost } from './client.js';
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Quote - 获取报价
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* 获取 Legacy Swap 报价
|
|
14
|
+
*
|
|
15
|
+
* Legacy API 提供更多自定义选项,适合需要精细控制路由的场景。
|
|
16
|
+
*
|
|
17
|
+
* @param params 报价参数
|
|
18
|
+
* @param config Jupiter 配置
|
|
19
|
+
* @returns Quote 响应
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import { Sol } from 'four-flap-meme-sdk'
|
|
24
|
+
*
|
|
25
|
+
* Sol.setJupiterConfig({ apiKey: 'your-api-key' })
|
|
26
|
+
*
|
|
27
|
+
* // 基础报价
|
|
28
|
+
* const quote = await Sol.getLegacyQuote({
|
|
29
|
+
* inputMint: 'So11111111111111111111111111111111111111112',
|
|
30
|
+
* outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
31
|
+
* amount: '100000000', // 0.1 SOL
|
|
32
|
+
* })
|
|
33
|
+
*
|
|
34
|
+
* console.log('输出数量:', quote.outAmount)
|
|
35
|
+
* console.log('最小输出:', quote.otherAmountThreshold)
|
|
36
|
+
* console.log('价格影响:', quote.priceImpactPct)
|
|
37
|
+
* console.log('路由:', quote.routePlan.map(r => r.swapInfo.label).join(' -> '))
|
|
38
|
+
*
|
|
39
|
+
* // 高级选项
|
|
40
|
+
* const advancedQuote = await Sol.getLegacyQuote({
|
|
41
|
+
* inputMint: 'So11111111111111111111111111111111111111112',
|
|
42
|
+
* outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
43
|
+
* amount: '100000000',
|
|
44
|
+
* slippageBps: 100, // 1% 滑点
|
|
45
|
+
* dexes: ['Raydium', 'Orca V2'], // 只用这些 DEX
|
|
46
|
+
* onlyDirectRoutes: true, // 单跳
|
|
47
|
+
* })
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export async function getLegacyQuote(params, config) {
|
|
51
|
+
const queryParams = {
|
|
52
|
+
inputMint: params.inputMint,
|
|
53
|
+
outputMint: params.outputMint,
|
|
54
|
+
amount: String(params.amount),
|
|
55
|
+
slippageBps: params.slippageBps,
|
|
56
|
+
swapMode: params.swapMode,
|
|
57
|
+
restrictIntermediateTokens: params.restrictIntermediateTokens,
|
|
58
|
+
onlyDirectRoutes: params.onlyDirectRoutes,
|
|
59
|
+
asLegacyTransaction: params.asLegacyTransaction,
|
|
60
|
+
platformFeeBps: params.platformFeeBps,
|
|
61
|
+
maxAccounts: params.maxAccounts,
|
|
62
|
+
instructionVersion: params.instructionVersion,
|
|
63
|
+
dynamicSlippage: params.dynamicSlippage,
|
|
64
|
+
};
|
|
65
|
+
// 处理数组参数
|
|
66
|
+
if (params.dexes?.length) {
|
|
67
|
+
queryParams.dexes = params.dexes.join(',');
|
|
68
|
+
}
|
|
69
|
+
if (params.excludeDexes?.length) {
|
|
70
|
+
queryParams.excludeDexes = params.excludeDexes.join(',');
|
|
71
|
+
}
|
|
72
|
+
return jupGet('/swap/v1/quote', queryParams, config);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 简化的 Legacy 报价获取
|
|
76
|
+
*
|
|
77
|
+
* @param inputMint 输入代币 Mint
|
|
78
|
+
* @param outputMint 输出代币 Mint
|
|
79
|
+
* @param amount 数量
|
|
80
|
+
* @param slippageBps 滑点 BPS (默认: 50)
|
|
81
|
+
* @param config Jupiter 配置
|
|
82
|
+
* @returns Quote 响应
|
|
83
|
+
*/
|
|
84
|
+
export async function getLegacyQuoteSimple(inputMint, outputMint, amount, slippageBps = 50, config) {
|
|
85
|
+
return getLegacyQuote({
|
|
86
|
+
inputMint,
|
|
87
|
+
outputMint,
|
|
88
|
+
amount,
|
|
89
|
+
slippageBps,
|
|
90
|
+
}, config);
|
|
91
|
+
}
|
|
92
|
+
// ============================================================================
|
|
93
|
+
// Swap - 构建交易
|
|
94
|
+
// ============================================================================
|
|
95
|
+
/**
|
|
96
|
+
* 构建 Legacy Swap 交易
|
|
97
|
+
*
|
|
98
|
+
* @param params Swap 参数
|
|
99
|
+
* @param config Jupiter 配置
|
|
100
|
+
* @returns Swap 响应(包含未签名交易)
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* // 1. 获取报价
|
|
105
|
+
* const quote = await Sol.getLegacyQuote({
|
|
106
|
+
* inputMint: 'So11111111111111111111111111111111111111112',
|
|
107
|
+
* outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
108
|
+
* amount: '100000000',
|
|
109
|
+
* })
|
|
110
|
+
*
|
|
111
|
+
* // 2. 构建交易
|
|
112
|
+
* const swap = await Sol.buildLegacySwap({
|
|
113
|
+
* quoteResponse: quote,
|
|
114
|
+
* userPublicKey: wallet.publicKey.toBase58(),
|
|
115
|
+
* })
|
|
116
|
+
*
|
|
117
|
+
* // 3. 签名并发送
|
|
118
|
+
* const tx = VersionedTransaction.deserialize(
|
|
119
|
+
* Buffer.from(swap.swapTransaction, 'base64')
|
|
120
|
+
* )
|
|
121
|
+
* tx.sign([wallet])
|
|
122
|
+
* const signature = await connection.sendTransaction(tx)
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export async function buildLegacySwap(params, config) {
|
|
126
|
+
return jupPost('/swap/v1/swap', params, config);
|
|
127
|
+
}
|
|
128
|
+
// ============================================================================
|
|
129
|
+
// Swap Instructions - 获取分解指令
|
|
130
|
+
// ============================================================================
|
|
131
|
+
/**
|
|
132
|
+
* 获取 Swap 分解指令
|
|
133
|
+
*
|
|
134
|
+
* 返回分解的指令而非完整交易,允许自定义组装交易。
|
|
135
|
+
* 适用于需要同时添加优先费和 Jito tip 等高级场景。
|
|
136
|
+
*
|
|
137
|
+
* @param params Swap 参数 (与 buildLegacySwap 相同)
|
|
138
|
+
* @param config Jupiter 配置
|
|
139
|
+
* @returns 分解的指令
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* import {
|
|
144
|
+
* TransactionMessage,
|
|
145
|
+
* VersionedTransaction,
|
|
146
|
+
* AddressLookupTableAccount
|
|
147
|
+
* } from '@solana/web3.js'
|
|
148
|
+
*
|
|
149
|
+
* // 1. 获取报价
|
|
150
|
+
* const quote = await Sol.getLegacyQuote({
|
|
151
|
+
* inputMint: 'So11111111111111111111111111111111111111112',
|
|
152
|
+
* outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
153
|
+
* amount: '100000000',
|
|
154
|
+
* })
|
|
155
|
+
*
|
|
156
|
+
* // 2. 获取分解指令
|
|
157
|
+
* const instructions = await Sol.getLegacySwapInstructions({
|
|
158
|
+
* userPublicKey: wallet.publicKey.toBase58(),
|
|
159
|
+
* quoteResponse: quote,
|
|
160
|
+
* prioritizationFeeLamports: {
|
|
161
|
+
* jitoTipLamports: 10000, // 添加 Jito tip
|
|
162
|
+
* }
|
|
163
|
+
* })
|
|
164
|
+
*
|
|
165
|
+
* // 3. 获取 Address Lookup Tables
|
|
166
|
+
* const lookupTables = await Promise.all(
|
|
167
|
+
* instructions.addressLookupTableAddresses.map(addr =>
|
|
168
|
+
* connection.getAddressLookupTable(new PublicKey(addr))
|
|
169
|
+
* )
|
|
170
|
+
* )
|
|
171
|
+
*
|
|
172
|
+
* // 4. 反序列化指令
|
|
173
|
+
* const allInstructions = [
|
|
174
|
+
* ...instructions.computeBudgetInstructions,
|
|
175
|
+
* ...instructions.setupInstructions,
|
|
176
|
+
* instructions.swapInstruction,
|
|
177
|
+
* ...(instructions.cleanupInstruction ? [instructions.cleanupInstruction] : []),
|
|
178
|
+
* ...instructions.otherInstructions, // Jito tip 指令在这里
|
|
179
|
+
* ].map(ix => deserializeInstruction(ix))
|
|
180
|
+
*
|
|
181
|
+
* // 5. 构建版本化交易
|
|
182
|
+
* const messageV0 = new TransactionMessage({
|
|
183
|
+
* payerKey: wallet.publicKey,
|
|
184
|
+
* recentBlockhash: blockhash,
|
|
185
|
+
* instructions: allInstructions,
|
|
186
|
+
* }).compileToV0Message(lookupTables)
|
|
187
|
+
*
|
|
188
|
+
* const tx = new VersionedTransaction(messageV0)
|
|
189
|
+
* tx.sign([wallet])
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
export async function getLegacySwapInstructions(params, config) {
|
|
193
|
+
return jupPost('/swap/v1/swap-instructions', params, config);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* 获取所有支持的 DEX 及其 Program ID
|
|
197
|
+
*
|
|
198
|
+
* 返回 Program ID 到 DEX 标签的映射。
|
|
199
|
+
* 可用于 /quote 的 dexes 和 excludeDexes 参数。
|
|
200
|
+
*
|
|
201
|
+
* @param config Jupiter 配置
|
|
202
|
+
* @returns Program ID 到标签的映射
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* const dexMap = await Sol.getProgramIdToLabel()
|
|
207
|
+
*
|
|
208
|
+
* // 查看所有 DEX
|
|
209
|
+
* Object.entries(dexMap).forEach(([programId, label]) => {
|
|
210
|
+
* console.log(`${label}: ${programId}`)
|
|
211
|
+
* })
|
|
212
|
+
*
|
|
213
|
+
* // 常见 DEX:
|
|
214
|
+
* // Raydium: 675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8
|
|
215
|
+
* // Raydium CLMM: CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK
|
|
216
|
+
* // Orca V2: 9W959DqEETiGZocYWCQPaJ6sBmUzgfxXfqGeTEdp3aQP
|
|
217
|
+
* // Whirlpool: whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc
|
|
218
|
+
* // Meteora: Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB
|
|
219
|
+
* // Meteora DLMM: LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo
|
|
220
|
+
* // Pump.fun: 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
export async function getProgramIdToLabel(config) {
|
|
224
|
+
return jupGet('/swap/v1/program-id-to-label', {}, config);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* 获取所有支持的 DEX 标签列表
|
|
228
|
+
*
|
|
229
|
+
* @param config Jupiter 配置
|
|
230
|
+
* @returns DEX 标签数组
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```typescript
|
|
234
|
+
* const labels = await Sol.getAllDexLabels()
|
|
235
|
+
* // ['Raydium', 'Raydium CLMM', 'Orca V2', 'Whirlpool', ...]
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
export async function getAllDexLabels(config) {
|
|
239
|
+
const map = await getProgramIdToLabel(config);
|
|
240
|
+
return [...new Set(Object.values(map))].sort();
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* 通过标签获取 Program ID
|
|
244
|
+
*
|
|
245
|
+
* @param label DEX 标签
|
|
246
|
+
* @param config Jupiter 配置
|
|
247
|
+
* @returns Program ID 或 null
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```typescript
|
|
251
|
+
* const raydiumId = await Sol.getProgramIdByLabel('Raydium')
|
|
252
|
+
* // '675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8'
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
export async function getProgramIdByLabel(label, config) {
|
|
256
|
+
const map = await getProgramIdToLabel(config);
|
|
257
|
+
for (const [programId, dexLabel] of Object.entries(map)) {
|
|
258
|
+
if (dexLabel === label) {
|
|
259
|
+
return programId;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* 通过 Program ID 获取 DEX 标签
|
|
266
|
+
*
|
|
267
|
+
* @param programId Program ID
|
|
268
|
+
* @param config Jupiter 配置
|
|
269
|
+
* @returns DEX 标签或 null
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ```typescript
|
|
273
|
+
* const label = await Sol.getLabelByProgramId(
|
|
274
|
+
* '675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8'
|
|
275
|
+
* )
|
|
276
|
+
* // 'Raydium'
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
279
|
+
export async function getLabelByProgramId(programId, config) {
|
|
280
|
+
const map = await getProgramIdToLabel(config);
|
|
281
|
+
return map[programId] || null;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* 搜索 DEX
|
|
285
|
+
*
|
|
286
|
+
* @param keyword 搜索关键词(不区分大小写)
|
|
287
|
+
* @param config Jupiter 配置
|
|
288
|
+
* @returns 匹配的 { programId, label } 数组
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```typescript
|
|
292
|
+
* const results = await Sol.searchDex('raydium')
|
|
293
|
+
* // [
|
|
294
|
+
* // { programId: '675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8', label: 'Raydium' },
|
|
295
|
+
* // { programId: 'CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK', label: 'Raydium CLMM' },
|
|
296
|
+
* // { programId: 'CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C', label: 'Raydium CP' },
|
|
297
|
+
* // ]
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
export async function searchDex(keyword, config) {
|
|
301
|
+
const map = await getProgramIdToLabel(config);
|
|
302
|
+
const lowerKeyword = keyword.toLowerCase();
|
|
303
|
+
return Object.entries(map)
|
|
304
|
+
.filter(([, label]) => label.toLowerCase().includes(lowerKeyword))
|
|
305
|
+
.map(([programId, label]) => ({ programId, label }));
|
|
306
|
+
}
|
|
307
|
+
// ============================================================================
|
|
308
|
+
// 便捷方法
|
|
309
|
+
// ============================================================================
|
|
310
|
+
/**
|
|
311
|
+
* 获取路由标签
|
|
312
|
+
*
|
|
313
|
+
* @param quote Quote 响应
|
|
314
|
+
* @returns 路由标签数组
|
|
315
|
+
*/
|
|
316
|
+
export function getRouteLabels(quote) {
|
|
317
|
+
return quote.routePlan
|
|
318
|
+
.map(r => r.swapInfo.label)
|
|
319
|
+
.filter((label) => !!label);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* 计算路由跳数
|
|
323
|
+
*
|
|
324
|
+
* @param quote Quote 响应
|
|
325
|
+
* @returns 跳数
|
|
326
|
+
*/
|
|
327
|
+
export function getRouteHops(quote) {
|
|
328
|
+
return quote.routePlan.length;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* 获取报价摘要
|
|
332
|
+
*
|
|
333
|
+
* @param quote Quote 响应
|
|
334
|
+
* @returns 报价摘要
|
|
335
|
+
*/
|
|
336
|
+
export function getQuoteSummary(quote) {
|
|
337
|
+
return {
|
|
338
|
+
inputMint: quote.inputMint,
|
|
339
|
+
outputMint: quote.outputMint,
|
|
340
|
+
inAmount: quote.inAmount,
|
|
341
|
+
outAmount: quote.outAmount,
|
|
342
|
+
minOutAmount: quote.otherAmountThreshold,
|
|
343
|
+
priceImpact: parseFloat(quote.priceImpactPct),
|
|
344
|
+
slippageBps: quote.slippageBps,
|
|
345
|
+
route: getRouteLabels(quote).join(' → '),
|
|
346
|
+
hops: getRouteHops(quote),
|
|
347
|
+
usdValue: quote.swapUsdValue ? parseFloat(quote.swapUsdValue) : null,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* 比较多个报价
|
|
352
|
+
*
|
|
353
|
+
* @param quotes Quote 响应数组
|
|
354
|
+
* @returns 排序后的报价(输出最多的在前)
|
|
355
|
+
*/
|
|
356
|
+
export function compareQuotes(quotes) {
|
|
357
|
+
return [...quotes].sort((a, b) => {
|
|
358
|
+
const outA = BigInt(a.outAmount);
|
|
359
|
+
const outB = BigInt(b.outAmount);
|
|
360
|
+
if (outB > outA)
|
|
361
|
+
return 1;
|
|
362
|
+
if (outB < outA)
|
|
363
|
+
return -1;
|
|
364
|
+
return 0;
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* 获取最佳报价
|
|
369
|
+
*
|
|
370
|
+
* 比较不同 DEX 组合的报价,返回输出最多的
|
|
371
|
+
*
|
|
372
|
+
* @param inputMint 输入代币 Mint
|
|
373
|
+
* @param outputMint 输出代币 Mint
|
|
374
|
+
* @param amount 数量
|
|
375
|
+
* @param options 选项
|
|
376
|
+
* @param config Jupiter 配置
|
|
377
|
+
* @returns 最佳报价
|
|
378
|
+
*/
|
|
379
|
+
export async function getBestLegacyQuote(inputMint, outputMint, amount, options, config) {
|
|
380
|
+
const slippageBps = options?.slippageBps ?? 50;
|
|
381
|
+
// 获取普通报价
|
|
382
|
+
const normalQuote = await getLegacyQuote({
|
|
383
|
+
inputMint,
|
|
384
|
+
outputMint,
|
|
385
|
+
amount,
|
|
386
|
+
slippageBps,
|
|
387
|
+
}, config);
|
|
388
|
+
let directQuote = null;
|
|
389
|
+
let directSavings = null;
|
|
390
|
+
// 可选:比较直接路由
|
|
391
|
+
if (options?.compareDirectRoute) {
|
|
392
|
+
try {
|
|
393
|
+
directQuote = await getLegacyQuote({
|
|
394
|
+
inputMint,
|
|
395
|
+
outputMint,
|
|
396
|
+
amount,
|
|
397
|
+
slippageBps,
|
|
398
|
+
onlyDirectRoutes: true,
|
|
399
|
+
}, config);
|
|
400
|
+
// 计算差异
|
|
401
|
+
const normalOut = BigInt(normalQuote.outAmount);
|
|
402
|
+
const directOut = BigInt(directQuote.outAmount);
|
|
403
|
+
if (normalOut > directOut) {
|
|
404
|
+
directSavings = (normalOut - directOut).toString();
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
catch {
|
|
408
|
+
// 直接路由可能不可用
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return {
|
|
412
|
+
best: normalQuote,
|
|
413
|
+
direct: directQuote,
|
|
414
|
+
directSavings,
|
|
415
|
+
};
|
|
416
|
+
}
|