Created
April 16, 2024 10:38
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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