@picon-finance/dlmm-sdk 1.16.0 → 1.16.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.
@@ -1 +1 @@
1
- {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../src/entities/pool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../src/entities/pool.ts"],"names":[],"mappings":"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"}
@@ -72,41 +72,8 @@ export class Pool {
72
72
  }
73
73
  async swapExactIn(user, { xToY, amountIn, slippageToleranceBps, }) {
74
74
  const { quoteOutput, binArrayAddresses } = await this.#quoteExactIn({ xToY, amountIn, slippageToleranceBps });
75
- const { ataX: tokenUserAccountX, ataY: tokenUserAccountY, preInstructions, postInstructions, } = await processAssociatedTokenAccountPair({
76
- owner: user,
77
- tokenMintX: this.tokenMintX,
78
- tokenMintY: this.tokenMintY,
79
- tokenProgramX: this.tokenProgramX,
80
- tokenProgramY: this.tokenProgramY,
81
- amountX: xToY ? amountIn : undefined,
82
- amountY: xToY ? undefined : amountIn,
83
- });
84
- // Each mint's hook accounts are resolved against whichever role it plays in this swap —
85
- // input (user -> vault, owner = user) or output (vault -> user, owner = pool PDA).
86
- const xTransferAccounts = xToY
87
- ? { source: tokenUserAccountX, mint: this.tokenMintX, destination: this.tokenVaultX, owner: user.address }
88
- : { source: this.tokenVaultX, mint: this.tokenMintX, destination: tokenUserAccountX, owner: this.address };
89
- const yTransferAccounts = xToY
90
- ? { source: this.tokenVaultY, mint: this.tokenMintY, destination: tokenUserAccountY, owner: this.address }
91
- : { source: tokenUserAccountY, mint: this.tokenMintY, destination: this.tokenVaultY, owner: user.address };
92
- const [transferHookXAccounts, transferHookYAccounts] = await Promise.all([
93
- this.resolveTransferHookAccountsX(xTransferAccounts),
94
- this.resolveTransferHookAccountsY(yTransferAccounts),
95
- ]);
96
- const groups = [
97
- { kind: generated.AccountKind.BinArray, count: binArrayAddresses.length },
98
- ];
99
- const remainingAccounts = binArrayAddresses.map(address => ({ address, role: AccountRole.WRITABLE }));
100
- if (transferHookXAccounts.length > 0) {
101
- groups.push({ kind: generated.AccountKind.TransferHookX, count: transferHookXAccounts.length });
102
- remainingAccounts.push(...transferHookXAccounts.map(toRemainingAccountMeta));
103
- }
104
- if (transferHookYAccounts.length > 0) {
105
- groups.push({ kind: generated.AccountKind.TransferHookY, count: transferHookYAccounts.length });
106
- remainingAccounts.push(...transferHookYAccounts.map(toRemainingAccountMeta));
107
- }
108
- const remainingAccountsScheme = { groups };
109
- const swapIx = generated.getSwapExactInInstruction({
75
+ // The input leg is fixed, so it funds the wSOL leg (if any) directly.
76
+ const instructions = await this.#assembleSwapInstructions(user, xToY, amountIn, binArrayAddresses, ({ tokenUserAccountX, tokenUserAccountY, remainingAccountsScheme }) => generated.getSwapExactInInstruction({
110
77
  user,
111
78
  pool: this.address,
112
79
  tokenMintX: this.tokenMintX,
@@ -121,26 +88,47 @@ export class Pool {
121
88
  minAmountOut: quoteOutput.minAmountOut,
122
89
  xToY,
123
90
  remainingAccountsScheme,
124
- }, { programAddress: this.#programAddress });
125
- const swapIxWithBinArrays = { ...swapIx, accounts: [...swapIx.accounts, ...remainingAccounts] };
126
- const instructions = [...preInstructions, swapIxWithBinArrays, ...postInstructions];
91
+ }, { programAddress: this.#programAddress }));
127
92
  return { quoteOutput, instructions };
128
93
  }
129
94
  async swapExactOut(user, { xToY, amountOut, slippageToleranceBps, }) {
130
95
  const { quoteOutput, binArrayAddresses } = await this.#quoteExactOut({ xToY, amountOut, slippageToleranceBps });
96
+ // The real input isn't known until the swap executes, so the wSOL leg (if any) is funded with
97
+ // the worst-case maxAmountIn — any excess is unwrapped back to the owner in postInstructions.
98
+ const instructions = await this.#assembleSwapInstructions(user, xToY, quoteOutput.maxAmountIn, binArrayAddresses, ({ tokenUserAccountX, tokenUserAccountY, remainingAccountsScheme }) => generated.getSwapExactOutInstruction({
99
+ user,
100
+ pool: this.address,
101
+ tokenMintX: this.tokenMintX,
102
+ tokenMintY: this.tokenMintY,
103
+ tokenUserAccountX,
104
+ tokenUserAccountY,
105
+ tokenVaultX: this.tokenVaultX,
106
+ tokenVaultY: this.tokenVaultY,
107
+ tokenProgramX: this.tokenProgramX,
108
+ tokenProgramY: this.tokenProgramY,
109
+ amountOut,
110
+ maxAmountIn: quoteOutput.maxAmountIn,
111
+ xToY,
112
+ remainingAccountsScheme,
113
+ }, { programAddress: this.#programAddress }));
114
+ return { quoteOutput, instructions };
115
+ }
116
+ // Shared tail of both swap directions: sets up the user's X/Y ATAs (funding the wSOL leg, if
117
+ // any, with `fundingAmount`), resolves each mint's transfer-hook accounts against the role it
118
+ // plays in this swap — input (user -> vault, owner = user) or output (vault -> user, owner =
119
+ // pool PDA) — builds the remaining-accounts scheme, and splices the bin arrays + resolved hook
120
+ // accounts onto the instruction `buildSwapIx` produces. Only the funding amount and the
121
+ // instruction itself differ between exact-in and exact-out.
122
+ async #assembleSwapInstructions(user, xToY, fundingAmount, binArrayAddresses, buildSwapIx) {
131
123
  const { ataX: tokenUserAccountX, ataY: tokenUserAccountY, preInstructions, postInstructions, } = await processAssociatedTokenAccountPair({
132
124
  owner: user,
133
125
  tokenMintX: this.tokenMintX,
134
126
  tokenMintY: this.tokenMintY,
135
127
  tokenProgramX: this.tokenProgramX,
136
128
  tokenProgramY: this.tokenProgramY,
137
- // Funds the wSOL leg (if any) with the worst-case input, since the real amount isn't known
138
- // until the swap executes — any excess is unwrapped back to the owner in postInstructions.
139
- amountX: xToY ? quoteOutput.maxAmountIn : undefined,
140
- amountY: xToY ? undefined : quoteOutput.maxAmountIn,
129
+ amountX: xToY ? fundingAmount : undefined,
130
+ amountY: xToY ? undefined : fundingAmount,
141
131
  });
142
- // Each mint's hook accounts are resolved against whichever role it plays in this swap —
143
- // input (user -> vault, owner = user) or output (vault -> user, owner = pool PDA).
144
132
  const xTransferAccounts = xToY
145
133
  ? { source: tokenUserAccountX, mint: this.tokenMintX, destination: this.tokenVaultX, owner: user.address }
146
134
  : { source: this.tokenVaultX, mint: this.tokenMintX, destination: tokenUserAccountX, owner: this.address };
@@ -163,26 +151,13 @@ export class Pool {
163
151
  groups.push({ kind: generated.AccountKind.TransferHookY, count: transferHookYAccounts.length });
164
152
  remainingAccounts.push(...transferHookYAccounts.map(toRemainingAccountMeta));
165
153
  }
166
- const remainingAccountsScheme = { groups };
167
- const swapIx = generated.getSwapExactOutInstruction({
168
- user,
169
- pool: this.address,
170
- tokenMintX: this.tokenMintX,
171
- tokenMintY: this.tokenMintY,
154
+ const swapIx = buildSwapIx({
172
155
  tokenUserAccountX,
173
156
  tokenUserAccountY,
174
- tokenVaultX: this.tokenVaultX,
175
- tokenVaultY: this.tokenVaultY,
176
- tokenProgramX: this.tokenProgramX,
177
- tokenProgramY: this.tokenProgramY,
178
- amountOut,
179
- maxAmountIn: quoteOutput.maxAmountIn,
180
- xToY,
181
- remainingAccountsScheme,
182
- }, { programAddress: this.#programAddress });
183
- const swapIxWithBinArrays = { ...swapIx, accounts: [...swapIx.accounts, ...remainingAccounts] };
184
- const instructions = [...preInstructions, swapIxWithBinArrays, ...postInstructions];
185
- return { quoteOutput, instructions };
157
+ remainingAccountsScheme: { groups },
158
+ });
159
+ const swapIxWithBinArrays = { ...swapIx, accounts: [...(swapIx.accounts ?? []), ...remainingAccounts] };
160
+ return [...preInstructions, swapIxWithBinArrays, ...postInstructions];
186
161
  }
187
162
  // Public so Position (which only holds a reference to this Pool, not its private mint data)
188
163
  // can resolve hook accounts for its own deposit/withdraw/claimFee instructions without ever
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@picon-finance/dlmm-sdk",
3
- "version": "1.16.0",
3
+ "version": "1.16.1",
4
4
  "description": "Typescript SDK for interacting with the Picon DLMM protocol",
5
5
  "author": "Picon Finance",
6
6
  "license": "MIT",
@@ -178,70 +178,31 @@ export class Pool {
178
178
  const { quoteOutput, binArrayAddresses } =
179
179
  await this.#quoteExactIn({ xToY, amountIn, slippageToleranceBps });
180
180
 
181
- const {
182
- ataX: tokenUserAccountX,
183
- ataY: tokenUserAccountY,
184
- preInstructions,
185
- postInstructions,
186
- } = await processAssociatedTokenAccountPair({
187
- owner: user,
188
- tokenMintX: this.tokenMintX,
189
- tokenMintY: this.tokenMintY,
190
- tokenProgramX: this.tokenProgramX,
191
- tokenProgramY: this.tokenProgramY,
192
- amountX: xToY ? amountIn : undefined,
193
- amountY: xToY ? undefined : amountIn,
194
- });
195
-
196
- // Each mint's hook accounts are resolved against whichever role it plays in this swap —
197
- // input (user -> vault, owner = user) or output (vault -> user, owner = pool PDA).
198
- const xTransferAccounts: TransferHookAccounts = xToY
199
- ? { source: tokenUserAccountX, mint: this.tokenMintX, destination: this.tokenVaultX, owner: user.address }
200
- : { source: this.tokenVaultX, mint: this.tokenMintX, destination: tokenUserAccountX, owner: this.address };
201
- const yTransferAccounts: TransferHookAccounts = xToY
202
- ? { source: this.tokenVaultY, mint: this.tokenMintY, destination: tokenUserAccountY, owner: this.address }
203
- : { source: tokenUserAccountY, mint: this.tokenMintY, destination: this.tokenVaultY, owner: user.address };
204
-
205
- const [transferHookXAccounts, transferHookYAccounts] = await Promise.all([
206
- this.resolveTransferHookAccountsX(xTransferAccounts),
207
- this.resolveTransferHookAccountsY(yTransferAccounts),
208
- ]);
209
-
210
- const groups: generated.AccountGroup[] = [
211
- { kind: generated.AccountKind.BinArray, count: binArrayAddresses.length },
212
- ];
213
- const remainingAccounts = binArrayAddresses.map(address => ({ address, role: AccountRole.WRITABLE }));
214
-
215
- if (transferHookXAccounts.length > 0) {
216
- groups.push({ kind: generated.AccountKind.TransferHookX, count: transferHookXAccounts.length });
217
- remainingAccounts.push(...transferHookXAccounts.map(toRemainingAccountMeta));
218
- }
219
- if (transferHookYAccounts.length > 0) {
220
- groups.push({ kind: generated.AccountKind.TransferHookY, count: transferHookYAccounts.length });
221
- remainingAccounts.push(...transferHookYAccounts.map(toRemainingAccountMeta));
222
- }
223
-
224
- const remainingAccountsScheme: generated.RemainingAccountsScheme = { groups };
225
- const swapIx = generated.getSwapExactInInstruction({
181
+ // The input leg is fixed, so it funds the wSOL leg (if any) directly.
182
+ const instructions = await this.#assembleSwapInstructions(
226
183
  user,
227
- pool: this.address,
228
- tokenMintX: this.tokenMintX,
229
- tokenMintY: this.tokenMintY,
230
- tokenUserAccountX,
231
- tokenUserAccountY,
232
- tokenVaultX: this.tokenVaultX,
233
- tokenVaultY: this.tokenVaultY,
234
- tokenProgramX: this.tokenProgramX,
235
- tokenProgramY: this.tokenProgramY,
236
- amountIn,
237
- minAmountOut: quoteOutput.minAmountOut,
238
184
  xToY,
239
- remainingAccountsScheme,
240
- }, { programAddress: this.#programAddress });
241
-
242
- const swapIxWithBinArrays = { ...swapIx, accounts: [...swapIx.accounts, ...remainingAccounts] };
185
+ amountIn,
186
+ binArrayAddresses,
187
+ ({ tokenUserAccountX, tokenUserAccountY, remainingAccountsScheme }) =>
188
+ generated.getSwapExactInInstruction({
189
+ user,
190
+ pool: this.address,
191
+ tokenMintX: this.tokenMintX,
192
+ tokenMintY: this.tokenMintY,
193
+ tokenUserAccountX,
194
+ tokenUserAccountY,
195
+ tokenVaultX: this.tokenVaultX,
196
+ tokenVaultY: this.tokenVaultY,
197
+ tokenProgramX: this.tokenProgramX,
198
+ tokenProgramY: this.tokenProgramY,
199
+ amountIn,
200
+ minAmountOut: quoteOutput.minAmountOut,
201
+ xToY,
202
+ remainingAccountsScheme,
203
+ }, { programAddress: this.#programAddress }),
204
+ );
243
205
 
244
- const instructions = [...preInstructions, swapIxWithBinArrays, ...postInstructions];
245
206
  return { quoteOutput, instructions };
246
207
  }
247
208
 
@@ -260,6 +221,52 @@ export class Pool {
260
221
  const { quoteOutput, binArrayAddresses } =
261
222
  await this.#quoteExactOut({ xToY, amountOut, slippageToleranceBps });
262
223
 
224
+ // The real input isn't known until the swap executes, so the wSOL leg (if any) is funded with
225
+ // the worst-case maxAmountIn — any excess is unwrapped back to the owner in postInstructions.
226
+ const instructions = await this.#assembleSwapInstructions(
227
+ user,
228
+ xToY,
229
+ quoteOutput.maxAmountIn,
230
+ binArrayAddresses,
231
+ ({ tokenUserAccountX, tokenUserAccountY, remainingAccountsScheme }) =>
232
+ generated.getSwapExactOutInstruction({
233
+ user,
234
+ pool: this.address,
235
+ tokenMintX: this.tokenMintX,
236
+ tokenMintY: this.tokenMintY,
237
+ tokenUserAccountX,
238
+ tokenUserAccountY,
239
+ tokenVaultX: this.tokenVaultX,
240
+ tokenVaultY: this.tokenVaultY,
241
+ tokenProgramX: this.tokenProgramX,
242
+ tokenProgramY: this.tokenProgramY,
243
+ amountOut,
244
+ maxAmountIn: quoteOutput.maxAmountIn,
245
+ xToY,
246
+ remainingAccountsScheme,
247
+ }, { programAddress: this.#programAddress }),
248
+ );
249
+
250
+ return { quoteOutput, instructions };
251
+ }
252
+
253
+ // Shared tail of both swap directions: sets up the user's X/Y ATAs (funding the wSOL leg, if
254
+ // any, with `fundingAmount`), resolves each mint's transfer-hook accounts against the role it
255
+ // plays in this swap — input (user -> vault, owner = user) or output (vault -> user, owner =
256
+ // pool PDA) — builds the remaining-accounts scheme, and splices the bin arrays + resolved hook
257
+ // accounts onto the instruction `buildSwapIx` produces. Only the funding amount and the
258
+ // instruction itself differ between exact-in and exact-out.
259
+ async #assembleSwapInstructions(
260
+ user: TransactionSigner,
261
+ xToY: boolean,
262
+ fundingAmount: bigint,
263
+ binArrayAddresses: Address[],
264
+ buildSwapIx: (accounts: {
265
+ tokenUserAccountX: Address,
266
+ tokenUserAccountY: Address,
267
+ remainingAccountsScheme: generated.RemainingAccountsScheme,
268
+ }) => Instruction,
269
+ ): Promise<Instruction[]> {
263
270
  const {
264
271
  ataX: tokenUserAccountX,
265
272
  ataY: tokenUserAccountY,
@@ -271,14 +278,10 @@ export class Pool {
271
278
  tokenMintY: this.tokenMintY,
272
279
  tokenProgramX: this.tokenProgramX,
273
280
  tokenProgramY: this.tokenProgramY,
274
- // Funds the wSOL leg (if any) with the worst-case input, since the real amount isn't known
275
- // until the swap executes — any excess is unwrapped back to the owner in postInstructions.
276
- amountX: xToY ? quoteOutput.maxAmountIn : undefined,
277
- amountY: xToY ? undefined : quoteOutput.maxAmountIn,
281
+ amountX: xToY ? fundingAmount : undefined,
282
+ amountY: xToY ? undefined : fundingAmount,
278
283
  });
279
284
 
280
- // Each mint's hook accounts are resolved against whichever role it plays in this swap —
281
- // input (user -> vault, owner = user) or output (vault -> user, owner = pool PDA).
282
285
  const xTransferAccounts: TransferHookAccounts = xToY
283
286
  ? { source: tokenUserAccountX, mint: this.tokenMintX, destination: this.tokenVaultX, owner: user.address }
284
287
  : { source: this.tokenVaultX, mint: this.tokenMintX, destination: tokenUserAccountX, owner: this.address };
@@ -305,28 +308,14 @@ export class Pool {
305
308
  remainingAccounts.push(...transferHookYAccounts.map(toRemainingAccountMeta));
306
309
  }
307
310
 
308
- const remainingAccountsScheme: generated.RemainingAccountsScheme = { groups };
309
- const swapIx = generated.getSwapExactOutInstruction({
310
- user,
311
- pool: this.address,
312
- tokenMintX: this.tokenMintX,
313
- tokenMintY: this.tokenMintY,
311
+ const swapIx = buildSwapIx({
314
312
  tokenUserAccountX,
315
313
  tokenUserAccountY,
316
- tokenVaultX: this.tokenVaultX,
317
- tokenVaultY: this.tokenVaultY,
318
- tokenProgramX: this.tokenProgramX,
319
- tokenProgramY: this.tokenProgramY,
320
- amountOut,
321
- maxAmountIn: quoteOutput.maxAmountIn,
322
- xToY,
323
- remainingAccountsScheme,
324
- }, { programAddress: this.#programAddress });
325
-
326
- const swapIxWithBinArrays = { ...swapIx, accounts: [...swapIx.accounts, ...remainingAccounts] };
314
+ remainingAccountsScheme: { groups },
315
+ });
316
+ const swapIxWithBinArrays = { ...swapIx, accounts: [...(swapIx.accounts ?? []), ...remainingAccounts] };
327
317
 
328
- const instructions = [...preInstructions, swapIxWithBinArrays, ...postInstructions];
329
- return { quoteOutput, instructions };
318
+ return [...preInstructions, swapIxWithBinArrays, ...postInstructions];
330
319
  }
331
320
 
332
321
  // Public so Position (which only holds a reference to this Pool, not its private mint data)