removed Wallet capability
This commit is contained in:
parent
6e9cbd5003
commit
ca32f542ee
|
@ -45,10 +45,7 @@
|
|||
"prettier": "^2.0.5",
|
||||
"ts-jest": "^26.2.0",
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.1.3",
|
||||
"antd": "^4.12.2",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1"
|
||||
"typescript": "^4.1.3"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
|
@ -58,11 +55,10 @@
|
|||
"trailingComma": "all"
|
||||
},
|
||||
"dependencies": {
|
||||
"@project-serum/serum": "^0.13.18",
|
||||
"@project-serum/serum": "^0.13.20",
|
||||
"@solana/web3.js": "^0.90.0",
|
||||
"bn.js": "^5.1.2",
|
||||
"buffer-layout": "^1.2.0",
|
||||
"double.js": "^1.0.14",
|
||||
"@project-serum/sol-wallet-adapter": "^0.1.4"
|
||||
},
|
||||
"browserslist": [
|
||||
|
|
118
src/client.ts
118
src/client.ts
|
@ -13,7 +13,9 @@ import {
|
|||
import {
|
||||
encodeMangoInstruction,
|
||||
MangoGroupLayout,
|
||||
MarginAccountLayout, NUM_MARKETS, NUM_TOKENS,
|
||||
MarginAccountLayout,
|
||||
NUM_MARKETS,
|
||||
NUM_TOKENS,
|
||||
WideBits,
|
||||
} from './layout';
|
||||
import BN from 'bn.js';
|
||||
|
@ -24,10 +26,8 @@ import {
|
|||
nativeToUi,
|
||||
uiToNative,
|
||||
zeroKey,
|
||||
sendTransaction
|
||||
} from './utils';
|
||||
import { Market, OpenOrders } from '@project-serum/serum';
|
||||
import { Wallet } from '@project-serum/sol-wallet-adapter';
|
||||
import { TOKEN_PROGRAM_ID } from '@project-serum/serum/lib/token-instructions';
|
||||
import { Order } from '@project-serum/serum/lib/market';
|
||||
|
||||
|
@ -212,30 +212,8 @@ export class MarginAccount {
|
|||
}
|
||||
|
||||
getCollateralRatio(mangoGroup: MangoGroup, prices: number[]): number {
|
||||
let assetsVal = 0
|
||||
let liabsVal = 0
|
||||
for (let i = 0; i < NUM_TOKENS; i++) {
|
||||
assetsVal += this.getUiDeposit(mangoGroup, i) * prices[i]
|
||||
liabsVal += this.getUiBorrow(mangoGroup, i) * prices[i]
|
||||
}
|
||||
|
||||
if (liabsVal === 0) {
|
||||
return 100
|
||||
}
|
||||
|
||||
if (this.openOrdersAccounts == undefined) {
|
||||
return assetsVal / liabsVal
|
||||
}
|
||||
for (let i = 0; i < NUM_MARKETS; i++) {
|
||||
const openOrdersAccount = this.openOrdersAccounts[i]
|
||||
if (openOrdersAccount == undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
assetsVal += nativeToUi(openOrdersAccount.baseTokenTotal.toNumber(), mangoGroup.mintDecimals[i]) * prices[i]
|
||||
assetsVal += nativeToUi(openOrdersAccount.quoteTokenTotal.toNumber(), mangoGroup.mintDecimals[NUM_TOKENS-1])
|
||||
|
||||
}
|
||||
const assetsVal = this.getAssetsVal(mangoGroup, prices)
|
||||
const liabsVal = this.getLiabsVal(mangoGroup, prices)
|
||||
|
||||
return assetsVal / liabsVal
|
||||
}
|
||||
|
@ -249,53 +227,35 @@ export class MangoClient {
|
|||
async sendTransaction(
|
||||
connection: Connection,
|
||||
transaction: Transaction,
|
||||
payer: Account | Wallet,
|
||||
payer: Account,
|
||||
additionalSigners: Account[],
|
||||
notifications?: {sendingMessage: string, sentMessage: string, successMessage: string}
|
||||
): Promise<TransactionSignature> {
|
||||
transaction.recentBlockhash = (await connection.getRecentBlockhash('max')).blockhash
|
||||
transaction.setSigners(payer.publicKey, ...additionalSigners.map( a => a.publicKey ))
|
||||
// TODO test on mainnet
|
||||
|
||||
// if Wallet was provided, sign with wallet
|
||||
if (!(payer instanceof Account)) {
|
||||
// TODO test with wallet
|
||||
transaction.recentBlockhash = (await connection.getRecentBlockhash('max')).blockhash
|
||||
transaction.setSigners(payer.publicKey, ...additionalSigners.map( a => a.publicKey ))
|
||||
|
||||
let args = {
|
||||
transaction,
|
||||
wallet: payer,
|
||||
signers: additionalSigners,
|
||||
connection,
|
||||
}
|
||||
if (notifications) {
|
||||
args = {...args, ...notifications}
|
||||
}
|
||||
const signers = [payer].concat(additionalSigners)
|
||||
transaction.sign(...signers)
|
||||
const rawTransaction = transaction.serialize()
|
||||
return await sendAndConfirmRawTransaction(connection, rawTransaction, {skipPreflight: true})
|
||||
|
||||
return await sendTransaction(args)
|
||||
} else {
|
||||
// otherwise sign with the payer account
|
||||
const signers = [payer].concat(additionalSigners)
|
||||
transaction.sign(...signers)
|
||||
const rawTransaction = transaction.serialize()
|
||||
return await sendAndConfirmRawTransaction(connection, rawTransaction, {skipPreflight: true})
|
||||
}
|
||||
}
|
||||
async initMarginAccount(
|
||||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
dexProgramId: PublicKey, // Serum DEX program ID
|
||||
mangoGroup: MangoGroup,
|
||||
payer: Account | Wallet,
|
||||
owner: Account, // assumed to be same as payer for now
|
||||
): Promise<PublicKey> {
|
||||
|
||||
// Create a Solana account for the MarginAccount and allocate space
|
||||
const accInstr = await createAccountInstruction(connection, payer.publicKey, MarginAccountLayout.span, programId)
|
||||
const accInstr = await createAccountInstruction(connection,
|
||||
owner.publicKey, MarginAccountLayout.span, programId)
|
||||
|
||||
// Specify the accounts this instruction takes in (see program/src/instruction.rs)
|
||||
const keys = [
|
||||
{ isSigner: false, isWritable: false, pubkey: mangoGroup.publicKey},
|
||||
{ isSigner: false, isWritable: false, pubkey: mangoGroup.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: accInstr.account.publicKey },
|
||||
{ isSigner: true, isWritable: false, pubkey: payer.publicKey },
|
||||
{ isSigner: true, isWritable: false, pubkey: owner.publicKey },
|
||||
{ isSigner: false, isWritable: false, pubkey: SYSVAR_RENT_PUBKEY }
|
||||
]
|
||||
|
||||
|
@ -313,18 +273,8 @@ export class MangoClient {
|
|||
accInstr.account,
|
||||
]
|
||||
|
||||
let notifications;
|
||||
if (!(payer instanceof Account)) {
|
||||
const functionName = 'InitMarginAccount'
|
||||
notifications = {
|
||||
sendingMessage: `sending ${functionName} instruction...`,
|
||||
sentMessage: `${functionName} instruction sent`,
|
||||
successMessage: `${functionName} instruction success`
|
||||
}
|
||||
}
|
||||
|
||||
// sign, send and confirm transaction
|
||||
await this.sendTransaction(connection, transaction, payer, additionalSigners, notifications)
|
||||
await this.sendTransaction(connection, transaction, owner, additionalSigners)
|
||||
|
||||
return accInstr.account.publicKey
|
||||
}
|
||||
|
@ -334,7 +284,7 @@ export class MangoClient {
|
|||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
marginAccount: MarginAccount,
|
||||
owner: Account | Wallet,
|
||||
owner: Account,
|
||||
token: PublicKey,
|
||||
tokenAcc: PublicKey,
|
||||
|
||||
|
@ -362,16 +312,7 @@ export class MangoClient {
|
|||
transaction.add(instruction)
|
||||
const additionalSigners = []
|
||||
|
||||
let notifications;
|
||||
if (!(owner instanceof Account)) {
|
||||
const functionName = 'Deposit'
|
||||
notifications = {
|
||||
sendingMessage: `sending ${functionName} instruction...`,
|
||||
sentMessage: `${functionName} instruction sent`,
|
||||
successMessage: `${functionName} instruction success`
|
||||
}
|
||||
}
|
||||
return await this.sendTransaction(connection, transaction, owner, additionalSigners, notifications)
|
||||
return await this.sendTransaction(connection, transaction, owner, additionalSigners)
|
||||
}
|
||||
|
||||
async withdraw(
|
||||
|
@ -379,7 +320,7 @@ export class MangoClient {
|
|||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
marginAccount: MarginAccount,
|
||||
owner: Account | Wallet,
|
||||
owner: Account,
|
||||
token: PublicKey,
|
||||
tokenAcc: PublicKey,
|
||||
|
||||
|
@ -418,7 +359,7 @@ export class MangoClient {
|
|||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
marginAccount: MarginAccount,
|
||||
owner: Account | Wallet,
|
||||
owner: Account,
|
||||
token: PublicKey,
|
||||
|
||||
quantity: number
|
||||
|
@ -452,7 +393,7 @@ export class MangoClient {
|
|||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
marginAccount: MarginAccount,
|
||||
owner: Account | Wallet,
|
||||
owner: Account,
|
||||
|
||||
token: PublicKey,
|
||||
quantity: number
|
||||
|
@ -484,7 +425,7 @@ export class MangoClient {
|
|||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
liqeeMarginAccount: MarginAccount, // liquidatee marginAccount
|
||||
liqor: Account | Wallet, // liquidator
|
||||
liqor: Account, // liquidator
|
||||
tokenAccs: PublicKey[],
|
||||
depositQuantities: number[]
|
||||
): Promise<TransactionSignature> {
|
||||
|
@ -519,7 +460,7 @@ export class MangoClient {
|
|||
mangoGroup: MangoGroup,
|
||||
marginAccount: MarginAccount,
|
||||
spotMarket: Market,
|
||||
owner: Account | Wallet,
|
||||
owner: Account,
|
||||
|
||||
side: 'buy' | 'sell',
|
||||
price: number,
|
||||
|
@ -609,7 +550,7 @@ export class MangoClient {
|
|||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
marginAccount: MarginAccount,
|
||||
owner: Account | Wallet,
|
||||
owner: Account,
|
||||
spotMarket: Market,
|
||||
|
||||
): Promise<TransactionSignature> {
|
||||
|
@ -659,7 +600,7 @@ export class MangoClient {
|
|||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
marginAccount: MarginAccount,
|
||||
owner: Account | Wallet,
|
||||
owner: Account,
|
||||
spotMarket: Market,
|
||||
order: Order,
|
||||
): Promise<TransactionSignature> {
|
||||
|
@ -740,7 +681,7 @@ export class MangoClient {
|
|||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
owner: Account | Wallet
|
||||
owner: Account
|
||||
): Promise<MarginAccount[]> {
|
||||
|
||||
const filters = [
|
||||
|
@ -766,7 +707,8 @@ export class MangoClient {
|
|||
const accounts = await getFilteredProgramAccounts(connection, programId, filters);
|
||||
return accounts.map(
|
||||
({ publicKey, accountInfo }) =>
|
||||
new MarginAccount(publicKey, MarginAccountLayout.decode(accountInfo == null ? undefined : accountInfo.data))
|
||||
new MarginAccount(publicKey, MarginAccountLayout.decode(
|
||||
accountInfo == null ? undefined : accountInfo.data))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
import {struct, u8, blob, union, u32, Layout, bits, Blob, seq, BitStructure, UInt } from 'buffer-layout';
|
||||
import { bits, BitStructure, Blob, Layout, seq, struct, u32, u8, UInt, union } from 'buffer-layout';
|
||||
import { PublicKey } from '@solana/web3.js';
|
||||
import BN from 'bn.js';
|
||||
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
import React from "react";
|
||||
import { notification } from "antd";
|
||||
// import Link from '../components/Link';
|
||||
|
||||
export function notify({
|
||||
message = "",
|
||||
description = undefined as any,
|
||||
txid = "",
|
||||
type = "info",
|
||||
placement = "bottomLeft",
|
||||
}) {
|
||||
if (txid) {
|
||||
// <Link
|
||||
// external
|
||||
// to={'https://explorer.solana.com/tx/' + txid}
|
||||
// style={{ color: '#0000ff' }}
|
||||
// >
|
||||
// View transaction {txid.slice(0, 8)}...{txid.slice(txid.length - 8)}
|
||||
// </Link>
|
||||
|
||||
description = <></>;
|
||||
}
|
||||
(notification as any)[type]({
|
||||
message: <span style={{ color: "black" }}>{message}</span>,
|
||||
description: (
|
||||
<span style={{ color: "black", opacity: 0.5 }}>{description}</span>
|
||||
),
|
||||
placement,
|
||||
style: {
|
||||
backgroundColor: "white",
|
||||
},
|
||||
});
|
||||
}
|
291
src/utils.ts
291
src/utils.ts
|
@ -1,18 +1,8 @@
|
|||
import {
|
||||
Account, Commitment,
|
||||
Connection,
|
||||
PublicKey, RpcResponseAndContext, SimulatedTransactionResponse,
|
||||
SystemProgram,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
TransactionSignature,
|
||||
} from '@solana/web3.js';
|
||||
import { Account, Connection, PublicKey, SystemProgram, TransactionInstruction } from '@solana/web3.js';
|
||||
import { publicKeyLayout, u64 } from './layout';
|
||||
import BN from 'bn.js';
|
||||
import { WRAPPED_SOL_MINT } from '@project-serum/serum/lib/token-instructions';
|
||||
import { blob, struct, u8 } from 'buffer-layout';
|
||||
import {notify} from "./notifications";
|
||||
|
||||
|
||||
export const zeroKey = new PublicKey(new Uint8Array(32))
|
||||
|
||||
|
@ -143,282 +133,3 @@ export function nativeToUi(amount: number, decimals: number): number {
|
|||
return amount / Math.pow(10, decimals)
|
||||
|
||||
}
|
||||
|
||||
|
||||
const DEFAULT_TIMEOUT = 15000;
|
||||
|
||||
export async function sendTransaction({
|
||||
transaction,
|
||||
wallet,
|
||||
signers = [],
|
||||
connection,
|
||||
sendingMessage = 'Sending transaction...',
|
||||
sentMessage = 'Transaction sent',
|
||||
successMessage = 'Transaction confirmed',
|
||||
timeout = DEFAULT_TIMEOUT,
|
||||
}: {
|
||||
transaction: Transaction;
|
||||
wallet: any;
|
||||
signers?: Array<Account>;
|
||||
connection: Connection;
|
||||
sendingMessage?: string;
|
||||
sentMessage?: string;
|
||||
successMessage?: string;
|
||||
timeout?: number;
|
||||
}) {
|
||||
const signedTransaction = await signTransaction({
|
||||
transaction,
|
||||
wallet,
|
||||
signers,
|
||||
connection,
|
||||
});
|
||||
return await sendSignedTransaction({
|
||||
signedTransaction,
|
||||
connection,
|
||||
sendingMessage,
|
||||
sentMessage,
|
||||
successMessage,
|
||||
timeout,
|
||||
});
|
||||
}
|
||||
|
||||
export async function signTransaction({
|
||||
transaction,
|
||||
wallet,
|
||||
signers = [],
|
||||
connection,
|
||||
}: {
|
||||
transaction: Transaction;
|
||||
wallet: any;
|
||||
signers?: Array<Account>;
|
||||
connection: Connection;
|
||||
}) {
|
||||
transaction.recentBlockhash = (
|
||||
await connection.getRecentBlockhash('max')
|
||||
).blockhash;
|
||||
transaction.setSigners(wallet.publicKey, ...signers.map((s) => s.publicKey));
|
||||
if (signers.length > 0) {
|
||||
transaction.partialSign(...signers);
|
||||
}
|
||||
return await wallet.signTransaction(transaction);
|
||||
}
|
||||
|
||||
export async function signTransactions({
|
||||
transactionsAndSigners,
|
||||
wallet,
|
||||
connection,
|
||||
}: {
|
||||
transactionsAndSigners: {
|
||||
transaction: Transaction;
|
||||
signers?: Array<Account>;
|
||||
}[];
|
||||
wallet: any;
|
||||
connection: Connection;
|
||||
}) {
|
||||
const blockhash = (await connection.getRecentBlockhash('max')).blockhash;
|
||||
transactionsAndSigners.forEach(({ transaction, signers = [] }) => {
|
||||
transaction.recentBlockhash = blockhash;
|
||||
transaction.setSigners(
|
||||
wallet.publicKey,
|
||||
...signers.map((s) => s.publicKey),
|
||||
);
|
||||
|
||||
if (signers && signers.length > 0) {
|
||||
transaction.partialSign(...signers);
|
||||
}
|
||||
});
|
||||
return await wallet.signAllTransactions(
|
||||
transactionsAndSigners.map(({ transaction }) => transaction),
|
||||
);
|
||||
}
|
||||
|
||||
export const getUnixTs = () => {
|
||||
return new Date().getTime() / 1000;
|
||||
};
|
||||
|
||||
export async function sendSignedTransaction({
|
||||
signedTransaction,
|
||||
connection,
|
||||
sendingMessage = 'Sending transaction...',
|
||||
sentMessage = 'Transaction sent',
|
||||
successMessage = 'Transaction confirmed',
|
||||
timeout = DEFAULT_TIMEOUT,
|
||||
}: {
|
||||
signedTransaction: Transaction;
|
||||
connection: Connection;
|
||||
sendingMessage?: string;
|
||||
sentMessage?: string;
|
||||
successMessage?: string;
|
||||
timeout?: number;
|
||||
}): Promise<string> {
|
||||
const rawTransaction = signedTransaction.serialize();
|
||||
const startTime = getUnixTs();
|
||||
notify({ message: sendingMessage });
|
||||
const txid: TransactionSignature = await connection.sendRawTransaction(
|
||||
rawTransaction,
|
||||
{
|
||||
skipPreflight: true,
|
||||
},
|
||||
);
|
||||
notify({ message: sentMessage, type: 'success', txid });
|
||||
|
||||
console.log('Started awaiting confirmation for', txid);
|
||||
|
||||
let done = false;
|
||||
(async () => {
|
||||
while (!done && getUnixTs() - startTime < timeout) {
|
||||
connection.sendRawTransaction(rawTransaction, {
|
||||
skipPreflight: true,
|
||||
});
|
||||
await sleep(300);
|
||||
}
|
||||
})();
|
||||
try {
|
||||
await awaitTransactionSignatureConfirmation(txid, timeout, connection);
|
||||
} catch (err) {
|
||||
if (err.timeout) {
|
||||
throw new Error('Timed out awaiting confirmation on transaction');
|
||||
}
|
||||
let simulateResult: SimulatedTransactionResponse | null = null;
|
||||
try {
|
||||
simulateResult = (
|
||||
await simulateTransaction(connection, signedTransaction, 'single')
|
||||
).value;
|
||||
} catch (e) {}
|
||||
if (simulateResult && simulateResult.err) {
|
||||
if (simulateResult.logs) {
|
||||
for (let i = simulateResult.logs.length - 1; i >= 0; --i) {
|
||||
const line = simulateResult.logs[i];
|
||||
if (line.startsWith('Program log: ')) {
|
||||
throw new Error(
|
||||
'Transaction failed: ' + line.slice('Program log: '.length),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error(JSON.stringify(simulateResult.err));
|
||||
}
|
||||
throw new Error('Transaction failed');
|
||||
} finally {
|
||||
done = true;
|
||||
}
|
||||
notify({ message: successMessage, type: 'success', txid });
|
||||
|
||||
console.log('Latency', txid, getUnixTs() - startTime);
|
||||
return txid;
|
||||
}
|
||||
|
||||
async function awaitTransactionSignatureConfirmation(
|
||||
txid: TransactionSignature,
|
||||
timeout: number,
|
||||
connection: Connection,
|
||||
) {
|
||||
let done = false;
|
||||
const result = await new Promise((resolve, reject) => {
|
||||
(async () => {
|
||||
setTimeout(() => {
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
done = true;
|
||||
console.log('Timed out for txid', txid);
|
||||
reject({ timeout: true });
|
||||
}, timeout);
|
||||
try {
|
||||
connection.onSignature(
|
||||
txid,
|
||||
(result) => {
|
||||
console.log('WS confirmed', txid, result);
|
||||
done = true;
|
||||
if (result.err) {
|
||||
reject(result.err);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
},
|
||||
'recent',
|
||||
);
|
||||
console.log('Set up WS connection', txid);
|
||||
} catch (e) {
|
||||
done = true;
|
||||
console.log('WS error in setup', txid, e);
|
||||
}
|
||||
while (!done) {
|
||||
// eslint-disable-next-line no-loop-func
|
||||
(async () => {
|
||||
try {
|
||||
const signatureStatuses = await connection.getSignatureStatuses([
|
||||
txid,
|
||||
]);
|
||||
const result = signatureStatuses && signatureStatuses.value[0];
|
||||
if (!done) {
|
||||
if (!result) {
|
||||
console.log('REST null result for', txid, result);
|
||||
} else if (result.err) {
|
||||
console.log('REST error for', txid, result);
|
||||
done = true;
|
||||
reject(result.err);
|
||||
} else if (!result.confirmations) {
|
||||
console.log('REST no confirmations for', txid, result);
|
||||
} else {
|
||||
console.log('REST confirmation for', txid, result);
|
||||
done = true;
|
||||
resolve(result);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (!done) {
|
||||
console.log('REST connection error: txid', txid, e);
|
||||
}
|
||||
}
|
||||
})();
|
||||
await sleep(300);
|
||||
}
|
||||
})();
|
||||
});
|
||||
done = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
function mergeTransactions(transactions: (Transaction | undefined)[]) {
|
||||
const transaction = new Transaction();
|
||||
transactions
|
||||
.filter((t): t is Transaction => t !== undefined)
|
||||
.forEach((t) => {
|
||||
transaction.add(t);
|
||||
});
|
||||
return transaction;
|
||||
}
|
||||
|
||||
|
||||
export async function sleep(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
|
||||
/** Copy of Connection.simulateTransaction that takes a commitment parameter. */
|
||||
async function simulateTransaction(
|
||||
connection: Connection,
|
||||
transaction: Transaction,
|
||||
commitment: Commitment,
|
||||
): Promise<RpcResponseAndContext<SimulatedTransactionResponse>> {
|
||||
// @ts-ignore
|
||||
transaction.recentBlockhash = await connection._recentBlockhash(
|
||||
// @ts-ignore
|
||||
connection._disableBlockhashCaching,
|
||||
);
|
||||
|
||||
const signData = transaction.serializeMessage();
|
||||
// @ts-ignore
|
||||
const wireTransaction = transaction._serialize(signData);
|
||||
const encodedTransaction = wireTransaction.toString('base64');
|
||||
const config: any = { encoding: 'base64', commitment };
|
||||
const args = [encodedTransaction, config];
|
||||
|
||||
// @ts-ignore
|
||||
const res = await connection._rpcRequest('simulateTransaction', args);
|
||||
if (res.error) {
|
||||
throw new Error('failed to simulate transaction: ' + res.error.message);
|
||||
}
|
||||
return res.result;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue