use live data to estimate cu
Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
parent
ff0dfb9a2f
commit
28ace32c17
|
@ -0,0 +1,90 @@
|
|||
import WebSocket from 'ws';
|
||||
|
||||
export function manageFeeWebSocket(
|
||||
wsUrl: string,
|
||||
rollingWindowSize: number = 120,
|
||||
onMeanCalculated: (mean: number | null) => void,
|
||||
): () => void {
|
||||
let ws: WebSocket | null = null;
|
||||
const recentValues: number[] = [];
|
||||
|
||||
function calculateRollingMean(values: number[]): number | null {
|
||||
if (values.length === 0) return null;
|
||||
const sum = values.reduce((acc, val) => acc + val, 0);
|
||||
return Math.floor(sum / values.length);
|
||||
}
|
||||
|
||||
function connectWebSocket(): void {
|
||||
try {
|
||||
ws = new WebSocket(wsUrl);
|
||||
|
||||
ws.addEventListener('open', () => {
|
||||
try {
|
||||
// console.log('Fee WebSocket opened');
|
||||
const message = JSON.stringify({
|
||||
jsonrpc: '2.0',
|
||||
id: 1,
|
||||
method: 'blockPrioritizationFeesSubscribe',
|
||||
interval: 30,
|
||||
});
|
||||
ws?.send(message);
|
||||
} catch (error) {
|
||||
console.error('Error in open event:', error);
|
||||
onMeanCalculated(null);
|
||||
}
|
||||
});
|
||||
|
||||
ws.addEventListener('close', () => {
|
||||
// console.log('Fee WebSocket closed');
|
||||
ws = null;
|
||||
// Attempt to reconnect after a delay
|
||||
setTimeout(connectWebSocket, 5000);
|
||||
});
|
||||
|
||||
ws.addEventListener('error', (error) => {
|
||||
console.log('Fee WebSocket error:', error);
|
||||
onMeanCalculated(-1);
|
||||
ws?.close();
|
||||
});
|
||||
|
||||
ws.addEventListener('message', (event: MessageEvent): void => {
|
||||
try {
|
||||
const parsedData = JSON.parse(event.data as string);
|
||||
const value = parsedData?.params?.result?.value.by_tx[15];
|
||||
|
||||
if (value !== undefined && typeof value === 'number') {
|
||||
recentValues.push(value);
|
||||
if (recentValues.length > rollingWindowSize) {
|
||||
recentValues.shift();
|
||||
}
|
||||
|
||||
const rollingMean = calculateRollingMean(recentValues);
|
||||
onMeanCalculated(rollingMean);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error processing message:', error);
|
||||
onMeanCalculated(-1);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error in connectWebSocket:', error);
|
||||
onMeanCalculated(-1);
|
||||
// Attempt to reconnect after a delay
|
||||
setTimeout(connectWebSocket, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
// Start the WebSocket connection
|
||||
connectWebSocket();
|
||||
|
||||
// Return a function to close the WebSocket
|
||||
return () => {
|
||||
if (ws) {
|
||||
try {
|
||||
ws.close();
|
||||
} catch (error) {
|
||||
console.error('Error closing WebSocket:', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
|
@ -27,24 +27,35 @@ import { MangoClient } from '../src/client';
|
|||
import { MANGO_V4_ID, MANGO_V4_MAIN_GROUP } from '../src/constants';
|
||||
import { ZERO_I80F48 } from '../src/numbers/I80F48';
|
||||
import { createComputeBudgetIx } from '../src/utils/rpc';
|
||||
import { manageFeeWebSocket } from './manageFeeWs';
|
||||
|
||||
const CLUSTER: Cluster =
|
||||
(process.env.CLUSTER_OVERRIDE as Cluster) || 'mainnet-beta';
|
||||
const CLUSTER_URL =
|
||||
process.env.CLUSTER_URL_OVERRIDE || process.env.MB_CLUSTER_URL;
|
||||
const CLUSTER_URL_2 =
|
||||
process.env.CLUSTER_URL_OVERRIDE || process.env.MB_CLUSTER_URL_2;
|
||||
const LITE_RPC_URL = process.env.MB_CLUSTER_URL;
|
||||
const CLUSTER_URL_2 = process.env.MB_CLUSTER_URL_2;
|
||||
const LITE_RPC_URL = process.env.LITE_RPC_URL;
|
||||
const USER_KEYPAIR =
|
||||
process.env.USER_KEYPAIR_OVERRIDE || process.env.MB_PAYER_KEYPAIR;
|
||||
const GROUP = process.env.GROUP_OVERRIDE || MANGO_V4_MAIN_GROUP.toBase58();
|
||||
const SLEEP_MS = Number(process.env.SLEEP_MS) || 50_000; //
|
||||
const COMPUTE_UNIT_PRICE = Number(process.env.COMPUTE_UNIT_PRICE) || 150_000; //
|
||||
const SLEEP_MS = Number(process.env.SLEEP_MS) || 50_000;
|
||||
|
||||
console.log(`Starting with ${SLEEP_MS}`);
|
||||
console.log(`${CLUSTER_URL}`);
|
||||
console.log(
|
||||
`Starting with sleep ${SLEEP_MS}ms, cluster ${CLUSTER_URL}, cluster2 ${CLUSTER_URL_2}, liteRpcUrl ${LITE_RPC_URL}`,
|
||||
);
|
||||
|
||||
// TODO use mangolana to send txs
|
||||
let lamportsPerCu: number | null = null;
|
||||
try {
|
||||
const wsUrl = new URL(
|
||||
process.env.LITE_RPC_URL!.replace('https', 'wss'),
|
||||
).toString();
|
||||
|
||||
manageFeeWebSocket(wsUrl, 10, (mean) => {
|
||||
lamportsPerCu = mean;
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error in main execution:', error);
|
||||
}
|
||||
|
||||
interface OracleInterface {
|
||||
oracle: {
|
||||
|
@ -137,20 +148,25 @@ interface OracleInterface {
|
|||
|
||||
const ixsChunks = chunk(shuffle(pullIxs), 2, false);
|
||||
try {
|
||||
// use dont await, fire and forget
|
||||
// dont await, fire and forget
|
||||
sendSignAndConfirmTransactions({
|
||||
connection,
|
||||
wallet: new Wallet(user),
|
||||
backupConnections: [
|
||||
new Connection(LITE_RPC_URL!, 'recent'),
|
||||
new Connection(CLUSTER_URL_2!, 'recent'),
|
||||
...(CLUSTER_URL_2
|
||||
? [new Connection(LITE_RPC_URL!, 'recent')]
|
||||
: []),
|
||||
...(CLUSTER_URL_2
|
||||
? [new Connection(CLUSTER_URL_2!, 'recent')]
|
||||
: []),
|
||||
],
|
||||
transactionInstructions: ixsChunks.map((txChunk) => ({
|
||||
instructionsSet: [
|
||||
{
|
||||
signers: [],
|
||||
transactionInstruction:
|
||||
createComputeBudgetIx(COMPUTE_UNIT_PRICE),
|
||||
transactionInstruction: createComputeBudgetIx(
|
||||
Math.max(lamportsPerCu ?? 150_000, 150_000),
|
||||
),
|
||||
},
|
||||
...txChunk.map((tx) => ({
|
||||
signers: [],
|
||||
|
@ -168,14 +184,14 @@ interface OracleInterface {
|
|||
callbacks: {
|
||||
afterEveryTxSend: function (data) {
|
||||
console.log(
|
||||
` - https://solscan.io/tx/${data['txid']}, in ${(Date.now() - start) / 1000}s`,
|
||||
` - https://solscan.io/tx/${data['txid']}, in ${(Date.now() - start) / 1000}s, lamportsPerCu ${lamportsPerCu}`,
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(
|
||||
`Error in sending tx, ${JSON.stringify(error.message)}, https://solscan.io/tx/${error['txid']}, in ${(Date.now() - start) / 1000}s`,
|
||||
`Error in sending tx, ${JSON.stringify(error.message)}, https://solscan.io/tx/${error['txid']}, in ${(Date.now() - start) / 1000}s, lamportsPerCu ${lamportsPerCu}`,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ async function updateTokenParams(): Promise<void> {
|
|||
);
|
||||
if (maybeSbOracle.length > 0) {
|
||||
console.log(` - ${bank.name} ${maybeSbOracle[0][0]}`);
|
||||
builder.fallbackOracle(new PublicKey(maybeSbOracle[0][1]));
|
||||
builder.fallbackOracle(PublicKey.default);
|
||||
change = true;
|
||||
} else {
|
||||
return;
|
||||
|
@ -572,7 +572,7 @@ async function updateTokenParams(): Promise<void> {
|
|||
tokenOwnerRecord,
|
||||
PROPOSAL_TITLE
|
||||
? PROPOSAL_TITLE
|
||||
: 'Set sb on demand oracles as fallback oracles in mango-v4',
|
||||
: 'Reset sb on demand oracles as fallback oracles in mango-v4',
|
||||
PROPOSAL_LINK ?? '',
|
||||
Object.values(proposals).length,
|
||||
instructions,
|
||||
|
|
Loading…
Reference in New Issue