@shogun-sdk/intents-sdk 1.2.5 → 1.2.6-test

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +3 -19
  2. package/dist/esm/chains.js +3 -0
  3. package/dist/esm/chains.js.map +1 -1
  4. package/dist/esm/constants.js +9 -0
  5. package/dist/esm/constants.js.map +1 -1
  6. package/dist/esm/core/evm/chain-provider.js +2 -1
  7. package/dist/esm/core/evm/chain-provider.js.map +1 -1
  8. package/dist/esm/core/evm/cross-chain-limit-order.js +1 -1
  9. package/dist/esm/core/evm/cross-chain-limit-order.js.map +1 -1
  10. package/dist/esm/core/evm/permit2-signature-transfer.js +15 -0
  11. package/dist/esm/core/evm/permit2-signature-transfer.js.map +1 -0
  12. package/dist/esm/core/evm/single-chain-dca-order.js +1 -1
  13. package/dist/esm/core/evm/single-chain-dca-order.js.map +1 -1
  14. package/dist/esm/core/evm/single-chain-limit-order.js +1 -1
  15. package/dist/esm/core/evm/single-chain-limit-order.js.map +1 -1
  16. package/dist/esm/core/solana/dca/single-chain-dca-order.js +3 -2
  17. package/dist/esm/core/solana/dca/single-chain-dca-order.js.map +1 -1
  18. package/dist/esm/core/solana/dca/single-chain-limit-order.js +3 -2
  19. package/dist/esm/core/solana/dca/single-chain-limit-order.js.map +1 -1
  20. package/dist/esm/core/solana/utils.js +14 -4
  21. package/dist/esm/core/solana/utils.js.map +1 -1
  22. package/dist/esm/core/sui/single-chain-dca-order.js +2 -1
  23. package/dist/esm/core/sui/single-chain-dca-order.js.map +1 -1
  24. package/dist/esm/core/sui/single-chain-limit-order.js +2 -1
  25. package/dist/esm/core/sui/single-chain-limit-order.js.map +1 -1
  26. package/dist/esm/index.js +6 -3
  27. package/dist/esm/index.js.map +1 -1
  28. package/dist/esm/types/token-list.js +2 -0
  29. package/dist/esm/types/token-list.js.map +1 -0
  30. package/dist/esm/utils/defillama.js +1 -0
  31. package/dist/esm/utils/defillama.js.map +1 -1
  32. package/dist/esm/utils/quote/aggregator.js +158 -42
  33. package/dist/esm/utils/quote/aggregator.js.map +1 -1
  34. package/dist/esm/utils/quote/paraswap.js +1 -0
  35. package/dist/esm/utils/quote/paraswap.js.map +1 -1
  36. package/dist/esm/utils/quote/pumpfun/estimations.js +169 -0
  37. package/dist/esm/utils/quote/pumpfun/estimations.js.map +1 -0
  38. package/dist/esm/utils/quote/pumpfun/estimations_amm.js +130 -0
  39. package/dist/esm/utils/quote/pumpfun/estimations_amm.js.map +1 -0
  40. package/dist/esm/utils/quote/pumpfun/index.js +198 -0
  41. package/dist/esm/utils/quote/pumpfun/index.js.map +1 -0
  42. package/dist/esm/utils/quote/pumpfun/models.js +70 -0
  43. package/dist/esm/utils/quote/pumpfun/models.js.map +1 -0
  44. package/dist/esm/utils/quote/pumpfun/utils.js +269 -0
  45. package/dist/esm/utils/quote/pumpfun/utils.js.map +1 -0
  46. package/dist/esm/utils/quote/raydium.js +336 -0
  47. package/dist/esm/utils/quote/raydium.js.map +1 -0
  48. package/dist/esm/utils/quote/stablecoins-tokens.js +1 -0
  49. package/dist/esm/utils/quote/stablecoins-tokens.js.map +1 -1
  50. package/dist/esm/utils/quote/utils.js +8 -0
  51. package/dist/esm/utils/quote/utils.js.map +1 -0
  52. package/dist/esm/utils/tokens/index.js +37 -0
  53. package/dist/esm/utils/tokens/index.js.map +1 -0
  54. package/dist/types/chains.d.ts +4 -2
  55. package/dist/types/chains.d.ts.map +1 -1
  56. package/dist/types/constants.d.ts +2 -1
  57. package/dist/types/constants.d.ts.map +1 -1
  58. package/dist/types/core/evm/chain-provider.d.ts.map +1 -1
  59. package/dist/types/core/evm/permit2-signature-transfer.d.ts +3 -0
  60. package/dist/types/core/evm/permit2-signature-transfer.d.ts.map +1 -0
  61. package/dist/types/core/solana/dca/single-chain-dca-order.d.ts +1 -2
  62. package/dist/types/core/solana/dca/single-chain-dca-order.d.ts.map +1 -1
  63. package/dist/types/core/solana/dca/single-chain-limit-order.d.ts +1 -2
  64. package/dist/types/core/solana/dca/single-chain-limit-order.d.ts.map +1 -1
  65. package/dist/types/core/solana/utils.d.ts +2 -0
  66. package/dist/types/core/solana/utils.d.ts.map +1 -1
  67. package/dist/types/core/sui/single-chain-dca-order.d.ts.map +1 -1
  68. package/dist/types/core/sui/single-chain-limit-order.d.ts.map +1 -1
  69. package/dist/types/index.d.ts +5 -3
  70. package/dist/types/index.d.ts.map +1 -1
  71. package/dist/types/types/token-list.d.ts +30 -0
  72. package/dist/types/types/token-list.d.ts.map +1 -0
  73. package/dist/types/utils/defillama.d.ts +1 -0
  74. package/dist/types/utils/defillama.d.ts.map +1 -1
  75. package/dist/types/utils/quote/aggregator.d.ts +42 -5
  76. package/dist/types/utils/quote/aggregator.d.ts.map +1 -1
  77. package/dist/types/utils/quote/paraswap.d.ts.map +1 -1
  78. package/dist/types/utils/quote/pumpfun/estimations.d.ts +30 -0
  79. package/dist/types/utils/quote/pumpfun/estimations.d.ts.map +1 -0
  80. package/dist/types/utils/quote/pumpfun/estimations_amm.d.ts +49 -0
  81. package/dist/types/utils/quote/pumpfun/estimations_amm.d.ts.map +1 -0
  82. package/dist/types/utils/quote/pumpfun/index.d.ts +10 -0
  83. package/dist/types/utils/quote/pumpfun/index.d.ts.map +1 -0
  84. package/dist/types/utils/quote/pumpfun/models.d.ts +94 -0
  85. package/dist/types/utils/quote/pumpfun/models.d.ts.map +1 -0
  86. package/dist/types/utils/quote/pumpfun/utils.d.ts +50 -0
  87. package/dist/types/utils/quote/pumpfun/utils.d.ts.map +1 -0
  88. package/dist/types/utils/quote/raydium.d.ts +98 -0
  89. package/dist/types/utils/quote/raydium.d.ts.map +1 -0
  90. package/dist/types/utils/quote/stablecoins-tokens.d.ts.map +1 -1
  91. package/dist/types/utils/quote/utils.d.ts +5 -0
  92. package/dist/types/utils/quote/utils.d.ts.map +1 -0
  93. package/dist/types/utils/tokens/index.d.ts +20 -0
  94. package/dist/types/utils/tokens/index.d.ts.map +1 -0
  95. package/package.json +20 -18
  96. package/src/chains.ts +3 -0
  97. package/src/constants.ts +12 -2
  98. package/src/core/evm/chain-provider.ts +2 -1
  99. package/src/core/evm/cross-chain-limit-order.ts +1 -1
  100. package/src/core/evm/permit2-signature-transfer.ts +15 -0
  101. package/src/core/evm/single-chain-dca-order.ts +1 -1
  102. package/src/core/evm/single-chain-limit-order.ts +1 -1
  103. package/src/core/solana/dca/single-chain-dca-order.ts +3 -3
  104. package/src/core/solana/dca/single-chain-limit-order.ts +3 -2
  105. package/src/core/solana/utils.ts +24 -12
  106. package/src/core/sui/single-chain-dca-order.ts +2 -2
  107. package/src/core/sui/single-chain-limit-order.ts +2 -2
  108. package/src/index.ts +14 -4
  109. package/src/types/token-list.ts +35 -0
  110. package/src/utils/defillama.ts +1 -0
  111. package/src/utils/quote/aggregator.ts +210 -55
  112. package/src/utils/quote/paraswap.ts +1 -0
  113. package/src/utils/quote/pumpfun/estimations.ts +206 -0
  114. package/src/utils/quote/pumpfun/estimations_amm.ts +165 -0
  115. package/src/utils/quote/pumpfun/index.ts +266 -0
  116. package/src/utils/quote/pumpfun/models.ts +163 -0
  117. package/src/utils/quote/pumpfun/utils.ts +343 -0
  118. package/src/utils/quote/raydium.ts +506 -0
  119. package/src/utils/quote/stablecoins-tokens.ts +1 -0
  120. package/src/utils/quote/utils.ts +8 -0
  121. package/src/utils/tokens/index.ts +38 -0
