112 lines
3.2 KiB
TypeScript
112 lines
3.2 KiB
TypeScript
import { IDL } from '@blockworks-foundation/mango-v4'
|
|
import { BorshInstructionCoder } from '@project-serum/anchor'
|
|
import { Connection } from '@solana/web3.js'
|
|
import { MANGO_DATA_API_URL } from './constants'
|
|
import { TxCallbackOptions } from '@blockworks-foundation/mango-v4/dist/types/src/client'
|
|
|
|
const coder = new BorshInstructionCoder(IDL)
|
|
|
|
export function collectTxConfirmationData(
|
|
rpcEndpoint: string,
|
|
prioritizationFee: number,
|
|
txCallbackOptions: TxCallbackOptions,
|
|
) {
|
|
const start = new Date().getTime()
|
|
txConfirmationInner(
|
|
start,
|
|
rpcEndpoint,
|
|
prioritizationFee,
|
|
txCallbackOptions,
|
|
).catch((e) =>
|
|
txConfirmationInner(
|
|
start,
|
|
rpcEndpoint,
|
|
prioritizationFee,
|
|
txCallbackOptions,
|
|
),
|
|
)
|
|
}
|
|
|
|
async function txConfirmationInner(
|
|
startTime: number,
|
|
rpcEndpoint: string,
|
|
prioritization_fee: number,
|
|
txCallbackOptions: TxCallbackOptions,
|
|
) {
|
|
const connection = new Connection(rpcEndpoint, 'processed')
|
|
const { txid: signature, txSignatureBlockHash } = txCallbackOptions
|
|
await connection.confirmTransaction(
|
|
{
|
|
signature,
|
|
blockhash: txSignatureBlockHash.blockhash,
|
|
lastValidBlockHeight: txSignatureBlockHash.lastValidBlockHeight,
|
|
},
|
|
'processed',
|
|
)
|
|
const elapsed = new Date().getTime() - startTime
|
|
|
|
await connection.confirmTransaction(
|
|
{
|
|
signature,
|
|
blockhash: txSignatureBlockHash.blockhash,
|
|
lastValidBlockHeight: txSignatureBlockHash.lastValidBlockHeight,
|
|
},
|
|
'confirmed',
|
|
)
|
|
|
|
const confirmedTxn = await connection.getTransaction(signature, {
|
|
commitment: 'confirmed',
|
|
maxSupportedTransactionVersion: 0,
|
|
})
|
|
|
|
// search message ixs only (as opposed to inner)
|
|
// it's ok to do this since Mango does not CPI into itself and these metrics are for the frontend only
|
|
const messageInstructions =
|
|
confirmedTxn?.transaction.message.compiledInstructions
|
|
const instructionNames = []
|
|
if (messageInstructions) {
|
|
for (let ix of messageInstructions) {
|
|
const parsedInstruction = coder.decode(Buffer.from(ix.data))
|
|
if (parsedInstruction) {
|
|
instructionNames.push(parsedInstruction.name)
|
|
}
|
|
}
|
|
}
|
|
|
|
const confirmed = confirmedTxn !== null
|
|
const error =
|
|
confirmedTxn?.meta?.err !== null && confirmedTxn?.meta?.err !== undefined
|
|
const block_datetime = confirmedTxn?.blockTime
|
|
? new Date(confirmedTxn.blockTime * 1000).toISOString()
|
|
: null
|
|
|
|
const loaded_addresses =
|
|
(confirmedTxn?.meta?.loadedAddresses?.readonly.length ?? 0) +
|
|
(confirmedTxn?.meta?.loadedAddresses?.writable.length ?? 0)
|
|
|
|
const data = {
|
|
signature,
|
|
block_datetime,
|
|
confirmed,
|
|
error,
|
|
ui_confirmation_time_ms: elapsed,
|
|
fetch_blockhash_slot: txSignatureBlockHash.slot,
|
|
processed_slot: confirmedTxn?.slot,
|
|
instruction_names: instructionNames.join(','),
|
|
loaded_addresses,
|
|
prioritization_fee,
|
|
compute_units_consumed: confirmedTxn?.meta?.computeUnitsConsumed,
|
|
fee_lamports: confirmedTxn?.meta?.fee,
|
|
}
|
|
|
|
const resp = await fetch(`${MANGO_DATA_API_URL}/transaction-confirmation`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(data),
|
|
})
|
|
const body = await resp.json()
|
|
// console.log(body)
|
|
}
|