Solang currently uses Anchor's .view()
to fetch account state from the client. The issue is that when using .view()
in a frontend, it also prompts the wallet to sign a transaction. Is there a way to prevent the connected wallet from being prompted?
import { Button } from "@chakra-ui/react"
import { PublicKey } from "@solana/web3.js"
import { useWallet } from "@solana/wallet-adapter-react"
import { useProgram } from "@/contexts/ProgramContextProvider"
export default function ViewButton() {
const { publicKey } = useWallet()
const { program } = useProgram()
const onClick = async () => {
if (!publicKey || !program) return
const [pda] = PublicKey.findProgramAddressSync(
[Buffer.from("seed"), publicKey.toBuffer()],
program.programId
)
const val = await program.methods
.get()
.accounts({ dataAccount: pda })
.view()
alert(val)
}
return <Button onClick={onClick}>View</Button>
}
The standard way of fetching account data in Anchor using .fetch
currently isn't supported in Solang due to differences in how the account data is encoded (Solang doesn't use borsh).
// Cannot use this approach
const accountData = await program.account.accountType.fetch(address)
For additional context, here is the Solang program:
@program_id("GwnWG8hjzBBnXRtQAmr3Cbo6ShYjv5s6NHTAdsmURXKa")
contract pda_account {
bool private value = true;
@payer(payer) // payer address
@seed("seed") // hardcoded seed
@seed(abi.encode(payer)) // seed from payer address
@bump(bump) // bump seed for pda address
constructor(address payer, bytes bump) {
print("Hello, World!");
}
/// A message that can be called on instantiated contracts.
/// This one flips the value of the stored `bool` from `true`
/// to `false` and vice versa.
function flip() public {
value = !value;
}
/// Simply returns the current value of our `bool`.
function get() public view returns (bool) {
return value;
}
}
The program
instance was set up using useAnchorWallet()
const wallet = useAnchorWallet()
...
// Set up AnchorProvider using the connected wallet
const provider = new AnchorProvider(connection, wallet, {})
setProvider(provider)
// Program Id from IDL
const programId = IDL.metadata.address as unknown as PublicKey
// Create the program instance using the IDL, program ID, and provider
const program = new Program<PdaAccount>(IDL, programId, provider)