mango-v4-ui/utils/transactionConfirmationData.ts

112 lines
3.2 KiB
TypeScript
Raw Normal View History

import { IDL } from '@blockworks-foundation/mango-v4'
2024-01-09 17:02:38 -08:00
import { BorshInstructionCoder } from '@project-serum/anchor'
2024-01-09 21:35:25 -08:00
import { Connection } from '@solana/web3.js'
2024-01-09 17:02:38 -08:00
import { MANGO_DATA_API_URL } from './constants'
2024-01-09 21:35:25 -08:00
import { TxCallbackOptions } from '@blockworks-foundation/mango-v4/dist/types/src/client'
2024-01-09 17:02:38 -08:00
const coder = new BorshInstructionCoder(IDL)
export function collectTxConfirmationData(
rpcEndpoint: string,
prioritizationFee: number,
2024-01-09 21:35:25 -08:00
txCallbackOptions: TxCallbackOptions,
2024-01-09 17:02:38 -08:00
) {
const start = new Date().getTime()
txConfirmationInner(
start,
rpcEndpoint,
prioritizationFee,
txCallbackOptions,
).catch((e) =>
txConfirmationInner(
start,
rpcEndpoint,
prioritizationFee,
txCallbackOptions,
),
)
2024-01-09 17:02:38 -08:00
}
async function txConfirmationInner(
startTime: number,
2024-01-09 17:02:38 -08:00
rpcEndpoint: string,
prioritization_fee: number,
2024-01-09 21:35:25 -08:00
txCallbackOptions: TxCallbackOptions,
2024-01-09 17:02:38 -08:00
) {
const connection = new Connection(rpcEndpoint, 'processed')
2024-01-09 21:35:25 -08:00
const { txid: signature, txSignatureBlockHash } = txCallbackOptions
await connection.confirmTransaction(
{
signature,
blockhash: txSignatureBlockHash.blockhash,
lastValidBlockHeight: txSignatureBlockHash.lastValidBlockHeight,
},
'processed',
)
const elapsed = new Date().getTime() - startTime
2024-01-09 17:02:38 -08:00
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
2024-01-09 17:02:38 -08:00
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,
2024-01-09 17:02:38 -08:00
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)
}