Add resolveATA option for Position's increase_liquidity (#31)
- Add an option to auto-generate ATA to perform increase_liquidity for Whirlpool's position class
This commit is contained in:
parent
537306c096
commit
4416732e33
|
@ -45,7 +45,9 @@ export class PositionImpl implements Position {
|
|||
async increaseLiquidity(
|
||||
liquidityInput: IncreaseLiquidityInput,
|
||||
sourceWallet?: Address,
|
||||
positionWallet?: Address
|
||||
positionWallet?: Address,
|
||||
resolveATA?: boolean,
|
||||
ataPayer?: Address
|
||||
) {
|
||||
const sourceWalletKey = sourceWallet
|
||||
? AddressUtil.toPubKey(sourceWallet)
|
||||
|
@ -53,6 +55,7 @@ export class PositionImpl implements Position {
|
|||
const positionWalletKey = positionWallet
|
||||
? AddressUtil.toPubKey(positionWallet)
|
||||
: this.ctx.wallet.publicKey;
|
||||
const ataPayerKey = ataPayer ? AddressUtil.toPubKey(ataPayer) : this.ctx.wallet.publicKey;
|
||||
|
||||
const whirlpool = await this.fetcher.getPool(this.data.whirlpool, true);
|
||||
if (!whirlpool) {
|
||||
|
@ -60,8 +63,31 @@ export class PositionImpl implements Position {
|
|||
}
|
||||
|
||||
const txBuilder = new TransactionBuilder(this.ctx.provider);
|
||||
const tokenOwnerAccountA = await deriveATA(sourceWalletKey, whirlpool.tokenMintA);
|
||||
const tokenOwnerAccountB = await deriveATA(sourceWalletKey, whirlpool.tokenMintB);
|
||||
|
||||
let tokenOwnerAccountA: PublicKey;
|
||||
let tokenOwnerAccountB: PublicKey;
|
||||
|
||||
if (resolveATA) {
|
||||
const [ataA, ataB] = await resolveOrCreateATAs(
|
||||
this.ctx.connection,
|
||||
sourceWalletKey,
|
||||
[
|
||||
{ tokenMint: whirlpool.tokenMintA, wrappedSolAmountIn: liquidityInput.tokenMaxA },
|
||||
{ tokenMint: whirlpool.tokenMintB, wrappedSolAmountIn: liquidityInput.tokenMaxB },
|
||||
],
|
||||
() => this.fetcher.getAccountRentExempt(),
|
||||
ataPayerKey
|
||||
);
|
||||
const { address: ataAddrA, ...tokenOwnerAccountAIx } = ataA!;
|
||||
const { address: ataAddrB, ...tokenOwnerAccountBIx } = ataB!;
|
||||
tokenOwnerAccountA = ataAddrA;
|
||||
tokenOwnerAccountB = ataAddrB;
|
||||
txBuilder.addInstruction(tokenOwnerAccountAIx);
|
||||
txBuilder.addInstruction(tokenOwnerAccountBIx);
|
||||
} else {
|
||||
tokenOwnerAccountA = await deriveATA(sourceWalletKey, whirlpool.tokenMintA);
|
||||
tokenOwnerAccountB = await deriveATA(sourceWalletKey, whirlpool.tokenMintB);
|
||||
}
|
||||
const positionTokenAccount = await deriveATA(positionWalletKey, this.data.positionMint);
|
||||
|
||||
const increaseIx = increaseLiquidityIx(this.ctx.program, {
|
||||
|
|
|
@ -207,15 +207,21 @@ export interface Position {
|
|||
/**
|
||||
* Deposit additional tokens into this postiion.
|
||||
* The wallet must contain the position token and the necessary token A & B to complete the deposit.
|
||||
* If `wallet` is provided, the wallet owners have to sign this transaction.
|
||||
* If `positionWallet` are `wallet` is provided, the wallet owners have to sign this transaction.
|
||||
*
|
||||
* @param liquidityInput - input that defines the desired liquidity amount and maximum tokens willing to be to deposited.
|
||||
* @param wallet - the wallet to withdraw tokens to deposit into the position. If null, the WhirlpoolContext wallet is used.
|
||||
* @param positionWallet - optional - the wallet to that houses the position token. If null, the WhirlpoolContext wallet is used.
|
||||
* @param resolveATA - optional - if true, add instructions to create associated token accounts for tokenA,B for the destinationWallet if necessary.
|
||||
* @param ataPayer - optional - wallet that will fund the creation of the new associated token accounts
|
||||
* @return the transaction that will deposit the tokens into the position when executed.
|
||||
*/
|
||||
increaseLiquidity: (
|
||||
liquidityInput: IncreaseLiquidityInput,
|
||||
wallet?: Address
|
||||
wallet?: Address,
|
||||
positionWallet?: Address,
|
||||
resolveATA?: boolean,
|
||||
ataPayer?: Address
|
||||
) => Promise<TransactionBuilder>;
|
||||
|
||||
/**
|
||||
|
|
|
@ -51,7 +51,7 @@ describe("position-impl", () => {
|
|||
);
|
||||
|
||||
// [Action] Initialize Tick Arrays
|
||||
const initTickArrayTx = await pool.initTickArrayForTicks([lowerTick, upperTick]);
|
||||
const initTickArrayTx = (await pool.initTickArrayForTicks([lowerTick, upperTick]))!;
|
||||
await initTickArrayTx.buildAndExecute();
|
||||
|
||||
// [Action] Create a position at price 89, 120 with 50 token A
|
||||
|
@ -108,7 +108,7 @@ describe("position-impl", () => {
|
|||
assert.equal(postWithdrawData.liquidity.toString(), expectedPostWithdrawLiquidity.toString());
|
||||
});
|
||||
|
||||
it("decrease liquidity on position with a different destination, position wallet", async () => {
|
||||
it("increase & decrease liquidity on position with a different destination, position wallet", async () => {
|
||||
const { poolInitInfo } = await initTestPool(
|
||||
ctx,
|
||||
TickSpacing.Standard,
|
||||
|
@ -137,7 +137,7 @@ describe("position-impl", () => {
|
|||
);
|
||||
|
||||
// [Action] Initialize Tick Arrays
|
||||
const initTickArrayTx = await pool.initTickArrayForTicks([lowerTick, upperTick]);
|
||||
const initTickArrayTx = (await pool.initTickArrayForTicks([lowerTick, upperTick]))!;
|
||||
await initTickArrayTx.buildAndExecute();
|
||||
|
||||
// [Action] Create a position at price 89, 120 with 50 token A
|
||||
|
@ -194,6 +194,36 @@ describe("position-impl", () => {
|
|||
);
|
||||
await transfer(provider, walletPositionTokenAccount, newOwnerPositionTokenAccount, 1);
|
||||
|
||||
// Mint to this other wallet and increase more tokens
|
||||
await mintTokensToTestAccount(
|
||||
ctx.provider,
|
||||
poolInitInfo.tokenMintA,
|
||||
10_500_000_000,
|
||||
poolInitInfo.tokenMintB,
|
||||
10_500_000_000,
|
||||
otherWallet.publicKey
|
||||
);
|
||||
const increaseQuoteFromOtherWallet = increaseLiquidityQuoteByInputToken(
|
||||
poolInitInfo.tokenMintB,
|
||||
new Decimal(80),
|
||||
lowerTick,
|
||||
upperTick,
|
||||
Percentage.fromFraction(1, 100),
|
||||
pool
|
||||
);
|
||||
await (
|
||||
await position.increaseLiquidity(
|
||||
increaseQuoteFromOtherWallet,
|
||||
otherWallet.publicKey,
|
||||
otherWallet.publicKey,
|
||||
true
|
||||
)
|
||||
)
|
||||
.addSigner(otherWallet)
|
||||
.buildAndExecute();
|
||||
|
||||
const postSecondIncreaseData = await position.refreshData();
|
||||
|
||||
// Withdraw liquidity into another wallet
|
||||
const destinationWallet = anchor.web3.Keypair.generate();
|
||||
await (
|
||||
|
@ -208,7 +238,7 @@ describe("position-impl", () => {
|
|||
.buildAndExecute();
|
||||
|
||||
const postWithdrawData = await position.refreshData();
|
||||
const expectedPostWithdrawLiquidity = postIncreaseData.liquidity.sub(
|
||||
const expectedPostWithdrawLiquidity = postSecondIncreaseData.liquidity.sub(
|
||||
decrease_quote.liquidityAmount
|
||||
);
|
||||
assert.equal(postWithdrawData.liquidity.toString(), expectedPostWithdrawLiquidity.toString());
|
||||
|
|
|
@ -28,7 +28,7 @@ import {
|
|||
} from "@orca-so/common-sdk";
|
||||
import { mintTokensToTestAccount } from "../../utils/test-builders";
|
||||
|
||||
describe.only("whirlpool-impl", () => {
|
||||
describe("whirlpool-impl", () => {
|
||||
const provider = anchor.Provider.local();
|
||||
anchor.setProvider(anchor.Provider.env());
|
||||
const program = anchor.workspace.Whirlpool;
|
||||
|
|
|
@ -237,7 +237,6 @@ export async function initPosition(
|
|||
upperTick,
|
||||
quote,
|
||||
sourceWalletKey,
|
||||
sourceWalletKey,
|
||||
ctx.wallet.publicKey
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue