@symmetry-hq/temp-v3-sdk 0.0.37 → 0.0.39
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/src/constants.d.ts +1 -0
- package/dist/src/constants.js +2 -1
- package/dist/src/index.d.ts +17 -9
- package/dist/src/index.js +123 -7
- package/dist/src/instructions/management/addBounty.js +1 -1
- package/dist/src/instructions/management/luts.d.ts +1 -0
- package/dist/src/instructions/management/luts.js +18 -9
- package/dist/src/states/intents/rebalanceIntent.d.ts +23 -0
- package/dist/src/states/intents/rebalanceIntent.js +23 -0
- package/dist/src/txUtils.d.ts +4 -0
- package/dist/test.js +18 -4
- package/package.json +1 -1
- package/src/constants.ts +2 -0
- package/src/index.ts +188 -41
- package/src/instructions/management/addBounty.ts +1 -1
- package/src/instructions/management/luts.ts +41 -17
- package/src/states/intents/rebalanceIntent.ts +23 -1
- package/src/txUtils.ts +5 -0
- package/test.ts +19 -4
package/dist/src/constants.d.ts
CHANGED
package/dist/src/constants.js
CHANGED
|
@@ -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.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,4 @@ 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;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { Connection, PublicKey, TransactionInstruction, TransactionSignature } from '@solana/web3.js';
|
|
2
|
-
import {
|
|
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 {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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<
|
|
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>;
|
|
@@ -164,10 +162,20 @@ export declare class SymmetryCore {
|
|
|
164
162
|
keeper: string;
|
|
165
163
|
rebalance_intent: string;
|
|
166
164
|
}): Promise<TxPayloadBatchSequence>;
|
|
165
|
+
addBountyTx(params: {
|
|
166
|
+
keeper: string;
|
|
167
|
+
basket: string;
|
|
168
|
+
amount: number;
|
|
169
|
+
}): Promise<TxPayloadBatchSequence>;
|
|
167
170
|
claimBasketFeesTx(params: {
|
|
168
171
|
claimer: string;
|
|
169
172
|
basket: string;
|
|
170
173
|
}): Promise<TxPayloadBatchSequence>;
|
|
174
|
+
rewriteLookupTablesTx(params: {
|
|
175
|
+
signer: string;
|
|
176
|
+
basket_mint: string;
|
|
177
|
+
additional_accounts: string[];
|
|
178
|
+
}): Promise<TxPayloadBatchSequence>;
|
|
171
179
|
signAndSendVersionedTxs(params: {
|
|
172
180
|
versionedTxs: VersionedTxs;
|
|
173
181
|
wallet: Wallet;
|
package/dist/src/index.js
CHANGED
|
@@ -17,29 +17,31 @@ 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");
|
|
33
40
|
const basket_1 = require("./states/basket");
|
|
41
|
+
const config_1 = require("./states/config");
|
|
34
42
|
const intent_2 = require("./states/intents/intent");
|
|
35
43
|
const rebalanceIntent_3 = require("./states/intents/rebalanceIntent");
|
|
36
44
|
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
45
|
class SymmetryCore {
|
|
44
46
|
constructor(params) {
|
|
45
47
|
var _a;
|
|
@@ -257,7 +259,11 @@ class SymmetryCore {
|
|
|
257
259
|
}]] };
|
|
258
260
|
let versionedTxs = yield (0, txUtils_1.prepareVersionedTxs)(this.sdkParams.connection, txBatchData);
|
|
259
261
|
let txPayloadBatchSequence = (0, txUtils_1.prepareTxPayloadBatchSequence)(txBatchData, versionedTxs);
|
|
260
|
-
return
|
|
262
|
+
return {
|
|
263
|
+
mint: mint.toBase58(),
|
|
264
|
+
basket: basket.toBase58(),
|
|
265
|
+
batches: txPayloadBatchSequence.batches,
|
|
266
|
+
};
|
|
261
267
|
});
|
|
262
268
|
}
|
|
263
269
|
editCreatorTx(context, settings) {
|
|
@@ -1068,6 +1074,37 @@ class SymmetryCore {
|
|
|
1068
1074
|
return txPayloadBatchSequence;
|
|
1069
1075
|
});
|
|
1070
1076
|
}
|
|
1077
|
+
addBountyTx(params) {
|
|
1078
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1079
|
+
let keeper = new web3_js_1.PublicKey(params.keeper);
|
|
1080
|
+
let basket = yield this.fetchBasket(params.basket);
|
|
1081
|
+
let globalConfig = yield this.fetchGlobalConfig();
|
|
1082
|
+
let bountyWsolAmount = 0;
|
|
1083
|
+
if (globalConfig.bountyMint.equals(constants_1.MINTS["mainnet"].WSOL)) {
|
|
1084
|
+
bountyWsolAmount = params.amount;
|
|
1085
|
+
}
|
|
1086
|
+
let wsolIxs = yield (0, txUtils_1.wrapWsolIxs)(this.sdkParams.connection, keeper, bountyWsolAmount);
|
|
1087
|
+
let ix = (0, addBounty_1.addBountyIx)({
|
|
1088
|
+
keeper: keeper,
|
|
1089
|
+
basket: basket.ownAddress,
|
|
1090
|
+
bountyMint: basket.settings.bountyMint,
|
|
1091
|
+
amount: params.amount,
|
|
1092
|
+
});
|
|
1093
|
+
let txBatchData = { batches: [[{
|
|
1094
|
+
payer: keeper,
|
|
1095
|
+
instructions: [
|
|
1096
|
+
...wsolIxs,
|
|
1097
|
+
ix,
|
|
1098
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
|
|
1099
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
|
|
1100
|
+
],
|
|
1101
|
+
lookupTables: [],
|
|
1102
|
+
}]] };
|
|
1103
|
+
let versionedTxs = yield (0, txUtils_1.prepareVersionedTxs)(this.sdkParams.connection, txBatchData);
|
|
1104
|
+
let txPayloadBatchSequence = (0, txUtils_1.prepareTxPayloadBatchSequence)(txBatchData, versionedTxs);
|
|
1105
|
+
return txPayloadBatchSequence;
|
|
1106
|
+
});
|
|
1107
|
+
}
|
|
1071
1108
|
claimBasketFeesTx(params) {
|
|
1072
1109
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1073
1110
|
let claimer = new web3_js_1.PublicKey(params.claimer);
|
|
@@ -1116,6 +1153,85 @@ class SymmetryCore {
|
|
|
1116
1153
|
return txPayloadBatchSequence;
|
|
1117
1154
|
});
|
|
1118
1155
|
}
|
|
1156
|
+
rewriteLookupTablesTx(params) {
|
|
1157
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1158
|
+
const signer = new web3_js_1.PublicKey(params.signer);
|
|
1159
|
+
const basketMint = new web3_js_1.PublicKey(params.basket_mint);
|
|
1160
|
+
const additionalAccounts = params.additional_accounts.map(a => new web3_js_1.PublicKey(a));
|
|
1161
|
+
const basketAddress = (0, pda_1.getBasketState)(basketMint);
|
|
1162
|
+
const basket = yield this.fetchBasket(basketAddress.toBase58());
|
|
1163
|
+
const activeLut0 = basket.lookupTables.active[0];
|
|
1164
|
+
const activeLut1 = basket.lookupTables.active[1];
|
|
1165
|
+
let oldTempLut0 = basket.lookupTables.temp[0];
|
|
1166
|
+
let oldTempLut1 = basket.lookupTables.temp[1];
|
|
1167
|
+
const slot = yield this.sdkParams.connection.getSlot("finalized");
|
|
1168
|
+
const newLut0 = (0, pda_1.getLookupTableAccount)(basketAddress, slot);
|
|
1169
|
+
const newLut1 = (0, pda_1.getLookupTableAccount)(basketAddress, slot - 1);
|
|
1170
|
+
// Step 1: create lookup tables
|
|
1171
|
+
const createIx = (0, luts_1.createBasketLookupTablesInstruction)({
|
|
1172
|
+
signer,
|
|
1173
|
+
basket: basketAddress,
|
|
1174
|
+
oldTempLookupTable0: oldTempLut0,
|
|
1175
|
+
oldTempLookupTable1: oldTempLut1,
|
|
1176
|
+
newTempLookupTable0: newLut0,
|
|
1177
|
+
newTempLookupTable1: newLut1,
|
|
1178
|
+
slot,
|
|
1179
|
+
});
|
|
1180
|
+
const txBatchData = { batches: [
|
|
1181
|
+
[{
|
|
1182
|
+
payer: signer,
|
|
1183
|
+
instructions: [
|
|
1184
|
+
createIx,
|
|
1185
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
|
|
1186
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
|
|
1187
|
+
],
|
|
1188
|
+
lookupTables: [],
|
|
1189
|
+
}],
|
|
1190
|
+
] };
|
|
1191
|
+
// Step 2: extend LUTs in batches of ~20
|
|
1192
|
+
const BATCH_SIZE = constants_1.LUT_EXTEND_BATCH_SIZE;
|
|
1193
|
+
for (let i = 0; i < additionalAccounts.length; i += BATCH_SIZE) {
|
|
1194
|
+
const batch = additionalAccounts.slice(i, i + BATCH_SIZE);
|
|
1195
|
+
const extendIx = (0, luts_1.extendBasketLookupTablesIx)({
|
|
1196
|
+
signer,
|
|
1197
|
+
basket: basketAddress,
|
|
1198
|
+
tempLookupTable0: newLut0,
|
|
1199
|
+
tempLookupTable1: newLut1,
|
|
1200
|
+
additionalAccounts: batch,
|
|
1201
|
+
});
|
|
1202
|
+
txBatchData.batches.push([{
|
|
1203
|
+
payer: signer,
|
|
1204
|
+
instructions: [
|
|
1205
|
+
extendIx,
|
|
1206
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
|
|
1207
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
|
|
1208
|
+
],
|
|
1209
|
+
lookupTables: [],
|
|
1210
|
+
}]);
|
|
1211
|
+
}
|
|
1212
|
+
// Step 3: overwrite active LUTs
|
|
1213
|
+
const overwriteIx = (0, luts_1.overwriteBasketLookupTablesIx)({
|
|
1214
|
+
signer,
|
|
1215
|
+
basket: basketAddress,
|
|
1216
|
+
tempLookupTable0: newLut0,
|
|
1217
|
+
tempLookupTable1: newLut1,
|
|
1218
|
+
activeLookupTable0: activeLut0,
|
|
1219
|
+
activeLookupTable1: activeLut1,
|
|
1220
|
+
});
|
|
1221
|
+
txBatchData.batches.push([{
|
|
1222
|
+
payer: signer,
|
|
1223
|
+
instructions: [
|
|
1224
|
+
overwriteIx,
|
|
1225
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
|
|
1226
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
|
|
1227
|
+
],
|
|
1228
|
+
lookupTables: [],
|
|
1229
|
+
}]);
|
|
1230
|
+
const versionedTxs = yield (0, txUtils_1.prepareVersionedTxs)(this.sdkParams.connection, txBatchData);
|
|
1231
|
+
const txPayloadBatchSequence = (0, txUtils_1.prepareTxPayloadBatchSequence)(txBatchData, versionedTxs);
|
|
1232
|
+
return txPayloadBatchSequence;
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1119
1235
|
signAndSendVersionedTxs(params) {
|
|
1120
1236
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1121
1237
|
let { versionedTxs, wallet } = params;
|
|
@@ -12,7 +12,7 @@ function addBountyIx(params) {
|
|
|
12
12
|
let bountyVault = (0, pda_1.getBountyVaultPda)();
|
|
13
13
|
let globalConfig = (0, pda_1.getGlobalConfigPda)();
|
|
14
14
|
let keeperBountyAta = (0, pda_1.getAta)(keeper, bountyMint);
|
|
15
|
-
let bountyVaultAta = (0, pda_1.getAta)(
|
|
15
|
+
let bountyVaultAta = (0, pda_1.getAta)(bountyVault, bountyMint);
|
|
16
16
|
const data = Buffer.concat([
|
|
17
17
|
ADD_BOUNTY_DISCRIMINATOR,
|
|
18
18
|
Buffer.from(new anchor_1.BN(amount).toArray("le", 8)), // u64 LE
|
|
@@ -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
|
-
|
|
18
|
-
|
|
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:
|
|
27
|
-
{ pubkey:
|
|
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)
|
package/dist/src/txUtils.d.ts
CHANGED
|
@@ -46,6 +46,10 @@ export interface TxPayloadBatch {
|
|
|
46
46
|
export interface TxPayloadBatchSequence {
|
|
47
47
|
batches: TxPayloadBatch[];
|
|
48
48
|
}
|
|
49
|
+
export interface BasketCreationTx extends TxPayloadBatchSequence {
|
|
50
|
+
mint: string;
|
|
51
|
+
basket: string;
|
|
52
|
+
}
|
|
49
53
|
export declare function prepareTxPayloadBatchSequence(txBatchData: TxBatchData, versionedTxs?: VersionedTxs): TxPayloadBatchSequence;
|
|
50
54
|
export declare function delay(ms: number): Promise<void>;
|
|
51
55
|
export declare function getMultipleAccountsInfoBatched(connection: Connection, pubkeys: PublicKey[]): Promise<Map<string, AccountInfo<Buffer> | null>>;
|
package/dist/test.js
CHANGED
|
@@ -22,6 +22,7 @@ let connection = new web3_js_1.Connection("https://api.devnet.solana.com");
|
|
|
22
22
|
function testStates() {
|
|
23
23
|
return __awaiter(this, void 0, void 0, function* () {
|
|
24
24
|
var _a, _b;
|
|
25
|
+
return;
|
|
25
26
|
let wallet = new anchor_1.Wallet(web3_js_1.Keypair.fromSecretKey(new Uint8Array(kp)));
|
|
26
27
|
console.log(wallet.publicKey.toBase58());
|
|
27
28
|
let sdk = new src_1.SymmetryCore({
|
|
@@ -45,12 +46,16 @@ function testStates() {
|
|
|
45
46
|
let basket = yield sdk.fetchBasket("GrBFFvtdRL25o7gcRnV1kGvz1Qc7iscUmDp1ZvyBSyUa");
|
|
46
47
|
basket = yield sdk.loadBasketPrice(basket);
|
|
47
48
|
console.log(basket.formatted);
|
|
49
|
+
// console.log(basket.composition[0].mint.toBase58(), "amount:", basket.composition[0].amount.toString(), "price:", basket.composition[0].price?.price, "value:", basket.composition[0].value);
|
|
50
|
+
// console.log(basket.composition[1].mint.toBase58(), "amount:", basket.composition[1].amount.toString(), "price:", basket.composition[1].price?.price, "value:", basket.composition[1].value);
|
|
51
|
+
// console.log(basket.composition[2].mint.toBase58(), "amount:", basket.composition[2].amount.toString(), "price:", basket.composition[2].price?.price, "value:", basket.composition[2].value);
|
|
48
52
|
// return;
|
|
49
53
|
let tests = {
|
|
50
54
|
createGlobalConfig: false, // TESTED
|
|
51
55
|
editGlobalConfig: false, // TESTED
|
|
52
56
|
createBasket: false, // TESTED
|
|
53
57
|
editPrivateBasketSettings: false, // NOT TESTED
|
|
58
|
+
addBounty: false, // TESTED
|
|
54
59
|
editCreator: false, // TESTED
|
|
55
60
|
editManagerSettings: false, // TESTED
|
|
56
61
|
editFeeSettings: false, // TESTED
|
|
@@ -59,20 +64,20 @@ function testStates() {
|
|
|
59
64
|
editLpSettings: false, // TESTED
|
|
60
65
|
editMetadata: false, // TESTED
|
|
61
66
|
editDepositsSettings: false, // TESTED
|
|
62
|
-
editForceRebalanceSettings: false, //
|
|
63
|
-
editCustomRebalanceSettings: false, //
|
|
67
|
+
editForceRebalanceSettings: false, // TESTED
|
|
68
|
+
editCustomRebalanceSettings: false, // TESTED
|
|
64
69
|
editAddTokenDelay: false, // NOT TESTED
|
|
65
70
|
editUpdateWeightsDelay: false, // NOT TESTED
|
|
66
71
|
editMakeDirectSwapDelay: false, // NOT TESTED
|
|
67
72
|
addOrEditToken: false, // TESTED
|
|
68
73
|
updateWeights: false, // NOT TESTED
|
|
69
74
|
makeDirectSwap: false, // NOT TESTED
|
|
70
|
-
executeIntent: false, //
|
|
75
|
+
executeIntent: false, // TESTED
|
|
71
76
|
buyBasket: false, // TESTED
|
|
72
77
|
depositTokens: false, // TESTED
|
|
73
78
|
lockDeposits: false, // TESTED
|
|
74
79
|
sellBasket: false, // TESTED
|
|
75
|
-
rebalanceBasket: false, //
|
|
80
|
+
rebalanceBasket: false, // TESTED
|
|
76
81
|
rebalanceBasketCustom: false, // NOT TESTED
|
|
77
82
|
startPriceUpdates: false, // TESTED
|
|
78
83
|
updateTokenPrices: false, // TESTED
|
|
@@ -99,6 +104,15 @@ function testStates() {
|
|
|
99
104
|
});
|
|
100
105
|
console.log(resCreateBasket);
|
|
101
106
|
}
|
|
107
|
+
if (tests.addBounty) {
|
|
108
|
+
let tx = yield sdk.addBountyTx({
|
|
109
|
+
keeper: wallet.publicKey.toBase58(),
|
|
110
|
+
basket: basket.ownAddress.toBase58(),
|
|
111
|
+
amount: 250 * 10 ** 6,
|
|
112
|
+
});
|
|
113
|
+
let res = yield sdk.signAndSendTxPayloadBatchSequence({ txPayloadBatchSequence: tx, wallet });
|
|
114
|
+
console.log(res);
|
|
115
|
+
}
|
|
102
116
|
let task_context = {
|
|
103
117
|
basket: basket.ownAddress.toBase58(),
|
|
104
118
|
manager: wallet.publicKey.toBase58(),
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,75 +1,88 @@
|
|
|
1
1
|
import Decimal from 'decimal.js';
|
|
2
2
|
|
|
3
3
|
import { BN } from '@coral-xyz/anchor';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
closeAccount, closeAccountInstructionData, createAssociatedTokenAccountIdempotentInstruction,
|
|
6
|
+
createAssociatedTokenAccountInstruction, createCloseAccountInstruction,
|
|
7
|
+
createSyncNativeInstruction
|
|
8
|
+
} from '@solana/spl-token';
|
|
5
9
|
import {
|
|
6
10
|
ComputeBudgetProgram, Connection, Keypair, PublicKey, TransactionInstruction,
|
|
7
11
|
TransactionSignature
|
|
8
12
|
} from '@solana/web3.js';
|
|
9
13
|
|
|
14
|
+
import {
|
|
15
|
+
COMPUTE_UNITS, LUT_EXTEND_BATCH_SIZE, MINTS, PRIORITY_FEE, PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT,
|
|
16
|
+
PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT
|
|
17
|
+
} from './constants';
|
|
10
18
|
import { claimBountyIx } from './instructions/automation/claimBounty';
|
|
19
|
+
import { flashDepositIx, flashWithdrawIx } from './instructions/automation/flashSwap';
|
|
11
20
|
import { startPriceUpdatesIx, updateTokenPricesIx } from './instructions/automation/priceUpdate';
|
|
12
21
|
import {
|
|
13
|
-
cancelRebalanceIx,
|
|
14
|
-
createRebalanceIntentIx, initRebalanceIntentIx, resizeRebalanceIntentIx
|
|
22
|
+
cancelRebalanceIx, createRebalanceIntentIx, initRebalanceIntentIx, resizeRebalanceIntentIx
|
|
15
23
|
} from './instructions/automation/rebalanceIntent';
|
|
24
|
+
import { addBountyIx } from './instructions/management/addBounty';
|
|
16
25
|
import { createGlobalConfigIx, editGlobalConfigIx } from './instructions/management/admin';
|
|
26
|
+
import { claimFeesIx } from './instructions/management/claimFees';
|
|
17
27
|
import {
|
|
18
28
|
createBasketIx, createBasketStateAccountIx, resizeBasketStateIx
|
|
19
29
|
} from './instructions/management/createBasket';
|
|
20
30
|
import {
|
|
21
31
|
cancelIntentIx, createEditBasketIntentIx, executeEditBasketIntentIx
|
|
22
32
|
} from './instructions/management/edit';
|
|
33
|
+
import {
|
|
34
|
+
createBasketLookupTablesInstruction, extendBasketLookupTablesIx, overwriteBasketLookupTablesIx
|
|
35
|
+
} from './instructions/management/luts';
|
|
23
36
|
import {
|
|
24
37
|
getAta, getBasketFeesPda, getBasketState, getBasketTokenMintPda, getGlobalConfigPda,
|
|
25
|
-
getIntentPda, getRebalanceIntentPda, getRentPayerPda
|
|
38
|
+
getIntentPda, getLookupTableAccount, getRebalanceIntentPda, getRentPayerPda
|
|
26
39
|
} from './instructions/pda';
|
|
27
40
|
import { depositTokensIx, lockDepositsIx, mintBasketIx } from './instructions/user/deposit';
|
|
28
41
|
import { redeemTokensIx } from './instructions/user/withdraw';
|
|
29
|
-
import {
|
|
42
|
+
import { getJupTokenLedgerAndSwapInstructions } from './jup';
|
|
43
|
+
import {
|
|
44
|
+
Basket, BasketLayout, FormattedAccumulatedFees, FormattedAddTokenSettings, FormattedAsset,
|
|
45
|
+
FormattedAutomationSettings, FormattedBasket, FormattedCreatorSettings,
|
|
46
|
+
FormattedCustomRebalanceSettings, FormattedDepositsSettings, FormattedFeeSettings,
|
|
47
|
+
FormattedForceRebalanceSettings, FormattedLookupTables, FormattedLpSettings,
|
|
48
|
+
FormattedMakeDirectSwapSettings, FormattedManagersSettings, FormattedMetadataSettings,
|
|
49
|
+
FormattedOracle, FormattedOracleAggregator, FormattedOracleSettings, FormattedScheduleSettings,
|
|
50
|
+
FormattedUpdateWeightsSettings
|
|
51
|
+
} from './layouts/basket';
|
|
30
52
|
import { FormattedGlobalConfig, GlobalConfig, GlobalConfigLayout } from './layouts/config';
|
|
31
53
|
import { decimalToFraction } from './layouts/fraction';
|
|
32
54
|
import {
|
|
33
|
-
|
|
34
|
-
EditCustomRebalanceSettings, EditDepositsSettings, EditFeeSettings,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
UpdateWeightsInput
|
|
39
|
-
FormattedIntentStatus,
|
|
40
|
-
FormattedTaskType,
|
|
41
|
-
FormattedIntent,
|
|
42
|
-
FormattedBounty,
|
|
43
|
-
FormattedBountySchedule,
|
|
44
|
-
AddOrEditTokenInput,
|
|
55
|
+
AddOrEditTokenInput, EditAddTokenSettings, EditAutomationSettings, EditCreatorSettings,
|
|
56
|
+
EditCustomRebalanceSettings, EditDepositsSettings, EditFeeSettings, EditForceRebalanceSettings,
|
|
57
|
+
EditLpSettings, EditMakeDirectSwapSettings, EditManagerSettings, EditMetadataSettings,
|
|
58
|
+
EditScheduleSettings, EditUpdateWeightsSettings, FormattedBounty, FormattedBountySchedule,
|
|
59
|
+
FormattedIntent, FormattedIntentStatus, FormattedTaskType, Intent, MakeDirectSwapInput,
|
|
60
|
+
OracleInput, Settings, TaskContext, TaskType, UpdateWeightsInput
|
|
45
61
|
} from './layouts/intents/intent';
|
|
46
|
-
import { FormattedRebalanceType, FormattedRebalanceAction, FormattedOraclePrice, FormattedTokenAuction, FormattedTaskCompletion, FormattedRebalanceIntent } from './layouts/intents/rebalanceIntent';
|
|
47
62
|
import {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
FormattedOracleSettings, FormattedOracleAggregator, FormattedOracle, FormattedBasket,
|
|
54
|
-
} from './layouts/basket';
|
|
55
|
-
import { RebalanceIntent, RebalanceType } from './layouts/intents/rebalanceIntent';
|
|
63
|
+
FormattedOraclePrice, FormattedRebalanceAction, FormattedRebalanceIntent,
|
|
64
|
+
FormattedRebalanceType, FormattedTaskCompletion, FormattedTokenAuction, RebalanceIntent,
|
|
65
|
+
RebalanceType
|
|
66
|
+
} from './layouts/intents/rebalanceIntent';
|
|
67
|
+
import { FormattedOracleType } from './layouts/oracle';
|
|
56
68
|
import {
|
|
57
|
-
BasketFilter, computeTokenMintsHash, fetchBaskektsMultiple, fetchBasket, fetchBaskets,
|
|
69
|
+
BasketFilter, computeTokenMintsHash, fetchBaskektsMultiple, fetchBasket, fetchBaskets,
|
|
70
|
+
loadBasketPrice
|
|
58
71
|
} from './states/basket';
|
|
59
|
-
import {
|
|
60
|
-
import {
|
|
72
|
+
import { fetchGlobalConfig } from './states/config';
|
|
73
|
+
import {
|
|
74
|
+
fetchIntent, fetchIntents, fetchIntentsMultiple, IntentFilter
|
|
75
|
+
} from './states/intents/intent';
|
|
76
|
+
import {
|
|
77
|
+
computeRebalanceIntentBountyAmount, fetchRebalanceIntent, fetchRebalanceIntents,
|
|
78
|
+
fetchRebalanceIntentsMultiple, RebalanceIntentFilter
|
|
79
|
+
} from './states/intents/rebalanceIntent';
|
|
61
80
|
import {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
wrapWsolIxs
|
|
81
|
+
BasketCreationTx,
|
|
82
|
+
prepareTxPayloadBatchSequence, prepareVersionedTxs, sendTxPayloadBatchSequence,
|
|
83
|
+
sendVersionedTxs, signTxPayloadBatchSequence, signVersionedTxs, TxBatchData,
|
|
84
|
+
TxPayloadBatchSequence, VersionedTxs, Wallet, wrapWsolIxs
|
|
66
85
|
} from './txUtils';
|
|
67
|
-
import { FormattedOracleType } from './layouts/oracle';
|
|
68
|
-
import { fetchGlobalConfig } from './states/config';
|
|
69
|
-
import { flashDepositIx, flashWithdrawIx } from './instructions/automation/flashSwap';
|
|
70
|
-
import { claimFeesIx } from './instructions/management/claimFees';
|
|
71
|
-
import { getJupTokenLedgerAndSwapInstructions } from './jup';
|
|
72
|
-
import { COMPUTE_UNITS, MINTS, PRIORITY_FEE } from './constants';
|
|
73
86
|
|
|
74
87
|
export class SymmetryCore {
|
|
75
88
|
|
|
@@ -242,7 +255,7 @@ export class SymmetryCore {
|
|
|
242
255
|
host_management_fee_bps: number,
|
|
243
256
|
host_performance_fee_bps: number,
|
|
244
257
|
},
|
|
245
|
-
}): Promise<
|
|
258
|
+
}): Promise<BasketCreationTx> {
|
|
246
259
|
const creator = new PublicKey(params.creator);
|
|
247
260
|
const host = new PublicKey(params.host_platform_params?.host_pubkey ?? params.creator);
|
|
248
261
|
const hostFees = {
|
|
@@ -303,7 +316,11 @@ export class SymmetryCore {
|
|
|
303
316
|
|
|
304
317
|
let versionedTxs = await prepareVersionedTxs(this.sdkParams.connection, txBatchData);
|
|
305
318
|
let txPayloadBatchSequence = prepareTxPayloadBatchSequence(txBatchData, versionedTxs);
|
|
306
|
-
return
|
|
319
|
+
return {
|
|
320
|
+
mint: mint.toBase58(),
|
|
321
|
+
basket: basket.toBase58(),
|
|
322
|
+
batches: txPayloadBatchSequence.batches,
|
|
323
|
+
};
|
|
307
324
|
}
|
|
308
325
|
|
|
309
326
|
async editCreatorTx(context: TaskContext, settings: EditCreatorSettings): Promise<TxPayloadBatchSequence> {
|
|
@@ -1215,6 +1232,44 @@ export class SymmetryCore {
|
|
|
1215
1232
|
return txPayloadBatchSequence;
|
|
1216
1233
|
}
|
|
1217
1234
|
|
|
1235
|
+
async addBountyTx(params: {
|
|
1236
|
+
keeper: string,
|
|
1237
|
+
basket: string,
|
|
1238
|
+
amount: number,
|
|
1239
|
+
}): Promise<TxPayloadBatchSequence> {
|
|
1240
|
+
let keeper = new PublicKey(params.keeper);
|
|
1241
|
+
let basket = await this.fetchBasket(params.basket);
|
|
1242
|
+
let globalConfig = await this.fetchGlobalConfig();
|
|
1243
|
+
let bountyWsolAmount = 0;
|
|
1244
|
+
if (globalConfig.bountyMint.equals(MINTS["mainnet"].WSOL)) {
|
|
1245
|
+
bountyWsolAmount = params.amount;
|
|
1246
|
+
}
|
|
1247
|
+
let wsolIxs = await wrapWsolIxs(
|
|
1248
|
+
this.sdkParams.connection,
|
|
1249
|
+
keeper,
|
|
1250
|
+
bountyWsolAmount,
|
|
1251
|
+
);
|
|
1252
|
+
let ix = addBountyIx({
|
|
1253
|
+
keeper: keeper,
|
|
1254
|
+
basket: basket.ownAddress,
|
|
1255
|
+
bountyMint: basket.settings.bountyMint,
|
|
1256
|
+
amount: params.amount,
|
|
1257
|
+
});
|
|
1258
|
+
let txBatchData: TxBatchData = {batches: [[{
|
|
1259
|
+
payer: keeper,
|
|
1260
|
+
instructions: [
|
|
1261
|
+
...wsolIxs,
|
|
1262
|
+
ix,
|
|
1263
|
+
ComputeBudgetProgram.setComputeUnitLimit({units: COMPUTE_UNITS}),
|
|
1264
|
+
ComputeBudgetProgram.setComputeUnitPrice({microLamports: this.sdkParams.priorityFee}),
|
|
1265
|
+
],
|
|
1266
|
+
lookupTables: [],
|
|
1267
|
+
}]]};
|
|
1268
|
+
let versionedTxs = await prepareVersionedTxs(this.sdkParams.connection, txBatchData);
|
|
1269
|
+
let txPayloadBatchSequence = prepareTxPayloadBatchSequence(txBatchData, versionedTxs);
|
|
1270
|
+
return txPayloadBatchSequence;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1218
1273
|
async claimBasketFeesTx(params: {
|
|
1219
1274
|
claimer: string,
|
|
1220
1275
|
basket: string,
|
|
@@ -1265,6 +1320,98 @@ export class SymmetryCore {
|
|
|
1265
1320
|
return txPayloadBatchSequence;
|
|
1266
1321
|
}
|
|
1267
1322
|
|
|
1323
|
+
async rewriteLookupTablesTx(params: {
|
|
1324
|
+
signer: string,
|
|
1325
|
+
basket_mint: string,
|
|
1326
|
+
additional_accounts: string[],
|
|
1327
|
+
}): Promise<TxPayloadBatchSequence> {
|
|
1328
|
+
const signer = new PublicKey(params.signer);
|
|
1329
|
+
const basketMint = new PublicKey(params.basket_mint);
|
|
1330
|
+
const additionalAccounts = params.additional_accounts.map(a => new PublicKey(a));
|
|
1331
|
+
|
|
1332
|
+
const basketAddress = getBasketState(basketMint);
|
|
1333
|
+
const basket = await this.fetchBasket(basketAddress.toBase58());
|
|
1334
|
+
|
|
1335
|
+
const activeLut0 = basket.lookupTables.active[0];
|
|
1336
|
+
const activeLut1 = basket.lookupTables.active[1];
|
|
1337
|
+
let oldTempLut0 = basket.lookupTables.temp[0];
|
|
1338
|
+
let oldTempLut1 = basket.lookupTables.temp[1];
|
|
1339
|
+
|
|
1340
|
+
const slot = await this.sdkParams.connection.getSlot("finalized");
|
|
1341
|
+
const newLut0 = getLookupTableAccount(basketAddress, slot);
|
|
1342
|
+
const newLut1 = getLookupTableAccount(basketAddress, slot - 1);
|
|
1343
|
+
|
|
1344
|
+
// Step 1: create lookup tables
|
|
1345
|
+
const createIx = createBasketLookupTablesInstruction({
|
|
1346
|
+
signer,
|
|
1347
|
+
basket: basketAddress,
|
|
1348
|
+
oldTempLookupTable0: oldTempLut0,
|
|
1349
|
+
oldTempLookupTable1: oldTempLut1,
|
|
1350
|
+
newTempLookupTable0: newLut0,
|
|
1351
|
+
newTempLookupTable1: newLut1,
|
|
1352
|
+
slot,
|
|
1353
|
+
});
|
|
1354
|
+
|
|
1355
|
+
const txBatchData: TxBatchData = { batches: [
|
|
1356
|
+
[{
|
|
1357
|
+
payer: signer,
|
|
1358
|
+
instructions: [
|
|
1359
|
+
createIx,
|
|
1360
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
|
|
1361
|
+
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
|
|
1362
|
+
],
|
|
1363
|
+
lookupTables: [],
|
|
1364
|
+
}],
|
|
1365
|
+
]};
|
|
1366
|
+
|
|
1367
|
+
// Step 2: extend LUTs in batches of ~20
|
|
1368
|
+
const BATCH_SIZE = LUT_EXTEND_BATCH_SIZE;
|
|
1369
|
+
for (let i = 0; i < additionalAccounts.length; i += BATCH_SIZE) {
|
|
1370
|
+
const batch = additionalAccounts.slice(i, i + BATCH_SIZE);
|
|
1371
|
+
const extendIx = extendBasketLookupTablesIx({
|
|
1372
|
+
signer,
|
|
1373
|
+
basket: basketAddress,
|
|
1374
|
+
tempLookupTable0: newLut0,
|
|
1375
|
+
tempLookupTable1: newLut1,
|
|
1376
|
+
additionalAccounts: batch,
|
|
1377
|
+
});
|
|
1378
|
+
txBatchData.batches.push([{
|
|
1379
|
+
payer: signer,
|
|
1380
|
+
instructions: [
|
|
1381
|
+
extendIx,
|
|
1382
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
|
|
1383
|
+
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
|
|
1384
|
+
],
|
|
1385
|
+
lookupTables: [],
|
|
1386
|
+
}]);
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
// Step 3: overwrite active LUTs
|
|
1390
|
+
const overwriteIx = overwriteBasketLookupTablesIx({
|
|
1391
|
+
signer,
|
|
1392
|
+
basket: basketAddress,
|
|
1393
|
+
tempLookupTable0: newLut0,
|
|
1394
|
+
tempLookupTable1: newLut1,
|
|
1395
|
+
activeLookupTable0: activeLut0,
|
|
1396
|
+
activeLookupTable1: activeLut1,
|
|
1397
|
+
});
|
|
1398
|
+
|
|
1399
|
+
txBatchData.batches.push([{
|
|
1400
|
+
payer: signer,
|
|
1401
|
+
instructions: [
|
|
1402
|
+
overwriteIx,
|
|
1403
|
+
ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNITS }),
|
|
1404
|
+
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
|
|
1405
|
+
],
|
|
1406
|
+
lookupTables: [],
|
|
1407
|
+
}]);
|
|
1408
|
+
|
|
1409
|
+
const versionedTxs = await prepareVersionedTxs(this.sdkParams.connection, txBatchData);
|
|
1410
|
+
const txPayloadBatchSequence = prepareTxPayloadBatchSequence(txBatchData, versionedTxs);
|
|
1411
|
+
return txPayloadBatchSequence;
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
|
|
1268
1415
|
async signAndSendVersionedTxs(params: {
|
|
1269
1416
|
versionedTxs: VersionedTxs,
|
|
1270
1417
|
wallet: Wallet,
|
|
@@ -26,7 +26,7 @@ export function addBountyIx(params: {
|
|
|
26
26
|
let bountyVault = getBountyVaultPda();
|
|
27
27
|
let globalConfig = getGlobalConfigPda();
|
|
28
28
|
let keeperBountyAta = getAta(keeper, bountyMint);
|
|
29
|
-
let bountyVaultAta = getAta(
|
|
29
|
+
let bountyVaultAta = getAta(bountyVault, bountyMint);
|
|
30
30
|
|
|
31
31
|
const data = Buffer.concat([
|
|
32
32
|
ADD_BOUNTY_DISCRIMINATOR,
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { BN, Program } from '@coral-xyz/anchor';
|
|
2
|
-
import { PublicKey, SystemProgram, TransactionInstruction } from '@solana/web3.js';
|
|
3
|
-
import { ADDRESS_LOOKUP_TABLE_PROGRAM_ID, BASKETS_V3_PROGRAM_ID } from '../../constants';
|
|
4
|
-
import { getLookupTableInfoAccount } from '../pda';
|
|
2
|
+
import { AccountMeta, PublicKey, SystemProgram, TransactionInstruction } from '@solana/web3.js';
|
|
5
3
|
|
|
4
|
+
import {
|
|
5
|
+
ADDRESS_LOOKUP_TABLE_PROGRAM_ID, BASKETS_V3_PROGRAM_ID, PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT,
|
|
6
|
+
PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT
|
|
7
|
+
} from '../../constants';
|
|
8
|
+
import { getGlobalConfigPda, getLookupTableInfoAccount } from '../pda';
|
|
6
9
|
|
|
7
10
|
const CREATE_BASKET_LOOKUP_TABLES_DISCRIMINATOR = Buffer.from([227,98,152,128,87,46,244,99]);
|
|
8
11
|
const EXTEND_BASKET_LOOKUP_TABLES_DISCRIMINATOR = Buffer.from([98, 129, 153, 127, 181, 160, 117, 74]);
|
|
@@ -29,32 +32,48 @@ export function createBasketLookupTablesInstruction(params: {
|
|
|
29
32
|
slot,
|
|
30
33
|
} = params;
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
const globalConfig = getGlobalConfigPda();
|
|
36
|
+
const hasOldTemp = !oldTempLookupTable0.equals(PublicKey.default)
|
|
37
|
+
&& !oldTempLookupTable1.equals(PublicKey.default);
|
|
34
38
|
|
|
35
39
|
const data = Buffer.concat([
|
|
36
40
|
CREATE_BASKET_LOOKUP_TABLES_DISCRIMINATOR,
|
|
37
|
-
new BN(slot).toArray("le", 8),
|
|
41
|
+
Buffer.from(new BN(slot).toArray("le", 8)),
|
|
38
42
|
]);
|
|
39
43
|
|
|
40
|
-
const keys = [
|
|
44
|
+
const keys: AccountMeta[] = [
|
|
41
45
|
{ pubkey: signer, isSigner: true, isWritable: true },
|
|
42
46
|
{ pubkey: basket, isSigner: false, isWritable: true },
|
|
43
|
-
{ pubkey:
|
|
44
|
-
{ pubkey:
|
|
47
|
+
{ pubkey: globalConfig, isSigner: false, isWritable: false },
|
|
48
|
+
{ pubkey: hasOldTemp ? oldTempLookupTable0 : PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT, isSigner: false, isWritable: true },
|
|
49
|
+
{ pubkey: hasOldTemp ? oldTempLookupTable1 : PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT, isSigner: false, isWritable: true },
|
|
45
50
|
{ pubkey: newTempLookupTable0, isSigner: false, isWritable: true },
|
|
46
51
|
{ pubkey: newTempLookupTable1, isSigner: false, isWritable: true },
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
if (hasOldTemp) {
|
|
55
|
+
keys.push(
|
|
56
|
+
{ pubkey: getLookupTableInfoAccount(oldTempLookupTable0), isSigner: false, isWritable: true },
|
|
57
|
+
{ pubkey: getLookupTableInfoAccount(oldTempLookupTable1), isSigner: false, isWritable: true },
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
keys.push(
|
|
62
|
+
{ pubkey: BASKETS_V3_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
63
|
+
{ pubkey: BASKETS_V3_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
keys.push(
|
|
49
68
|
{ pubkey: ADDRESS_LOOKUP_TABLE_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
50
69
|
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
51
|
-
|
|
70
|
+
);
|
|
52
71
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
return new TransactionInstruction({
|
|
73
|
+
keys,
|
|
74
|
+
programId: BASKETS_V3_PROGRAM_ID,
|
|
75
|
+
data,
|
|
76
|
+
});
|
|
58
77
|
}
|
|
59
78
|
|
|
60
79
|
export function extendBasketLookupTablesIx(
|
|
@@ -63,6 +82,7 @@ export function extendBasketLookupTablesIx(
|
|
|
63
82
|
basket: PublicKey;
|
|
64
83
|
tempLookupTable0: PublicKey;
|
|
65
84
|
tempLookupTable1: PublicKey;
|
|
85
|
+
additionalAccounts: PublicKey[];
|
|
66
86
|
}): TransactionInstruction {
|
|
67
87
|
|
|
68
88
|
const keys = [
|
|
@@ -72,6 +92,7 @@ export function extendBasketLookupTablesIx(
|
|
|
72
92
|
{ pubkey: params.tempLookupTable1, isWritable: true, isSigner: false },
|
|
73
93
|
{ pubkey: ADDRESS_LOOKUP_TABLE_PROGRAM_ID, isWritable: false, isSigner: false },
|
|
74
94
|
{ pubkey: SystemProgram.programId, isWritable: false, isSigner: false },
|
|
95
|
+
...params.additionalAccounts.map(pubkey => ({pubkey, isWritable: false, isSigner: false})),
|
|
75
96
|
];
|
|
76
97
|
|
|
77
98
|
return new TransactionInstruction({
|
|
@@ -99,6 +120,9 @@ export function overwriteBasketLookupTablesIx(
|
|
|
99
120
|
{ pubkey: params.tempLookupTable1, isWritable: true, isSigner: false },
|
|
100
121
|
{ pubkey: params.activeLookupTable0, isWritable: true, isSigner: false },
|
|
101
122
|
{ pubkey: params.activeLookupTable1, isWritable: true, isSigner: false },
|
|
123
|
+
{ pubkey: getLookupTableInfoAccount(params.activeLookupTable0), isWritable: true, isSigner: false },
|
|
124
|
+
{ pubkey: getLookupTableInfoAccount(params.activeLookupTable1), isWritable: true, isSigner: false },
|
|
125
|
+
{ pubkey: ADDRESS_LOOKUP_TABLE_PROGRAM_ID, isWritable: false, isSigner: false },
|
|
102
126
|
{ pubkey: SystemProgram.programId, isWritable: false, isSigner: false },
|
|
103
127
|
];
|
|
104
128
|
|
|
@@ -493,7 +493,29 @@ class RebalanceIntentRustClass {
|
|
|
493
493
|
}
|
|
494
494
|
}
|
|
495
495
|
|
|
496
|
-
|
|
496
|
+
/**
|
|
497
|
+
* Returns all valid swap pairs available during the rebalance auction phase.
|
|
498
|
+
*
|
|
499
|
+
* **Swap direction (basket perspective):**
|
|
500
|
+
* - `inMint` / `inAmount`: what the basket is supposed to **receive**.
|
|
501
|
+
* - `outMint` / `outAmount`: what the basket wants to **swap** (give away).
|
|
502
|
+
* So each pair describes an **outMint → inMint** swap. When generating swap
|
|
503
|
+
* transactions, use this direction: swap `outMint` → `inMint` (sell outAmount of
|
|
504
|
+
* outMint, receive inAmount of inMint).
|
|
505
|
+
*
|
|
506
|
+
* Only runs when the rebalance is in Auction action and the current time falls
|
|
507
|
+
* within one of the three auction windows. For the active auction, target amounts
|
|
508
|
+
* are refreshed if they haven't been updated since the auction started.
|
|
509
|
+
*
|
|
510
|
+
* Iterates over completed price-update tokens to compute exchange rates via
|
|
511
|
+
* getSwapAmounts (using time-since-start and auction duration). Pairs with
|
|
512
|
+
* positive in/out amounts are collected and sorted by value descending
|
|
513
|
+
* (highest value first).
|
|
514
|
+
*
|
|
515
|
+
* @param rebalanceIntent - The rebalance intent state
|
|
516
|
+
* @param basket - The basket (used to update target amounts when needed)
|
|
517
|
+
* @returns Array of swap pairs, or empty array when not in auction or outside auction windows
|
|
518
|
+
*/
|
|
497
519
|
export function getSwapPairs(
|
|
498
520
|
rebalanceIntent: RebalanceIntent,
|
|
499
521
|
basket: Basket,
|
package/src/txUtils.ts
CHANGED
|
@@ -93,6 +93,11 @@ export interface TxPayloadBatchSequence {
|
|
|
93
93
|
batches: TxPayloadBatch[];
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
export interface BasketCreationTx extends TxPayloadBatchSequence {
|
|
97
|
+
mint: string;
|
|
98
|
+
basket: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
96
101
|
export function prepareTxPayloadBatchSequence(
|
|
97
102
|
txBatchData: TxBatchData,
|
|
98
103
|
versionedTxs?: VersionedTxs,
|
package/test.ts
CHANGED
|
@@ -17,6 +17,7 @@ let jupApiKey = "";
|
|
|
17
17
|
let connection = new Connection("https://api.devnet.solana.com");
|
|
18
18
|
|
|
19
19
|
async function testStates() {
|
|
20
|
+
return;
|
|
20
21
|
let wallet = new Wallet(Keypair.fromSecretKey(new Uint8Array(kp)));
|
|
21
22
|
console.log(wallet.publicKey.toBase58());
|
|
22
23
|
|
|
@@ -44,6 +45,9 @@ async function testStates() {
|
|
|
44
45
|
let basket = await sdk.fetchBasket("GrBFFvtdRL25o7gcRnV1kGvz1Qc7iscUmDp1ZvyBSyUa");
|
|
45
46
|
basket = await sdk.loadBasketPrice(basket);
|
|
46
47
|
console.log(basket.formatted);
|
|
48
|
+
// console.log(basket.composition[0].mint.toBase58(), "amount:", basket.composition[0].amount.toString(), "price:", basket.composition[0].price?.price, "value:", basket.composition[0].value);
|
|
49
|
+
// console.log(basket.composition[1].mint.toBase58(), "amount:", basket.composition[1].amount.toString(), "price:", basket.composition[1].price?.price, "value:", basket.composition[1].value);
|
|
50
|
+
// console.log(basket.composition[2].mint.toBase58(), "amount:", basket.composition[2].amount.toString(), "price:", basket.composition[2].price?.price, "value:", basket.composition[2].value);
|
|
47
51
|
// return;
|
|
48
52
|
|
|
49
53
|
let tests = {
|
|
@@ -53,6 +57,7 @@ async function testStates() {
|
|
|
53
57
|
|
|
54
58
|
createBasket: false, // TESTED
|
|
55
59
|
editPrivateBasketSettings: false, // NOT TESTED
|
|
60
|
+
addBounty: false, // TESTED
|
|
56
61
|
|
|
57
62
|
editCreator: false, // TESTED
|
|
58
63
|
editManagerSettings: false, // TESTED
|
|
@@ -62,8 +67,8 @@ async function testStates() {
|
|
|
62
67
|
editLpSettings: false, // TESTED
|
|
63
68
|
editMetadata: false, // TESTED
|
|
64
69
|
editDepositsSettings: false, // TESTED
|
|
65
|
-
editForceRebalanceSettings: false, //
|
|
66
|
-
editCustomRebalanceSettings: false, //
|
|
70
|
+
editForceRebalanceSettings: false, // TESTED
|
|
71
|
+
editCustomRebalanceSettings: false, // TESTED
|
|
67
72
|
editAddTokenDelay: false, // NOT TESTED
|
|
68
73
|
editUpdateWeightsDelay: false, // NOT TESTED
|
|
69
74
|
editMakeDirectSwapDelay: false, // NOT TESTED
|
|
@@ -72,7 +77,7 @@ async function testStates() {
|
|
|
72
77
|
updateWeights: false, // NOT TESTED
|
|
73
78
|
makeDirectSwap: false, // NOT TESTED
|
|
74
79
|
|
|
75
|
-
executeIntent: false, //
|
|
80
|
+
executeIntent: false, // TESTED
|
|
76
81
|
|
|
77
82
|
buyBasket: false, // TESTED
|
|
78
83
|
depositTokens: false, // TESTED
|
|
@@ -80,7 +85,7 @@ async function testStates() {
|
|
|
80
85
|
|
|
81
86
|
sellBasket: false, // TESTED
|
|
82
87
|
|
|
83
|
-
rebalanceBasket: false, //
|
|
88
|
+
rebalanceBasket: false, // TESTED
|
|
84
89
|
rebalanceBasketCustom: false, // NOT TESTED
|
|
85
90
|
|
|
86
91
|
startPriceUpdates: false, // TESTED
|
|
@@ -113,6 +118,16 @@ async function testStates() {
|
|
|
113
118
|
console.log(resCreateBasket);
|
|
114
119
|
}
|
|
115
120
|
|
|
121
|
+
if (tests.addBounty) {
|
|
122
|
+
let tx = await sdk.addBountyTx({
|
|
123
|
+
keeper: wallet.publicKey.toBase58(),
|
|
124
|
+
basket: basket.ownAddress.toBase58(),
|
|
125
|
+
amount: 250 * 10 ** 6,
|
|
126
|
+
});
|
|
127
|
+
let res = await sdk.signAndSendTxPayloadBatchSequence({txPayloadBatchSequence: tx, wallet});
|
|
128
|
+
console.log(res);
|
|
129
|
+
}
|
|
130
|
+
|
|
116
131
|
let task_context: TaskContext = {
|
|
117
132
|
basket: basket.ownAddress.toBase58(),
|
|
118
133
|
manager: wallet.publicKey.toBase58(),
|