@symmetry-hq/temp-v3-sdk 0.0.38 → 0.0.40

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.
@@ -19,3 +19,5 @@ export declare const USDC_DECIMALS = 6;
19
19
  export declare const MAX_SUPPORTED_TOKENS_PER_BASKET: number;
20
20
  export declare const MAX_ORACLES_PER_TOKEN: number;
21
21
  export declare const MAX_EXTRA_DATA_PER_ORACLE: number;
22
+ export declare const LUT_EXTEND_BATCH_SIZE = 20;
23
+ export declare const UPDATE_TOKEN_PRICES_MAX_ACCOUNTS = 50;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MAX_EXTRA_DATA_PER_ORACLE = exports.MAX_ORACLES_PER_TOKEN = exports.MAX_SUPPORTED_TOKENS_PER_BASKET = exports.USDC_DECIMALS = exports.WSOL_DECIMALS = exports.HUNDRED_PERCENT_BPS = exports.X64 = exports.MAX_TRANSFER_TOKENS = exports.MAX_MANAGERS_PER_BASKET = exports.INTENT_TASK_DATA_SIZE = exports.PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT = exports.PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT = exports.MINTS = exports.RENT_SYSVAR_ID = exports.ADDRESS_LOOKUP_TABLE_PROGRAM_ID = exports.METADATA_PROGRAM_ID = exports.BASKETS_V3_PROGRAM_ID = exports.PRIORITY_FEE = exports.COMPUTE_UNITS = void 0;
6
+ exports.UPDATE_TOKEN_PRICES_MAX_ACCOUNTS = exports.LUT_EXTEND_BATCH_SIZE = exports.MAX_EXTRA_DATA_PER_ORACLE = exports.MAX_ORACLES_PER_TOKEN = exports.MAX_SUPPORTED_TOKENS_PER_BASKET = exports.USDC_DECIMALS = exports.WSOL_DECIMALS = exports.HUNDRED_PERCENT_BPS = exports.X64 = exports.MAX_TRANSFER_TOKENS = exports.MAX_MANAGERS_PER_BASKET = exports.INTENT_TASK_DATA_SIZE = exports.PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT = exports.PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT = exports.MINTS = exports.RENT_SYSVAR_ID = exports.ADDRESS_LOOKUP_TABLE_PROGRAM_ID = exports.METADATA_PROGRAM_ID = exports.BASKETS_V3_PROGRAM_ID = exports.PRIORITY_FEE = exports.COMPUTE_UNITS = void 0;
7
7
  const web3_js_1 = require("@solana/web3.js");
8
8
  const decimal_js_1 = __importDefault(require("decimal.js"));
9
9
  exports.COMPUTE_UNITS = 1000000;
@@ -34,3 +34,5 @@ exports.USDC_DECIMALS = 6;
34
34
  exports.MAX_SUPPORTED_TOKENS_PER_BASKET = 100;
35
35
  exports.MAX_ORACLES_PER_TOKEN = 4;
36
36
  exports.MAX_EXTRA_DATA_PER_ORACLE = 4;
37
+ exports.LUT_EXTEND_BATCH_SIZE = 20;
38
+ exports.UPDATE_TOKEN_PRICES_MAX_ACCOUNTS = 50;
@@ -1,16 +1,14 @@
1
1
  import { Connection, PublicKey, TransactionInstruction, TransactionSignature } from '@solana/web3.js';
2
- import { Basket } from './layouts/basket';
2
+ import { getJupTokenLedgerAndSwapInstructions } from './jup';
3
+ import { Basket, FormattedAccumulatedFees, FormattedAddTokenSettings, FormattedAsset, FormattedAutomationSettings, FormattedBasket, FormattedCreatorSettings, FormattedCustomRebalanceSettings, FormattedDepositsSettings, FormattedFeeSettings, FormattedForceRebalanceSettings, FormattedLookupTables, FormattedLpSettings, FormattedMakeDirectSwapSettings, FormattedManagersSettings, FormattedMetadataSettings, FormattedOracle, FormattedOracleAggregator, FormattedOracleSettings, FormattedScheduleSettings, FormattedUpdateWeightsSettings } from './layouts/basket';
3
4
  import { FormattedGlobalConfig, GlobalConfig } from './layouts/config';
