@crypticdot/defituna-client 3.1.1 → 3.1.3
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.mts +63 -8
- package/dist/index.d.ts +63 -8
- package/dist/index.js +138 -13
- package/dist/index.mjs +132 -7
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -137,6 +137,7 @@ __export(index_exports, {
|
|
|
137
137
|
TUNA_ERROR__POSITION_IS_LIQUIDATED: () => TUNA_ERROR__POSITION_IS_LIQUIDATED,
|
|
138
138
|
TUNA_ERROR__POSITION_IS_UNHEALTHY: () => TUNA_ERROR__POSITION_IS_UNHEALTHY,
|
|
139
139
|
TUNA_ERROR__POSITION_NOT_EMPTY: () => TUNA_ERROR__POSITION_NOT_EMPTY,
|
|
140
|
+
TUNA_ERROR__POSITION_SIZE_LIMIT_EXCEEDED: () => TUNA_ERROR__POSITION_SIZE_LIMIT_EXCEEDED,
|
|
140
141
|
TUNA_ERROR__PROTOCOL_FEE_IS_OUT_OF_RANGE: () => TUNA_ERROR__PROTOCOL_FEE_IS_OUT_OF_RANGE,
|
|
141
142
|
TUNA_ERROR__REBALANCE_CONDITIONS_NOT_MET: () => TUNA_ERROR__REBALANCE_CONDITIONS_NOT_MET,
|
|
142
143
|
TUNA_ERROR__RECIPIENT_ACCOUNT_IS_NOT_SET: () => TUNA_ERROR__RECIPIENT_ACCOUNT_IS_NOT_SET,
|
|
@@ -225,6 +226,7 @@ __export(index_exports, {
|
|
|
225
226
|
decreaseTunaSpotPositionOrcaInstructions: () => decreaseTunaSpotPositionOrcaInstructions,
|
|
226
227
|
depositInstruction: () => depositInstruction,
|
|
227
228
|
depositInstructions: () => depositInstructions,
|
|
229
|
+
extendAddressLookupTableForMarketInstructions: () => extendAddressLookupTableForMarketInstructions,
|
|
228
230
|
fetchAllLendingPosition: () => fetchAllLendingPosition,
|
|
229
231
|
fetchAllLendingPositionWithFilter: () => fetchAllLendingPositionWithFilter,
|
|
230
232
|
fetchAllMarket: () => fetchAllMarket,
|
|
@@ -349,6 +351,7 @@ __export(index_exports, {
|
|
|
349
351
|
getDepositInstructionDataDecoder: () => getDepositInstructionDataDecoder,
|
|
350
352
|
getDepositInstructionDataEncoder: () => getDepositInstructionDataEncoder,
|
|
351
353
|
getIncreaseLpPositionQuote: () => getIncreaseLpPositionQuote,
|
|
354
|
+
getIncreaseSpotPositionQuote: () => getIncreaseSpotPositionQuote,
|
|
352
355
|
getIncreaseTunaLpPositionFusionDiscriminatorBytes: () => getIncreaseTunaLpPositionFusionDiscriminatorBytes,
|
|
353
356
|
getIncreaseTunaLpPositionFusionInstruction: () => getIncreaseTunaLpPositionFusionInstruction,
|
|
354
357
|
getIncreaseTunaLpPositionFusionInstructionDataCodec: () => getIncreaseTunaLpPositionFusionInstructionDataCodec,
|
|
@@ -946,7 +949,9 @@ function getMarketEncoder() {
|
|
|
946
949
|
["borrowLimitB", (0, import_kit8.getU64Encoder)()],
|
|
947
950
|
["maxSwapSlippage", (0, import_kit8.getU32Encoder)()],
|
|
948
951
|
["rebalanceProtocolFee", (0, import_kit8.getU32Encoder)()],
|
|
949
|
-
["
|
|
952
|
+
["spotPositionSizeLimitA", (0, import_kit8.getU64Encoder)()],
|
|
953
|
+
["spotPositionSizeLimitB", (0, import_kit8.getU64Encoder)()],
|
|
954
|
+
["reserved", (0, import_kit8.fixEncoderSize)((0, import_kit8.getBytesEncoder)(), 191)]
|
|
950
955
|
]),
|
|
951
956
|
(value) => ({ ...value, discriminator: MARKET_DISCRIMINATOR })
|
|
952
957
|
);
|
|
@@ -973,7 +978,9 @@ function getMarketDecoder() {
|
|
|
973
978
|
["borrowLimitB", (0, import_kit8.getU64Decoder)()],
|
|
974
979
|
["maxSwapSlippage", (0, import_kit8.getU32Decoder)()],
|
|
975
980
|
["rebalanceProtocolFee", (0, import_kit8.getU32Decoder)()],
|
|
976
|
-
["
|
|
981
|
+
["spotPositionSizeLimitA", (0, import_kit8.getU64Decoder)()],
|
|
982
|
+
["spotPositionSizeLimitB", (0, import_kit8.getU64Decoder)()],
|
|
983
|
+
["reserved", (0, import_kit8.fixDecoderSize)((0, import_kit8.getBytesDecoder)(), 191)]
|
|
977
984
|
]);
|
|
978
985
|
}
|
|
979
986
|
function getMarketCodec() {
|
|
@@ -2109,6 +2116,7 @@ var TUNA_ERROR__POSITION_IS_AUTO_REBALANCEABLE = 6057;
|
|
|
2109
2116
|
var TUNA_ERROR__INCORRECT_POSITION_DIRECTION = 6058;
|
|
2110
2117
|
var TUNA_ERROR__RECIPIENT_ACCOUNT_IS_NOT_SET = 6059;
|
|
2111
2118
|
var TUNA_ERROR__M_A_PRICE_DEVIATION_THRESHOLD_EXCEEDED = 6060;
|
|
2119
|
+
var TUNA_ERROR__POSITION_SIZE_LIMIT_EXCEEDED = 6061;
|
|
2112
2120
|
var tunaErrorMessages;
|
|
2113
2121
|
if (process.env.NODE_ENV !== "production") {
|
|
2114
2122
|
tunaErrorMessages = {
|
|
@@ -2144,6 +2152,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
2144
2152
|
[TUNA_ERROR__POSITION_IS_LIQUIDATED]: `Position is already liquidated`,
|
|
2145
2153
|
[TUNA_ERROR__POSITION_IS_UNHEALTHY]: `Position is unhealthy`,
|
|
2146
2154
|
[TUNA_ERROR__POSITION_NOT_EMPTY]: `Position is not empty`,
|
|
2155
|
+
[TUNA_ERROR__POSITION_SIZE_LIMIT_EXCEEDED]: `Position size exceeds the maximum allowed value`,
|
|
2147
2156
|
[TUNA_ERROR__PROTOCOL_FEE_IS_OUT_OF_RANGE]: `Protocol fee is out of range`,
|
|
2148
2157
|
[TUNA_ERROR__REBALANCE_CONDITIONS_NOT_MET]: `Rebalance conditions are not met`,
|
|
2149
2158
|
[TUNA_ERROR__RECIPIENT_ACCOUNT_IS_NOT_SET]: `Optional recipient account is not set`,
|
|
@@ -3681,7 +3690,9 @@ function getCreateMarketInstructionDataEncoder() {
|
|
|
3681
3690
|
["borrowLimitA", (0, import_kit26.getU64Encoder)()],
|
|
3682
3691
|
["borrowLimitB", (0, import_kit26.getU64Encoder)()],
|
|
3683
3692
|
["maxSwapSlippage", (0, import_kit26.getU32Encoder)()],
|
|
3684
|
-
["rebalanceProtocolFee", (0, import_kit26.getU32Encoder)()]
|
|
3693
|
+
["rebalanceProtocolFee", (0, import_kit26.getU32Encoder)()],
|
|
3694
|
+
["spotPositionSizeLimitA", (0, import_kit26.getU64Encoder)()],
|
|
3695
|
+
["spotPositionSizeLimitB", (0, import_kit26.getU64Encoder)()]
|
|
3685
3696
|
]),
|
|
3686
3697
|
(value) => ({ ...value, discriminator: CREATE_MARKET_DISCRIMINATOR })
|
|
3687
3698
|
);
|
|
@@ -3702,7 +3713,9 @@ function getCreateMarketInstructionDataDecoder() {
|
|
|
3702
3713
|
["borrowLimitA", (0, import_kit26.getU64Decoder)()],
|
|
3703
3714
|
["borrowLimitB", (0, import_kit26.getU64Decoder)()],
|
|
3704
3715
|
["maxSwapSlippage", (0, import_kit26.getU32Decoder)()],
|
|
3705
|
-
["rebalanceProtocolFee", (0, import_kit26.getU32Decoder)()]
|
|
3716
|
+
["rebalanceProtocolFee", (0, import_kit26.getU32Decoder)()],
|
|
3717
|
+
["spotPositionSizeLimitA", (0, import_kit26.getU64Decoder)()],
|
|
3718
|
+
["spotPositionSizeLimitB", (0, import_kit26.getU64Decoder)()]
|
|
3706
3719
|
]);
|
|
3707
3720
|
}
|
|
3708
3721
|
function getCreateMarketInstructionDataCodec() {
|
|
@@ -9468,7 +9481,9 @@ function getUpdateMarketInstructionDataEncoder() {
|
|
|
9468
9481
|
["borrowLimitA", (0, import_kit68.getU64Encoder)()],
|
|
9469
9482
|
["borrowLimitB", (0, import_kit68.getU64Encoder)()],
|
|
9470
9483
|
["maxSwapSlippage", (0, import_kit68.getU32Encoder)()],
|
|
9471
|
-
["rebalanceProtocolFee", (0, import_kit68.getU32Encoder)()]
|
|
9484
|
+
["rebalanceProtocolFee", (0, import_kit68.getU32Encoder)()],
|
|
9485
|
+
["spotPositionSizeLimitA", (0, import_kit68.getU64Encoder)()],
|
|
9486
|
+
["spotPositionSizeLimitB", (0, import_kit68.getU64Encoder)()]
|
|
9472
9487
|
]),
|
|
9473
9488
|
(value) => ({ ...value, discriminator: UPDATE_MARKET_DISCRIMINATOR })
|
|
9474
9489
|
);
|
|
@@ -9488,7 +9503,9 @@ function getUpdateMarketInstructionDataDecoder() {
|
|
|
9488
9503
|
["borrowLimitA", (0, import_kit68.getU64Decoder)()],
|
|
9489
9504
|
["borrowLimitB", (0, import_kit68.getU64Decoder)()],
|
|
9490
9505
|
["maxSwapSlippage", (0, import_kit68.getU32Decoder)()],
|
|
9491
|
-
["rebalanceProtocolFee", (0, import_kit68.getU32Decoder)()]
|
|
9506
|
+
["rebalanceProtocolFee", (0, import_kit68.getU32Decoder)()],
|
|
9507
|
+
["spotPositionSizeLimitA", (0, import_kit68.getU64Decoder)()],
|
|
9508
|
+
["spotPositionSizeLimitB", (0, import_kit68.getU64Decoder)()]
|
|
9492
9509
|
]);
|
|
9493
9510
|
}
|
|
9494
9511
|
function getUpdateMarketInstructionDataCodec() {
|
|
@@ -10163,7 +10180,7 @@ async function createAddressLookupTableInstructions(authority, addresses, recent
|
|
|
10163
10180
|
authority,
|
|
10164
10181
|
payer: authority
|
|
10165
10182
|
});
|
|
10166
|
-
return { instructions: [createInstruction, extendInstruction], lookupTableAddress: pda[0] };
|
|
10183
|
+
return { instructions: [createInstruction, extendInstruction], lookupTableAddress: pda[0], addresses };
|
|
10167
10184
|
}
|
|
10168
10185
|
|
|
10169
10186
|
// src/utils/lpPositionMath.ts
|
|
@@ -10271,6 +10288,97 @@ function calculateProtocolFee(collateralAmount, borrowAmount, protocolFeeRateOnC
|
|
|
10271
10288
|
return collateralAmount * BigInt(protocolFeeRateOnCollateral) / BigInt(HUNDRED_PERCENT) + borrowAmount * BigInt(protocolFeeRate) / BigInt(HUNDRED_PERCENT);
|
|
10272
10289
|
}
|
|
10273
10290
|
|
|
10291
|
+
// src/utils/spotPositionMath.ts
|
|
10292
|
+
var import_fusionamm_core4 = require("@crypticdot/fusionamm-core");
|
|
10293
|
+
function getIncreaseSpotPositionQuote(args) {
|
|
10294
|
+
const {
|
|
10295
|
+
fusionPool,
|
|
10296
|
+
tickArrays,
|
|
10297
|
+
leverage,
|
|
10298
|
+
protocolFeeRate,
|
|
10299
|
+
protocolFeeRateOnCollateral,
|
|
10300
|
+
totalAmount,
|
|
10301
|
+
collateralToken,
|
|
10302
|
+
positionToken
|
|
10303
|
+
} = args;
|
|
10304
|
+
if (leverage < 1) {
|
|
10305
|
+
throw new Error("leverage must be greater or equal than 1.0");
|
|
10306
|
+
}
|
|
10307
|
+
if (protocolFeeRate < 0) {
|
|
10308
|
+
throw new Error("protocolFeeRate must be greater or equal than zero");
|
|
10309
|
+
}
|
|
10310
|
+
if (protocolFeeRateOnCollateral < 0) {
|
|
10311
|
+
throw new Error("protocolFeeRate must be greater or equal than zero");
|
|
10312
|
+
}
|
|
10313
|
+
if (totalAmount < 0) {
|
|
10314
|
+
throw new Error("totalAmount must be greater or equal than zero");
|
|
10315
|
+
}
|
|
10316
|
+
if (totalAmount == 0n) {
|
|
10317
|
+
return {
|
|
10318
|
+
collateral: 0n,
|
|
10319
|
+
borrow: 0n,
|
|
10320
|
+
protocolFeeA: 0n,
|
|
10321
|
+
protocolFeeB: 0n,
|
|
10322
|
+
priceImpact: 0
|
|
10323
|
+
};
|
|
10324
|
+
}
|
|
10325
|
+
let borrow;
|
|
10326
|
+
let collateral;
|
|
10327
|
+
let nextSqrtPrice = fusionPool.sqrtPrice;
|
|
10328
|
+
if (positionToken != collateralToken) {
|
|
10329
|
+
const price = (0, import_fusionamm_core4.sqrtPriceToPrice)(fusionPool.sqrtPrice, 1, 1);
|
|
10330
|
+
const totalAmountInOppositeToken = BigInt(
|
|
10331
|
+
Math.floor(positionToken == 0 /* A */ ? Number(totalAmount) / price : Number(totalAmount) * price)
|
|
10332
|
+
);
|
|
10333
|
+
const swapQuote = (0, import_fusionamm_core4.swapQuoteByOutputToken)(
|
|
10334
|
+
totalAmountInOppositeToken,
|
|
10335
|
+
positionToken == 0 /* A */,
|
|
10336
|
+
0,
|
|
10337
|
+
fusionPool,
|
|
10338
|
+
tickArrays
|
|
10339
|
+
);
|
|
10340
|
+
nextSqrtPrice = swapQuote.nextSqrtPrice;
|
|
10341
|
+
const inputAmount = swapQuote.tokenEstIn;
|
|
10342
|
+
collateral = leverage > 1 ? BigInt(Math.floor(Number(inputAmount) / leverage)) : inputAmount;
|
|
10343
|
+
borrow = inputAmount - collateral;
|
|
10344
|
+
} else {
|
|
10345
|
+
if (leverage > 1) {
|
|
10346
|
+
collateral = BigInt(Math.floor(Number(totalAmount) / leverage));
|
|
10347
|
+
const swapQuote = (0, import_fusionamm_core4.swapQuoteByOutputToken)(
|
|
10348
|
+
totalAmount - collateral,
|
|
10349
|
+
positionToken == 0 /* A */,
|
|
10350
|
+
0,
|
|
10351
|
+
fusionPool,
|
|
10352
|
+
tickArrays
|
|
10353
|
+
);
|
|
10354
|
+
nextSqrtPrice = swapQuote.nextSqrtPrice;
|
|
10355
|
+
borrow = swapQuote.tokenEstIn;
|
|
10356
|
+
} else {
|
|
10357
|
+
collateral = totalAmount;
|
|
10358
|
+
borrow = 0n;
|
|
10359
|
+
}
|
|
10360
|
+
}
|
|
10361
|
+
const collateralExcludingFee = collateral;
|
|
10362
|
+
const borrowExcludingFee = borrow;
|
|
10363
|
+
collateral = reverseApplyTunaProtocolFee(collateral, protocolFeeRateOnCollateral);
|
|
10364
|
+
borrow = reverseApplyTunaProtocolFee(borrow, protocolFeeRate);
|
|
10365
|
+
const protocolFeeA = (collateralToken == 0 /* A */ ? collateral - collateralExcludingFee : 0n) + (positionToken == 1 /* B */ ? borrow - borrowExcludingFee : 0n);
|
|
10366
|
+
const protocolFeeB = (collateralToken == 1 /* B */ ? collateral - collateralExcludingFee : 0n) + (positionToken == 0 /* A */ ? borrow - borrowExcludingFee : 0n);
|
|
10367
|
+
const oldPrice = (0, import_fusionamm_core4.sqrtPriceToPrice)(fusionPool.sqrtPrice, 1, 1);
|
|
10368
|
+
const newPrice = (0, import_fusionamm_core4.sqrtPriceToPrice)(nextSqrtPrice, 1, 1);
|
|
10369
|
+
const priceImpact = Math.abs(newPrice / oldPrice - 1) * 100;
|
|
10370
|
+
return {
|
|
10371
|
+
collateral,
|
|
10372
|
+
borrow,
|
|
10373
|
+
protocolFeeA,
|
|
10374
|
+
protocolFeeB,
|
|
10375
|
+
priceImpact
|
|
10376
|
+
};
|
|
10377
|
+
}
|
|
10378
|
+
function reverseApplyTunaProtocolFee(amount, protocolFeeRate) {
|
|
10379
|
+
return amount * BigInt(HUNDRED_PERCENT) / BigInt(HUNDRED_PERCENT - protocolFeeRate);
|
|
10380
|
+
}
|
|
10381
|
+
|
|
10274
10382
|
// src/txbuilder/increaseTunaLpPositionOrca.ts
|
|
10275
10383
|
var import_whirlpools_client2 = require("@orca-so/whirlpools-client");
|
|
10276
10384
|
var import_whirlpools_core2 = require("@orca-so/whirlpools-core");
|
|
@@ -10504,7 +10612,7 @@ async function increaseTunaLpPositionOrcaInstruction(authority, tunaPosition, tu
|
|
|
10504
10612
|
|
|
10505
10613
|
// src/txbuilder/increaseTunaLpPositionFusion.ts
|
|
10506
10614
|
var import_fusionamm_client2 = require("@crypticdot/fusionamm-client");
|
|
10507
|
-
var
|
|
10615
|
+
var import_fusionamm_core5 = require("@crypticdot/fusionamm-core");
|
|
10508
10616
|
var import_kit80 = require("@solana/kit");
|
|
10509
10617
|
var import_memo2 = require("@solana-program/memo");
|
|
10510
10618
|
var import_token_20223 = require("@solana-program/token-2022");
|
|
@@ -10574,12 +10682,12 @@ async function increaseTunaLpPositionFusionInstructions(rpc, authority, position
|
|
|
10574
10682
|
mintB.programAddress
|
|
10575
10683
|
);
|
|
10576
10684
|
createInstructions.push(...createFeeRecipientAtaBInstructions.init);
|
|
10577
|
-
const lowerTickArrayStartIndex = (0,
|
|
10685
|
+
const lowerTickArrayStartIndex = (0, import_fusionamm_core5.getTickArrayStartTickIndex)(
|
|
10578
10686
|
tunaPosition.data.tickLowerIndex,
|
|
10579
10687
|
fusionPool.data.tickSpacing
|
|
10580
10688
|
);
|
|
10581
10689
|
const [lowerTickArrayAddress] = await (0, import_fusionamm_client2.getTickArrayAddress)(fusionPool.address, lowerTickArrayStartIndex);
|
|
10582
|
-
const upperTickArrayStartIndex = (0,
|
|
10690
|
+
const upperTickArrayStartIndex = (0, import_fusionamm_core5.getTickArrayStartTickIndex)(
|
|
10583
10691
|
tunaPosition.data.tickUpperIndex,
|
|
10584
10692
|
fusionPool.data.tickSpacing
|
|
10585
10693
|
);
|
|
@@ -13503,7 +13611,7 @@ async function openAndIncreaseTunaLpPositionOrcaInstruction(authority, positionM
|
|
|
13503
13611
|
|
|
13504
13612
|
// src/txbuilder/openAndIncreaseTunaLpPositionFusion.ts
|
|
13505
13613
|
var import_fusionamm_client14 = require("@crypticdot/fusionamm-client");
|
|
13506
|
-
var
|
|
13614
|
+
var import_fusionamm_core6 = require("@crypticdot/fusionamm-core");
|
|
13507
13615
|
var import_kit97 = require("@solana/kit");
|
|
13508
13616
|
var import_sysvars2 = require("@solana/sysvars");
|
|
13509
13617
|
var import_memo19 = require("@solana-program/memo");
|
|
@@ -13575,9 +13683,9 @@ async function openAndIncreaseTunaLpPositionFusionInstructions(rpc, authority, f
|
|
|
13575
13683
|
mintB.programAddress
|
|
13576
13684
|
);
|
|
13577
13685
|
createInstructions.push(...createFeeRecipientAtaBInstructions.init);
|
|
13578
|
-
const lowerTickArrayIndex = (0,
|
|
13686
|
+
const lowerTickArrayIndex = (0, import_fusionamm_core6.getTickArrayStartTickIndex)(args.tickLowerIndex, fusionPool.data.tickSpacing);
|
|
13579
13687
|
const [lowerTickArrayAddress] = await (0, import_fusionamm_client14.getTickArrayAddress)(fusionPool.address, lowerTickArrayIndex);
|
|
13580
|
-
const upperTickArrayIndex = (0,
|
|
13688
|
+
const upperTickArrayIndex = (0, import_fusionamm_core6.getTickArrayStartTickIndex)(args.tickUpperIndex, fusionPool.data.tickSpacing);
|
|
13581
13689
|
const [upperTickArrayAddress] = await (0, import_fusionamm_client14.getTickArrayAddress)(fusionPool.address, upperTickArrayIndex);
|
|
13582
13690
|
const [lowerTickArray, upperTickArray] = await (0, import_fusionamm_client14.fetchAllMaybeTickArray)(rpc, [
|
|
13583
13691
|
lowerTickArrayAddress,
|
|
@@ -14645,6 +14753,7 @@ async function withdrawInstruction(authority, mint, funds, shares) {
|
|
|
14645
14753
|
var import_fusionamm_client18 = require("@crypticdot/fusionamm-client");
|
|
14646
14754
|
var import_whirlpools_client17 = require("@orca-so/whirlpools-client");
|
|
14647
14755
|
var import_kit102 = require("@solana/kit");
|
|
14756
|
+
var import_address_lookup_table2 = require("@solana-program/address-lookup-table");
|
|
14648
14757
|
var import_memo26 = require("@solana-program/memo");
|
|
14649
14758
|
var import_system2 = require("@solana-program/system");
|
|
14650
14759
|
var import_token2 = require("@solana-program/token");
|
|
@@ -14728,6 +14837,19 @@ async function createAddressLookupTableForMarketInstructions(rpc, poolAddress, m
|
|
|
14728
14837
|
const addresses = await getAddressesForMarketLookupTable(rpc, poolAddress, marketMaker);
|
|
14729
14838
|
return createAddressLookupTableInstructions(authority, addresses, recentSlot);
|
|
14730
14839
|
}
|
|
14840
|
+
async function extendAddressLookupTableForMarketInstructions(rpc, poolAddress, marketMaker, authority, lookupTableAddress) {
|
|
14841
|
+
const marketAddresses = await getAddressesForMarketLookupTable(rpc, poolAddress, marketMaker);
|
|
14842
|
+
const lookupTable = await (0, import_address_lookup_table2.fetchAddressLookupTable)(rpc, lookupTableAddress);
|
|
14843
|
+
const existingAddresses = lookupTable.data.addresses;
|
|
14844
|
+
const addresses = marketAddresses.filter((addr) => !existingAddresses.includes(addr));
|
|
14845
|
+
const extendInstruction = (0, import_address_lookup_table2.getExtendLookupTableInstruction)({
|
|
14846
|
+
address: lookupTableAddress,
|
|
14847
|
+
addresses,
|
|
14848
|
+
authority,
|
|
14849
|
+
payer: authority
|
|
14850
|
+
});
|
|
14851
|
+
return { instructions: [extendInstruction], lookupTableAddress, addresses };
|
|
14852
|
+
}
|
|
14731
14853
|
|
|
14732
14854
|
// src/txbuilder/repayTunaLpPositionDebt.ts
|
|
14733
14855
|
var import_memo27 = require("@solana-program/memo");
|
|
@@ -15296,6 +15418,7 @@ async function rebalanceTunaLpPositionFusionInstruction(authority, tunaPosition,
|
|
|
15296
15418
|
TUNA_ERROR__POSITION_IS_LIQUIDATED,
|
|
15297
15419
|
TUNA_ERROR__POSITION_IS_UNHEALTHY,
|
|
15298
15420
|
TUNA_ERROR__POSITION_NOT_EMPTY,
|
|
15421
|
+
TUNA_ERROR__POSITION_SIZE_LIMIT_EXCEEDED,
|
|
15299
15422
|
TUNA_ERROR__PROTOCOL_FEE_IS_OUT_OF_RANGE,
|
|
15300
15423
|
TUNA_ERROR__REBALANCE_CONDITIONS_NOT_MET,
|
|
15301
15424
|
TUNA_ERROR__RECIPIENT_ACCOUNT_IS_NOT_SET,
|
|
@@ -15384,6 +15507,7 @@ async function rebalanceTunaLpPositionFusionInstruction(authority, tunaPosition,
|
|
|
15384
15507
|
decreaseTunaSpotPositionOrcaInstructions,
|
|
15385
15508
|
depositInstruction,
|
|
15386
15509
|
depositInstructions,
|
|
15510
|
+
extendAddressLookupTableForMarketInstructions,
|
|
15387
15511
|
fetchAllLendingPosition,
|
|
15388
15512
|
fetchAllLendingPositionWithFilter,
|
|
15389
15513
|
fetchAllMarket,
|
|
@@ -15508,6 +15632,7 @@ async function rebalanceTunaLpPositionFusionInstruction(authority, tunaPosition,
|
|
|
15508
15632
|
getDepositInstructionDataDecoder,
|
|
15509
15633
|
getDepositInstructionDataEncoder,
|
|
15510
15634
|
getIncreaseLpPositionQuote,
|
|
15635
|
+
getIncreaseSpotPositionQuote,
|
|
15511
15636
|
getIncreaseTunaLpPositionFusionDiscriminatorBytes,
|
|
15512
15637
|
getIncreaseTunaLpPositionFusionInstruction,
|
|
15513
15638
|
getIncreaseTunaLpPositionFusionInstructionDataCodec,
|
package/dist/index.mjs
CHANGED
|
@@ -310,7 +310,9 @@ function getMarketEncoder() {
|
|
|
310
310
|
["borrowLimitB", getU64Encoder2()],
|
|
311
311
|
["maxSwapSlippage", getU32Encoder()],
|
|
312
312
|
["rebalanceProtocolFee", getU32Encoder()],
|
|
313
|
-
["
|
|
313
|
+
["spotPositionSizeLimitA", getU64Encoder2()],
|
|
314
|
+
["spotPositionSizeLimitB", getU64Encoder2()],
|
|
315
|
+
["reserved", fixEncoderSize2(getBytesEncoder2(), 191)]
|
|
314
316
|
]),
|
|
315
317
|
(value) => ({ ...value, discriminator: MARKET_DISCRIMINATOR })
|
|
316
318
|
);
|
|
@@ -337,7 +339,9 @@ function getMarketDecoder() {
|
|
|
337
339
|
["borrowLimitB", getU64Decoder2()],
|
|
338
340
|
["maxSwapSlippage", getU32Decoder()],
|
|
339
341
|
["rebalanceProtocolFee", getU32Decoder()],
|
|
340
|
-
["
|
|
342
|
+
["spotPositionSizeLimitA", getU64Decoder2()],
|
|
343
|
+
["spotPositionSizeLimitB", getU64Decoder2()],
|
|
344
|
+
["reserved", fixDecoderSize2(getBytesDecoder2(), 191)]
|
|
341
345
|
]);
|
|
342
346
|
}
|
|
343
347
|
function getMarketCodec() {
|
|
@@ -1575,6 +1579,7 @@ var TUNA_ERROR__POSITION_IS_AUTO_REBALANCEABLE = 6057;
|
|
|
1575
1579
|
var TUNA_ERROR__INCORRECT_POSITION_DIRECTION = 6058;
|
|
1576
1580
|
var TUNA_ERROR__RECIPIENT_ACCOUNT_IS_NOT_SET = 6059;
|
|
1577
1581
|
var TUNA_ERROR__M_A_PRICE_DEVIATION_THRESHOLD_EXCEEDED = 6060;
|
|
1582
|
+
var TUNA_ERROR__POSITION_SIZE_LIMIT_EXCEEDED = 6061;
|
|
1578
1583
|
var tunaErrorMessages;
|
|
1579
1584
|
if (process.env.NODE_ENV !== "production") {
|
|
1580
1585
|
tunaErrorMessages = {
|
|
@@ -1610,6 +1615,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
1610
1615
|
[TUNA_ERROR__POSITION_IS_LIQUIDATED]: `Position is already liquidated`,
|
|
1611
1616
|
[TUNA_ERROR__POSITION_IS_UNHEALTHY]: `Position is unhealthy`,
|
|
1612
1617
|
[TUNA_ERROR__POSITION_NOT_EMPTY]: `Position is not empty`,
|
|
1618
|
+
[TUNA_ERROR__POSITION_SIZE_LIMIT_EXCEEDED]: `Position size exceeds the maximum allowed value`,
|
|
1613
1619
|
[TUNA_ERROR__PROTOCOL_FEE_IS_OUT_OF_RANGE]: `Protocol fee is out of range`,
|
|
1614
1620
|
[TUNA_ERROR__REBALANCE_CONDITIONS_NOT_MET]: `Rebalance conditions are not met`,
|
|
1615
1621
|
[TUNA_ERROR__RECIPIENT_ACCOUNT_IS_NOT_SET]: `Optional recipient account is not set`,
|
|
@@ -3271,7 +3277,9 @@ function getCreateMarketInstructionDataEncoder() {
|
|
|
3271
3277
|
["borrowLimitA", getU64Encoder6()],
|
|
3272
3278
|
["borrowLimitB", getU64Encoder6()],
|
|
3273
3279
|
["maxSwapSlippage", getU32Encoder7()],
|
|
3274
|
-
["rebalanceProtocolFee", getU32Encoder7()]
|
|
3280
|
+
["rebalanceProtocolFee", getU32Encoder7()],
|
|
3281
|
+
["spotPositionSizeLimitA", getU64Encoder6()],
|
|
3282
|
+
["spotPositionSizeLimitB", getU64Encoder6()]
|
|
3275
3283
|
]),
|
|
3276
3284
|
(value) => ({ ...value, discriminator: CREATE_MARKET_DISCRIMINATOR })
|
|
3277
3285
|
);
|
|
@@ -3292,7 +3300,9 @@ function getCreateMarketInstructionDataDecoder() {
|
|
|
3292
3300
|
["borrowLimitA", getU64Decoder6()],
|
|
3293
3301
|
["borrowLimitB", getU64Decoder6()],
|
|
3294
3302
|
["maxSwapSlippage", getU32Decoder7()],
|
|
3295
|
-
["rebalanceProtocolFee", getU32Decoder7()]
|
|
3303
|
+
["rebalanceProtocolFee", getU32Decoder7()],
|
|
3304
|
+
["spotPositionSizeLimitA", getU64Decoder6()],
|
|
3305
|
+
["spotPositionSizeLimitB", getU64Decoder6()]
|
|
3296
3306
|
]);
|
|
3297
3307
|
}
|
|
3298
3308
|
function getCreateMarketInstructionDataCodec() {
|
|
@@ -9576,7 +9586,9 @@ function getUpdateMarketInstructionDataEncoder() {
|
|
|
9576
9586
|
["borrowLimitA", getU64Encoder21()],
|
|
9577
9587
|
["borrowLimitB", getU64Encoder21()],
|
|
9578
9588
|
["maxSwapSlippage", getU32Encoder33()],
|
|
9579
|
-
["rebalanceProtocolFee", getU32Encoder33()]
|
|
9589
|
+
["rebalanceProtocolFee", getU32Encoder33()],
|
|
9590
|
+
["spotPositionSizeLimitA", getU64Encoder21()],
|
|
9591
|
+
["spotPositionSizeLimitB", getU64Encoder21()]
|
|
9580
9592
|
]),
|
|
9581
9593
|
(value) => ({ ...value, discriminator: UPDATE_MARKET_DISCRIMINATOR })
|
|
9582
9594
|
);
|
|
@@ -9596,7 +9608,9 @@ function getUpdateMarketInstructionDataDecoder() {
|
|
|
9596
9608
|
["borrowLimitA", getU64Decoder21()],
|
|
9597
9609
|
["borrowLimitB", getU64Decoder21()],
|
|
9598
9610
|
["maxSwapSlippage", getU32Decoder33()],
|
|
9599
|
-
["rebalanceProtocolFee", getU32Decoder33()]
|
|
9611
|
+
["rebalanceProtocolFee", getU32Decoder33()],
|
|
9612
|
+
["spotPositionSizeLimitA", getU64Decoder21()],
|
|
9613
|
+
["spotPositionSizeLimitB", getU64Decoder21()]
|
|
9600
9614
|
]);
|
|
9601
9615
|
}
|
|
9602
9616
|
function getUpdateMarketInstructionDataCodec() {
|
|
@@ -10325,7 +10339,7 @@ async function createAddressLookupTableInstructions(authority, addresses, recent
|
|
|
10325
10339
|
authority,
|
|
10326
10340
|
payer: authority
|
|
10327
10341
|
});
|
|
10328
|
-
return { instructions: [createInstruction, extendInstruction], lookupTableAddress: pda[0] };
|
|
10342
|
+
return { instructions: [createInstruction, extendInstruction], lookupTableAddress: pda[0], addresses };
|
|
10329
10343
|
}
|
|
10330
10344
|
|
|
10331
10345
|
// src/utils/lpPositionMath.ts
|
|
@@ -10441,6 +10455,100 @@ function calculateProtocolFee(collateralAmount, borrowAmount, protocolFeeRateOnC
|
|
|
10441
10455
|
return collateralAmount * BigInt(protocolFeeRateOnCollateral) / BigInt(HUNDRED_PERCENT) + borrowAmount * BigInt(protocolFeeRate) / BigInt(HUNDRED_PERCENT);
|
|
10442
10456
|
}
|
|
10443
10457
|
|
|
10458
|
+
// src/utils/spotPositionMath.ts
|
|
10459
|
+
import {
|
|
10460
|
+
sqrtPriceToPrice,
|
|
10461
|
+
swapQuoteByOutputToken
|
|
10462
|
+
} from "@crypticdot/fusionamm-core";
|
|
10463
|
+
function getIncreaseSpotPositionQuote(args) {
|
|
10464
|
+
const {
|
|
10465
|
+
fusionPool,
|
|
10466
|
+
tickArrays,
|
|
10467
|
+
leverage,
|
|
10468
|
+
protocolFeeRate,
|
|
10469
|
+
protocolFeeRateOnCollateral,
|
|
10470
|
+
totalAmount,
|
|
10471
|
+
collateralToken,
|
|
10472
|
+
positionToken
|
|
10473
|
+
} = args;
|
|
10474
|
+
if (leverage < 1) {
|
|
10475
|
+
throw new Error("leverage must be greater or equal than 1.0");
|
|
10476
|
+
}
|
|
10477
|
+
if (protocolFeeRate < 0) {
|
|
10478
|
+
throw new Error("protocolFeeRate must be greater or equal than zero");
|
|
10479
|
+
}
|
|
10480
|
+
if (protocolFeeRateOnCollateral < 0) {
|
|
10481
|
+
throw new Error("protocolFeeRate must be greater or equal than zero");
|
|
10482
|
+
}
|
|
10483
|
+
if (totalAmount < 0) {
|
|
10484
|
+
throw new Error("totalAmount must be greater or equal than zero");
|
|
10485
|
+
}
|
|
10486
|
+
if (totalAmount == 0n) {
|
|
10487
|
+
return {
|
|
10488
|
+
collateral: 0n,
|
|
10489
|
+
borrow: 0n,
|
|
10490
|
+
protocolFeeA: 0n,
|
|
10491
|
+
protocolFeeB: 0n,
|
|
10492
|
+
priceImpact: 0
|
|
10493
|
+
};
|
|
10494
|
+
}
|
|
10495
|
+
let borrow;
|
|
10496
|
+
let collateral;
|
|
10497
|
+
let nextSqrtPrice = fusionPool.sqrtPrice;
|
|
10498
|
+
if (positionToken != collateralToken) {
|
|
10499
|
+
const price = sqrtPriceToPrice(fusionPool.sqrtPrice, 1, 1);
|
|
10500
|
+
const totalAmountInOppositeToken = BigInt(
|
|
10501
|
+
Math.floor(positionToken == 0 /* A */ ? Number(totalAmount) / price : Number(totalAmount) * price)
|
|
10502
|
+
);
|
|
10503
|
+
const swapQuote = swapQuoteByOutputToken(
|
|
10504
|
+
totalAmountInOppositeToken,
|
|
10505
|
+
positionToken == 0 /* A */,
|
|
10506
|
+
0,
|
|
10507
|
+
fusionPool,
|
|
10508
|
+
tickArrays
|
|
10509
|
+
);
|
|
10510
|
+
nextSqrtPrice = swapQuote.nextSqrtPrice;
|
|
10511
|
+
const inputAmount = swapQuote.tokenEstIn;
|
|
10512
|
+
collateral = leverage > 1 ? BigInt(Math.floor(Number(inputAmount) / leverage)) : inputAmount;
|
|
10513
|
+
borrow = inputAmount - collateral;
|
|
10514
|
+
} else {
|
|
10515
|
+
if (leverage > 1) {
|
|
10516
|
+
collateral = BigInt(Math.floor(Number(totalAmount) / leverage));
|
|
10517
|
+
const swapQuote = swapQuoteByOutputToken(
|
|
10518
|
+
totalAmount - collateral,
|
|
10519
|
+
positionToken == 0 /* A */,
|
|
10520
|
+
0,
|
|
10521
|
+
fusionPool,
|
|
10522
|
+
tickArrays
|
|
10523
|
+
);
|
|
10524
|
+
nextSqrtPrice = swapQuote.nextSqrtPrice;
|
|
10525
|
+
borrow = swapQuote.tokenEstIn;
|
|
10526
|
+
} else {
|
|
10527
|
+
collateral = totalAmount;
|
|
10528
|
+
borrow = 0n;
|
|
10529
|
+
}
|
|
10530
|
+
}
|
|
10531
|
+
const collateralExcludingFee = collateral;
|
|
10532
|
+
const borrowExcludingFee = borrow;
|
|
10533
|
+
collateral = reverseApplyTunaProtocolFee(collateral, protocolFeeRateOnCollateral);
|
|
10534
|
+
borrow = reverseApplyTunaProtocolFee(borrow, protocolFeeRate);
|
|
10535
|
+
const protocolFeeA = (collateralToken == 0 /* A */ ? collateral - collateralExcludingFee : 0n) + (positionToken == 1 /* B */ ? borrow - borrowExcludingFee : 0n);
|
|
10536
|
+
const protocolFeeB = (collateralToken == 1 /* B */ ? collateral - collateralExcludingFee : 0n) + (positionToken == 0 /* A */ ? borrow - borrowExcludingFee : 0n);
|
|
10537
|
+
const oldPrice = sqrtPriceToPrice(fusionPool.sqrtPrice, 1, 1);
|
|
10538
|
+
const newPrice = sqrtPriceToPrice(nextSqrtPrice, 1, 1);
|
|
10539
|
+
const priceImpact = Math.abs(newPrice / oldPrice - 1) * 100;
|
|
10540
|
+
return {
|
|
10541
|
+
collateral,
|
|
10542
|
+
borrow,
|
|
10543
|
+
protocolFeeA,
|
|
10544
|
+
protocolFeeB,
|
|
10545
|
+
priceImpact
|
|
10546
|
+
};
|
|
10547
|
+
}
|
|
10548
|
+
function reverseApplyTunaProtocolFee(amount, protocolFeeRate) {
|
|
10549
|
+
return amount * BigInt(HUNDRED_PERCENT) / BigInt(HUNDRED_PERCENT - protocolFeeRate);
|
|
10550
|
+
}
|
|
10551
|
+
|
|
10444
10552
|
// src/txbuilder/increaseTunaLpPositionOrca.ts
|
|
10445
10553
|
import {
|
|
10446
10554
|
fetchMaybeWhirlpool,
|
|
@@ -15009,6 +15117,7 @@ import { fetchWhirlpool as fetchWhirlpool3, getOracleAddress as getOracleAddress
|
|
|
15009
15117
|
import {
|
|
15010
15118
|
address as address3
|
|
15011
15119
|
} from "@solana/kit";
|
|
15120
|
+
import { fetchAddressLookupTable, getExtendLookupTableInstruction as getExtendLookupTableInstruction2 } from "@solana-program/address-lookup-table";
|
|
15012
15121
|
import { MEMO_PROGRAM_ADDRESS as MEMO_PROGRAM_ADDRESS26 } from "@solana-program/memo";
|
|
15013
15122
|
import { SYSTEM_PROGRAM_ADDRESS } from "@solana-program/system";
|
|
15014
15123
|
import { TOKEN_PROGRAM_ADDRESS as TOKEN_PROGRAM_ADDRESS2 } from "@solana-program/token";
|
|
@@ -15097,6 +15206,19 @@ async function createAddressLookupTableForMarketInstructions(rpc, poolAddress, m
|
|
|
15097
15206
|
const addresses = await getAddressesForMarketLookupTable(rpc, poolAddress, marketMaker);
|
|
15098
15207
|
return createAddressLookupTableInstructions(authority, addresses, recentSlot);
|
|
15099
15208
|
}
|
|
15209
|
+
async function extendAddressLookupTableForMarketInstructions(rpc, poolAddress, marketMaker, authority, lookupTableAddress) {
|
|
15210
|
+
const marketAddresses = await getAddressesForMarketLookupTable(rpc, poolAddress, marketMaker);
|
|
15211
|
+
const lookupTable = await fetchAddressLookupTable(rpc, lookupTableAddress);
|
|
15212
|
+
const existingAddresses = lookupTable.data.addresses;
|
|
15213
|
+
const addresses = marketAddresses.filter((addr) => !existingAddresses.includes(addr));
|
|
15214
|
+
const extendInstruction = getExtendLookupTableInstruction2({
|
|
15215
|
+
address: lookupTableAddress,
|
|
15216
|
+
addresses,
|
|
15217
|
+
authority,
|
|
15218
|
+
payer: authority
|
|
15219
|
+
});
|
|
15220
|
+
return { instructions: [extendInstruction], lookupTableAddress, addresses };
|
|
15221
|
+
}
|
|
15100
15222
|
|
|
15101
15223
|
// src/txbuilder/repayTunaLpPositionDebt.ts
|
|
15102
15224
|
import { MEMO_PROGRAM_ADDRESS as MEMO_PROGRAM_ADDRESS27 } from "@solana-program/memo";
|
|
@@ -15693,6 +15815,7 @@ export {
|
|
|
15693
15815
|
TUNA_ERROR__POSITION_IS_LIQUIDATED,
|
|
15694
15816
|
TUNA_ERROR__POSITION_IS_UNHEALTHY,
|
|
15695
15817
|
TUNA_ERROR__POSITION_NOT_EMPTY,
|
|
15818
|
+
TUNA_ERROR__POSITION_SIZE_LIMIT_EXCEEDED,
|
|
15696
15819
|
TUNA_ERROR__PROTOCOL_FEE_IS_OUT_OF_RANGE,
|
|
15697
15820
|
TUNA_ERROR__REBALANCE_CONDITIONS_NOT_MET,
|
|
15698
15821
|
TUNA_ERROR__RECIPIENT_ACCOUNT_IS_NOT_SET,
|
|
@@ -15781,6 +15904,7 @@ export {
|
|
|
15781
15904
|
decreaseTunaSpotPositionOrcaInstructions,
|
|
15782
15905
|
depositInstruction,
|
|
15783
15906
|
depositInstructions,
|
|
15907
|
+
extendAddressLookupTableForMarketInstructions,
|
|
15784
15908
|
fetchAllLendingPosition,
|
|
15785
15909
|
fetchAllLendingPositionWithFilter,
|
|
15786
15910
|
fetchAllMarket,
|
|
@@ -15905,6 +16029,7 @@ export {
|
|
|
15905
16029
|
getDepositInstructionDataDecoder,
|
|
15906
16030
|
getDepositInstructionDataEncoder,
|
|
15907
16031
|
getIncreaseLpPositionQuote,
|
|
16032
|
+
getIncreaseSpotPositionQuote,
|
|
15908
16033
|
getIncreaseTunaLpPositionFusionDiscriminatorBytes,
|
|
15909
16034
|
getIncreaseTunaLpPositionFusionInstruction,
|
|
15910
16035
|
getIncreaseTunaLpPositionFusionInstructionDataCodec,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crypticdot/defituna-client",
|
|
3
3
|
"description": "Typescript client to interact with DefiTuna's on-chain program.",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.3",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"rimraf": "^6.0.1",
|
|
52
52
|
"vitest": "^3.1.1",
|
|
53
53
|
"solana-bankrun": "^0.4.0",
|
|
54
|
-
"@crypticdot/defituna-program": "3.1.
|
|
54
|
+
"@crypticdot/defituna-program": "3.1.3"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "node ./codama.mjs && tsup src/index.ts --format cjs,esm --dts",
|