@@ -0,0 +1,343 @@
1
+ import {
2
+ address,
3
+ fetchEncodedAccount,
4
+ fetchEncodedAccounts,
5
+ getAddressEncoder,
6
+ getProgramDerivedAddress,
7
+ unwrapOption,
8
+ type Address,
9
+ } from '@solana/kit';
10
+ import { getDefaultSolanaRPC } from '../../../core/solana/client.js';
11
+ import {
12
+ getBondingCurveDecoder,
13
+ getGlobalAccountDecoder,
14
+ getGlobalConfigDecoder,
15
+ getPumpPoolDataDecoder,
16
+ type BondingCurve,
17
+ type GlobalAccount,
18
+ type GlobalConfig,
19
+ type PumpPoolData,
20
+ type TokenAccount,
21
+ } from './models.js';
22
+ import { getTokenDecoder } from '@solana-program/token';
23
+ import { ONE_DAY_MS, TEN_MINUTES_MS, TWO_SECONDS_MS } from '../utils.js';
24
+
25
+ export const PUMP_FUN_PROGRAM_ADDRESS = address('6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P');
26
+ export const PUMP_FUN_AMM_PROGRAM_ADDRESS = address('pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA');
27
+ export const WRAPPED_NATIVE_TOKEN_PUBKEY = address('So11111111111111111111111111111111111111112');
28
+ export const GLOBAL_CONFIG_AMM = address('ADyA8hdefvWN2dbGGWFotbzWxrAvLW83WG6QCVXvJKqw');
29
+ export const ANCHOR_DISCRIMINATOR_SIZE = 8;
30
+
31
+ let globalAccountCache: { data: [GlobalAccount, Address]; expiresAt: number } | null = null;
32
+ let globalConfigCache: { data: [GlobalConfig, Address]; expiresAt: number } | null = null;
33
+ const migratedPoolCache = new Map<string, { data: [PumpPoolData, Address]; expiresAt: number }>();
34
+ const poolTokensInfoCache = new Map<string, { data: [TokenAccount, TokenAccount]; expiresAt: number }>();
35
+
36
+ /**
37
+ * Finds the PDA for a PumpFun bonding curve
38
+ */
39
+ async function findBondingCurvePda(tokenMint: Address): Promise<Address> {
40
+ const [pda] = await getProgramDerivedAddress({
41
+ programAddress: PUMP_FUN_PROGRAM_ADDRESS,
42
+ seeds: [new TextEncoder().encode('bonding-curve'), getAddressEncoder().encode(tokenMint)],
43
+ });
44
+
45
+ return pda;
46
+ }
47
+
48
+ /**
49
+ * Finds the PDA for the PumpFun global account
50
+ */
51
+ async function findGlobalAccountPda(): Promise<Address> {
52
+ const [pda] = await getProgramDerivedAddress({
53
+ programAddress: PUMP_FUN_PROGRAM_ADDRESS,
54
+ seeds: [new TextEncoder().encode('global')],
55
+ });
56
+
57
+ return pda;
58
+ }
59
+
60
+ /**
61
+ * Finds the PDA for pool authority in the AMM program
62
+ */
63
+ async function findPoolAuthorityPdaAmm(mint: Address): Promise<Address> {
64
+ const [pda] = await getProgramDerivedAddress({
65
+ programAddress: PUMP_FUN_PROGRAM_ADDRESS,
66
+ seeds: [new TextEncoder().encode('pool-authority'), getAddressEncoder().encode(mint)],
67
+ });
68
+
69
+ return pda;
70
+ }
71
+
72
+ /**
73
+ * Finds the PDA for a pool in the AMM program
74
+ */
75
+ async function findPoolPdaAmm(poolAuthority: Address, baseMint: Address, quoteMint: Address): Promise<Address> {
76
+ const [pda] = await getProgramDerivedAddress({
77
+ programAddress: PUMP_FUN_AMM_PROGRAM_ADDRESS,
78
+ seeds: [
79
+ new TextEncoder().encode('pool'),
80
+ new Uint8Array([0, 0]), // Pool type bytes
81
+ getAddressEncoder().encode(poolAuthority),
82
+ getAddressEncoder().encode(baseMint),
83
+ getAddressEncoder().encode(quoteMint),
84
+ ],
85
+ });
86
+
87
+ return pda;
88
+ }
89
+
90
+ /**
91
+ * Fetches and deserializes a PumpFun bonding curve account
92
+ *
93
+ * @param tokenMint - The token mint address
94
+ * @param options - Optional RPC configuration
95
+ * @returns Tuple of [BondingCurve data, PDA address]
96
+ * @throws Error if account doesn't exist or deserialization fails
97
+ */
98
+ export async function getPumpFunBondingCurve(tokenMint: Address): Promise<[BondingCurve, Address]> {
99
+ const rpc = getDefaultSolanaRPC();
100
+
101
+ try {
102
+ // Derive the PDA for the bonding curve
103
+ const pda = await findBondingCurvePda(tokenMint);
104
+
105
+ // Fetch the account data
106
+ const encodedAccount = await fetchEncodedAccount(rpc, pda);
107
+
108
+ if (!encodedAccount.exists) {
109
+ throw new Error(`Bonding curve account not found for token mint: ${tokenMint}`);
110
+ }
111
+
112
+ // Anchor accounts have an 8-byte discriminator prefix
113
+ const dataWithoutDiscriminator = encodedAccount.data.slice(8);
114
+
115
+ try {
116
+ const decoder = getBondingCurveDecoder();
117
+ const bondingCurve = decoder.decode(dataWithoutDiscriminator);
118
+
119
+ return [bondingCurve, pda];
120
+ } catch (decodingError) {
121
+ throw new Error(
122
+ `Failed to deserialize bonding curve: ${decodingError instanceof Error ? decodingError.message : String(decodingError)}`,
123
+ );
124
+ }
125
+ } catch (error) {
126
+ throw new Error(`Failed to fetch bonding curve account: ${error instanceof Error ? error.message : String(error)}`);
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Fetches and deserializes the PumpFun global account
132
+ *
133
+ * @returns Tuple of [GlobalAccount data, PDA address]
134
+ * @throws {Error} if account doesn't exist
135
+ * @throws {Error} if deserialization fails
136
+ */
137
+ export async function getPumpFunGlobalAccount(): Promise<[GlobalAccount, Address]> {
138
+ // Return cached value if valid
139
+ if (globalAccountCache && Date.now() < globalAccountCache.expiresAt) {
140
+ return globalAccountCache.data;
141
+ }
142
+
143
+ const rpc = getDefaultSolanaRPC();
144
+ const pda = await findGlobalAccountPda();
145
+
146
+ const encodedAccount = await fetchEncodedAccount(rpc, pda);
147
+
148
+ if (!encodedAccount.exists) {
149
+ throw new Error(`GlobalAccount not found: ${pda}`);
150
+ }
151
+
152
+ // Validate minimum size
153
+ if (encodedAccount.data.length < ANCHOR_DISCRIMINATOR_SIZE) {
154
+ throw new Error(
155
+ `GlobalAccount deserialization failed: Account data too small: ${encodedAccount.data.length} bytes`,
156
+ );
157
+ }
158
+
159
+ // Skip Anchor's 8-byte discriminator
160
+ const dataWithoutDiscriminator = encodedAccount.data.slice(ANCHOR_DISCRIMINATOR_SIZE);
161
+
162
+ try {
163
+ const decoder = getGlobalAccountDecoder();
164
+ const globalAccount = decoder.decode(dataWithoutDiscriminator);
165
+
166
+ // Update cache
167
+ globalAccountCache = {
168
+ data: [globalAccount, pda],
169
+ expiresAt: Date.now() + TEN_MINUTES_MS,
170
+ };
171
+
172
+ return [globalAccount, pda];
173
+ } catch (error) {
174
+ throw new Error(`GlobalAccount deserialization failed: ${error instanceof Error ? error.message : String(error)}`);
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Fetches and deserializes the PumpFun global config account
180
+ *
181
+ * @returns Tuple of [GlobalConfig data, PDA address]
182
+ * @throws {Error} if account doesn't exist
183
+ * @throws {Error} if deserialization fails
184
+ */
185
+ export async function getPumpFunGlobalConfig(): Promise<[GlobalConfig, Address]> {
186
+ // Return cached value if valid
187
+ if (globalConfigCache && Date.now() < globalConfigCache.expiresAt) {
188
+ return globalConfigCache.data;
189
+ }
190
+
191
+ const rpc = getDefaultSolanaRPC();
192
+
193
+ const encodedAccount = await fetchEncodedAccount(rpc, GLOBAL_CONFIG_AMM);
194
+
195
+ if (!encodedAccount.exists) {
196
+ throw new Error(`GlobalConfig account not found: ${GLOBAL_CONFIG_AMM}`);
197
+ }
198
+
199
+ // Validate minimum size
200
+ if (encodedAccount.data.length < ANCHOR_DISCRIMINATOR_SIZE) {
201
+ throw new Error(`GlobalConfig deserialization failed: Account data too small: ${encodedAccount.data.length} bytes`);
202
+ }
203
+
204
+ // Skip Anchor's 8-byte discriminator
205
+ const dataWithoutDiscriminator = encodedAccount.data.slice(ANCHOR_DISCRIMINATOR_SIZE);
206
+
207
+ try {
208
+ const decoder = getGlobalConfigDecoder();
209
+ const globalConfig = decoder.decode(dataWithoutDiscriminator);
210
+
211
+ // Update cache
212
+ globalConfigCache = {
213
+ data: [globalConfig, GLOBAL_CONFIG_AMM],
214
+ expiresAt: Date.now() + TEN_MINUTES_MS,
215
+ };
216
+
217
+ return [globalConfig, GLOBAL_CONFIG_AMM];
218
+ } catch (error) {
219
+ throw new Error(`GlobalConfig deserialization failed: ${error instanceof Error ? error.message : String(error)}`);
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Fetches the migrated AMM pool for a token
225
+ *
226
+ * @param baseMint - The token mint address (NOT WSOL)
227
+ * @returns Tuple of [PumpPoolData, pool PDA address]
228
+ * @throws Error if pool doesn't exist or deserialization fails
229
+ */
230
+ export async function getPumpFunMigratedPool(baseMint: Address): Promise<[PumpPoolData, Address]> {
231
+ // 2s in-memory cache
232
+ const cacheKey = String(baseMint);
233
+ const cached = migratedPoolCache.get(cacheKey);
234
+ if (cached && Date.now() < cached.expiresAt) {
235
+ return cached.data;
236
+ }
237
+
238
+ const rpc = getDefaultSolanaRPC();
239
+
240
+ try {
241
+ const poolAuthorityPda = await findPoolAuthorityPdaAmm(baseMint);
242
+ const poolPda = await findPoolPdaAmm(poolAuthorityPda, baseMint, WRAPPED_NATIVE_TOKEN_PUBKEY);
243
+
244
+ const encodedAccount = await fetchEncodedAccount(rpc, poolPda);
245
+
246
+ if (!encodedAccount.exists) {
247
+ throw new Error(`Migrated pool not found for token mint: ${baseMint}`);
248
+ }
249
+
250
+ const dataWithoutDiscriminator = encodedAccount.data.slice(ANCHOR_DISCRIMINATOR_SIZE);
251
+
252
+ try {
253
+ const decoder = getPumpPoolDataDecoder();
254
+ const poolData = decoder.decode(dataWithoutDiscriminator);
255
+
256
+ // Update short-lived cache
257
+ migratedPoolCache.set(cacheKey, {
258
+ data: [poolData, poolPda],
259
+ expiresAt: Date.now() + ONE_DAY_MS,
260
+ });
261
+
262
+ return [poolData, poolPda];
263
+ } catch (decodingError) {
264
+ throw new Error(
265
+ `Failed to deserialize pool data: ${decodingError instanceof Error ? decodingError.message : String(decodingError)}`,
266
+ );
267
+ }
268
+ } catch (error) {
269
+ throw new Error(`Failed to fetch migrated pool: ${error instanceof Error ? error.message : String(error)}`);
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Fetches and deserializes token account information for pool base and quote tokens
275
+ *
276
+ * @param poolBaseTokenAccount - Base token account public key
277
+ * @param poolQuoteTokenAccount - Quote token account public key
278
+ * @returns Tuple containing [baseTokenAccount, quoteTokenAccount]
279
+ * @throws Error if accounts don't exist or deserialization fails
280
+ */
281
+ export async function getPoolTokensInfo(
282
+ poolBaseTokenAccount: Address,
283
+ poolQuoteTokenAccount: Address,
284
+ ): Promise<[TokenAccount, TokenAccount]> {
285
+ // 2s in-memory cache
286
+ const cacheKey = `${poolBaseTokenAccount}-${poolQuoteTokenAccount}`;
287
+ const cached = poolTokensInfoCache.get(cacheKey);
288
+ if (cached && Date.now() < cached.expiresAt) {
289
+ return cached.data;
290
+ }
291
+
292
+ const rpc = getDefaultSolanaRPC();
293
+
294
+ const accountsInfo = await fetchEncodedAccounts(rpc, [poolBaseTokenAccount, poolQuoteTokenAccount]);
295
+
296
+ // Validate base token account exists
297
+ const baseAccountInfo = accountsInfo[0];
298
+ if (!baseAccountInfo || !baseAccountInfo.exists) {
299
+ throw new Error(`Base token account not found: ${poolBaseTokenAccount}`);
300
+ }
301
+
302
+ // Validate quote token account exists
303
+ const quoteAccountInfo = accountsInfo[1];
304
+ if (!quoteAccountInfo || !quoteAccountInfo.exists) {
305
+ throw new Error(`Quote token account not found: ${poolQuoteTokenAccount}`);
306
+ }
307
+
308
+ const tokenDecoder = getTokenDecoder();
309
+
310
+ // Deserialize base token account
311
+ const baseDecoded = tokenDecoder.decode(baseAccountInfo.data);
312
+ const baseTokenAccount: TokenAccount = {
313
+ mint: baseDecoded.mint,
314
+ owner: baseDecoded.owner,
315
+ amount: baseDecoded.amount,
316
+ delegate: unwrapOption(baseDecoded.delegate),
317
+ state: baseDecoded.state,
318
+ isNative: unwrapOption(baseDecoded.isNative),
319
+ delegatedAmount: baseDecoded.delegatedAmount,
320
+ closeAuthority: unwrapOption(baseDecoded.closeAuthority),
321
+ };
322
+
323
+ // Deserialize quote token account
324
+ const quoteDecoded = tokenDecoder.decode(quoteAccountInfo.data);
325
+ const quoteTokenAccount: TokenAccount = {
326
+ mint: quoteDecoded.mint,
327
+ owner: quoteDecoded.owner,
328
+ amount: quoteDecoded.amount,
329
+ delegate: unwrapOption(quoteDecoded.delegate),
330
+ state: quoteDecoded.state,
331
+ isNative: unwrapOption(quoteDecoded.isNative),
332
+ delegatedAmount: quoteDecoded.delegatedAmount,
333
+ closeAuthority: unwrapOption(quoteDecoded.closeAuthority),
334
+ };
335
+
336
+ // Update short-lived cache
337
+ poolTokensInfoCache.set(cacheKey, {
338
+ data: [baseTokenAccount, quoteTokenAccount],
339
+ expiresAt: Date.now() + TWO_SECONDS_MS,
340
+ });
341
+
342
+ return [baseTokenAccount, quoteTokenAccount];
343
+ }