mango-v4/ts/client/src/utils/rpc.ts

125 lines
3.1 KiB
TypeScript
Raw Normal View History

import { AnchorProvider } from '@coral-xyz/anchor';
import NodeWallet from '@coral-xyz/anchor/dist/cjs/nodewallet';
import {
AddressLookupTableAccount,
2023-01-02 12:35:39 -08:00
ComputeBudgetProgram,
2022-11-15 20:10:03 -08:00
MessageV0,
2022-11-16 06:11:39 -08:00
Signer,
TransactionInstruction,
2022-11-15 20:10:03 -08:00
VersionedTransaction,
} from '@solana/web3.js';
export async function sendTransaction(
provider: AnchorProvider,
ixs: TransactionInstruction[],
alts: AddressLookupTableAccount[],
opts: any = {},
): Promise<string> {
const connection = provider.connection;
const latestBlockhash = await connection.getLatestBlockhash(
opts.preflightCommitment ??
provider.opts.preflightCommitment ??
'finalized',
);
const payer = (provider as AnchorProvider).wallet;
2023-01-02 12:35:39 -08:00
if (opts.prioritizationFee) {
ixs = [createComputeBudgetIx(opts.prioritizationFee), ...ixs];
2023-01-02 12:35:39 -08:00
}
2022-11-15 20:10:03 -08:00
const message = MessageV0.compile({
payerKey: (provider as AnchorProvider).wallet.publicKey,
instructions: ixs,
recentBlockhash: latestBlockhash.blockhash,
addressLookupTableAccounts: alts,
});
2022-11-18 11:22:12 -08:00
let vtx = new VersionedTransaction(message);
2022-11-15 20:10:03 -08:00
if (opts?.additionalSigners?.length) {
vtx.sign([...opts?.additionalSigners]);
}
if (
typeof payer.signTransaction === 'function' &&
!(payer instanceof NodeWallet)
) {
2022-11-18 11:22:12 -08:00
vtx = (await payer.signTransaction(
vtx as any,
)) as unknown as VersionedTransaction;
2022-11-16 06:11:39 -08:00
} else {
// Maybe this path is only correct for NodeWallet?
vtx.sign([(payer as any).payer as Signer]);
2022-11-16 06:11:39 -08:00
}
2022-11-15 20:10:03 -08:00
2022-11-21 11:50:24 -08:00
const signature = await connection.sendRawTransaction(vtx.serialize(), {
skipPreflight: true, // mergedOpts.skipPreflight,
2022-11-21 11:50:24 -08:00
});
// const signature = await connection.sendTransactionss(
// vtx as any as VersionedTransaction,
// {
// skipPreflight: true,
// },
// );
if (opts.postSendTxCallback) {
try {
opts.postSendTxCallback({ txid: signature });
} catch (e) {
console.warn(`postSendTxCallback error ${e}`);
}
}
const txConfirmationCommitment = opts.txConfirmationCommitment ?? 'processed';
2022-08-26 12:42:10 -07:00
let status: any;
if (
latestBlockhash.blockhash != null &&
latestBlockhash.lastValidBlockHeight != null
2022-08-26 12:42:10 -07:00
) {
status = (
await connection.confirmTransaction(
{
signature: signature,
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
2022-08-26 12:42:10 -07:00
},
txConfirmationCommitment,
2022-08-26 12:42:10 -07:00
)
).value;
} else {
status = (
await connection.confirmTransaction(signature, txConfirmationCommitment)
).value;
2022-08-26 12:42:10 -07:00
}
if (status.err) {
2022-11-21 14:03:11 -08:00
console.warn('Tx status: ', status);
throw new MangoError({
txid: signature,
2022-11-21 14:03:11 -08:00
message: `${JSON.stringify(status)}`,
});
}
return signature;
}
2023-01-02 12:35:39 -08:00
export const createComputeBudgetIx = (
microLamports: number,
2023-01-02 12:35:39 -08:00
): TransactionInstruction => {
const computeBudgetIx = ComputeBudgetProgram.setComputeUnitPrice({
microLamports,
2023-01-02 12:35:39 -08:00
});
return computeBudgetIx;
};
class MangoError extends Error {
message: string;
txid: string;
constructor({ txid, message }) {
super();
this.message = message;
this.txid = txid;
}
}