@symmetry-hq/sdk 1.0.11 → 1.0.13
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.js +16 -0
- package/dist/src/states/intents/rebalanceIntent.js +20 -10
- package/dist/src/states/oracles/oracle.d.ts +1 -1
- package/dist/src/states/oracles/oracle.js +9 -14
- package/dist/src/states/oracles/pythOracle.d.ts +6 -2
- package/dist/src/states/oracles/pythOracle.js +11 -8
- package/dist/src/states/oracles/raydiumCpmmOracle.d.ts +1 -1
- package/dist/src/states/oracles/raydiumCpmmOracle.js +4 -3
- package/dist/src/txUtils.d.ts +10 -3
- package/dist/src/txUtils.js +199 -80
- package/dist/test.js +7 -7
- package/package.json +1 -1
- package/src/index.ts +21 -1
- package/src/states/intents/rebalanceIntent.ts +20 -10
- package/src/states/oracles/oracle.ts +11 -16
- package/src/states/oracles/pythOracle.ts +19 -14
- package/src/states/oracles/raydiumCpmmOracle.ts +5 -4
- package/src/txUtils.ts +218 -109
- package/test.ts +12 -10
package/dist/src/index.js
CHANGED
|
@@ -729,6 +729,12 @@ class SymmetryCore {
|
|
|
729
729
|
let maxBountyPerTask = parseInt(maxBounty.toString());
|
|
730
730
|
bountyWsolAmount = maxBountyPerTask + boundBounty;
|
|
731
731
|
}
|
|
732
|
+
if (editType === intent_1.TaskType.EditAutomationSettings && editData.enabled == true) {
|
|
733
|
+
let bountyBalance = parseInt(vault.settings.bountyBalance.toString());
|
|
734
|
+
let requiredBounty = parseInt(globalConfig.minBountyForVaultAutomation.toString());
|
|
735
|
+
if (bountyBalance < requiredBounty)
|
|
736
|
+
bountyWsolAmount += 2 * requiredBounty - bountyBalance;
|
|
737
|
+
}
|
|
732
738
|
let wsolIxs = yield (0, txUtils_1.wrapWsolIxs)(this.sdkParams.connection, manager, bountyWsolAmount);
|
|
733
739
|
let intentSeedArray = web3_js_1.Keypair.generate().publicKey.toBytes();
|
|
734
740
|
let tokenProgram = undefined;
|
|
@@ -1367,6 +1373,16 @@ class SymmetryCore {
|
|
|
1367
1373
|
maxBountyPerTask = maxBountyAmount;
|
|
1368
1374
|
bountyWsolAmount = (0, rebalanceIntent_3.computeRebalanceIntentBountyAmount)(rebalanceIntent_2.RebalanceType.Vault, vault.numTokens, boundBounty, maxBountyPerTask, Math.floor(maxBountyPerTask / bountyPerPriceUpdateTaskDivisor));
|
|
1369
1375
|
}
|
|
1376
|
+
let isManager = vault.settings.creator.equals(keeper);
|
|
1377
|
+
for (let i = 0; i < vault.settings.managers.managers.length; i++)
|
|
1378
|
+
if (vault.settings.managers.managers[i].equals(keeper))
|
|
1379
|
+
isManager = true;
|
|
1380
|
+
if (isManager) {
|
|
1381
|
+
let bountyBalance = parseInt(vault.settings.bountyBalance.toString());
|
|
1382
|
+
let requiredBounty = parseInt(globalConfig.minBountyForVaultAutomation.toString());
|
|
1383
|
+
if (bountyBalance < requiredBounty)
|
|
1384
|
+
bountyWsolAmount += 2 * requiredBounty - bountyBalance;
|
|
1385
|
+
}
|
|
1370
1386
|
let wsolIxs = yield (0, txUtils_1.wrapWsolIxs)(this.sdkParams.connection, keeper, bountyWsolAmount);
|
|
1371
1387
|
const rebalanceIntent = (0, pda_1.getRebalanceIntentPda)(vault.ownAddress, vault.ownAddress);
|
|
1372
1388
|
let rentPayer = (0, pda_1.getRentPayerPda)();
|
|
@@ -153,23 +153,33 @@ function formatRebalanceIntent(rebalanceIntent, vault) {
|
|
|
153
153
|
})),
|
|
154
154
|
};
|
|
155
155
|
if (vault) {
|
|
156
|
+
const auctionTokenByMint = new Map(auctionData.tokens.map(token => [token.mint, token]));
|
|
157
|
+
const mintDataTokenByMint = new Map(mintData.tokens.map(token => [token.mint, token]));
|
|
156
158
|
let minRatio = 1;
|
|
157
|
-
for (
|
|
158
|
-
if (
|
|
159
|
+
for (const vaultToken of vault.composition) {
|
|
160
|
+
if (vaultToken.amount == 0)
|
|
159
161
|
continue;
|
|
160
|
-
|
|
162
|
+
const auctionToken = auctionTokenByMint.get(vaultToken.mint);
|
|
163
|
+
if (!auctionToken)
|
|
164
|
+
continue;
|
|
165
|
+
let ratio = auctionToken.amount / vaultToken.amount;
|
|
161
166
|
minRatio = Math.min(minRatio, ratio);
|
|
162
167
|
}
|
|
163
168
|
let mintValue = 0;
|
|
164
169
|
let remainingValue = 0;
|
|
165
170
|
let mintAmount = Math.floor(vault.supply_outstanding * minRatio);
|
|
166
|
-
for (
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
for (const vaultToken of vault.composition) {
|
|
172
|
+
const mint = vaultToken.mint;
|
|
173
|
+
const auctionToken = auctionTokenByMint.get(mint);
|
|
174
|
+
const mintDataToken = mintDataTokenByMint.get(mint);
|
|
175
|
+
if (!auctionToken || !mintDataToken)
|
|
176
|
+
continue;
|
|
177
|
+
let contributionAmount = Math.floor(vaultToken.amount * minRatio);
|
|
178
|
+
contributionAmount = Math.min(contributionAmount, auctionToken.amount);
|
|
179
|
+
mintDataToken.contribution_amount = contributionAmount;
|
|
180
|
+
mintDataToken.remaining_amount = auctionToken.amount - contributionAmount;
|
|
181
|
+
mintValue += contributionAmount * auctionToken.price;
|
|
182
|
+
remainingValue += (auctionToken.amount - contributionAmount) * auctionToken.price;
|
|
173
183
|
}
|
|
174
184
|
mintData.mintValue = mintValue;
|
|
175
185
|
mintData.mintAmount = mintAmount;
|
|
@@ -20,5 +20,5 @@ export declare class PriceAggregator {
|
|
|
20
20
|
minOraclesThresh: number;
|
|
21
21
|
confMultiplier: Fraction;
|
|
22
22
|
constructor(numOracles: number, oracles: OracleData[], minConfBps: number, confThreshBps: number, minOraclesThresh: number, confMultiplier: Fraction);
|
|
23
|
-
static fetch(oracleAggregator: OracleAggregator, lutAccounts: AddressLookupTableAccount[], accountInfoMap: Map<string, AccountInfo<Buffer> | null>,
|
|
23
|
+
static fetch(oracleAggregator: OracleAggregator, lutAccounts: AddressLookupTableAccount[], accountInfoMap: Map<string, AccountInfo<Buffer> | null>, wsolPrice: OraclePrice, usdcPrice: OraclePrice, pythPriceOverrides?: Map<string, OraclePrice>): OraclePrice;
|
|
24
24
|
}
|
|
@@ -54,7 +54,7 @@ class PriceAggregator {
|
|
|
54
54
|
if (!(0 <= this.minOraclesThresh && this.minOraclesThresh <= constants_2.U32_MAX.toNumber()))
|
|
55
55
|
throw new Error(`Minimum number of oracles must be between 0 and ${constants_2.U32_MAX}`);
|
|
56
56
|
}
|
|
57
|
-
static fetch(oracleAggregator, lutAccounts, accountInfoMap,
|
|
57
|
+
static fetch(oracleAggregator, lutAccounts, accountInfoMap, wsolPrice, usdcPrice, pythPriceOverrides) {
|
|
58
58
|
let validated = true;
|
|
59
59
|
const agg = oracleAggregator;
|
|
60
60
|
const oracleResults = [];
|
|
@@ -62,15 +62,11 @@ class PriceAggregator {
|
|
|
62
62
|
const oracleData = agg.oracles[i];
|
|
63
63
|
const settings = oracleData.oracleSettings;
|
|
64
64
|
let loadedAccounts = [];
|
|
65
|
-
let firstLoadedPubkey;
|
|
66
65
|
for (let j = 0; j < settings.numRequiredAccounts; j++) {
|
|
67
66
|
const lutId = oracleData.accountsToLoadLutIds[j];
|
|
68
67
|
const lutIdx = oracleData.accountsToLoadLutIndices[j];
|
|
69
68
|
const pubkey = lutAccounts[lutId].state.addresses[lutIdx];
|
|
70
69
|
const account = accountInfoMap.get(pubkey.toBase58());
|
|
71
|
-
if (!firstLoadedPubkey) {
|
|
72
|
-
firstLoadedPubkey = pubkey;
|
|
73
|
-
}
|
|
74
70
|
// @ts-ignore
|
|
75
71
|
loadedAccounts.push(account);
|
|
76
72
|
}
|
|
@@ -95,17 +91,16 @@ class PriceAggregator {
|
|
|
95
91
|
let result = (() => {
|
|
96
92
|
switch (settings.oracleType) {
|
|
97
93
|
case oracle_1.OracleType.Pyth:
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return pythOracle_1.PythOracle.fetch(settings, loadedAccounts, solPrice, usdPrice);
|
|
94
|
+
const lutId = oracleData.accountsToLoadLutIds[0];
|
|
95
|
+
const lutIdx = oracleData.accountsToLoadLutIndices[0];
|
|
96
|
+
const pubkey = lutAccounts[lutId].state.addresses[lutIdx];
|
|
97
|
+
const override = pythPriceOverrides === null || pythPriceOverrides === void 0 ? void 0 : pythPriceOverrides.get(pubkey.toBase58());
|
|
98
|
+
const price = pythOracle_1.PythOracle.fetch(settings, loadedAccounts, wsolPrice, usdcPrice);
|
|
99
|
+
return (override ? override : price);
|
|
105
100
|
case oracle_1.OracleType.RaydiumClmm:
|
|
106
|
-
return raydiumClmmOracle_1.RaydiumCLMMOracle.fetch(settings, loadedAccounts,
|
|
101
|
+
return raydiumClmmOracle_1.RaydiumCLMMOracle.fetch(settings, loadedAccounts, wsolPrice, usdcPrice);
|
|
107
102
|
case oracle_1.OracleType.RaydiumCpmm:
|
|
108
|
-
return raydiumCpmmOracle_1.RaydiumCPMMOracle.fetch(settings, loadedAccounts,
|
|
103
|
+
return raydiumCpmmOracle_1.RaydiumCPMMOracle.fetch(settings, loadedAccounts, wsolPrice, usdcPrice);
|
|
109
104
|
default:
|
|
110
105
|
throw new Error(`Invalid oracle type: ${settings.oracleType}`);
|
|
111
106
|
}
|
|
@@ -14,7 +14,7 @@ export interface HermesPythPriceData {
|
|
|
14
14
|
emaConf?: string | number;
|
|
15
15
|
}
|
|
16
16
|
export declare function fetchHermesPythPrices(priceFeedIds: string[]): Promise<Map<string, HermesPythPriceData>>;
|
|
17
|
-
export declare function buildPythOraclePriceFromHermesPriceData(oracleParams: OracleSettings, priceData: HermesPythPriceData,
|
|
17
|
+
export declare function buildPythOraclePriceFromHermesPriceData(oracleParams: OracleSettings, priceData: HermesPythPriceData, wsolPrice: OraclePrice, usdcPrice: OraclePrice): OraclePrice;
|
|
18
18
|
export type VerificationLevel = {
|
|
19
19
|
kind: 'Partial';
|
|
20
20
|
numSignatures: number;
|
|
@@ -38,6 +38,10 @@ export interface InstructionWithSigners {
|
|
|
38
38
|
signers: Keypair[];
|
|
39
39
|
computeUnits?: number;
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Build closeEncodedVaa instruction
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildCloseEncodedVaaInstruction(writeAuthority: PublicKey, encodedVaa: PublicKey, wormholeProgramId?: PublicKey): TransactionInstruction;
|
|
41
45
|
export interface PythUpdateResult {
|
|
42
46
|
postInstructions: InstructionWithSigners[];
|
|
43
47
|
closeInstructions: InstructionWithSigners[];
|
|
@@ -140,5 +144,5 @@ export declare class PythState {
|
|
|
140
144
|
static decode(buf: Buffer, offset?: number): [PythState, number];
|
|
141
145
|
}
|
|
142
146
|
export declare class PythOracle {
|
|
143
|
-
static fetch(oracleParams: OracleSettings, accountInfos: AccountInfo<Buffer>[],
|
|
147
|
+
static fetch(oracleParams: OracleSettings, accountInfos: AccountInfo<Buffer>[], wsolPrice?: OraclePrice, usdcPrice?: OraclePrice): OraclePrice;
|
|
144
148
|
}
|
|
@@ -20,6 +20,7 @@ exports.buildFreshVaultPythPriceOverrides = buildFreshVaultPythPriceOverrides;
|
|
|
20
20
|
exports.getRandomTipAccount = getRandomTipAccount;
|
|
21
21
|
exports.buildJitoTipInstruction = buildJitoTipInstruction;
|
|
22
22
|
exports.getPythPriceFeedAccountAddress = getPythPriceFeedAccountAddress;
|
|
23
|
+
exports.buildCloseEncodedVaaInstruction = buildCloseEncodedVaaInstruction;
|
|
23
24
|
exports.parsePriceFeedMessage = parsePriceFeedMessage;
|
|
24
25
|
exports.parseAccumulatorUpdateData = parseAccumulatorUpdateData;
|
|
25
26
|
exports.getSizeOfTransaction = getSizeOfTransaction;
|
|
@@ -72,17 +73,19 @@ function fetchHermesPythPrices(priceFeedIds) {
|
|
|
72
73
|
return result;
|
|
73
74
|
});
|
|
74
75
|
}
|
|
75
|
-
function buildPythOraclePriceFromHermesPriceData(oracleParams, priceData,
|
|
76
|
+
function buildPythOraclePriceFromHermesPriceData(oracleParams, priceData, wsolPrice, usdcPrice) {
|
|
76
77
|
var _a;
|
|
78
|
+
let quoteDecimals = (oracleParams.quote == oracle_1.Quote.Usdc) ? constants_1.USDC_DECIMALS : ((oracleParams.quote == oracle_1.Quote.Wsol) ? constants_1.WSOL_DECIMALS : 0);
|
|
77
79
|
let pr = new decimal_js_1.default(priceData.price.toString())
|
|
78
|
-
.mul(decimal_js_1.default.pow(10, priceData.expo - oracleParams.tokenDecimals));
|
|
80
|
+
.mul(decimal_js_1.default.pow(10, priceData.expo - oracleParams.tokenDecimals + quoteDecimals));
|
|
79
81
|
let ema = new decimal_js_1.default(((_a = priceData.emaPrice) !== null && _a !== void 0 ? _a : priceData.price).toString())
|
|
80
|
-
.mul(decimal_js_1.default.pow(10, priceData.expo - oracleParams.tokenDecimals));
|
|
82
|
+
.mul(decimal_js_1.default.pow(10, priceData.expo - oracleParams.tokenDecimals + quoteDecimals));
|
|
81
83
|
let cf = new decimal_js_1.default(priceData.conf.toString())
|
|
82
|
-
.mul(decimal_js_1.default.pow(10, priceData.expo - oracleParams.tokenDecimals));
|
|
84
|
+
.mul(decimal_js_1.default.pow(10, priceData.expo - oracleParams.tokenDecimals + quoteDecimals));
|
|
83
85
|
const lastUpdateTimestamp = priceData.publishTime;
|
|
84
|
-
let quotePrice = (oracleParams.quote === oracle_1.Quote.Usdc) ?
|
|
85
|
-
((oracleParams.quote === oracle_1.Quote.Wsol) ?
|
|
86
|
+
let quotePrice = (oracleParams.quote === oracle_1.Quote.Usdc) ? usdcPrice :
|
|
87
|
+
((oracleParams.quote === oracle_1.Quote.Wsol) ? wsolPrice :
|
|
88
|
+
new oracle_2.OraclePrice(new decimal_js_1.default(1), new decimal_js_1.default(0), 0));
|
|
86
89
|
pr = pr.mul(quotePrice.price);
|
|
87
90
|
ema = ema.mul(quotePrice.price);
|
|
88
91
|
cf = cf.mul(quotePrice.price);
|
|
@@ -711,7 +714,7 @@ class PythState {
|
|
|
711
714
|
}
|
|
712
715
|
exports.PythState = PythState;
|
|
713
716
|
class PythOracle {
|
|
714
|
-
static fetch(oracleParams, accountInfos,
|
|
717
|
+
static fetch(oracleParams, accountInfos, wsolPrice, usdcPrice) {
|
|
715
718
|
//@ts-ignore
|
|
716
719
|
let state = null;
|
|
717
720
|
try {
|
|
@@ -729,7 +732,7 @@ class PythOracle {
|
|
|
729
732
|
publishTime: parseInt(state.priceMessage.publishTime.toString()),
|
|
730
733
|
emaPrice: state.priceMessage.emaPrice.toString(),
|
|
731
734
|
emaConf: state.priceMessage.emaConf.toString(),
|
|
732
|
-
},
|
|
735
|
+
}, wsolPrice !== null && wsolPrice !== void 0 ? wsolPrice : new oracle_2.OraclePrice(new decimal_js_1.default(1), new decimal_js_1.default(0), 0), usdcPrice !== null && usdcPrice !== void 0 ? usdcPrice : new oracle_2.OraclePrice(new decimal_js_1.default(1), new decimal_js_1.default(0), 0));
|
|
733
736
|
}
|
|
734
737
|
}
|
|
735
738
|
exports.PythOracle = PythOracle;
|
|
@@ -115,6 +115,6 @@ export declare class RaydiumCPMMOracle {
|
|
|
115
115
|
* - SELL: delta_quote_out = netQuote * delta_base / (netBase + delta_base)
|
|
116
116
|
*/
|
|
117
117
|
static calculateMaxPriceImpactForMinLiquidity(oracleParams: OracleSettings, netBase: Decimal, netQuote: Decimal, spotPriceUsd: Decimal, quotePrice: OraclePrice): Decimal;
|
|
118
|
-
static fetch(oracleParams: OracleSettings, accountInfos: AccountInfo<Buffer>[],
|
|
118
|
+
static fetch(oracleParams: OracleSettings, accountInfos: AccountInfo<Buffer>[], wsolPrice: OraclePrice, usdcPrice: OraclePrice): OraclePrice;
|
|
119
119
|
}
|
|
120
120
|
export {};
|
|
@@ -462,7 +462,7 @@ class RaydiumCPMMOracle {
|
|
|
462
462
|
const maxImpact = decimal_js_1.default.max(impactBuy, impactSell);
|
|
463
463
|
return maxImpact.mul(new decimal_js_1.default(10000)); // Convert to bps
|
|
464
464
|
}
|
|
465
|
-
static fetch(oracleParams, accountInfos,
|
|
465
|
+
static fetch(oracleParams, accountInfos, wsolPrice, usdcPrice) {
|
|
466
466
|
const poolStateInfo = accountInfos[0];
|
|
467
467
|
const vault0Info = accountInfos[1];
|
|
468
468
|
const vault1Info = accountInfos[2];
|
|
@@ -473,8 +473,9 @@ class RaydiumCPMMOracle {
|
|
|
473
473
|
const [decodedObservationState, ____] = ObservationState.decode(observationStateInfo.data, 8);
|
|
474
474
|
const currentTime = new bn_js_1.default(Math.floor(Date.now() / 1000));
|
|
475
475
|
// Determine quote oracle
|
|
476
|
-
let quotePrice = (oracleParams.quote === oracle_1.Quote.Usdc) ?
|
|
477
|
-
((oracleParams.quote === oracle_1.Quote.Wsol) ?
|
|
476
|
+
let quotePrice = (oracleParams.quote === oracle_1.Quote.Usdc) ? usdcPrice :
|
|
477
|
+
((oracleParams.quote === oracle_1.Quote.Wsol) ? wsolPrice :
|
|
478
|
+
new oracle_2.OraclePrice(new decimal_js_1.default(1), new decimal_js_1.default(0), 0));
|
|
478
479
|
// Get spot price with reserves
|
|
479
480
|
const { netBase, netQuote, spotPrice } = this.getSpotPriceWithReserves(decodedPoolState, decodedVault0State, decodedVault1State, oracleParams.side, quotePrice);
|
|
480
481
|
// Get TWAP prices
|
package/dist/src/txUtils.d.ts
CHANGED
|
@@ -56,10 +56,17 @@ export declare function getMultipleAccountsInfoBatched(connection: Connection, p
|
|
|
56
56
|
export declare function getAddressLookupTableAccounts(connection: Connection, keys: PublicKey[]): Promise<Map<string, AddressLookupTableAccount>>;
|
|
57
57
|
export declare function getMultipleAddressLookupTableAccounts(connection: Connection, batches: PublicKey[][][]): Promise<AddressLookupTableAccount[][][]>;
|
|
58
58
|
export declare function compileVersionedTransaction(blockhash: string, addressLookupTableAccounts: AddressLookupTableAccount[], payerPubkey: PublicKey, ixs: TransactionInstruction[]): VersionedTransaction;
|
|
59
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Send + confirm a batch of versioned transactions with parallel rebroadcasting.
|
|
61
|
+
* All txs within each batch are sent and confirmed concurrently.
|
|
62
|
+
* Batches are processed sequentially (batch 1 must all confirm before batch 2 starts).
|
|
63
|
+
*/
|
|
64
|
+
export declare function sendVersionedTxs(connection: Connection, versionedTxs: VersionedTxs, simulateTransactions?: boolean, rebroadcastIntervalMs?: number, confirmTimeoutMs?: number): Promise<TransactionSignature[][]>;
|
|
65
|
+
/**
|
|
66
|
+
* Sign + send a TxPayloadBatchSequence using fast parallel rebroadcasting.
|
|
67
|
+
*/
|
|
68
|
+
export declare function sendTxPayloadBatchSequence(connection: Connection, txPayloadBatchSequence: TxPayloadBatchSequence, simulateTransactions?: boolean): Promise<TransactionSignature[][]>;
|
|
60
69
|
export declare function prepareVersionedTxs(connection: Connection, txBatchData: TxBatchData): Promise<VersionedTxs>;
|
|
61
|
-
export declare function sendVersionedTxs(connection: Connection, versionedTxs: VersionedTxs, simulateTransactions?: boolean): Promise<TransactionSignature[][]>;
|
|
62
70
|
export declare function signVersionedTxs(wallet: Wallet, versionedTxs: VersionedTxs): Promise<VersionedTxs>;
|
|
63
71
|
export declare function signTxPayloadBatchSequence(wallet: Wallet, txPayloadBatchSequence: TxPayloadBatchSequence): Promise<TxPayloadBatchSequence>;
|
|
64
|
-
export declare function sendTxPayloadBatchSequence(connection: Connection, txPayloadBatchSequence: TxPayloadBatchSequence, simulateTransactions?: boolean): Promise<TransactionSignature[][]>;
|
|
65
72
|
export {};
|
package/dist/src/txUtils.js
CHANGED
|
@@ -16,12 +16,11 @@ exports.getMultipleAccountsInfoBatched = getMultipleAccountsInfoBatched;
|
|
|
16
16
|
exports.getAddressLookupTableAccounts = getAddressLookupTableAccounts;
|
|
17
17
|
exports.getMultipleAddressLookupTableAccounts = getMultipleAddressLookupTableAccounts;
|
|
18
18
|
exports.compileVersionedTransaction = compileVersionedTransaction;
|
|
19
|
-
exports.sendVersionedTransaction = sendVersionedTransaction;
|
|
20
|
-
exports.prepareVersionedTxs = prepareVersionedTxs;
|
|
21
19
|
exports.sendVersionedTxs = sendVersionedTxs;
|
|
20
|
+
exports.sendTxPayloadBatchSequence = sendTxPayloadBatchSequence;
|
|
21
|
+
exports.prepareVersionedTxs = prepareVersionedTxs;
|
|
22
22
|
exports.signVersionedTxs = signVersionedTxs;
|
|
23
23
|
exports.signTxPayloadBatchSequence = signTxPayloadBatchSequence;
|
|
24
|
-
exports.sendTxPayloadBatchSequence = sendTxPayloadBatchSequence;
|
|
25
24
|
const spl_token_1 = require("@solana/spl-token");
|
|
26
25
|
const web3_js_1 = require("@solana/web3.js");
|
|
27
26
|
const constants_1 = require("./constants");
|
|
@@ -165,57 +164,164 @@ function compileVersionedTransaction(blockhash, addressLookupTableAccounts, paye
|
|
|
165
164
|
}
|
|
166
165
|
return versionedTx;
|
|
167
166
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
167
|
+
const REBROADCAST_INTERVAL_MS = 500;
|
|
168
|
+
const TX_CONFIRM_TIMEOUT_MS = 15000;
|
|
169
|
+
// export async function sendVersionedTransaction(
|
|
170
|
+
// connection: Connection,
|
|
171
|
+
// tx: VersionedTransaction,
|
|
172
|
+
// blockhash: string,
|
|
173
|
+
// lastValidBlockHeight: number,
|
|
174
|
+
// simulateTransactions: boolean,
|
|
175
|
+
// ): Promise<TransactionSignature> {
|
|
176
|
+
// const serializedTx = tx.serialize();
|
|
177
|
+
// let txId: TransactionSignature;
|
|
178
|
+
// if (simulateTransactions) {
|
|
179
|
+
// txId = await connection.sendRawTransaction(
|
|
180
|
+
// serializedTx,
|
|
181
|
+
// { preflightCommitment: "confirmed", maxRetries: 0 }
|
|
182
|
+
// ).catch(e => {
|
|
183
|
+
// console.log(e.message);
|
|
184
|
+
// throw new Error("Simulation failed");
|
|
185
|
+
// });
|
|
186
|
+
// for (let i = 0; i < 4; i++) {
|
|
187
|
+
// await delay(3000).then(() =>
|
|
188
|
+
// connection.sendRawTransaction(
|
|
189
|
+
// serializedTx,
|
|
190
|
+
// {preflightCommitment: "confirmed", maxRetries: 0}
|
|
191
|
+
// ).catch(() => {})
|
|
192
|
+
// );
|
|
193
|
+
// }
|
|
194
|
+
// console.log("Simulation txId:", txId);
|
|
195
|
+
// } else {
|
|
196
|
+
// txId = await connection.sendRawTransaction(
|
|
197
|
+
// serializedTx,
|
|
198
|
+
// { skipPreflight: true, maxRetries: 0 }
|
|
199
|
+
// );
|
|
200
|
+
// for (let i = 0; i < 4; i++) {
|
|
201
|
+
// await delay(3000).then(() =>
|
|
202
|
+
// connection.sendRawTransaction(
|
|
203
|
+
// serializedTx,
|
|
204
|
+
// {preflightCommitment: "confirmed", maxRetries: 0}
|
|
205
|
+
// ).catch(() => {})
|
|
206
|
+
// );
|
|
207
|
+
// }
|
|
208
|
+
// console.log("Sending tx:", txId);
|
|
209
|
+
// }
|
|
210
|
+
// let confirmation = null;
|
|
211
|
+
// let result = null;
|
|
212
|
+
// connection.confirmTransaction({
|
|
213
|
+
// blockhash,
|
|
214
|
+
// lastValidBlockHeight,
|
|
215
|
+
// signature: txId,
|
|
216
|
+
// }, "confirmed").catch(() => null).then((res) => confirmation = res);
|
|
217
|
+
// let iterations = 10;
|
|
218
|
+
// while (confirmation === null && result === null && iterations > 0) {
|
|
219
|
+
// await delay(1000);
|
|
220
|
+
// result = await connection.getTransaction(txId, {
|
|
221
|
+
// commitment: "confirmed",
|
|
222
|
+
// maxSupportedTransactionVersion: 0,
|
|
223
|
+
// }).catch(() => null);
|
|
224
|
+
// if (result && result.meta && result.meta?.err) {
|
|
225
|
+
// console.log(result.meta.err);
|
|
226
|
+
// throw new Error(txId);
|
|
227
|
+
// }
|
|
228
|
+
// iterations--;
|
|
229
|
+
// }
|
|
230
|
+
// if (result) return txId;
|
|
231
|
+
// //@ts-ignore
|
|
232
|
+
// if (!confirmation || confirmation.value.err) {
|
|
233
|
+
// //@ts-ignore
|
|
234
|
+
// console.log(confirmation?.value.err);
|
|
235
|
+
// throw new Error(txId);
|
|
236
|
+
// }
|
|
237
|
+
// return txId;
|
|
238
|
+
// }
|
|
239
|
+
/**
|
|
240
|
+
* Send + confirm a batch of versioned transactions with parallel rebroadcasting.
|
|
241
|
+
* All txs within each batch are sent and confirmed concurrently.
|
|
242
|
+
* Batches are processed sequentially (batch 1 must all confirm before batch 2 starts).
|
|
243
|
+
*/
|
|
244
|
+
function sendVersionedTxs(connection_1, versionedTxs_1) {
|
|
245
|
+
return __awaiter(this, arguments, void 0, function* (connection, versionedTxs, simulateTransactions = false, rebroadcastIntervalMs = REBROADCAST_INTERVAL_MS, confirmTimeoutMs = TX_CONFIRM_TIMEOUT_MS) {
|
|
246
|
+
const { batches, blockhash, lastValidBlockHeight } = versionedTxs;
|
|
247
|
+
const batchTxIds = [];
|
|
248
|
+
for (const batch of batches) {
|
|
249
|
+
const txIds = yield Promise.all(batch.map((tx) => __awaiter(this, void 0, void 0, function* () {
|
|
250
|
+
var _a, _b, _c;
|
|
251
|
+
const serializedTx = tx.serialize();
|
|
252
|
+
let txId;
|
|
253
|
+
if (simulateTransactions) {
|
|
254
|
+
txId = yield connection.sendRawTransaction(serializedTx, { preflightCommitment: "confirmed", maxRetries: 0 }).catch(e => {
|
|
255
|
+
console.log(e.message);
|
|
256
|
+
throw new Error("Simulation failed");
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
txId = yield connection.sendRawTransaction(serializedTx, { skipPreflight: true, maxRetries: 0 });
|
|
261
|
+
}
|
|
262
|
+
const rebroadcastInterval = setInterval(() => {
|
|
263
|
+
connection.sendRawTransaction(serializedTx, { skipPreflight: true, maxRetries: 0 }).catch(() => { });
|
|
264
|
+
}, rebroadcastIntervalMs);
|
|
265
|
+
let timeoutId;
|
|
266
|
+
try {
|
|
267
|
+
const confirmPromise = connection.confirmTransaction({
|
|
268
|
+
blockhash,
|
|
269
|
+
lastValidBlockHeight,
|
|
270
|
+
signature: txId,
|
|
271
|
+
}, "confirmed");
|
|
272
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
273
|
+
timeoutId = setTimeout(() => reject(new Error("timeout")), confirmTimeoutMs);
|
|
274
|
+
});
|
|
275
|
+
const confirmation = yield Promise.race([confirmPromise, timeoutPromise]);
|
|
276
|
+
if (confirmation.value.err) {
|
|
277
|
+
console.log("Tx error:", txId, confirmation.value.err);
|
|
278
|
+
return "Error";
|
|
279
|
+
}
|
|
280
|
+
return txId;
|
|
281
|
+
}
|
|
282
|
+
catch (e) {
|
|
283
|
+
if ((e === null || e === void 0 ? void 0 : e.message) === "timeout") {
|
|
284
|
+
const result = yield connection.getTransaction(txId, {
|
|
285
|
+
commitment: "confirmed",
|
|
286
|
+
maxSupportedTransactionVersion: 0,
|
|
287
|
+
}).catch(() => null);
|
|
288
|
+
if (result && !((_a = result.meta) === null || _a === void 0 ? void 0 : _a.err))
|
|
289
|
+
return txId;
|
|
290
|
+
if ((_b = result === null || result === void 0 ? void 0 : result.meta) === null || _b === void 0 ? void 0 : _b.err)
|
|
291
|
+
console.log("Tx error:", txId, result.meta.err);
|
|
292
|
+
}
|
|
293
|
+
console.log("Error sending tx:", (_c = e === null || e === void 0 ? void 0 : e.message) !== null && _c !== void 0 ? _c : e);
|
|
294
|
+
return "Error";
|
|
295
|
+
}
|
|
296
|
+
finally {
|
|
297
|
+
clearInterval(rebroadcastInterval);
|
|
298
|
+
if (timeoutId !== undefined)
|
|
299
|
+
clearTimeout(timeoutId);
|
|
300
|
+
}
|
|
301
|
+
})));
|
|
302
|
+
batchTxIds.push(txIds);
|
|
209
303
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
304
|
+
return batchTxIds;
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Sign + send a TxPayloadBatchSequence using fast parallel rebroadcasting.
|
|
309
|
+
*/
|
|
310
|
+
function sendTxPayloadBatchSequence(connection_1, txPayloadBatchSequence_1) {
|
|
311
|
+
return __awaiter(this, arguments, void 0, function* (connection, txPayloadBatchSequence, simulateTransactions = false) {
|
|
312
|
+
var _a, _b, _c, _d;
|
|
313
|
+
const txs = [];
|
|
314
|
+
for (const batch of txPayloadBatchSequence.batches) {
|
|
315
|
+
const batchTxs = [];
|
|
316
|
+
for (const tx of batch.transactions)
|
|
317
|
+
batchTxs.push(web3_js_1.VersionedTransaction.deserialize(Buffer.from(tx.tx_b64, 'base64')));
|
|
318
|
+
txs.push(batchTxs);
|
|
217
319
|
}
|
|
218
|
-
return
|
|
320
|
+
return yield sendVersionedTxs(connection, {
|
|
321
|
+
blockhash: (_b = (_a = txPayloadBatchSequence.batches[0].transactions[0]) === null || _a === void 0 ? void 0 : _a.recent_blockhash) !== null && _b !== void 0 ? _b : "",
|
|
322
|
+
lastValidBlockHeight: (_d = (_c = txPayloadBatchSequence.batches[0].transactions[0]) === null || _c === void 0 ? void 0 : _c.last_valid_block_height) !== null && _d !== void 0 ? _d : 0,
|
|
323
|
+
batches: txs,
|
|
324
|
+
}, simulateTransactions);
|
|
219
325
|
});
|
|
220
326
|
}
|
|
221
327
|
function prepareVersionedTxs(connection, txBatchData) {
|
|
@@ -242,17 +348,29 @@ function prepareVersionedTxs(connection, txBatchData) {
|
|
|
242
348
|
};
|
|
243
349
|
});
|
|
244
350
|
}
|
|
245
|
-
function sendVersionedTxs(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
351
|
+
// export async function sendVersionedTxs(
|
|
352
|
+
// connection: Connection,
|
|
353
|
+
// versionedTxs: VersionedTxs,
|
|
354
|
+
// simulateTransactions: boolean = false,
|
|
355
|
+
// ): Promise<TransactionSignature[][]> {
|
|
356
|
+
// const { batches, blockhash, lastValidBlockHeight } = versionedTxs;
|
|
357
|
+
// let batchTxIds: TransactionSignature[][] = [];
|
|
358
|
+
// for (const batch of batches) {
|
|
359
|
+
// let txIds = await Promise.all(
|
|
360
|
+
// batch.map(tx =>
|
|
361
|
+
// sendVersionedTransaction(
|
|
362
|
+
// connection,
|
|
363
|
+
// tx,
|
|
364
|
+
// blockhash,
|
|
365
|
+
// lastValidBlockHeight,
|
|
366
|
+
// simulateTransactions
|
|
367
|
+
// ).catch(e => {console.log("Error sending tx:", e.message); return "Error"})
|
|
368
|
+
// )
|
|
369
|
+
// );
|
|
370
|
+
// batchTxIds.push(txIds);
|
|
371
|
+
// }
|
|
372
|
+
// return batchTxIds;
|
|
373
|
+
// }
|
|
256
374
|
function signVersionedTxs(wallet, versionedTxs) {
|
|
257
375
|
return __awaiter(this, void 0, void 0, function* () {
|
|
258
376
|
let txs = [];
|
|
@@ -285,20 +403,21 @@ function signTxPayloadBatchSequence(wallet, txPayloadBatchSequence) {
|
|
|
285
403
|
return txPayloadBatchSequence;
|
|
286
404
|
});
|
|
287
405
|
}
|
|
288
|
-
function sendTxPayloadBatchSequence(
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
406
|
+
// export async function sendTxPayloadBatchSequence(
|
|
407
|
+
// connection: Connection,
|
|
408
|
+
// txPayloadBatchSequence: TxPayloadBatchSequence,
|
|
409
|
+
// simulateTransactions: boolean = false,
|
|
410
|
+
// ): Promise<TransactionSignature[][]> {
|
|
411
|
+
// let txs: VersionedTransaction[][] = [];
|
|
412
|
+
// for (const batch of txPayloadBatchSequence.batches) {
|
|
413
|
+
// let batchTxs: VersionedTransaction[] = [];
|
|
414
|
+
// for (const tx of batch.transactions)
|
|
415
|
+
// batchTxs.push(VersionedTransaction.deserialize(Buffer.from(tx.tx_b64, 'base64')));
|
|
416
|
+
// txs.push(batchTxs);
|
|
417
|
+
// }
|
|
418
|
+
// return await sendVersionedTxs(connection, {
|
|
419
|
+
// blockhash: txPayloadBatchSequence.batches[0].transactions[0]?.recent_blockhash ?? "",
|
|
420
|
+
// lastValidBlockHeight: txPayloadBatchSequence.batches[0].transactions[0]?.last_valid_block_height ?? 0,
|
|
421
|
+
// batches: txs,
|
|
422
|
+
// }, simulateTransactions);
|
|
423
|
+
// }
|
package/dist/test.js
CHANGED
|
@@ -72,7 +72,7 @@ function testStates() {
|
|
|
72
72
|
editGlobalConfig: false, // TESTED
|
|
73
73
|
createVault: false, // TESTED
|
|
74
74
|
editPrivateVaultSettings: false, // NOT TESTED
|
|
75
|
-
addBounty:
|
|
75
|
+
addBounty: false, // TESTED
|
|
76
76
|
editCreator: false, // TESTED
|
|
77
77
|
editManagerSettings: false, // TESTED
|
|
78
78
|
editFeeSettings: false, // TESTED
|
|
@@ -521,13 +521,13 @@ function testStates() {
|
|
|
521
521
|
symmetryLimitOrderFeeBps: 0,
|
|
522
522
|
symmetryFeesExtraData: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,],
|
|
523
523
|
bountyMint: new web3_js_1.PublicKey("So11111111111111111111111111111111111111112"),
|
|
524
|
-
minBountyForVaultAutomation: new anchor_1.BN(
|
|
525
|
-
bountyBondAmount: new anchor_1.BN(
|
|
524
|
+
minBountyForVaultAutomation: new anchor_1.BN(2000 * 5000),
|
|
525
|
+
bountyBondAmount: new anchor_1.BN(20 * 5000),
|
|
526
526
|
bountyPerTask: {
|
|
527
|
-
minBounty: new anchor_1.BN(
|
|
528
|
-
maxBounty: new anchor_1.BN(
|
|
529
|
-
minBountyUntil: new anchor_1.BN(
|
|
530
|
-
maxBountyAfter: new anchor_1.BN(
|
|
527
|
+
minBounty: new anchor_1.BN(20 * 5000),
|
|
528
|
+
maxBounty: new anchor_1.BN(50 * 5000),
|
|
529
|
+
minBountyUntil: new anchor_1.BN(10),
|
|
530
|
+
maxBountyAfter: new anchor_1.BN(40),
|
|
531
531
|
},
|
|
532
532
|
bountyPerPriceUpdateTaskDivisor: new anchor_1.BN(3),
|
|
533
533
|
minRemainingValue: { high: new anchor_1.BN(0), low: new anchor_1.BN("1844674407370955161") },
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -762,6 +762,14 @@ export class SymmetryCore {
|
|
|
762
762
|
let maxBountyPerTask = parseInt(maxBounty.toString());
|
|
763
763
|
bountyWsolAmount = maxBountyPerTask + boundBounty;
|
|
764
764
|
}
|
|
765
|
+
|
|
766
|
+
if (editType === TaskType.EditAutomationSettings && (editData as EditAutomationSettings).enabled == true) {
|
|
767
|
+
let bountyBalance = parseInt(vault.settings.bountyBalance.toString());
|
|
768
|
+
let requiredBounty = parseInt(globalConfig.minBountyForVaultAutomation.toString());
|
|
769
|
+
if (bountyBalance < requiredBounty)
|
|
770
|
+
bountyWsolAmount += 2 * requiredBounty - bountyBalance;
|
|
771
|
+
}
|
|
772
|
+
|
|
765
773
|
let wsolIxs = await wrapWsolIxs(
|
|
766
774
|
this.sdkParams.connection,
|
|
767
775
|
manager,
|
|
@@ -1525,7 +1533,19 @@ export class SymmetryCore {
|
|
|
1525
1533
|
Math.floor(maxBountyPerTask / bountyPerPriceUpdateTaskDivisor),
|
|
1526
1534
|
);
|
|
1527
1535
|
}
|
|
1528
|
-
|
|
1536
|
+
|
|
1537
|
+
let isManager = vault.settings.creator.equals(keeper);
|
|
1538
|
+
for (let i = 0; i < vault.settings.managers.managers.length; i++)
|
|
1539
|
+
if (vault.settings.managers.managers[i].equals(keeper))
|
|
1540
|
+
isManager = true;
|
|
1541
|
+
|
|
1542
|
+
if (isManager) {
|
|
1543
|
+
let bountyBalance = parseInt(vault.settings.bountyBalance.toString());
|
|
1544
|
+
let requiredBounty = parseInt(globalConfig.minBountyForVaultAutomation.toString());
|
|
1545
|
+
if (bountyBalance < requiredBounty)
|
|
1546
|
+
bountyWsolAmount += 2 * requiredBounty - bountyBalance;
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1529
1549
|
let wsolIxs = await wrapWsolIxs(
|
|
1530
1550
|
this.sdkParams.connection,
|
|
1531
1551
|
keeper,
|
|
@@ -147,23 +147,33 @@ export function formatRebalanceIntent(rebalanceIntent: RebalanceIntent, vault?:
|
|
|
147
147
|
})),
|
|
148
148
|
}
|
|
149
149
|
if (vault) {
|
|
150
|
+
const auctionTokenByMint = new Map(auctionData.tokens.map(token => [token.mint, token]));
|
|
151
|
+
const mintDataTokenByMint = new Map(mintData.tokens.map(token => [token.mint, token]));
|
|
150
152
|
let minRatio = 1;
|
|
151
|
-
for (
|
|
152
|
-
if (
|
|
153
|
+
for (const vaultToken of vault.composition) {
|
|
154
|
+
if (vaultToken.amount == 0)
|
|
153
155
|
continue;
|
|
154
|
-
|
|
156
|
+
const auctionToken = auctionTokenByMint.get(vaultToken.mint);
|
|
157
|
+
if (!auctionToken) continue;
|
|
158
|
+
|
|
159
|
+
let ratio = auctionToken.amount / vaultToken.amount;
|
|
155
160
|
minRatio = Math.min(minRatio, ratio);
|
|
156
161
|
}
|
|
157
162
|
let mintValue = 0;
|
|
158
163
|
let remainingValue = 0;
|
|
159
164
|
let mintAmount = Math.floor(vault.supply_outstanding * minRatio);
|
|
160
|
-
for (
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
for (const vaultToken of vault.composition) {
|
|
166
|
+
const mint = vaultToken.mint;
|
|
167
|
+
const auctionToken = auctionTokenByMint.get(mint);
|
|
168
|
+
const mintDataToken = mintDataTokenByMint.get(mint);
|
|
169
|
+
if (!auctionToken || !mintDataToken) continue;
|
|
170
|
+
|
|
171
|
+
let contributionAmount = Math.floor(vaultToken.amount * minRatio);
|
|
172
|
+
contributionAmount = Math.min(contributionAmount, auctionToken.amount);
|
|
173
|
+
mintDataToken.contribution_amount = contributionAmount;
|
|
174
|
+
mintDataToken.remaining_amount = auctionToken.amount - contributionAmount;
|
|
175
|
+
mintValue += contributionAmount * auctionToken.price;
|
|
176
|
+
remainingValue += (auctionToken.amount - contributionAmount) * auctionToken.price;
|
|
167
177
|
}
|
|
168
178
|
mintData.mintValue = mintValue;
|
|
169
179
|
mintData.mintAmount = mintAmount;
|
|
@@ -6,7 +6,7 @@ import { AccountInfo, AddressLookupTableAccount, PublicKey } from '@solana/web3.
|
|
|
6
6
|
import { HUNDRED_PERCENT_BPS } from '../../constants';
|
|
7
7
|
import { Fraction, fractionToDecimal } from '../../layouts/fraction';
|
|
8
8
|
import {
|
|
9
|
-
|
|
9
|
+
OracleAggregator, OracleData, OracleType,
|
|
10
10
|
} from '../../layouts/oracle';
|
|
11
11
|
import { U32_MAX } from './constants';
|
|
12
12
|
import { PythOracle } from './pythOracle';
|
|
@@ -79,8 +79,8 @@ export class PriceAggregator{
|
|
|
79
79
|
oracleAggregator: OracleAggregator,
|
|
80
80
|
lutAccounts: AddressLookupTableAccount[],
|
|
81
81
|
accountInfoMap: Map<string, AccountInfo<Buffer> | null>,
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
wsolPrice: OraclePrice,
|
|
83
|
+
usdcPrice: OraclePrice,
|
|
84
84
|
pythPriceOverrides?: Map<string, OraclePrice>,
|
|
85
85
|
): OraclePrice {
|
|
86
86
|
let validated: boolean = true;
|
|
@@ -93,15 +93,11 @@ export class PriceAggregator{
|
|
|
93
93
|
const settings = oracleData.oracleSettings;
|
|
94
94
|
|
|
95
95
|
let loadedAccounts: AccountInfo<Buffer>[] = [];
|
|
96
|
-
let firstLoadedPubkey: PublicKey | undefined;
|
|
97
96
|
for (let j = 0; j < settings.numRequiredAccounts; j++) {
|
|
98
97
|
const lutId = oracleData.accountsToLoadLutIds[j];
|
|
99
98
|
const lutIdx = oracleData.accountsToLoadLutIndices[j];
|
|
100
99
|
const pubkey = lutAccounts[lutId].state.addresses[lutIdx];
|
|
101
100
|
const account = accountInfoMap.get(pubkey.toBase58());
|
|
102
|
-
if (!firstLoadedPubkey) {
|
|
103
|
-
firstLoadedPubkey = pubkey;
|
|
104
|
-
}
|
|
105
101
|
// @ts-ignore
|
|
106
102
|
loadedAccounts.push(account);
|
|
107
103
|
}
|
|
@@ -127,17 +123,16 @@ export class PriceAggregator{
|
|
|
127
123
|
let result = (() => {
|
|
128
124
|
switch (settings.oracleType) {
|
|
129
125
|
case OracleType.Pyth:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return PythOracle.fetch(settings, loadedAccounts, solPrice, usdPrice);
|
|
126
|
+
const lutId = oracleData.accountsToLoadLutIds[0];
|
|
127
|
+
const lutIdx = oracleData.accountsToLoadLutIndices[0];
|
|
128
|
+
const pubkey = lutAccounts[lutId].state.addresses[lutIdx];
|
|
129
|
+
const override = pythPriceOverrides?.get(pubkey.toBase58());
|
|
130
|
+
const price = PythOracle.fetch(settings, loadedAccounts, wsolPrice, usdcPrice);
|
|
131
|
+
return (override ? override : price);
|
|
137
132
|
case OracleType.RaydiumClmm:
|
|
138
|
-
return RaydiumCLMMOracle.fetch(settings, loadedAccounts,
|
|
133
|
+
return RaydiumCLMMOracle.fetch(settings, loadedAccounts, wsolPrice, usdcPrice);
|
|
139
134
|
case OracleType.RaydiumCpmm:
|
|
140
|
-
return RaydiumCPMMOracle.fetch(settings, loadedAccounts,
|
|
135
|
+
return RaydiumCPMMOracle.fetch(settings, loadedAccounts, wsolPrice, usdcPrice);
|
|
141
136
|
default:
|
|
142
137
|
throw new Error(`Invalid oracle type: ${settings.oracleType}`);
|
|
143
138
|
}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
SystemProgram, Transaction, TransactionInstruction, TransactionMessage, VersionedTransaction
|
|
8
8
|
} from '@solana/web3.js';
|
|
9
9
|
|
|
10
|
-
import { HUNDRED_PERCENT_BPS, PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT, PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT } from '../../constants';
|
|
10
|
+
import { HUNDRED_PERCENT_BPS, PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT, PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT, USDC_DECIMALS, WSOL_DECIMALS } from '../../constants';
|
|
11
11
|
import { OracleSettings, OracleType, PYTH_USDC_ORACLE_SETTINGS, PYTH_WSOL_ORACLE_SETTINGS, Quote } from '../../layouts/oracle';
|
|
12
12
|
import { TxBatchData, TxData } from '../../txUtils';
|
|
13
13
|
import { HERMES_PUBLIC_ENDPOINT, SOLANA_DEVNET_ENDPOINT } from './constants';
|
|
@@ -87,20 +87,25 @@ export async function fetchHermesPythPrices(priceFeedIds: string[]): Promise<Map
|
|
|
87
87
|
export function buildPythOraclePriceFromHermesPriceData(
|
|
88
88
|
oracleParams: OracleSettings,
|
|
89
89
|
priceData: HermesPythPriceData,
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
wsolPrice: OraclePrice,
|
|
91
|
+
usdcPrice: OraclePrice,
|
|
92
92
|
): OraclePrice {
|
|
93
|
+
let quoteDecimals =
|
|
94
|
+
(oracleParams.quote == Quote.Usdc) ? USDC_DECIMALS : (
|
|
95
|
+
(oracleParams.quote == Quote.Wsol) ? WSOL_DECIMALS : 0);
|
|
96
|
+
|
|
93
97
|
let pr = new Decimal(priceData.price.toString())
|
|
94
|
-
.mul(Decimal.pow(10, priceData.expo - oracleParams.tokenDecimals));
|
|
98
|
+
.mul(Decimal.pow(10, priceData.expo - oracleParams.tokenDecimals + quoteDecimals));
|
|
95
99
|
let ema = new Decimal((priceData.emaPrice ?? priceData.price).toString())
|
|
96
|
-
.mul(Decimal.pow(10, priceData.expo - oracleParams.tokenDecimals));
|
|
100
|
+
.mul(Decimal.pow(10, priceData.expo - oracleParams.tokenDecimals + quoteDecimals));
|
|
97
101
|
let cf = new Decimal(priceData.conf.toString())
|
|
98
|
-
.mul(Decimal.pow(10, priceData.expo - oracleParams.tokenDecimals));
|
|
102
|
+
.mul(Decimal.pow(10, priceData.expo - oracleParams.tokenDecimals + quoteDecimals));
|
|
99
103
|
const lastUpdateTimestamp = priceData.publishTime;
|
|
100
|
-
|
|
104
|
+
|
|
101
105
|
let quotePrice =
|
|
102
|
-
|
|
103
|
-
|
|
106
|
+
(oracleParams.quote === Quote.Usdc) ? usdcPrice :
|
|
107
|
+
((oracleParams.quote === Quote.Wsol) ? wsolPrice :
|
|
108
|
+
new OraclePrice(new Decimal(1), new Decimal(0), 0));
|
|
104
109
|
|
|
105
110
|
pr = pr.mul(quotePrice.price);
|
|
106
111
|
ema = ema.mul(quotePrice.price);
|
|
@@ -490,7 +495,7 @@ function buildVerifyEncodedVaaV1Instruction(
|
|
|
490
495
|
/**
|
|
491
496
|
* Build closeEncodedVaa instruction
|
|
492
497
|
*/
|
|
493
|
-
function buildCloseEncodedVaaInstruction(
|
|
498
|
+
export function buildCloseEncodedVaaInstruction(
|
|
494
499
|
writeAuthority: PublicKey,
|
|
495
500
|
encodedVaa: PublicKey,
|
|
496
501
|
wormholeProgramId: PublicKey = DEFAULT_WORMHOLE_PROGRAM_ID
|
|
@@ -976,8 +981,8 @@ export class PythOracle {
|
|
|
976
981
|
static fetch(
|
|
977
982
|
oracleParams: OracleSettings,
|
|
978
983
|
accountInfos: AccountInfo<Buffer>[],
|
|
979
|
-
|
|
980
|
-
|
|
984
|
+
wsolPrice?: OraclePrice,
|
|
985
|
+
usdcPrice?: OraclePrice,
|
|
981
986
|
): OraclePrice {
|
|
982
987
|
//@ts-ignore
|
|
983
988
|
let state: PythState = null;
|
|
@@ -999,8 +1004,8 @@ export class PythOracle {
|
|
|
999
1004
|
emaPrice: state.priceMessage.emaPrice.toString(),
|
|
1000
1005
|
emaConf: state.priceMessage.emaConf.toString(),
|
|
1001
1006
|
},
|
|
1002
|
-
|
|
1003
|
-
|
|
1007
|
+
wsolPrice ?? new OraclePrice(new Decimal(1), new Decimal(0), 0),
|
|
1008
|
+
usdcPrice ?? new OraclePrice(new Decimal(1), new Decimal(0), 0),
|
|
1004
1009
|
);
|
|
1005
1010
|
}
|
|
1006
1011
|
|
|
@@ -667,8 +667,8 @@ export class RaydiumCPMMOracle {
|
|
|
667
667
|
static fetch(
|
|
668
668
|
oracleParams: OracleSettings,
|
|
669
669
|
accountInfos: AccountInfo<Buffer>[],
|
|
670
|
-
|
|
671
|
-
|
|
670
|
+
wsolPrice: OraclePrice,
|
|
671
|
+
usdcPrice: OraclePrice,
|
|
672
672
|
): OraclePrice {
|
|
673
673
|
const poolStateInfo = accountInfos[0];
|
|
674
674
|
const vault0Info = accountInfos[1];
|
|
@@ -684,8 +684,9 @@ export class RaydiumCPMMOracle {
|
|
|
684
684
|
|
|
685
685
|
// Determine quote oracle
|
|
686
686
|
let quotePrice =
|
|
687
|
-
|
|
688
|
-
|
|
687
|
+
(oracleParams.quote === Quote.Usdc) ? usdcPrice :
|
|
688
|
+
((oracleParams.quote === Quote.Wsol) ? wsolPrice :
|
|
689
|
+
new OraclePrice(new Decimal(1), new Decimal(0), 0));
|
|
689
690
|
|
|
690
691
|
// Get spot price with reserves
|
|
691
692
|
const { netBase, netQuote, spotPrice } = this.getSpotPriceWithReserves(
|
package/src/txUtils.ts
CHANGED
|
@@ -232,81 +232,190 @@ export function compileVersionedTransaction(
|
|
|
232
232
|
return versionedTx;
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
-
|
|
235
|
+
const REBROADCAST_INTERVAL_MS = 500;
|
|
236
|
+
const TX_CONFIRM_TIMEOUT_MS = 15_000;
|
|
237
|
+
|
|
238
|
+
// export async function sendVersionedTransaction(
|
|
239
|
+
// connection: Connection,
|
|
240
|
+
// tx: VersionedTransaction,
|
|
241
|
+
// blockhash: string,
|
|
242
|
+
// lastValidBlockHeight: number,
|
|
243
|
+
// simulateTransactions: boolean,
|
|
244
|
+
// ): Promise<TransactionSignature> {
|
|
245
|
+
// const serializedTx = tx.serialize();
|
|
246
|
+
// let txId: TransactionSignature;
|
|
247
|
+
// if (simulateTransactions) {
|
|
248
|
+
// txId = await connection.sendRawTransaction(
|
|
249
|
+
// serializedTx,
|
|
250
|
+
// { preflightCommitment: "confirmed", maxRetries: 0 }
|
|
251
|
+
// ).catch(e => {
|
|
252
|
+
// console.log(e.message);
|
|
253
|
+
// throw new Error("Simulation failed");
|
|
254
|
+
// });
|
|
255
|
+
// for (let i = 0; i < 4; i++) {
|
|
256
|
+
// await delay(3000).then(() =>
|
|
257
|
+
// connection.sendRawTransaction(
|
|
258
|
+
// serializedTx,
|
|
259
|
+
// {preflightCommitment: "confirmed", maxRetries: 0}
|
|
260
|
+
// ).catch(() => {})
|
|
261
|
+
// );
|
|
262
|
+
// }
|
|
263
|
+
// console.log("Simulation txId:", txId);
|
|
264
|
+
// } else {
|
|
265
|
+
// txId = await connection.sendRawTransaction(
|
|
266
|
+
// serializedTx,
|
|
267
|
+
// { skipPreflight: true, maxRetries: 0 }
|
|
268
|
+
// );
|
|
269
|
+
// for (let i = 0; i < 4; i++) {
|
|
270
|
+
// await delay(3000).then(() =>
|
|
271
|
+
// connection.sendRawTransaction(
|
|
272
|
+
// serializedTx,
|
|
273
|
+
// {preflightCommitment: "confirmed", maxRetries: 0}
|
|
274
|
+
// ).catch(() => {})
|
|
275
|
+
// );
|
|
276
|
+
// }
|
|
277
|
+
// console.log("Sending tx:", txId);
|
|
278
|
+
// }
|
|
279
|
+
|
|
280
|
+
// let confirmation = null;
|
|
281
|
+
// let result = null;
|
|
282
|
+
|
|
283
|
+
// connection.confirmTransaction({
|
|
284
|
+
// blockhash,
|
|
285
|
+
// lastValidBlockHeight,
|
|
286
|
+
// signature: txId,
|
|
287
|
+
// }, "confirmed").catch(() => null).then((res) => confirmation = res);
|
|
288
|
+
|
|
289
|
+
// let iterations = 10;
|
|
290
|
+
// while (confirmation === null && result === null && iterations > 0) {
|
|
291
|
+
// await delay(1000);
|
|
292
|
+
// result = await connection.getTransaction(txId, {
|
|
293
|
+
// commitment: "confirmed",
|
|
294
|
+
// maxSupportedTransactionVersion: 0,
|
|
295
|
+
// }).catch(() => null);
|
|
296
|
+
// if (result && result.meta && result.meta?.err) {
|
|
297
|
+
// console.log(result.meta.err);
|
|
298
|
+
// throw new Error(txId);
|
|
299
|
+
// }
|
|
300
|
+
// iterations--;
|
|
301
|
+
// }
|
|
302
|
+
|
|
303
|
+
// if (result) return txId;
|
|
304
|
+
|
|
305
|
+
// //@ts-ignore
|
|
306
|
+
// if (!confirmation || confirmation.value.err) {
|
|
307
|
+
// //@ts-ignore
|
|
308
|
+
// console.log(confirmation?.value.err);
|
|
309
|
+
// throw new Error(txId);
|
|
310
|
+
// }
|
|
311
|
+
|
|
312
|
+
// return txId;
|
|
313
|
+
// }
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Send + confirm a batch of versioned transactions with parallel rebroadcasting.
|
|
317
|
+
* All txs within each batch are sent and confirmed concurrently.
|
|
318
|
+
* Batches are processed sequentially (batch 1 must all confirm before batch 2 starts).
|
|
319
|
+
*/
|
|
320
|
+
export async function sendVersionedTxs(
|
|
236
321
|
connection: Connection,
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
): Promise<TransactionSignature> {
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
if (simulateTransactions) {
|
|
245
|
-
txId = await connection.sendRawTransaction(
|
|
246
|
-
serializedTx,
|
|
247
|
-
{ preflightCommitment: "confirmed", maxRetries: 0 }
|
|
248
|
-
).catch(e => {
|
|
249
|
-
console.log(e.message);
|
|
250
|
-
throw new Error("Simulation failed");
|
|
251
|
-
});
|
|
252
|
-
for (let i = 0; i < 4; i++) {
|
|
253
|
-
await delay(3000).then(() =>
|
|
254
|
-
connection.sendRawTransaction(
|
|
255
|
-
serializedTx,
|
|
256
|
-
{preflightCommitment: "confirmed", maxRetries: 0}
|
|
257
|
-
).catch(() => {})
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
console.log("Simulation txId:", txId);
|
|
261
|
-
} else {
|
|
262
|
-
txId = await connection.sendRawTransaction(
|
|
263
|
-
serializedTx,
|
|
264
|
-
{ skipPreflight: true, maxRetries: 0 }
|
|
265
|
-
);
|
|
266
|
-
for (let i = 0; i < 4; i++) {
|
|
267
|
-
await delay(3000).then(() =>
|
|
268
|
-
connection.sendRawTransaction(
|
|
269
|
-
serializedTx,
|
|
270
|
-
{preflightCommitment: "confirmed", maxRetries: 0}
|
|
271
|
-
).catch(() => {})
|
|
272
|
-
);
|
|
273
|
-
}
|
|
274
|
-
console.log("Sending tx:", txId);
|
|
275
|
-
}
|
|
322
|
+
versionedTxs: VersionedTxs,
|
|
323
|
+
simulateTransactions: boolean = false,
|
|
324
|
+
rebroadcastIntervalMs: number = REBROADCAST_INTERVAL_MS,
|
|
325
|
+
confirmTimeoutMs: number = TX_CONFIRM_TIMEOUT_MS,
|
|
326
|
+
): Promise<TransactionSignature[][]> {
|
|
327
|
+
const { batches, blockhash, lastValidBlockHeight } = versionedTxs;
|
|
328
|
+
const batchTxIds: TransactionSignature[][] = [];
|
|
276
329
|
|
|
277
|
-
|
|
278
|
-
|
|
330
|
+
for (const batch of batches) {
|
|
331
|
+
const txIds = await Promise.all(
|
|
332
|
+
batch.map(async (tx) => {
|
|
333
|
+
const serializedTx = tx.serialize();
|
|
334
|
+
let txId: TransactionSignature;
|
|
279
335
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
console.log(result.meta.err);
|
|
295
|
-
throw new Error(txId);
|
|
296
|
-
}
|
|
297
|
-
iterations--;
|
|
298
|
-
}
|
|
336
|
+
if (simulateTransactions) {
|
|
337
|
+
txId = await connection.sendRawTransaction(
|
|
338
|
+
serializedTx,
|
|
339
|
+
{ preflightCommitment: "confirmed", maxRetries: 0 },
|
|
340
|
+
).catch(e => {
|
|
341
|
+
console.log(e.message);
|
|
342
|
+
throw new Error("Simulation failed");
|
|
343
|
+
});
|
|
344
|
+
} else {
|
|
345
|
+
txId = await connection.sendRawTransaction(
|
|
346
|
+
serializedTx,
|
|
347
|
+
{ skipPreflight: true, maxRetries: 0 },
|
|
348
|
+
);
|
|
349
|
+
}
|
|
299
350
|
|
|
300
|
-
|
|
351
|
+
const rebroadcastInterval = setInterval(() => {
|
|
352
|
+
connection.sendRawTransaction(
|
|
353
|
+
serializedTx,
|
|
354
|
+
{ skipPreflight: true, maxRetries: 0 },
|
|
355
|
+
).catch(() => {});
|
|
356
|
+
}, rebroadcastIntervalMs);
|
|
301
357
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
358
|
+
let timeoutId: ReturnType<typeof setTimeout> | undefined;
|
|
359
|
+
try {
|
|
360
|
+
const confirmPromise = connection.confirmTransaction({
|
|
361
|
+
blockhash,
|
|
362
|
+
lastValidBlockHeight,
|
|
363
|
+
signature: txId,
|
|
364
|
+
}, "confirmed");
|
|
365
|
+
|
|
366
|
+
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
367
|
+
timeoutId = setTimeout(() => reject(new Error("timeout")), confirmTimeoutMs);
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
const confirmation = await Promise.race([confirmPromise, timeoutPromise]);
|
|
371
|
+
|
|
372
|
+
if (confirmation.value.err) {
|
|
373
|
+
console.log("Tx error:", txId, confirmation.value.err);
|
|
374
|
+
return "Error";
|
|
375
|
+
}
|
|
376
|
+
return txId;
|
|
377
|
+
} catch (e: any) {
|
|
378
|
+
if (e?.message === "timeout") {
|
|
379
|
+
const result = await connection.getTransaction(txId, {
|
|
380
|
+
commitment: "confirmed",
|
|
381
|
+
maxSupportedTransactionVersion: 0,
|
|
382
|
+
}).catch(() => null);
|
|
383
|
+
if (result && !result.meta?.err) return txId;
|
|
384
|
+
if (result?.meta?.err) console.log("Tx error:", txId, result.meta.err);
|
|
385
|
+
}
|
|
386
|
+
console.log("Error sending tx:", e?.message ?? e);
|
|
387
|
+
return "Error";
|
|
388
|
+
} finally {
|
|
389
|
+
clearInterval(rebroadcastInterval);
|
|
390
|
+
if (timeoutId !== undefined) clearTimeout(timeoutId);
|
|
391
|
+
}
|
|
392
|
+
}),
|
|
393
|
+
);
|
|
394
|
+
batchTxIds.push(txIds);
|
|
307
395
|
}
|
|
396
|
+
return batchTxIds;
|
|
397
|
+
}
|
|
308
398
|
|
|
309
|
-
|
|
399
|
+
/**
|
|
400
|
+
* Sign + send a TxPayloadBatchSequence using fast parallel rebroadcasting.
|
|
401
|
+
*/
|
|
402
|
+
export async function sendTxPayloadBatchSequence(
|
|
403
|
+
connection: Connection,
|
|
404
|
+
txPayloadBatchSequence: TxPayloadBatchSequence,
|
|
405
|
+
simulateTransactions: boolean = false,
|
|
406
|
+
): Promise<TransactionSignature[][]> {
|
|
407
|
+
const txs: VersionedTransaction[][] = [];
|
|
408
|
+
for (const batch of txPayloadBatchSequence.batches) {
|
|
409
|
+
const batchTxs: VersionedTransaction[] = [];
|
|
410
|
+
for (const tx of batch.transactions)
|
|
411
|
+
batchTxs.push(VersionedTransaction.deserialize(Buffer.from(tx.tx_b64, 'base64')));
|
|
412
|
+
txs.push(batchTxs);
|
|
413
|
+
}
|
|
414
|
+
return await sendVersionedTxs(connection, {
|
|
415
|
+
blockhash: txPayloadBatchSequence.batches[0].transactions[0]?.recent_blockhash ?? "",
|
|
416
|
+
lastValidBlockHeight: txPayloadBatchSequence.batches[0].transactions[0]?.last_valid_block_height ?? 0,
|
|
417
|
+
batches: txs,
|
|
418
|
+
}, simulateTransactions);
|
|
310
419
|
}
|
|
311
420
|
|
|
312
421
|
export async function prepareVersionedTxs(
|
|
@@ -342,30 +451,30 @@ export async function prepareVersionedTxs(
|
|
|
342
451
|
};
|
|
343
452
|
}
|
|
344
453
|
|
|
345
|
-
export async function sendVersionedTxs(
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
): Promise<TransactionSignature[][]> {
|
|
350
|
-
|
|
351
|
-
|
|
454
|
+
// export async function sendVersionedTxs(
|
|
455
|
+
// connection: Connection,
|
|
456
|
+
// versionedTxs: VersionedTxs,
|
|
457
|
+
// simulateTransactions: boolean = false,
|
|
458
|
+
// ): Promise<TransactionSignature[][]> {
|
|
459
|
+
// const { batches, blockhash, lastValidBlockHeight } = versionedTxs;
|
|
460
|
+
// let batchTxIds: TransactionSignature[][] = [];
|
|
352
461
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
462
|
+
// for (const batch of batches) {
|
|
463
|
+
// let txIds = await Promise.all(
|
|
464
|
+
// batch.map(tx =>
|
|
465
|
+
// sendVersionedTransaction(
|
|
466
|
+
// connection,
|
|
467
|
+
// tx,
|
|
468
|
+
// blockhash,
|
|
469
|
+
// lastValidBlockHeight,
|
|
470
|
+
// simulateTransactions
|
|
471
|
+
// ).catch(e => {console.log("Error sending tx:", e.message); return "Error"})
|
|
472
|
+
// )
|
|
473
|
+
// );
|
|
474
|
+
// batchTxIds.push(txIds);
|
|
475
|
+
// }
|
|
476
|
+
// return batchTxIds;
|
|
477
|
+
// }
|
|
369
478
|
|
|
370
479
|
|
|
371
480
|
export async function signVersionedTxs(
|
|
@@ -406,21 +515,21 @@ export async function signTxPayloadBatchSequence(
|
|
|
406
515
|
return txPayloadBatchSequence;
|
|
407
516
|
}
|
|
408
517
|
|
|
409
|
-
export async function sendTxPayloadBatchSequence(
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
): Promise<TransactionSignature[][]> {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
}
|
|
518
|
+
// export async function sendTxPayloadBatchSequence(
|
|
519
|
+
// connection: Connection,
|
|
520
|
+
// txPayloadBatchSequence: TxPayloadBatchSequence,
|
|
521
|
+
// simulateTransactions: boolean = false,
|
|
522
|
+
// ): Promise<TransactionSignature[][]> {
|
|
523
|
+
// let txs: VersionedTransaction[][] = [];
|
|
524
|
+
// for (const batch of txPayloadBatchSequence.batches) {
|
|
525
|
+
// let batchTxs: VersionedTransaction[] = [];
|
|
526
|
+
// for (const tx of batch.transactions)
|
|
527
|
+
// batchTxs.push(VersionedTransaction.deserialize(Buffer.from(tx.tx_b64, 'base64')));
|
|
528
|
+
// txs.push(batchTxs);
|
|
529
|
+
// }
|
|
530
|
+
// return await sendVersionedTxs(connection, {
|
|
531
|
+
// blockhash: txPayloadBatchSequence.batches[0].transactions[0]?.recent_blockhash ?? "",
|
|
532
|
+
// lastValidBlockHeight: txPayloadBatchSequence.batches[0].transactions[0]?.last_valid_block_height ?? 0,
|
|
533
|
+
// batches: txs,
|
|
534
|
+
// }, simulateTransactions);
|
|
535
|
+
// }
|
package/test.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
|
|
1
|
+
import { ComputeBudgetProgram, Connection, Keypair, PublicKey } from "@solana/web3.js";
|
|
2
2
|
import { BN, Wallet } from "@coral-xyz/anchor";
|
|
3
3
|
import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes";
|
|
4
|
-
import { Vault, Intent, RebalanceIntent, SymmetryCore, TaskContext, KeeperMonitor } from "./src";
|
|
4
|
+
import { Vault, Intent, RebalanceIntent, SymmetryCore, TaskContext, KeeperMonitor, isRebalanceRequired } from "./src";
|
|
5
5
|
import { AddOrEditTokenInput, UpdateWeightsInput, MakeDirectSwapInput } from "./src";
|
|
6
6
|
import { EditCreatorSettings, EditManagerSettings, EditFeeSettings, EditScheduleSettings, EditAutomationSettings, EditLpSettings, EditMetadataSettings, EditDepositsSettings, EditForceRebalanceSettings, EditCustomRebalanceSettings, EditAddTokenSettings, EditUpdateWeightsSettings, EditMakeDirectSwapSettings } from "./src";
|
|
7
7
|
import { getRebalanceIntentPda } from "./src/instructions/pda";
|
|
8
|
-
import { PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT } from "./src/constants";
|
|
8
|
+
import { COMPUTE_UNITS, PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT } from "./src/constants";
|
|
9
9
|
import { getJupTokenLedgerAndSwapInstructions } from "./src/jup";
|
|
10
10
|
import { getSwapPairs } from "./src/states/intents/rebalanceIntent";
|
|
11
|
+
import { buildCloseEncodedVaaInstruction } from "./src/states/oracles/pythOracle";
|
|
12
|
+
import { prepareTxPayloadBatchSequence, prepareVersionedTxs, TxBatchData } from "./src/txUtils";
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
let kp = Array.from(Keypair.generate().secretKey);
|
|
@@ -73,7 +75,7 @@ async function testStates() {
|
|
|
73
75
|
|
|
74
76
|
createVault: false, // TESTED
|
|
75
77
|
editPrivateVaultSettings: false, // NOT TESTED
|
|
76
|
-
addBounty:
|
|
78
|
+
addBounty: false, // TESTED
|
|
77
79
|
|
|
78
80
|
editCreator: false, // TESTED
|
|
79
81
|
editManagerSettings: false, // TESTED
|
|
@@ -565,13 +567,13 @@ async function testStates() {
|
|
|
565
567
|
symmetryFeesExtraData: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
|
|
566
568
|
|
|
567
569
|
bountyMint: new PublicKey("So11111111111111111111111111111111111111112"),
|
|
568
|
-
minBountyForVaultAutomation: new BN(
|
|
569
|
-
bountyBondAmount: new BN(
|
|
570
|
+
minBountyForVaultAutomation: new BN(2000 * 5000),
|
|
571
|
+
bountyBondAmount: new BN(20 * 5000),
|
|
570
572
|
bountyPerTask: {
|
|
571
|
-
minBounty: new BN(
|
|
572
|
-
maxBounty: new BN(
|
|
573
|
-
minBountyUntil: new BN(
|
|
574
|
-
maxBountyAfter: new BN(
|
|
573
|
+
minBounty: new BN(20 * 5000),
|
|
574
|
+
maxBounty: new BN(50 * 5000),
|
|
575
|
+
minBountyUntil: new BN(10),
|
|
576
|
+
maxBountyAfter: new BN(40),
|
|
575
577
|
},
|
|
576
578
|
bountyPerPriceUpdateTaskDivisor: new BN(3),
|
|
577
579
|
minRemainingValue: {high: new BN(0), low: new BN("1844674407370955161")},
|