@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.
- package/dist/entities/pool.d.ts.map +1 -1
- package/dist/entities/pool.js +37 -62
- package/package.json +1 -1
- package/src/entities/pool.ts +75 -86
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../src/entities/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAEf,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACzB,MAAM,aAAa,CAAC;AAMrB,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAIL,KAAK,QAAQ,EACb,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EACjB,MAAM,UAAU,CAAC;AAUlB,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,gBAAgB,IAAI,oBAAoB,EAC9C,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,QAAQ,EAKT,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,qBAAa,IAAI;;IAQf,OAAO,eAYN;IAED,IAAW,GAAG,+5nBAAwB;IAEtC,IAAW,cAAc,YAAmC;IAC5D,IAAW,OAAO,oBAAoC;IACtD,IAAW,IAAI,mBAAiC;IAChD,IAAW,WAAW,WAAoC;IAE1D,IAAW,UAAU,YAAmC;IACxD,IAAW,UAAU,YAAmC;IAExD,IAAW,cAAc,WAAwC;IACjE,IAAW,cAAc,WAAwC;IAEjE,IAAW,WAAW,YAAoC;IAC1D,IAAW,WAAW,YAAoC;IAE1D,IAAW,aAAa,YAAyC;IACjE,IAAW,aAAa,YAAyC;IAEpD,eAAe,IAAI,OAAO,CAAC;QAAE,YAAY,CAAC,EAAE,WAAW,CAAC;QAAC,YAAY,CAAC,EAAE,WAAW,CAAA;KAAE,CAAC,CAMlG;IAEY,WAAW,CAAC,GAAG,GAAE,MAA8C,GAAG,OAAO,CAAC,QAAQ,CAAC,CAE/F;IAEY,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,OAAO,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAQpD,WAAW,CACtB,OAAO,EAAE,OAAO,EAChB,MAAM,CAAC,EAAE,mBAAmB,GAC3B,OAAO,CAAC,QAAQ,CAAC,CAEnB;IAEY,yBAAyB,CACpC,YAAY,EAAE,OAAO,EACrB,MAAM,CAAC,EAAE,mBAAmB,GAC3B,OAAO,CAAC,QAAQ,CAAC,CAMnB;IAEY,8BAA8B,CACzC,aAAa,EAAE,OAAO,EAAE,EACxB,MAAM,CAAC,EAAE,mBAAmB,GAC3B,OAAO,CAAC,QAAQ,EAAE,CAAC,CAMrB;IAEY,YAAY,CACvB,KAAK,EAAE,iBAAiB,EACxB,YAAY,EAAE,iBAAiB,EAC/B,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GACrE,OAAO,CAAC,WAAW,EAAE,CAAC,CAMxB;IAEY,aAAa,CACxB,KAAK,EAAE,iBAAiB,EACxB,YAAY,EAAE,OAAO,GACpB,OAAO,CAAC,WAAW,CAAC,CAKtB;IAEY,WAAW,CACtB,IAAI,EAAE,iBAAiB,EACvB,EACE,IAAI,EACJ,QAAQ,EACR,oBAAoB,GACrB,EAAE;QACD,IAAI,EAAE,OAAO,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,oBAAoB,EAAE,MAAM,CAAC;KAC9B,GACA,OAAO,CAAC;QAAE,WAAW,EAAE,kBAAkB,CAAC;QAAC,YAAY,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../src/entities/pool.ts"],"names":[],"mappings":"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"}
|
package/dist/entities/pool.js
CHANGED
|
@@ -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
|
-
|
|
76
|
-
|
|
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
|
-
|
|
138
|
-
|
|
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
|
|
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
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
package/src/entities/pool.ts
CHANGED
|
@@ -178,70 +178,31 @@ export class Pool {
|
|
|
178
178
|
const { quoteOutput, binArrayAddresses } =
|
|
179
179
|
await this.#quoteExactIn({ xToY, amountIn, slippageToleranceBps });
|
|
180
180
|
|
|
181
|
-
|
|
182
|
-
|
|
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
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
-
|
|
275
|
-
|
|
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
|
|
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
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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
|
-
|
|
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)
|