Skip to content

Commit 4347c7a

Browse files
committed
Add preflight check for error
1 parent ef7c68e commit 4347c7a

File tree

5 files changed

+53
-1
lines changed

5 files changed

+53
-1
lines changed

packages/gill-extra/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ export * from "./get-solscan-explorer-link.js";
1313
export * from "./ixs/index.js";
1414
export * from "./poll-confirm-transaction.js";
1515
export * from "./transaction.js";
16+
export * from "./transaction-error.js";
1617
export * from "./types.js";
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type { TransactionError } from "@solana/kit";
2+
import { getSolanaErrorFromTransactionError } from "@solana/kit";
3+
4+
export const parseTransactionError = (
5+
err: TransactionError,
6+
logs: string[] | null,
7+
): string => {
8+
// First, try to extract Anchor error from logs
9+
const anchorError = [...(logs ?? [])]
10+
.reverse()
11+
.find((log) => log.includes("AnchorError"));
12+
13+
if (anchorError) {
14+
const errorMessageStart = anchorError.indexOf("Error Message: ");
15+
if (errorMessageStart !== -1) {
16+
return anchorError.slice(errorMessageStart + 15).trim();
17+
}
18+
}
19+
20+
const solanaError = getSolanaErrorFromTransactionError(err);
21+
return solanaError.message;
22+
};

packages/gill-extra/src/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ export interface SendTXOptions
2424
* @default true
2525
*/
2626
waitForAccountRefetch?: boolean;
27+
/**
28+
* If true, skips the pre-flight simulation.
29+
*/
30+
skipPreflight?: boolean;
2731
}
2832

2933
export type SendTXFunction = (

packages/grill/src/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ export type TransactionStatusEvent = {
3535
sig: Signature;
3636
explorerLink: string;
3737
}
38+
| {
39+
type: "error-simulation-failed";
40+
errorMessage: string;
41+
}
3842
);
3943

4044
export type TransactionStatusEventCallback = (

packages/grill/src/utils/internal/create-send-tx.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ import type { SolanaClient } from "gill";
1414
import type { TransactionStatusEvent } from "../../types.js";
1515
import {
1616
getSignatureFromBytes,
17+
parseTransactionError,
1718
pollConfirmTransaction,
1819
} from "@macalinao/gill-extra";
1920
import {
2021
compressTransactionMessageUsingAddressLookupTables,
22+
getSolanaErrorFromTransactionError,
2123
signAndSendTransactionMessageWithSigners,
2224
} from "@solana/kit";
23-
import { createTransaction } from "gill";
25+
import { createTransaction, simulateTransactionFactory } from "gill";
2426

2527
export interface CreateSendTXParams {
2628
signer: TransactionSendingSigner | null;
@@ -41,6 +43,7 @@ export const createSendTX = ({
4143
onTransactionStatusEvent,
4244
getExplorerLink,
4345
}: CreateSendTXParams): SendTXFunction => {
46+
const simulateTransaction = simulateTransactionFactory({ rpc });
4447
return async (
4548
name: string,
4649
ixs: readonly Instruction[],
@@ -84,6 +87,24 @@ export const createSendTX = ({
8487
)
8588
: transactionMessage;
8689

90+
// preflight
91+
if (!options.skipPreflight) {
92+
const simulationResult = await simulateTransaction(
93+
finalTransactionMessage,
94+
);
95+
if (simulationResult.value.err) {
96+
onTransactionStatusEvent({
97+
...baseEvent,
98+
type: "error-simulation-failed",
99+
errorMessage: parseTransactionError(
100+
simulationResult.value.err,
101+
simulationResult.value.logs,
102+
),
103+
});
104+
throw getSolanaErrorFromTransactionError(simulationResult.value.err);
105+
}
106+
}
107+
87108
onTransactionStatusEvent({
88109
...baseEvent,
89110
type: "awaiting-wallet-signature",

0 commit comments

Comments
 (0)