Skip to content

Instantly share code, notes, and snippets.

@zikyfranky
Created April 16, 2024 10:38
Show Gist options
  • Save zikyfranky/da0117a0e587899e39ffea10255abc1f to your computer and use it in GitHub Desktop.
Save zikyfranky/da0117a0e587899e39ffea10255abc1f to your computer and use it in GitHub Desktop.
This is a snippet to have anchor view function not trigger wallet confirmation
async readOnly(instruction: TransactionInstruction, instructionName: string): Promise<{ value: any }> {
// Filter through your IDL to get the actual read instruction schema and return type
const ixx = IDL.instructions.find((i) => i.name == instructionName);
// This checks if the instruction contains Mutable account, if it does, then it isn't a read only instruction
const isMut = ixx && [...ixx.accounts].find((a: any) => a.isMut);
const returnType = ixx && (ixx as any).returns;
if (isMut || !returnType) return { value: null }; // basically return null value if ix is mutable or it doesn't contain a return type
const { blockhash } = await this.connection.getLatestBlockhash(); // Fetch recent block
const msg = new TransactionMessage({
instructions: [instruction],
payerKey: this.wallet.publicKey,
recentBlockhash: blockhash,
}).compileToV0Message();
const tx = new VersionedTransaction(msg);
// Simulate tx (This wouldn't ask for the pop up confirmation)
const sim = await this.connection.simulateTransaction(tx);
if (sim.value.err) {
// Handle Error
throw new Error("Error");
}
let base64: Buffer | null = null;
if (sim.value.returnData?.data) {
base64 = decode(sim.value.returnData.data[0]); // get the base64 of your return value
} else {
// Read through all the transaction logs.
const returnPrefix = `Program return: ${this.program.programId} `;
const returnLogEntry = sim.value.logs!.find((log) =>
log.startsWith(returnPrefix)
);
if (returnLogEntry) {
base64 = decode(returnLogEntry.slice(returnPrefix.length)); // get the base64 of your return value
}
}
if (!base64) return { value: null }; // if it doesn't exist, return null as well
const coder = IdlCoder.fieldLayout(
{ type: returnType },
Array.from([...(IDL.accounts ?? [])])
);
return { value: coder.decode(base64) }; // convert the base64 to the correct return type
}
// Returns a "viewFunction" instruction instead of an actual value
const ix = await program.methods.viewFunction().accounts({}).view();
const returnValue = await readOnly(ix, "viewFunction");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment