@marinade.finance/web3js-common
Advanced tools
Comparing version 2.3.0 to 2.3.1
{ | ||
"name": "@marinade.finance/web3js-common", | ||
"version": "2.3.0", | ||
"version": "2.3.1", | ||
"description": "Web3 JS reusable utilities", | ||
@@ -24,3 +24,3 @@ "repository": { | ||
"devDependencies": { | ||
"@marinade.finance/ts-common": "2.3.0", | ||
"@marinade.finance/ts-common": "2.3.1", | ||
"@solana/web3.js": "^1.91.1", | ||
@@ -33,3 +33,3 @@ "@solana/buffer-layout": "^4.0.1", | ||
"peerDependencies": { | ||
"@marinade.finance/ts-common": "2.3.0", | ||
"@marinade.finance/ts-common": "2.3.1", | ||
"@solana/web3.js": "^1.91.1", | ||
@@ -36,0 +36,0 @@ "@solana/buffer-layout": "^4.0.1", |
import { Transaction, VersionedTransaction } from '@solana/web3.js'; | ||
export declare class ExecutionError extends Error { | ||
readonly txSignature?: string; | ||
readonly cause?: Error; | ||
readonly logs?: string[]; | ||
readonly transaction?: Transaction | VersionedTransaction; | ||
constructor({ msg, cause, logs, transaction, }: { | ||
constructor({ msg, txSignature, cause, logs, transaction, }: { | ||
msg?: string; | ||
txSignature?: string; | ||
cause?: Error; | ||
@@ -9,0 +11,0 @@ logs?: string[]; |
@@ -5,4 +5,5 @@ "use strict"; | ||
class ExecutionError extends Error { | ||
constructor({ msg, cause, logs, transaction, }) { | ||
constructor({ msg, txSignature, cause, logs, transaction, }) { | ||
super(msg); | ||
this.txSignature = txSignature; | ||
this.cause = cause; | ||
@@ -9,0 +10,0 @@ this.logs = logs; |
@@ -1,2 +0,2 @@ | ||
import { Connection, Transaction, VersionedTransactionResponse, SimulatedTransactionResponse, Keypair, Signer, TransactionInstruction, TransactionResponse, PublicKey, SendOptions, VersionedTransaction, Finality } from '@solana/web3.js'; | ||
import { Connection, Transaction, VersionedTransactionResponse, SimulatedTransactionResponse, Keypair, Signer, TransactionInstruction, TransactionResponse, PublicKey, SendOptions, VersionedTransaction, Finality, TransactionSignature } from '@solana/web3.js'; | ||
import { Wallet } from './wallet'; | ||
@@ -22,2 +22,4 @@ import { LoggerPlaceholder } from '@marinade.finance/ts-common'; | ||
export declare function executeTx({ connection, transaction, signers, errMessage, simulate, printOnly, logger, feePayer, sendOpts, confirmOpts, computeUnitLimit, computeUnitPrice, }: ExecuteTxParams): Promise<VersionedTransactionResponse | SimulatedTransactionResponse | undefined>; | ||
export declare function updateTransactionBlockhash(transaction: Transaction, connection: Connection): Promise<Transaction>; | ||
export declare function confirmTransaction(connection: Connection, txSig: TransactionSignature, confirmOpts?: Finality, logger?: LoggerPlaceholder): Promise<VersionedTransactionResponse | undefined>; | ||
export declare function executeTxSimple(connection: Connection, transaction: Transaction, signers?: (Wallet | Keypair | Signer)[], sendOpts?: SendOptions, confirmOpts?: Finality): Promise<VersionedTransactionResponse | SimulatedTransactionResponse | undefined>; | ||
@@ -24,0 +26,0 @@ export declare function executeTxWithExceededBlockhashRetry(txParams: ExecuteTxParams): Promise<VersionedTransactionResponse | SimulatedTransactionResponse | undefined>; |
128
src/tx.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.debugStr = exports.splitAndExecuteTx = exports.filterSignersForInstruction = exports.isVersionedTransaction = exports.isSimulatedTransactionResponse = exports.executeTxWithExceededBlockhashRetry = exports.executeTxSimple = exports.executeTx = exports.transaction = exports.TRANSACTION_SAFE_SIZE = void 0; | ||
exports.debugStr = exports.splitAndExecuteTx = exports.filterSignersForInstruction = exports.isVersionedTransaction = exports.isSimulatedTransactionResponse = exports.executeTxWithExceededBlockhashRetry = exports.executeTxSimple = exports.confirmTransaction = exports.updateTransactionBlockhash = exports.executeTx = exports.transaction = exports.TRANSACTION_SAFE_SIZE = void 0; | ||
const web3_js_1 = require("@solana/web3.js"); | ||
@@ -32,3 +32,3 @@ const wallet_1 = require("./wallet"); | ||
async function executeTx({ connection, transaction, signers = [], errMessage, simulate = false, printOnly = false, logger, feePayer, sendOpts = {}, confirmOpts, computeUnitLimit, computeUnitPrice, }) { | ||
var _a, _b, _c, _d; | ||
var _a, _b; | ||
let result = undefined; | ||
@@ -51,5 +51,3 @@ if (printOnly) { | ||
transaction.feePayer === undefined) { | ||
const currentBlockhash = await connection.getLatestBlockhash(); | ||
transaction.lastValidBlockHeight = currentBlockhash.lastValidBlockHeight; | ||
transaction.recentBlockhash = currentBlockhash.blockhash; | ||
await updateTransactionBlockhash(transaction, connection); | ||
transaction.feePayer = | ||
@@ -78,36 +76,6 @@ (_b = (_a = transaction.feePayer) !== null && _a !== void 0 ? _a : feePayer) !== null && _b !== void 0 ? _b : signers[0].publicKey; | ||
else if (!printOnly) { | ||
let confirmFinality = confirmOpts; | ||
if (confirmFinality === undefined && | ||
(connection.commitment === 'finalized' || | ||
connection.commitment === 'confirmed')) { | ||
confirmFinality = connection.commitment; | ||
} | ||
confirmFinality = confirmFinality || 'confirmed'; | ||
txSig = await connection.sendRawTransaction(transaction.serialize(), sendOpts); | ||
const txSearchConnection = new web3_js_1.Connection(connection.rpcEndpoint, { | ||
commitment: confirmFinality, | ||
}); | ||
let txRes = await txSearchConnection.getTransaction(txSig, { | ||
commitment: confirmFinality, | ||
maxSupportedTransactionVersion: 0, // TODO: configurable? | ||
}); | ||
const confirmBlockhash = connection.getLatestBlockhash(confirmFinality); | ||
while (txRes === null && | ||
(await connection.isBlockhashValid((await confirmBlockhash).blockhash, { | ||
commitment: confirmFinality, | ||
})).value) { | ||
txRes = await txSearchConnection.getTransaction(txSig, { | ||
commitment: confirmFinality, | ||
maxSupportedTransactionVersion: 0, | ||
}); | ||
} | ||
if (txRes === null) { | ||
throw new Error(`Transaction ${txSig} not found, failed to get from ${connection.rpcEndpoint}`); | ||
} | ||
if ((_c = txRes.meta) === null || _c === void 0 ? void 0 : _c.err) { | ||
throw new Error(`Transaction ${txSig} failure, result: ${JSON.stringify(txRes)}`); | ||
} | ||
(0, ts_common_1.logDebug)(logger, 'Transaction signature: ' + txSig); | ||
(0, ts_common_1.logDebug)(logger, (_d = txRes.meta) === null || _d === void 0 ? void 0 : _d.logMessages); | ||
result = txRes; | ||
// retry when not having recent blockhash | ||
txSig = await sendRawTransactionWithRetry(connection, transaction, sendOpts); | ||
// Checking if executed | ||
result = await confirmTransaction(connection, txSig, confirmOpts, logger); | ||
} | ||
@@ -117,3 +85,4 @@ } | ||
throw new error_1.ExecutionError({ | ||
msg: txSig ? `${txSig} ` : '' + errMessage, | ||
txSignature: txSig, | ||
msg: errMessage, | ||
cause: e, | ||
@@ -129,2 +98,74 @@ logs: e.logs | ||
exports.executeTx = executeTx; | ||
async function updateTransactionBlockhash(transaction, connection) { | ||
const currentBlockhash = await connection.getLatestBlockhash(); | ||
transaction.lastValidBlockHeight = currentBlockhash.lastValidBlockHeight; | ||
transaction.recentBlockhash = currentBlockhash.blockhash; | ||
return transaction; | ||
} | ||
exports.updateTransactionBlockhash = updateTransactionBlockhash; | ||
async function sendRawTransactionWithRetry(connection, transaction, sendOpts) { | ||
try { | ||
return await connection.sendRawTransaction(transaction.serialize(), sendOpts); | ||
} | ||
catch (e) { | ||
if ((0, ts_common_1.checkErrorMessage)(e, 'blockhash not found')) { | ||
(0, ts_common_1.logDebug)(undefined, 'Blockhash not found, retrying to update transaction blockhash, reason: ' + | ||
e); | ||
await updateTransactionBlockhash(transaction, connection); | ||
return await connection.sendRawTransaction(transaction.serialize(), sendOpts); | ||
} | ||
else { | ||
throw e; | ||
} | ||
} | ||
} | ||
async function confirmTransaction(connection, txSig, confirmOpts, logger) { | ||
var _a, _b; | ||
let confirmFinality = confirmOpts; | ||
if (confirmFinality === undefined && | ||
(connection.commitment === 'finalized' || | ||
connection.commitment === 'confirmed')) { | ||
confirmFinality = connection.commitment; | ||
} | ||
confirmFinality = confirmFinality || 'confirmed'; | ||
const txSearchConnection = new web3_js_1.Connection(connection.rpcEndpoint, { | ||
commitment: confirmFinality, | ||
}); | ||
(0, ts_common_1.logDebug)(logger, `Waiting to confirm transaction signature: ${txSig} (timeout ~2 minutes)`); | ||
let txRes = await txSearchConnection.getTransaction(txSig, { | ||
commitment: confirmFinality, | ||
maxSupportedTransactionVersion: 0, // TODO: configurable? | ||
}); | ||
const confirmBlockhash = connection.getLatestBlockhash(confirmFinality); | ||
// TODO: waiting time is configured to be reasonable working with public mainnet API | ||
let waitingTime = 3000; | ||
while (txRes === null && | ||
(await connection.isBlockhashValid((await confirmBlockhash).blockhash, { | ||
commitment: confirmFinality, | ||
})).value) { | ||
await (0, ts_common_1.sleep)(waitingTime < 10000 ? (waitingTime += 1000) : waitingTime); | ||
try { | ||
(0, ts_common_1.logDebug)(logger, `Checking outcome of transaction '${txSig}'`); | ||
txRes = await txSearchConnection.getTransaction(txSig, { | ||
commitment: confirmFinality, | ||
maxSupportedTransactionVersion: 0, | ||
}); | ||
} | ||
catch (e) { | ||
if ((0, ts_common_1.checkErrorMessage)(e, 'Too many requests for a specific RPC call')) { | ||
(0, ts_common_1.logDebug)(logger, `Error confirming transaction '${txSig}': ` + e); | ||
} | ||
} | ||
} | ||
if (txRes === null) { | ||
throw new Error(`Transaction ${txSig} not found, failed to get from ${connection.rpcEndpoint}`); | ||
} | ||
if ((_a = txRes.meta) === null || _a === void 0 ? void 0 : _a.err) { | ||
throw new Error(`Transaction ${txSig} failure, result: ${JSON.stringify(txRes)}`); | ||
} | ||
(0, ts_common_1.logDebug)(logger, 'Transaction signature: ' + txSig); | ||
(0, ts_common_1.logDebug)(logger, (_b = txRes.meta) === null || _b === void 0 ? void 0 : _b.logMessages); | ||
return txRes; | ||
} | ||
exports.confirmTransaction = confirmTransaction; | ||
async function executeTxSimple(connection, transaction, signers, sendOpts, confirmOpts) { | ||
@@ -147,2 +188,9 @@ return await executeTx({ | ||
if ((0, ts_common_1.checkErrorMessage)(e, 'block height exceeded')) { | ||
const txSig = e instanceof error_1.ExecutionError && e.txSignature !== undefined | ||
? `${e.txSignature} ` | ||
: ''; | ||
(0, ts_common_1.logDebug)(txParams.logger, `Failed to execute transaction ${txSig}` + | ||
'due to block height exceeded, retrying, ' + | ||
'original error: ' + | ||
e); | ||
txParams.transaction.recentBlockhash = undefined; | ||
@@ -149,0 +197,0 @@ return await executeTx(txParams); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
116992
1686