4
- import { OracleInput, EditAddTokenSettings, EditAutomationSettings, EditCreatorSettings, EditCustomRebalanceSettings, EditDepositsSettings, EditFeeSettings, EditForceRebalanceSettings, EditLpSettings, EditMakeDirectSwapSettings, EditManagerSettings, EditMetadataSettings, EditScheduleSettings, EditUpdateWeightsSettings, Intent, MakeDirectSwapInput, Settings, TaskContext, TaskType, UpdateWeightsInput, FormattedIntentStatus, FormattedTaskType, FormattedIntent, FormattedBounty, FormattedBountySchedule, AddOrEditTokenInput } from './layouts/intents/intent';
5
- import { FormattedRebalanceType, FormattedRebalanceAction, FormattedOraclePrice, FormattedTokenAuction, FormattedTaskCompletion, FormattedRebalanceIntent } from './layouts/intents/rebalanceIntent';
6
- import { FormattedCreatorSettings, FormattedManagersSettings, FormattedFeeSettings, FormattedScheduleSettings, FormattedAutomationSettings, FormattedLpSettings, FormattedMetadataSettings, FormattedDepositsSettings, FormattedForceRebalanceSettings, FormattedCustomRebalanceSettings, FormattedAddTokenSettings, FormattedUpdateWeightsSettings, FormattedMakeDirectSwapSettings, FormattedAccumulatedFees, FormattedLookupTables, FormattedAsset, FormattedOracleSettings, FormattedOracleAggregator, FormattedOracle, FormattedBasket } from './layouts/basket';
7
- import { RebalanceIntent } from './layouts/intents/rebalanceIntent';
5
+ import { AddOrEditTokenInput, EditAddTokenSettings, EditAutomationSettings, EditCreatorSettings, EditCustomRebalanceSettings, EditDepositsSettings, EditFeeSettings, EditForceRebalanceSettings, EditLpSettings, EditMakeDirectSwapSettings, EditManagerSettings, EditMetadataSettings, EditScheduleSettings, EditUpdateWeightsSettings, FormattedBounty, FormattedBountySchedule, FormattedIntent, FormattedIntentStatus, FormattedTaskType, Intent, MakeDirectSwapInput, OracleInput, Settings, TaskContext, TaskType, UpdateWeightsInput } from './layouts/intents/intent';
6
+ import { FormattedOraclePrice, FormattedRebalanceAction, FormattedRebalanceIntent, FormattedRebalanceType, FormattedTaskCompletion, FormattedTokenAuction, RebalanceIntent } from './layouts/intents/rebalanceIntent';
7
+ import { FormattedOracleType } from './layouts/oracle';
8
8
  import { BasketFilter } from './states/basket';
9
9
  import { IntentFilter } from './states/intents/intent';
10
10
  import { RebalanceIntentFilter } from './states/intents/rebalanceIntent';
11
- import { TxPayloadBatchSequence, VersionedTxs, Wallet } from './txUtils';
12
- import { FormattedOracleType } from './layouts/oracle';
13
- import { getJupTokenLedgerAndSwapInstructions } from './jup';
11
+ import { BasketCreationTx, TxPayloadBatchSequence, VersionedTxs, Wallet } from './txUtils';
14
12
  export declare class SymmetryCore {
15
13
  private sdkParams;
16
14
  constructor(params: {
@@ -58,7 +56,7 @@ export declare class SymmetryCore {
58
56
  host_management_fee_bps: number;
59
57
  host_performance_fee_bps: number;
60
58
  };
61
- }): Promise<TxPayloadBatchSequence>;
59
+ }): Promise<BasketCreationTx>;
62
60
  editCreatorTx(context: TaskContext, settings: EditCreatorSettings): Promise<TxPayloadBatchSequence>;
63
61
  editManagersTx(context: TaskContext, settings: EditManagerSettings): Promise<TxPayloadBatchSequence>;
64
62
  editScheduleTx(context: TaskContext, settings: EditScheduleSettings): Promise<TxPayloadBatchSequence>;
@@ -133,6 +131,17 @@ export declare class SymmetryCore {
133
131
  basket: string;
134
132
  rebalance_intent: string;
135
133
  }): Promise<TxPayloadBatchSequence>;
134
+ /**
135
+ * Build update token prices transactions.
136
+ * For pyth oracle accounts, fetches feed IDs, builds vaa [create init encode], [write verify],
137
+ * [update feed], [close vaa] instructions. For all tokens, builds [update token prices] instructions.
138
+ * and returns TxPayloadBatchSequence ready for signAndSendTxPayloadBatchSequence.
139
+ * Batch layout:
140
+ * batch 0: [ [vaa1CreateInitEncodeIxs], [vaa2CreateInitEncodeIxs], ... ]
141
+ * batch 1: [ [vaa1WriteVerifyIxs], [vaa2WriteVerifyIxs], ... ]
142
+ * batch 2: [ [updateFeed1], [updateFeed2], ... ]
143
+ * batch 3: [ [updateTokenPrices], [...], [closeVaa1Ix, closeVaa2Ix, ...]]
144
+ */
136
145
  updateTokenPricesTx(params: {
137
146
  keeper: string;
138
147
  basket: string;
@@ -173,6 +182,11 @@ export declare class SymmetryCore {
173
182
  claimer: string;
174
183
  basket: string;
175
184
  }): Promise<TxPayloadBatchSequence>;
185
+ rewriteLookupTablesTx(params: {
186
+ signer: string;
187
+ basket_mint: string;
188
+ additional_accounts: string[];
189
+ }): Promise<TxPayloadBatchSequence>;
176
190
  signAndSendVersionedTxs(params: {
177
191
  versionedTxs: VersionedTxs;
178
192
  wallet: Wallet;
package/dist/src/index.js CHANGED
@@ -17,30 +17,33 @@ const decimal_js_1 = __importDefault(require("decimal.js"));
17
17
  const anchor_1 = require("@coral-xyz/anchor");
18
18
  const spl_token_1 = require("@solana/spl-token");
19
19
  const web3_js_1 = require("@solana/web3.js");
20
+ const constants_1 = require("./constants");
20
21
  const claimBounty_1 = require("./instructions/automation/claimBounty");
22
+ const flashSwap_1 = require("./instructions/automation/flashSwap");
21
23
  const priceUpdate_1 = require("./instructions/automation/priceUpdate");
22
24
  const rebalanceIntent_1 = require("./instructions/automation/rebalanceIntent");
25
+ const addBounty_1 = require("./instructions/management/addBounty");
23
26
  const admin_1 = require("./instructions/management/admin");
27
+ const claimFees_1 = require("./instructions/management/claimFees");
24
28
  const createBasket_1 = require("./instructions/management/createBasket");
25
29
  const edit_1 = require("./instructions/management/edit");
30
+ const luts_1 = require("./instructions/management/luts");
26
31
  const pda_1 = require("./instructions/pda");
27
32
  const deposit_1 = require("./instructions/user/deposit");
28
33
  const withdraw_1 = require("./instructions/user/withdraw");
34
+ const jup_1 = require("./jup");
35
+ Object.defineProperty(exports, "getJupTokenLedgerAndSwapInstructions", { enumerable: true, get: function () { return jup_1.getJupTokenLedgerAndSwapInstructions; } });
29
36
  const fraction_1 = require("./layouts/fraction");
30
37
  const intent_1 = require("./layouts/intents/intent");
31
38
  Object.defineProperty(exports, "TaskType", { enumerable: true, get: function () { return intent_1.TaskType; } });
32
39
  const rebalanceIntent_2 = require("./layouts/intents/rebalanceIntent");
40
+ const oracle_1 = require("./layouts/oracle");
33
41
  const basket_1 = require("./states/basket");
42
+ const config_1 = require("./states/config");
34
43
  const intent_2 = require("./states/intents/intent");
35
44
  const rebalanceIntent_3 = require("./states/intents/rebalanceIntent");
45
+ const pythOracle_1 = require("./states/oracles/pythOracle");
36
46
  const txUtils_1 = require("./txUtils");
37
- const config_1 = require("./states/config");
38
- const flashSwap_1 = require("./instructions/automation/flashSwap");
39
- const claimFees_1 = require("./instructions/management/claimFees");
40
- const jup_1 = require("./jup");
41
- Object.defineProperty(exports, "getJupTokenLedgerAndSwapInstructions", { enumerable: true, get: function () { return jup_1.getJupTokenLedgerAndSwapInstructions; } });
42
- const constants_1 = require("./constants");
43
- const addBounty_1 = require("./instructions/management/addBounty");
44
47
  class SymmetryCore {
45
48
  constructor(params) {
46
49
  var _a;
@@ -258,7 +261,11 @@ class SymmetryCore {
258
261
  }]] };
259
262
  let versionedTxs = yield (0, txUtils_1.prepareVersionedTxs)(this.sdkParams.connection, txBatchData);
260
263
  let txPayloadBatchSequence = (0, txUtils_1.prepareTxPayloadBatchSequence)(txBatchData, versionedTxs);
261
- return txPayloadBatchSequence;
264
+ return {
265
+ mint: mint.toBase58(),
266
+ basket: basket.toBase58(),
267
+ batches: txPayloadBatchSequence.batches,
268
+ };
262
269
  });
