I'm building a transaction on devnet that previously worked when I tested my program. I don't think it's the program itself, but how I am passing down the signatures which is slightly different from what I was doing in the test.ts file where I used this to sign all of the transactions...const ownerWallet = provider.wallet as anchor.Wallet;
I'm not using a provider clientside, just passing down the program ID as a string to the PDA using new PublicKey()
. I'm creating 3 PDA accounts, 2 of which use the signer publicKey as part of the seed. The last one is meant to be a PDA that isn't controlled by the person creating the game account (hence the absence of the wallet.publicKey.
However, I'm getting an error that says, Signature Verification Failed: Missing Signature for <the wallet publicKey I'm using>
which seems odd because I'm using await wallet?.signTransaction(tx);
at the bottom within the try-catch.
export const useGameBuilder = () => {
const PROGRAM_ID = new PublicKey('<ProgramIDHere>')
const initializeGame = async (wallet: any, connection: Connection): Promise<void> => {
if (!wallet) return;
let [gameAcctPDA] = web3.PublicKey.findProgramAddressSync(
[Buffer.from( "game" ), wallet.publicKey!.toBuffer()],
PROGRAM_ID
);
console.log('gameAcct: ', gameAcctPDA.toString());
let [wordVaultAcctPDA] = web3.PublicKey.findProgramAddressSync(
[Buffer.from("vault"), wallet.publicKey!.toBuffer()],
PROGRAM_ID
);
console.log('wordVaultAcct: ', wordVaultAcctPDA.toString())
let [moneyVaultAcctPDA, bump] = web3.PublicKey.findProgramAddressSync(
[Buffer.from("pot")],
PROGRAM_ID
);
console.log('moneyVaultAcct: ', moneyVaultAcctPDA.toString())
const gameAccounts: InitializeCreateGameInstructionAccounts = {
game: gameAcctPDA,
wordVault: wordVaultAcctPDA,
moneyPotVault: moneyVaultAcctPDA,
owner: wallet.publicKey!
}
const gameCreationArgs: InitializeCreateGameInstructionArgs = {
name: 'TestVerse',
minDeposit: 0.1
}
const transactionInstruction = createInitializeCreateGameInstruction(gameAccounts, gameCreationArgs);
try {
const tx = new Transaction().add(transactionInstruction);
tx!.feePayer = wallet!.publicKey!;
const latestBlockhash = await connection.getLatestBlockhash();
tx.recentBlockhash = latestBlockhash.blockhash;
await wallet?.signTransaction(tx);
// Serialize and send the transaction
const signedTx = tx!.serialize();
const txId = await connection.sendRawTransaction(signedTx);
console.log('Transaction ID:', txId);
} catch (error) {
console.log('error creating game', error);
}
};
return { initializeGame };
};
I don't think I need to use partialSign here but I could be wrong. I'm not explicitly creating the accounts in the transaction. I'm passing the wallet from phantom that I'm using with useWallet
to be the owner/signer of the instruction and to be used as the seed phrase when the accounts as created. Not sure why it's saying it's missing the signature for the publicKey of the wallet I'm trying to sign with though since I'm running await wallet?.signTransaction(tx);
I also get the amount of the transaction in the Phantom wallet. So I know part of it is working. Tell me it costs 0.0039 SOL
EDIT: Ok this works. I just pass in the wallet seed manually and create a Signer, I'd still like to get it working with a wallet though.
const initializeGame = async (wallet: AnchorWallet, connection: Connection): Promise<void> => {
if (!wallet) return;
const seed = new Uint8Array([numbers here])
const keypair = Keypair.fromSecretKey(seed)
const sign: Signer = {
publicKey: keypair.publicKey,
secretKey: seed
}
let [gameAcctPDA] = web3.PublicKey.findProgramAddressSync(
[Buffer.from( "game" ), keypair.publicKey.toBuffer()],
PROGRAM_ID
);
console.log('gameAcct: ', gameAcctPDA.toString());
let [wordVaultAcctPDA] = web3.PublicKey.findProgramAddressSync(
[Buffer.from("word"), keypair.publicKey.toBuffer()],
PROGRAM_ID
);
console.log('wordVaultAcct: ', wordVaultAcctPDA.toString())
let [moneyVaultAcctPDA, bump] = web3.PublicKey.findProgramAddressSync(
[Buffer.from("pot")],
PROGRAM_ID
);
console.log('moneyVaultAcct: ', moneyVaultAcctPDA.toString())
const gameAccounts: InitializeCreateGameInstructionAccounts = {
game: gameAcctPDA,
wordVault: wordVaultAcctPDA,
moneyPotVault: moneyVaultAcctPDA,
owner: sign.publicKey
}
const gameCreationArgs: InitializeCreateGameInstructionArgs = {
name: 'TestVerse',
minDeposit: 0.1
}
const transactionInstruction = createInitializeCreateGameInstruction(gameAccounts, gameCreationArgs);
try {
const tx = new Transaction().add(transactionInstruction);
tx!.feePayer = sign!.publicKey!;
const latestBlockhash = await connection.getLatestBlockhash();
tx.recentBlockhash = latestBlockhash.blockhash;
tx!.sign(sign);
// await wallet?.signTransaction(tx);
// Serialize and send the transaction
const signedTx = tx!.serialize();
const txId = await connection.sendRawTransaction(signedTx);
console.log('Transaction ID:', txId);
} catch (error) {
console.log('error creating game', error);
}
};
return { initializeGame };