@symmetry-hq/temp-v3-sdk 0.0.36 → 0.0.38
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/index.d.ts +15 -0
- package/dist/src/index.js +108 -8
- package/dist/src/instructions/automation/priceUpdate.d.ts +1 -0
- package/dist/src/instructions/automation/priceUpdate.js +8 -0
- package/dist/src/instructions/management/addBounty.js +1 -1
- package/dist/src/keeperMonitor.d.ts +22 -0
- package/dist/src/keeperMonitor.js +214 -0
- package/dist/src/states/intents/rebalanceIntent.js +5 -5
- package/dist/test.d.ts +1 -22
- package/dist/test.js +39 -175
- package/package.json +1 -1
- package/src/index.ts +140 -8
- package/src/instructions/automation/priceUpdate.ts +12 -2
- package/src/instructions/management/addBounty.ts +1 -1
- package/src/keeperMonitor.ts +179 -0
- package/src/states/intents/rebalanceIntent.ts +5 -5
- package/test.ts +43 -163
package/dist/src/index.d.ts
CHANGED
|
@@ -119,6 +119,15 @@ export declare class SymmetryCore {
|
|
|
119
119
|
min_bounty_amount?: number;
|
|
120
120
|
max_bounty_amount?: number;
|
|
121
121
|
}): Promise<TxPayloadBatchSequence>;
|
|
122
|
+
rebalanceBasketTx(params: {
|
|
123
|
+
keeper: string;
|
|
124
|
+
basket_mint: string;
|
|
125
|
+
rebalance_slippage_bps?: number;
|
|
126
|
+
per_trade_rebalance_slippage_bps?: number;
|
|
127
|
+
execution_start_time?: number;
|
|
128
|
+
min_bounty_amount?: number;
|
|
129
|
+
max_bounty_amount?: number;
|
|
130
|
+
}): Promise<TxPayloadBatchSequence>;
|
|
122
131
|
startPriceUpdatesTx(params: {
|
|
123
132
|
keeper: string;
|
|
124
133
|
basket: string;
|
|
@@ -155,6 +164,11 @@ export declare class SymmetryCore {
|
|
|
155
164
|
keeper: string;
|
|
156
165
|
rebalance_intent: string;
|
|
157
166
|
}): Promise<TxPayloadBatchSequence>;
|
|
167
|
+
addBountyTx(params: {
|
|
168
|
+
keeper: string;
|
|
169
|
+
basket: string;
|
|
170
|
+
amount: number;
|
|
171
|
+
}): Promise<TxPayloadBatchSequence>;
|
|
158
172
|
claimBasketFeesTx(params: {
|
|
159
173
|
claimer: string;
|
|
160
174
|
basket: string;
|
|
@@ -174,3 +188,4 @@ export { FormattedRebalanceType, FormattedRebalanceAction, FormattedOraclePrice,
|
|
|
174
188
|
export { FormattedCreatorSettings, FormattedManagersSettings, FormattedFeeSettings, FormattedScheduleSettings, FormattedAutomationSettings, FormattedLpSettings, FormattedMetadataSettings, FormattedDepositsSettings, FormattedForceRebalanceSettings, FormattedCustomRebalanceSettings, FormattedAddTokenSettings, FormattedUpdateWeightsSettings, FormattedMakeDirectSwapSettings, FormattedAccumulatedFees, FormattedLookupTables, FormattedAsset, FormattedOracleSettings, FormattedOracleAggregator, FormattedOracle, FormattedOracleType, FormattedBasket, };
|
|
175
189
|
export { EditCreatorSettings, EditManagerSettings, EditFeeSettings, EditScheduleSettings, EditAutomationSettings, EditLpSettings, EditMetadataSettings, EditDepositsSettings, EditForceRebalanceSettings, EditCustomRebalanceSettings, EditAddTokenSettings, EditUpdateWeightsSettings, EditMakeDirectSwapSettings, AddOrEditTokenInput, OracleInput, UpdateWeightsInput, MakeDirectSwapInput, Settings, TaskContext, TaskType, };
|
|
176
190
|
export { getJupTokenLedgerAndSwapInstructions, };
|
|
191
|
+
export { KeeperMonitor } from './keeperMonitor';
|
package/dist/src/index.js
CHANGED
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.getJupTokenLedgerAndSwapInstructions = exports.TaskType = exports.SymmetryCore = void 0;
|
|
15
|
+
exports.KeeperMonitor = exports.getJupTokenLedgerAndSwapInstructions = exports.TaskType = exports.SymmetryCore = void 0;
|
|
16
16
|
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");
|
|
@@ -40,6 +40,7 @@ const claimFees_1 = require("./instructions/management/claimFees");
|
|
|
40
40
|
const jup_1 = require("./jup");
|
|
41
41
|
Object.defineProperty(exports, "getJupTokenLedgerAndSwapInstructions", { enumerable: true, get: function () { return jup_1.getJupTokenLedgerAndSwapInstructions; } });
|
|
42
42
|
const constants_1 = require("./constants");
|
|
43
|
+
const addBounty_1 = require("./instructions/management/addBounty");
|
|
43
44
|
class SymmetryCore {
|
|
44
45
|
constructor(params) {
|
|
45
46
|
var _a;
|
|
@@ -767,6 +768,70 @@ class SymmetryCore {
|
|
|
767
768
|
return txPayloadBatchSequence;
|
|
768
769
|
});
|
|
769
770
|
}
|
|
771
|
+
rebalanceBasketTx(params) {
|
|
772
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
773
|
+
var _a, _b, _c, _d, _e, _f;
|
|
774
|
+
let keeper = new web3_js_1.PublicKey(params.keeper);
|
|
775
|
+
let rebalanceSlippageBps = (_a = params.rebalance_slippage_bps) !== null && _a !== void 0 ? _a : 100;
|
|
776
|
+
let perTradeRebalanceSlippageBps = (_b = params.per_trade_rebalance_slippage_bps) !== null && _b !== void 0 ? _b : 100;
|
|
777
|
+
let executionStartTime = (_c = params.execution_start_time) !== null && _c !== void 0 ? _c : 0;
|
|
778
|
+
let minBountyAmount = (_d = params.min_bounty_amount) !== null && _d !== void 0 ? _d : 0;
|
|
779
|
+
let maxBountyAmount = (_e = params.max_bounty_amount) !== null && _e !== void 0 ? _e : 0;
|
|
780
|
+
const basket = yield this.fetchBasket((0, pda_1.getBasketState)(new web3_js_1.PublicKey(params.basket_mint)).toBase58());
|
|
781
|
+
let globalConfig = yield this.fetchGlobalConfig();
|
|
782
|
+
let bountyWsolAmount = 0;
|
|
783
|
+
if (globalConfig.bountyMint.equals(constants_1.MINTS["mainnet"].WSOL)) {
|
|
784
|
+
let boundBounty = parseInt(globalConfig.bountyBondAmount.toString());
|
|
785
|
+
let maxBountyPerTask = parseInt(globalConfig.bountyPerTask.maxBounty.toString());
|
|
786
|
+
let bountyPerPriceUpdateTaskDivisor = parseInt(globalConfig.bountyPerPriceUpdateTaskDivisor.toString());
|
|
787
|
+
if (maxBountyAmount > maxBountyPerTask)
|
|
788
|
+
maxBountyPerTask = maxBountyAmount;
|
|
789
|
+
bountyWsolAmount = (0, rebalanceIntent_3.computeRebalanceIntentBountyAmount)(rebalanceIntent_2.RebalanceType.Basket, basket.numTokens, boundBounty, maxBountyPerTask, Math.floor(maxBountyPerTask / bountyPerPriceUpdateTaskDivisor));
|
|
790
|
+
}
|
|
791
|
+
let wsolIxs = yield (0, txUtils_1.wrapWsolIxs)(this.sdkParams.connection, keeper, bountyWsolAmount);
|
|
792
|
+
const rebalanceIntent = (0, pda_1.getRebalanceIntentPda)(basket.ownAddress, basket.ownAddress);
|
|
793
|
+
let rentPayer = (0, pda_1.getRentPayerPda)();
|
|
794
|
+
let renPayerAi = yield this.sdkParams.connection.getAccountInfo(rentPayer);
|
|
795
|
+
let rebalanceIntentRentPayer = keeper;
|
|
796
|
+
// TODO: check actual lamports required for rent
|
|
797
|
+
if ((_f = renPayerAi === null || renPayerAi === void 0 ? void 0 : renPayerAi.lamports) !== null && _f !== void 0 ? _f : 0 > 0)
|
|
798
|
+
rebalanceIntentRentPayer = rentPayer;
|
|
799
|
+
let bountyMint = basket.settings.bountyMint;
|
|
800
|
+
let txBatchData = { batches: [[{
|
|
801
|
+
payer: keeper,
|
|
802
|
+
instructions: [
|
|
803
|
+
...wsolIxs,
|
|
804
|
+
(0, rebalanceIntent_1.createRebalanceIntentIx)({
|
|
805
|
+
signer: keeper,
|
|
806
|
+
owner: basket.ownAddress,
|
|
807
|
+
basket: basket.ownAddress,
|
|
808
|
+
}),
|
|
809
|
+
(0, rebalanceIntent_1.resizeRebalanceIntentIx)(rebalanceIntent),
|
|
810
|
+
(0, rebalanceIntent_1.initRebalanceIntentIx)({
|
|
811
|
+
signer: keeper,
|
|
812
|
+
owner: basket.ownAddress,
|
|
813
|
+
basket: basket.ownAddress,
|
|
814
|
+
basketTokenMint: basket.mint,
|
|
815
|
+
rebalanceIntentRentPayer: rebalanceIntentRentPayer,
|
|
816
|
+
bountyMint: bountyMint,
|
|
817
|
+
rebalanceType: rebalanceIntent_2.RebalanceType.Basket,
|
|
818
|
+
basketRebalanceIntent: undefined,
|
|
819
|
+
rebalanceSlippageBps: rebalanceSlippageBps,
|
|
820
|
+
perTradeRebalanceSlippageBps: perTradeRebalanceSlippageBps,
|
|
821
|
+
executionStartTime: executionStartTime,
|
|
822
|
+
minBountyAmount: minBountyAmount,
|
|
823
|
+
maxBountyAmount: maxBountyAmount,
|
|
824
|
+
}),
|
|
825
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
|
|
826
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
|
|
827
|
+
],
|
|
828
|
+
lookupTables: [],
|
|
829
|
+
}]] };
|
|
830
|
+
let versionedTxs = yield (0, txUtils_1.prepareVersionedTxs)(this.sdkParams.connection, txBatchData);
|
|
831
|
+
let txPayloadBatchSequence = (0, txUtils_1.prepareTxPayloadBatchSequence)(txBatchData, versionedTxs);
|
|
832
|
+
return txPayloadBatchSequence;
|
|
833
|
+
});
|
|
834
|
+
}
|
|
770
835
|
startPriceUpdatesTx(params) {
|
|
771
836
|
return __awaiter(this, void 0, void 0, function* () {
|
|
772
837
|
let keeper = new web3_js_1.PublicKey(params.keeper);
|
|
@@ -820,6 +885,7 @@ class SymmetryCore {
|
|
|
820
885
|
while (tokenIndices.length < 20)
|
|
821
886
|
tokenIndices.push(0);
|
|
822
887
|
// TODO: in last instruction we should include performance fee accounts
|
|
888
|
+
let performanceFees = basket.settings.fees.hostPerformanceFeeBps + basket.settings.fees.creatorPerformanceFeeBps + basket.settings.fees.managersPerformanceFeeBps;
|
|
823
889
|
ixs.push((0, priceUpdate_1.updateTokenPricesIx)({
|
|
824
890
|
keeper: keeper,
|
|
825
891
|
basket: basket.ownAddress,
|
|
@@ -829,6 +895,7 @@ class SymmetryCore {
|
|
|
829
895
|
tokenIndices: tokenIndices,
|
|
830
896
|
additionalOracleAccounts: allKeys,
|
|
831
897
|
basketRebalanceIntent: basket.settings.activeRebalance.eq(new anchor_1.BN(0)) ? undefined : basketRebalanceIntent,
|
|
898
|
+
basketMint: performanceFees > 0 ? basket.mint : undefined,
|
|
832
899
|
}));
|
|
833
900
|
}
|
|
834
901
|
let txBatchData = { batches: [ixs.map(ix => ({
|
|
@@ -871,7 +938,7 @@ class SymmetryCore {
|
|
|
871
938
|
let ixWithdraw = (0, flashSwap_1.flashWithdrawIx)(flashParams);
|
|
872
939
|
let ixDeposit = (0, flashSwap_1.flashDepositIx)(flashParams);
|
|
873
940
|
let ixs = [];
|
|
874
|
-
ixs.concat([
|
|
941
|
+
ixs = ixs.concat([
|
|
875
942
|
(0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(keeper, (0, pda_1.getAta)(keeper, mintIn), keeper, mintIn),
|
|
876
943
|
(0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(keeper, (0, pda_1.getAta)(keeper, mintOut), keeper, mintOut),
|
|
877
944
|
]);
|
|
@@ -964,17 +1031,17 @@ class SymmetryCore {
|
|
|
964
1031
|
let rebalanceIntent = yield this.fetchRebalanceIntent(params.rebalance_intent);
|
|
965
1032
|
let keepersArray = [];
|
|
966
1033
|
if (!rebalanceIntent.startPriceUpdateTask.completedBy.equals(web3_js_1.PublicKey.default))
|
|
967
|
-
keepersArray.push(rebalanceIntent.startPriceUpdateTask.completedBy);
|
|
1034
|
+
keepersArray.push(rebalanceIntent.startPriceUpdateTask.completedBy.toBase58());
|
|
968
1035
|
if (!rebalanceIntent.finishPriceUpdateTask.completedBy.equals(web3_js_1.PublicKey.default))
|
|
969
|
-
keepersArray.push(rebalanceIntent.finishPriceUpdateTask.completedBy);
|
|
1036
|
+
keepersArray.push(rebalanceIntent.finishPriceUpdateTask.completedBy.toBase58());
|
|
970
1037
|
if (!rebalanceIntent.mintBasketTask.completedBy.equals(web3_js_1.PublicKey.default))
|
|
971
|
-
keepersArray.push(rebalanceIntent.mintBasketTask.completedBy);
|
|
1038
|
+
keepersArray.push(rebalanceIntent.mintBasketTask.completedBy.toBase58());
|
|
972
1039
|
for (let i = 0; i < rebalanceIntent.priceUpdateTasks.length; i++)
|
|
973
1040
|
if (!rebalanceIntent.priceUpdateTasks[i].completedBy.equals(web3_js_1.PublicKey.default))
|
|
974
|
-
keepersArray.push(rebalanceIntent.priceUpdateTasks[i].completedBy);
|
|
1041
|
+
keepersArray.push(rebalanceIntent.priceUpdateTasks[i].completedBy.toBase58());
|
|
975
1042
|
for (let i = 0; i < rebalanceIntent.tokenSettlementTasks.length; i++)
|
|
976
1043
|
if (!rebalanceIntent.tokenSettlementTasks[i].completedBy.equals(web3_js_1.PublicKey.default))
|
|
977
|
-
keepersArray.push(rebalanceIntent.tokenSettlementTasks[i].completedBy);
|
|
1044
|
+
keepersArray.push(rebalanceIntent.tokenSettlementTasks[i].completedBy.toBase58());
|
|
978
1045
|
keepersArray = Array.from(new Set(keepersArray));
|
|
979
1046
|
let batchSize = 10;
|
|
980
1047
|
let ixs = [];
|
|
@@ -986,7 +1053,7 @@ class SymmetryCore {
|
|
|
986
1053
|
bountyMint: rebalanceIntent.bounty.bountyMint,
|
|
987
1054
|
bountyDepositor: rebalanceIntent.bounty.bountyDepositor,
|
|
988
1055
|
rentPayer: rebalanceIntent.rentPayer,
|
|
989
|
-
keepers: keepersArray.slice(batchStart, batchStart + batchSize),
|
|
1056
|
+
keepers: keepersArray.map(keeper => new web3_js_1.PublicKey(keeper)).slice(batchStart, batchStart + batchSize),
|
|
990
1057
|
}));
|
|
991
1058
|
let txBatchData = { batches: [ixs.map(ix => ({
|
|
992
1059
|
payer: keeper,
|
|
@@ -1002,6 +1069,37 @@ class SymmetryCore {
|
|
|
1002
1069
|
return txPayloadBatchSequence;
|
|
1003
1070
|
});
|
|
1004
1071
|
}
|
|
1072
|
+
addBountyTx(params) {
|
|
1073
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1074
|
+
let keeper = new web3_js_1.PublicKey(params.keeper);
|
|
1075
|
+
let basket = yield this.fetchBasket(params.basket);
|
|
1076
|
+
let globalConfig = yield this.fetchGlobalConfig();
|
|
1077
|
+
let bountyWsolAmount = 0;
|
|
1078
|
+
if (globalConfig.bountyMint.equals(constants_1.MINTS["mainnet"].WSOL)) {
|
|
1079
|
+
bountyWsolAmount = params.amount;
|
|
1080
|
+
}
|
|
1081
|
+
let wsolIxs = yield (0, txUtils_1.wrapWsolIxs)(this.sdkParams.connection, keeper, bountyWsolAmount);
|
|
1082
|
+
let ix = (0, addBounty_1.addBountyIx)({
|
|
1083
|
+
keeper: keeper,
|
|
1084
|
+
basket: basket.ownAddress,
|
|
1085
|
+
bountyMint: basket.settings.bountyMint,
|
|
1086
|
+
amount: params.amount,
|
|
1087
|
+
});
|
|
1088
|
+
let txBatchData = { batches: [[{
|
|
1089
|
+
payer: keeper,
|
|
1090
|
+
instructions: [
|
|
1091
|
+
...wsolIxs,
|
|
1092
|
+
ix,
|
|
1093
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: constants_1.COMPUTE_UNITS }),
|
|
1094
|
+
web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: this.sdkParams.priorityFee }),
|
|
1095
|
+
],
|
|
1096
|
+
lookupTables: [],
|
|
1097
|
+
}]] };
|
|
1098
|
+
let versionedTxs = yield (0, txUtils_1.prepareVersionedTxs)(this.sdkParams.connection, txBatchData);
|
|
1099
|
+
let txPayloadBatchSequence = (0, txUtils_1.prepareTxPayloadBatchSequence)(txBatchData, versionedTxs);
|
|
1100
|
+
return txPayloadBatchSequence;
|
|
1101
|
+
});
|
|
1102
|
+
}
|
|
1005
1103
|
claimBasketFeesTx(params) {
|
|
1006
1104
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1007
1105
|
let claimer = new web3_js_1.PublicKey(params.claimer);
|
|
@@ -1066,3 +1164,5 @@ class SymmetryCore {
|
|
|
1066
1164
|
}
|
|
1067
1165
|
}
|
|
1068
1166
|
exports.SymmetryCore = SymmetryCore;
|
|
1167
|
+
var keeperMonitor_1 = require("./keeperMonitor");
|
|
1168
|
+
Object.defineProperty(exports, "KeeperMonitor", { enumerable: true, get: function () { return keeperMonitor_1.KeeperMonitor; } });
|
|
@@ -14,6 +14,7 @@ export declare function updateTokenPricesIx(params: {
|
|
|
14
14
|
lookupTable1: PublicKey;
|
|
15
15
|
tokenIndices: number[];
|
|
16
16
|
additionalOracleAccounts: PublicKey[];
|
|
17
|
+
basketMint?: PublicKey;
|
|
17
18
|
}): TransactionInstruction;
|
|
18
19
|
export declare function updateTokenPricesCustomIx(params: {
|
|
19
20
|
manager: PublicKey;
|
|
@@ -8,6 +8,7 @@ const constants_1 = require("../../constants");
|
|
|
8
8
|
const oracle_1 = require("../../layouts/oracle");
|
|
9
9
|
const pda_1 = require("../pda");
|
|
10
10
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
11
|
+
const spl_token_1 = require("@solana/spl-token");
|
|
11
12
|
const START_PRICE_UPDATES_DISCRIMINATOR = Buffer.from([240, 67, 241, 88, 0, 32, 224, 184]);
|
|
12
13
|
const UPDATE_TOKEN_PRICES_DISCRIMINATOR = Buffer.from([147, 87, 140, 33, 214, 189, 181, 242]);
|
|
13
14
|
const UPDATE_TOKEN_PRICES_CUSTOM_DISCRIMINATOR = Buffer.from([71, 100, 35, 136, 116, 239, 54, 126]);
|
|
@@ -50,6 +51,13 @@ function updateTokenPricesIx(params) {
|
|
|
50
51
|
];
|
|
51
52
|
// remaining accounts
|
|
52
53
|
keys.push(...params.additionalOracleAccounts.map((pubkey) => ({ pubkey, isSigner: false, isWritable: false })));
|
|
54
|
+
if (params.basketMint) {
|
|
55
|
+
let basketFeesWallet = (0, pda_1.getBasketFeesPda)(params.basket);
|
|
56
|
+
let basketFeesTokenAccount = (0, pda_1.getAta)(basketFeesWallet, params.basketMint);
|
|
57
|
+
keys.push({ pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false });
|
|
58
|
+
keys.push({ pubkey: params.basketMint, isSigner: false, isWritable: true });
|
|
59
|
+
keys.push({ pubkey: basketFeesTokenAccount, isSigner: false, isWritable: true });
|
|
60
|
+
}
|
|
53
61
|
return new web3_js_1.TransactionInstruction({
|
|
54
62
|
keys,
|
|
55
63
|
programId: constants_1.BASKETS_V3_PROGRAM_ID,
|
|
@@ -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
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Connection } from "@solana/web3.js";
|
|
2
|
+
import { Wallet } from "./txUtils";
|
|
3
|
+
import { SymmetryCore } from ".";
|
|
4
|
+
export declare class KeeperMonitor {
|
|
5
|
+
private params;
|
|
6
|
+
private intents;
|
|
7
|
+
private rebalanceIntents;
|
|
8
|
+
private baskets;
|
|
9
|
+
constructor(params: {
|
|
10
|
+
wallet: Wallet;
|
|
11
|
+
connection: Connection;
|
|
12
|
+
symmetryCore: SymmetryCore;
|
|
13
|
+
network: "devnet" | "mainnet";
|
|
14
|
+
jupiterApiKey: string;
|
|
15
|
+
maxAllowedAccounts: number;
|
|
16
|
+
});
|
|
17
|
+
delay: (ms: number) => Promise<unknown>;
|
|
18
|
+
update(): Promise<void>;
|
|
19
|
+
run(): Promise<void>;
|
|
20
|
+
checkIntents(): Promise<void>;
|
|
21
|
+
checkRebalanceIntents(): Promise<void>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.KeeperMonitor = void 0;
|
|
13
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
14
|
+
const _1 = require(".");
|
|
15
|
+
const rebalanceIntent_1 = require("./states/intents/rebalanceIntent");
|
|
16
|
+
class KeeperMonitor {
|
|
17
|
+
constructor(params) {
|
|
18
|
+
this.delay = (ms) => __awaiter(this, void 0, void 0, function* () { return new Promise(resolve => setTimeout(resolve, ms)); });
|
|
19
|
+
this.params = {
|
|
20
|
+
wallet: params.wallet,
|
|
21
|
+
connection: params.connection,
|
|
22
|
+
symmetryCore: new _1.SymmetryCore({
|
|
23
|
+
connection: params.connection,
|
|
24
|
+
network: params.network,
|
|
25
|
+
}),
|
|
26
|
+
network: params.network,
|
|
27
|
+
jupiterApiKey: params.jupiterApiKey,
|
|
28
|
+
maxAllowedAccounts: params.maxAllowedAccounts,
|
|
29
|
+
};
|
|
30
|
+
//@ts-ignore
|
|
31
|
+
this.globalConfig = {};
|
|
32
|
+
this.intents = [];
|
|
33
|
+
this.rebalanceIntents = [];
|
|
34
|
+
this.baskets = [];
|
|
35
|
+
}
|
|
36
|
+
update() {
|
|
37
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
this.baskets = yield this.params.symmetryCore.fetchAllBaskets();
|
|
39
|
+
this.rebalanceIntents = yield this.params.symmetryCore.fetchAllRebalanceIntents();
|
|
40
|
+
this.intents = yield this.params.symmetryCore.fetchAllIntents();
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
run() {
|
|
44
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
console.log("Starting keeper monitor", this.params.wallet.publicKey.toBase58());
|
|
46
|
+
while (true) {
|
|
47
|
+
yield this.update();
|
|
48
|
+
yield this.checkIntents();
|
|
49
|
+
yield this.checkRebalanceIntents();
|
|
50
|
+
yield this.delay(30 * 1000);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
checkIntents() {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
let now = Date.now() / 1000;
|
|
57
|
+
for (let intent of this.intents)
|
|
58
|
+
try {
|
|
59
|
+
if (intent.formatted.activation_timestamp < now)
|
|
60
|
+
try {
|
|
61
|
+
let tx = yield this.params.symmetryCore.executeBasketIntentTx({
|
|
62
|
+
keeper: this.params.wallet.publicKey.toBase58(),
|
|
63
|
+
intent: intent.ownAddress.toBase58(),
|
|
64
|
+
});
|
|
65
|
+
let res = yield this.params.symmetryCore.signAndSendTxPayloadBatchSequence({ txPayloadBatchSequence: tx, wallet: this.params.wallet });
|
|
66
|
+
console.log("Execute Basket Intent:", res);
|
|
67
|
+
let txCancel = yield this.params.symmetryCore.cancelBasketIntentTx({
|
|
68
|
+
keeper: this.params.wallet.publicKey.toBase58(),
|
|
69
|
+
intent: intent.ownAddress.toBase58(),
|
|
70
|
+
});
|
|
71
|
+
let resCancel = yield this.params.symmetryCore.signAndSendTxPayloadBatchSequence({ txPayloadBatchSequence: txCancel, wallet: this.params.wallet });
|
|
72
|
+
console.log("Cancel Basket Intent:", resCancel);
|
|
73
|
+
}
|
|
74
|
+
catch (_a) {
|
|
75
|
+
let tx = yield this.params.symmetryCore.cancelBasketIntentTx({
|
|
76
|
+
keeper: this.params.wallet.publicKey.toBase58(),
|
|
77
|
+
intent: intent.ownAddress.toBase58(),
|
|
78
|
+
});
|
|
79
|
+
let res = yield this.params.symmetryCore.signAndSendTxPayloadBatchSequence({ txPayloadBatchSequence: tx, wallet: this.params.wallet });
|
|
80
|
+
console.log("Cancel Basket Intent:", res);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (_b) { }
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
checkRebalanceIntents() {
|
|
87
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
let now = Date.now() / 1000;
|
|
89
|
+
for (let intent of this.rebalanceIntents)
|
|
90
|
+
try {
|
|
91
|
+
console.log(intent.ownAddress.toBase58());
|
|
92
|
+
if (intent.formatted.current_action == "not_active")
|
|
93
|
+
continue;
|
|
94
|
+
if (intent.formatted.current_action == "deposit_tokens")
|
|
95
|
+
continue;
|
|
96
|
+
if (intent.formatted.current_action == "start_price_updates")
|
|
97
|
+
try {
|
|
98
|
+
let tx = yield this.params.symmetryCore.startPriceUpdatesTx({
|
|
99
|
+
keeper: this.params.wallet.publicKey.toBase58(),
|
|
100
|
+
basket: intent.basket.toBase58(),
|
|
101
|
+
rebalance_intent: intent.ownAddress.toBase58(),
|
|
102
|
+
});
|
|
103
|
+
let res = yield this.params.symmetryCore.signAndSendTxPayloadBatchSequence({ txPayloadBatchSequence: tx, wallet: this.params.wallet });
|
|
104
|
+
console.log("Start Price Updates:", res);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
catch (_a) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (intent.formatted.current_action == "update_prices" && intent.formatted.last_action_timestamp < now)
|
|
111
|
+
try {
|
|
112
|
+
let tx = yield this.params.symmetryCore.updateTokenPricesTx({
|
|
113
|
+
keeper: this.params.wallet.publicKey.toBase58(),
|
|
114
|
+
basket: intent.basket.toBase58(),
|
|
115
|
+
rebalance_intent: intent.ownAddress.toBase58(),
|
|
116
|
+
});
|
|
117
|
+
let res = yield this.params.symmetryCore.signAndSendTxPayloadBatchSequence({ txPayloadBatchSequence: tx, wallet: this.params.wallet });
|
|
118
|
+
console.log("Update Prices:", res);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
catch (_b) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (intent.formatted.current_action == "update_prices") {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (intent.formatted.auctions[2].end_time >= now)
|
|
128
|
+
try {
|
|
129
|
+
let basket = this.baskets.find(basket => basket.ownAddress.equals(intent.basket));
|
|
130
|
+
let pairs = (0, rebalanceIntent_1.getSwapPairs)(intent, basket);
|
|
131
|
+
for (let pair of pairs)
|
|
132
|
+
try {
|
|
133
|
+
let { tokenLedgerInstruction, swapInstruction, addressLookupTableAddresses, quoteResponse } = yield (0, _1.getJupTokenLedgerAndSwapInstructions)({
|
|
134
|
+
keeper: this.params.wallet.publicKey,
|
|
135
|
+
basketMintIn: new web3_js_1.PublicKey(pair.inMint),
|
|
136
|
+
basketMintOut: new web3_js_1.PublicKey(pair.outMint),
|
|
137
|
+
basketAmountIn: pair.inAmount,
|
|
138
|
+
basketAmountOut: pair.outAmount,
|
|
139
|
+
swapMode: "ioc",
|
|
140
|
+
apiKey: this.params.jupiterApiKey,
|
|
141
|
+
maxJupAccounts: 45,
|
|
142
|
+
});
|
|
143
|
+
console.log(pair, "Jup Quote:", parseFloat(quoteResponse.outAmount), "Requested In:", pair.inAmount);
|
|
144
|
+
if (parseFloat(quoteResponse.outAmount) < pair.inAmount)
|
|
145
|
+
continue;
|
|
146
|
+
let tx = yield this.params.symmetryCore.flashSwapTx({
|
|
147
|
+
keeper: this.params.wallet.publicKey.toBase58(),
|
|
148
|
+
basket: basket.ownAddress.toBase58(),
|
|
149
|
+
rebalance_intent: intent.ownAddress.toBase58(),
|
|
150
|
+
mint_in: pair.inMint,
|
|
151
|
+
mint_out: pair.outMint,
|
|
152
|
+
amount_in: pair.inAmount,
|
|
153
|
+
amount_out: pair.outAmount,
|
|
154
|
+
mode: 2,
|
|
155
|
+
jup_token_ledger_ix: tokenLedgerInstruction,
|
|
156
|
+
jup_swap_ix: swapInstruction,
|
|
157
|
+
jup_address_lookup_table_addresses: addressLookupTableAddresses,
|
|
158
|
+
});
|
|
159
|
+
let res = yield this.params.symmetryCore.signAndSendTxPayloadBatchSequence({ txPayloadBatchSequence: tx, wallet: this.params.wallet });
|
|
160
|
+
console.log("Flash Swap:", res);
|
|
161
|
+
}
|
|
162
|
+
catch (_c) {
|
|
163
|
+
(e) => console.log(e);
|
|
164
|
+
}
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
catch (_d) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (intent.formatted.rebalance_type == "deposit")
|
|
171
|
+
try {
|
|
172
|
+
let tx = yield this.params.symmetryCore.mintTx({
|
|
173
|
+
keeper: this.params.wallet.publicKey.toBase58(),
|
|
174
|
+
rebalance_intent: intent.ownAddress.toBase58(),
|
|
175
|
+
});
|
|
176
|
+
let res = yield this.params.symmetryCore.signAndSendTxPayloadBatchSequence({ txPayloadBatchSequence: tx, wallet: this.params.wallet });
|
|
177
|
+
console.log("Mint:", res);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
catch (_e) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
let hasTokens = intent.formatted.tokens.find(token => token.amount > 0);
|
|
184
|
+
if (hasTokens && intent.formatted.rebalance_type == "withdraw")
|
|
185
|
+
try {
|
|
186
|
+
let tx = yield this.params.symmetryCore.redeemTokensTx({
|
|
187
|
+
keeper: this.params.wallet.publicKey.toBase58(),
|
|
188
|
+
rebalance_intent: intent.ownAddress.toBase58(),
|
|
189
|
+
});
|
|
190
|
+
let res = yield this.params.symmetryCore.signAndSendTxPayloadBatchSequence({ txPayloadBatchSequence: tx, wallet: this.params.wallet });
|
|
191
|
+
console.log("Redeem Tokens:", res);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
catch (_f) {
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
let tx = yield this.params.symmetryCore.claimBountyTx({
|
|
199
|
+
keeper: this.params.wallet.publicKey.toBase58(),
|
|
200
|
+
rebalance_intent: intent.ownAddress.toBase58(),
|
|
201
|
+
});
|
|
202
|
+
let res = yield this.params.symmetryCore.signAndSendTxPayloadBatchSequence({ txPayloadBatchSequence: tx, wallet: this.params.wallet });
|
|
203
|
+
console.log("Claim Bounty:", res);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
catch (_g) {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
catch (_h) { }
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
exports.KeeperMonitor = KeeperMonitor;
|
|
@@ -223,14 +223,14 @@ class RebalanceIntentRustClass {
|
|
|
223
223
|
this.self = rebalanceIntent;
|
|
224
224
|
}
|
|
225
225
|
findTokenIndex(mint) {
|
|
226
|
-
for (let i = 0; i <
|
|
226
|
+
for (let i = 0; i < this.self.priceUpdateTasks.length; i++)
|
|
227
227
|
if (this.self.tokens[i].mint.equals(mint))
|
|
228
228
|
return i;
|
|
229
229
|
return undefined;
|
|
230
230
|
}
|
|
231
231
|
getSelfTvl() {
|
|
232
232
|
let selfTvl = { high: new anchor_1.BN(0), low: new anchor_1.BN(0) };
|
|
233
|
-
for (let i = 0; i <
|
|
233
|
+
for (let i = 0; i < this.self.priceUpdateTasks.length; i++) {
|
|
234
234
|
if (this.self.priceUpdateTasks[i].completedTime.isZero()) {
|
|
235
235
|
continue;
|
|
236
236
|
}
|
|
@@ -377,7 +377,7 @@ class RebalanceIntentRustClass {
|
|
|
377
377
|
this.self.auctionUpdateTimestamp = new anchor_1.BN(Math.floor(Date.now() / 1000));
|
|
378
378
|
const selfTvl = this.getSelfTvl();
|
|
379
379
|
const { basketTvl, weightSum } = this.getBasketTvlAndWeightSum(basket);
|
|
380
|
-
for (let tokenIndex = 0; tokenIndex <
|
|
380
|
+
for (let tokenIndex = 0; tokenIndex < this.self.priceUpdateTasks.length; tokenIndex++) {
|
|
381
381
|
if (this.self.tokens[tokenIndex].mint.equals(web3_js_1.PublicKey.default)) {
|
|
382
382
|
continue;
|
|
383
383
|
}
|
|
@@ -456,10 +456,10 @@ function getSwapPairs(rebalanceIntent, basket) {
|
|
|
456
456
|
let timeSinceAuctionStart = timestamp.sub(currentAuction.startTime);
|
|
457
457
|
let auctionDuration = currentAuction.endTime.sub(currentAuction.startTime);
|
|
458
458
|
let allPairs = [];
|
|
459
|
-
for (let inTokenIndex = 0; inTokenIndex <
|
|
459
|
+
for (let inTokenIndex = 0; inTokenIndex < rebalanceIntentRustClass.self.priceUpdateTasks.length; inTokenIndex++) {
|
|
460
460
|
if (rebalanceIntentRustClass.self.priceUpdateTasks[inTokenIndex].completedTime.isZero())
|
|
461
461
|
continue;
|
|
462
|
-
for (let outTokenIndex = 0; outTokenIndex <
|
|
462
|
+
for (let outTokenIndex = 0; outTokenIndex < rebalanceIntentRustClass.self.priceUpdateTasks.length; outTokenIndex++) {
|
|
463
463
|
if (inTokenIndex === outTokenIndex)
|
|
464
464
|
continue;
|
|
465
465
|
if (rebalanceIntentRustClass.self.priceUpdateTasks[outTokenIndex].completedTime.isZero())
|
package/dist/test.d.ts
CHANGED
|
@@ -1,22 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { Wallet } from "@coral-xyz/anchor";
|
|
3
|
-
import { SymmetryCore } from "./src";
|
|
4
|
-
export declare class KeeperMonitor {
|
|
5
|
-
private params;
|
|
6
|
-
private intents;
|
|
7
|
-
private rebalanceIntents;
|
|
8
|
-
private baskets;
|
|
9
|
-
constructor(params: {
|
|
10
|
-
wallet: Wallet;
|
|
11
|
-
connection: Connection;
|
|
12
|
-
symmetryCore: SymmetryCore;
|
|
13
|
-
network: "devnet" | "mainnet";
|
|
14
|
-
jupiterApiKey: string;
|
|
15
|
-
maxAllowedAccounts: number;
|
|
16
|
-
});
|
|
17
|
-
delay: (ms: number) => Promise<unknown>;
|
|
18
|
-
update(): Promise<void>;
|
|
19
|
-
run(): Promise<void>;
|
|
20
|
-
checkIntents(): Promise<void>;
|
|
21
|
-
checkRebalanceIntents(): Promise<void>;
|
|
22
|
-
}
|
|
1
|
+
export {};
|