263
270
  }
264
271
  editCreatorTx(context, settings) {
@@ -855,30 +862,47 @@ class SymmetryCore {
855
862
  return txPayloadBatchSequence;
856
863
  });
857
864
  }
865
+ /**
866
+ * Build update token prices transactions.
867
+ * For pyth oracle accounts, fetches feed IDs, builds vaa [create init encode], [write verify],
868
+ * [update feed], [close vaa] instructions. For all tokens, builds [update token prices] instructions.
869
+ * and returns TxPayloadBatchSequence ready for signAndSendTxPayloadBatchSequence.
870
+ * Batch layout:
871
+ * batch 0: [ [vaa1CreateInitEncodeIxs], [vaa2CreateInitEncodeIxs], ... ]
872
+ * batch 1: [ [vaa1WriteVerifyIxs], [vaa2WriteVerifyIxs], ... ]
873
+ * batch 2: [ [updateFeed1], [updateFeed2], ... ]
874
+ * batch 3: [ [updateTokenPrices], [...], [closeVaa1Ix, closeVaa2Ix, ...]]
875
+ */
858
876
  updateTokenPricesTx(params) {
859
877
  return __awaiter(this, void 0, void 0, function* () {
860
878
  let keeper = new web3_js_1.PublicKey(params.keeper);
861
879
  let rebalanceIntent = new web3_js_1.PublicKey(params.rebalance_intent);
862
880
  let basketRebalanceIntent = (0, pda_1.getRebalanceIntentPda)(new web3_js_1.PublicKey(params.basket), new web3_js_1.PublicKey(params.basket));
863
881
  let basket = yield this.fetchBasket(params.basket);
864
- let ixs = [];
865
- let batchSize = 7;
866
- for (let batchStart = 0; batchStart < basket.numTokens; batchStart += batchSize) {
882
+ let pythPriceFeeds = [];
883
+ let updateTokenPricesIxs = [];
884
+ for (let startIndex = 0; startIndex < basket.numTokens; startIndex++) {
867
885
  let allKeys = [];
868
886
  let tokenIndices = [];
869
- for (let i = batchStart; i < basket.numTokens && i < batchStart + batchSize; i++) {
870
- tokenIndices.push(i);
871
- let agg = basket.composition[i].oracleAggregator;
887
+ for (let endIndex = startIndex; endIndex < basket.numTokens; endIndex++) {
888
+ let numAccounts = basket.composition[endIndex].oracleAggregator.oracles
889
+ .slice(0, basket.composition[endIndex].oracleAggregator.numOracles)
890
+ .reduce((acc, oracle) => acc + oracle.oracleSettings.numRequiredAccounts, 0);
891
+ if (allKeys.length + numAccounts > constants_1.UPDATE_TOKEN_PRICES_MAX_ACCOUNTS)
892
+ break;
893
+ if (tokenIndices.length == 20)
894
+ break;
895
+ startIndex = endIndex;
896
+ tokenIndices.push(endIndex);
897
+ let agg = basket.composition[endIndex].oracleAggregator;
872
898
  for (let i = 0; i < agg.numOracles; i++) {
873
- const oracleData = agg.oracles[i];
899
+ const oracleData = agg.oracles[endIndex];
874
900
  for (let j = 0; j < oracleData.oracleSettings.numRequiredAccounts; j++) {
875
901
  const lutId = oracleData.accountsToLoadLutIds[j];
876
902
  const lutIdx = oracleData.accountsToLoadLutIndices[j];
877
- if (lutId === 0 && lutIdx === 0)
878
- continue;
879
- if (!basket.lutPubkeys)
880
- continue;
881
903
  allKeys.push(basket.lutPubkeys[lutId].state.addresses[lutIdx]);
904
+ if (oracleData.oracleSettings.oracleType === oracle_1.OracleType.Pyth)
905
+ pythPriceFeeds.push(basket.lutPubkeys[lutId].state.addresses[lutIdx]);
882
906
  }
883
907
  }
884
908
  }
@@ -886,7 +910,7 @@ class SymmetryCore {
886
910
  tokenIndices.push(0);
887
911
  // TODO: in last instruction we should include performance fee accounts
888
912
  let performanceFees = basket.settings.fees.hostPerformanceFeeBps + basket.settings.fees.creatorPerformanceFeeBps + basket.settings.fees.managersPerformanceFeeBps;
889
- ixs.push((0, priceUpdate_1.updateTokenPricesIx)({
913
+ updateTokenPricesIxs.push((0, priceUpdate_1.updateTokenPricesIx)({
890
914
  keeper: keeper,
891
915
  basket: basket.ownAddress,
892
916
  rebalanceIntent: rebalanceIntent,
@@ -898,16 +922,67 @@ class SymmetryCore {
898
922
  basketMint: performanceFees > 0 ? basket.mint : undefined,
899
923
  }));
900
924
  }
901
- let txBatchData = { batches: [ixs.map(ix => ({
902
- payer: keeper,
903
- instructions: [
904
- ix,
905
- web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
906
- web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
907
- ],
908
- lookupTables: [basket.lookupTables.active[0], basket.lookupTables.active[1]],
909
- }))] };
925
+ let feedIds = yield (0, pythOracle_1.fetchFeedIdsFromAccounts)(this.sdkParams.connection, pythPriceFeeds);
926
+ const { vaaCreateInitEncodeIxs, vaaWriteVerifyIxs, updateFeedIxs, closeVaaIxs } = yield (0, pythOracle_1.buildPythPriceFeedUpdateIxs)(keeper, feedIds.feedIds);
927
+ let txBatchData = { batches: [
928
+ [
929
+ ...vaaCreateInitEncodeIxs.map(ixs => ({
930
+ payer: keeper,
931
+ instructions: [
932
+ ...ixs.ixs,
933
+ web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
934
+ web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
935
+ ],
936
+ lookupTables: [],
937
+ })),
938
+ ],
939
+ [
940
+ ...vaaWriteVerifyIxs.map(ixs => ({
941
+ payer: keeper,
942
+ instructions: [
943
+ ...ixs,
944
+ web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
945
+ web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
946
+ ],
947
+ lookupTables: [],
948
+ })),
949
+ ],
950
+ [
951
+ ...updateFeedIxs.map(ix => ({
952
+ payer: keeper,
953
+ instructions: [
954
+ ix,
955
+ web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
956
+ web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
957
+ ],
958
+ lookupTables: [],
959
+ })),
960
+ ],
961
+ [
962
+ ...updateTokenPricesIxs.map(ix => ({
963
+ payer: keeper,
964
+ instructions: [
965
+ ix,
966
+ web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
967
+ web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
968
+ ],
969
+ lookupTables: [basket.lookupTables.active[0], basket.lookupTables.active[1]],
970
+ })),
971
+ {
972
+ payer: keeper,
973
+ instructions: [
974
+ ...closeVaaIxs,
975
+ web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
976
+ web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
977
+ ],
978
+ lookupTables: [],
979
+ }
980
+ ],
981
+ ] };
910
982
  let versionedTxs = yield (0, txUtils_1.prepareVersionedTxs)(this.sdkParams.connection, txBatchData);
983
+ for (let [txId, vaaCreateInitEncodeIx] of vaaCreateInitEncodeIxs.entries()) {
984
+ versionedTxs.batches[0][txId].sign([vaaCreateInitEncodeIx.signer]);
985
+ }
911
986
  let txPayloadBatchSequence = (0, txUtils_1.prepareTxPayloadBatchSequence)(txBatchData, versionedTxs);
912
987
  return txPayloadBatchSequence;
913
988
  });
@@ -1148,6 +1223,85 @@ class SymmetryCore {
1148
1223
  return txPayloadBatchSequence;
1149
1224
  });
1150
1225
  }
1226
+ rewriteLookupTablesTx(params) {
1227
+ return __awaiter(this, void 0, void 0, function* () {
1228
+ const signer = new web3_js_1.PublicKey(params.signer);
1229
+ const basketMint = new web3_js_1.PublicKey(params.basket_mint);
1230
+ const additionalAccounts = params.additional_accounts.map(a => new web3_js_1.PublicKey(a));
1231
+ const basketAddress = (0, pda_1.getBasketState)(basketMint);
1232
+ const basket = yield this.fetchBasket(basketAddress.toBase58());
1233
+ const activeLut0 = basket.lookupTables.active[0];
1234
+ const activeLut1 = basket.lookupTables.active[1];
1235
+ let oldTempLut0 = basket.lookupTables.temp[0];
1236
+ let oldTempLut1 = basket.lookupTables.temp[1];
1237
+ const slot = yield this.sdkParams.connection.getSlot("finalized");
1238
+ const newLut0 = (0, pda_1.getLookupTableAccount)(basketAddress, slot);
1239
+ const newLut1 = (0, pda_1.getLookupTableAccount)(basketAddress, slot - 1);
1240
+ // Step 1: create lookup tables
1241
+ const createIx = (0, luts_1.createBasketLookupTablesInstruction)({
1242
+ signer,
1243
+ basket: basketAddress,
1244
+ oldTempLookupTable0: oldTempLut0,
1245
+ oldTempLookupTable1: oldTempLut1,
1246
+ newTempLookupTable0: newLut0,
1247
+ newTempLookupTable1: newLut1,
1248
+ slot,
1249
+ });
1250
+ const txBatchData = { batches: [
1251
+ [{
1252
+ payer: signer,
1253
+ instructions: [
1254
+ createIx,
1255
+ web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
1256
+ web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
1257
+ ],
1258
+ lookupTables: [],
1259
+ }],
1260
+ ] };
1261
+ // Step 2: extend LUTs in batches of ~20
1262
+ const BATCH_SIZE = constants_1.LUT_EXTEND_BATCH_SIZE;
1263
+ for (let i = 0; i < additionalAccounts.length; i += BATCH_SIZE) {
1264
+ const batch = additionalAccounts.slice(i, i + BATCH_SIZE);
1265
+ const extendIx = (0, luts_1.extendBasketLookupTablesIx)({
1266
+ signer,
1267
+ basket: basketAddress,
1268
+ tempLookupTable0: newLut0,
1269
+ tempLookupTable1: newLut1,
1270
+ additionalAccounts: batch,
1271
+ });
1272
+ txBatchData.batches.push([{
1273
+ payer: signer,
1274
+ instructions: [
1275
+ extendIx,
1276
+ web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
1277
+ web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
1278
+ ],
1279
+ lookupTables: [],
1280
+ }]);
1281
+ }
1282
+ // Step 3: overwrite active LUTs
1283
+ const overwriteIx = (0, luts_1.overwriteBasketLookupTablesIx)({
1284
+ signer,
1285
+ basket: basketAddress,
1286
+ tempLookupTable0: newLut0,
1287
+ tempLookupTable1: newLut1,
1288
+ activeLookupTable0: activeLut0,
1289
+ activeLookupTable1: activeLut1,
1290
+ });
1291
+ txBatchData.batches.push([{
1292
+ payer: signer,
1293
+ instructions: [
1294
+ overwriteIx,
1295
+ web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
1296
+ web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
1297
+ ],
1298
+ lookupTables: [],
1299
+ }]);
1300
+ const versionedTxs = yield (0, txUtils_1.prepareVersionedTxs)(this.sdkParams.connection, txBatchData);
1301
+ const txPayloadBatchSequence = (0, txUtils_1.prepareTxPayloadBatchSequence)(txBatchData, versionedTxs);
1302
+ return txPayloadBatchSequence;
1303
+ });
1304
+ }
1151
1305
  signAndSendVersionedTxs(params) {
1152
1306
  return __awaiter(this, void 0, void 0, function* () {
1153
1307
  let { versionedTxs, wallet } = params;
@@ -13,6 +13,7 @@ export declare function extendBasketLookupTablesIx(params: {
13
13
  basket: PublicKey;
14
14
  tempLookupTable0: PublicKey;
15
15
  tempLookupTable1: PublicKey;
16
+ additionalAccounts: PublicKey[];
16
17
  }): TransactionInstruction;
17
18
  export declare function overwriteBasketLookupTablesIx(params: {
18
19
  signer: PublicKey;
@@ -14,24 +14,29 @@ const OVERWRITE_BASKET_LOOKUP_TABLES_DISCRIMINATOR = Buffer.from([197, 116, 189,
14
14
  const CLOSE_DEACTIVATED_LOOKUP_TABLE_DISCRIMINATOR = Buffer.from([19, 4, 214, 20, 26, 43, 71, 233]);
15
15
  function createBasketLookupTablesInstruction(params) {
16
16
  const { signer, basket, oldTempLookupTable0, oldTempLookupTable1, newTempLookupTable0, newTempLookupTable1, slot, } = params;
17
- let newTempLookupTableInfo0 = (0, pda_1.getLookupTableInfoAccount)(newTempLookupTable0);
18
- let newTempLookupTableInfo1 = (0, pda_1.getLookupTableInfoAccount)(newTempLookupTable1);
17
+ const globalConfig = (0, pda_1.getGlobalConfigPda)();
18
+ const hasOldTemp = !oldTempLookupTable0.equals(web3_js_1.PublicKey.default)
19
+ && !oldTempLookupTable1.equals(web3_js_1.PublicKey.default);
19
20
  const data = Buffer.concat([
20
21
  CREATE_BASKET_LOOKUP_TABLES_DISCRIMINATOR,
21
- new anchor_1.BN(slot).toArray("le", 8),
22
+ Buffer.from(new anchor_1.BN(slot).toArray("le", 8)),
22
23
  ]);
23
24
  const keys = [
24
25
  { pubkey: signer, isSigner: true, isWritable: true },
25
26
  { pubkey: basket, isSigner: false, isWritable: true },
26
- { pubkey: oldTempLookupTable0, isSigner: false, isWritable: true },
27
- { pubkey: oldTempLookupTable1, isSigner: false, isWritable: true },
27
+ { pubkey: globalConfig, isSigner: false, isWritable: false },
28
+ { pubkey: hasOldTemp ? oldTempLookupTable0 : constants_1.PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT, isSigner: false, isWritable: true },
29
+ { pubkey: hasOldTemp ? oldTempLookupTable1 : constants_1.PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT, isSigner: false, isWritable: true },
28
30
  { pubkey: newTempLookupTable0, isSigner: false, isWritable: true },
29
31
  { pubkey: newTempLookupTable1, isSigner: false, isWritable: true },
30
- { pubkey: newTempLookupTableInfo0, isSigner: false, isWritable: true },
31
- { pubkey: newTempLookupTableInfo1, isSigner: false, isWritable: true },
32
- { pubkey: constants_1.ADDRESS_LOOKUP_TABLE_PROGRAM_ID, isSigner: false, isWritable: false },
33
- { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
34
32
  ];
33
+ if (hasOldTemp) {
34
+ keys.push({ pubkey: (0, pda_1.getLookupTableInfoAccount)(oldTempLookupTable0), isSigner: false, isWritable: true }, { pubkey: (0, pda_1.getLookupTableInfoAccount)(oldTempLookupTable1), isSigner: false, isWritable: true });
35
+ }
36
+ else {
37
+ keys.push({ pubkey: constants_1.BASKETS_V3_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: constants_1.BASKETS_V3_PROGRAM_ID, isSigner: false, isWritable: false });
38
+ }
39
+ keys.push({ pubkey: constants_1.ADDRESS_LOOKUP_TABLE_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false });
35
40
  return new web3_js_1.TransactionInstruction({
36
41
  keys,
37
42
  programId: constants_1.BASKETS_V3_PROGRAM_ID,
@@ -46,6 +51,7 @@ function extendBasketLookupTablesIx(params) {
46
51
  { pubkey: params.tempLookupTable1, isWritable: true, isSigner: false },
47
52
  { pubkey: constants_1.ADDRESS_LOOKUP_TABLE_PROGRAM_ID, isWritable: false, isSigner: false },
48
53
  { pubkey: web3_js_1.SystemProgram.programId, isWritable: false, isSigner: false },
54
+ ...params.additionalAccounts.map(pubkey => ({ pubkey, isWritable: false, isSigner: false })),
49
55
  ];
50
56
  return new web3_js_1.TransactionInstruction({
51
57
  keys,
@@ -61,6 +67,9 @@ function overwriteBasketLookupTablesIx(params) {
61
67
  { pubkey: params.tempLookupTable1, isWritable: true, isSigner: false },
62
68
  { pubkey: params.activeLookupTable0, isWritable: true, isSigner: false },
63
69
  { pubkey: params.activeLookupTable1, isWritable: true, isSigner: false },
70
+ { pubkey: (0, pda_1.getLookupTableInfoAccount)(params.activeLookupTable0), isWritable: true, isSigner: false },
71
+ { pubkey: (0, pda_1.getLookupTableInfoAccount)(params.activeLookupTable1), isWritable: true, isSigner: false },
72
+ { pubkey: constants_1.ADDRESS_LOOKUP_TABLE_PROGRAM_ID, isWritable: false, isSigner: false },
64
73
  { pubkey: web3_js_1.SystemProgram.programId, isWritable: false, isSigner: false },
65
74
  ];
66
75
  return new web3_js_1.TransactionInstruction({
@@ -10,6 +10,29 @@ export interface RebalanceIntentFilter {
10
10
  pubkey: string;
11
11
  }
12
12
  export declare function fetchRebalanceIntents(connection: Connection, filter?: RebalanceIntentFilter): Promise<RebalanceIntent[]>;
13
+ /**
14
+ * Returns all valid swap pairs available during the rebalance auction phase.
15
+ *
16
+ * **Swap direction (basket perspective):**
17
+ * - `inMint` / `inAmount`: what the basket is supposed to **receive**.
18
+ * - `outMint` / `outAmount`: what the basket wants to **swap** (give away).
19
+ * So each pair describes an **outMint → inMint** swap. When generating swap
20
+ * transactions, use this direction: swap `outMint` → `inMint` (sell outAmount of
21
+ * outMint, receive inAmount of inMint).
22
+ *
23
+ * Only runs when the rebalance is in Auction action and the current time falls
24
+ * within one of the three auction windows. For the active auction, target amounts
25
+ * are refreshed if they haven't been updated since the auction started.
26
+ *
27
+ * Iterates over completed price-update tokens to compute exchange rates via
28
+ * getSwapAmounts (using time-since-start and auction duration). Pairs with
29
+ * positive in/out amounts are collected and sorted by value descending
30
+ * (highest value first).
31
+ *
32
+ * @param rebalanceIntent - The rebalance intent state
33
+ * @param basket - The basket (used to update target amounts when needed)
34
+ * @returns Array of swap pairs, or empty array when not in auction or outside auction windows
35
+ */
13
36
  export declare function getSwapPairs(rebalanceIntent: RebalanceIntent, basket: Basket): {
14
37
  inMint: string;
15
38
  outMint: string;
@@ -436,6 +436,29 @@ class RebalanceIntentRustClass {
436
436
  }
437
437
  }
438
438
  }
439
+ /**
440
+ * Returns all valid swap pairs available during the rebalance auction phase.
441
+ *
442
+ * **Swap direction (basket perspective):**
443
+ * - `inMint` / `inAmount`: what the basket is supposed to **receive**.
444
+ * - `outMint` / `outAmount`: what the basket wants to **swap** (give away).
445
+ * So each pair describes an **outMint → inMint** swap. When generating swap
446
+ * transactions, use this direction: swap `outMint` → `inMint` (sell outAmount of
447
+ * outMint, receive inAmount of inMint).
448
+ *
449
+ * Only runs when the rebalance is in Auction action and the current time falls
450
+ * within one of the three auction windows. For the active auction, target amounts
451
+ * are refreshed if they haven't been updated since the auction started.
452
+ *
453
+ * Iterates over completed price-update tokens to compute exchange rates via
454
+ * getSwapAmounts (using time-since-start and auction duration). Pairs with
455
+ * positive in/out amounts are collected and sorted by value descending
456
+ * (highest value first).
457
+ *
458
+ * @param rebalanceIntent - The rebalance intent state
459
+ * @param basket - The basket (used to update target amounts when needed)
460
+ * @returns Array of swap pairs, or empty array when not in auction or outside auction windows
461
+ */
439
462
  function getSwapPairs(rebalanceIntent, basket) {
440
463
  let rebalanceIntentRustClass = new RebalanceIntentRustClass(rebalanceIntent);
441
464
  if (rebalanceIntentRustClass.self.currentAction !== rebalanceIntent_1.RebalanceAction.Auction)