-
-
Notifications
You must be signed in to change notification settings - Fork 31
Description
Discussed in https://github.com/orgs/sol4k/discussions/122
Originally posted by drgimenez February 4, 2025
Hi Sol4K Team,
I am currently integrating Sol4K into a project where I am implementing a bridge using Circle’s CCTP. As part of this, I need to call the depositForBurn(...) method of the TokenMessengerMinter program.
This method requires at least two accounts to be passed as signers in the transaction. However, I am encountering signature verification failures when attempting to include multiple signers.
What i have
- I have constructed the transaction using TransactionMessage.newMessage(...) with feePayer signer.
- I have called transaction.sign(signer); with each account that was included as a signer in the instructions or only with the fee payer and none of the forms worked.
Question
What is the correct way to include multiple signers in a Sol4K transaction when invoking a smart contract method that requires multiple signers?
Here is the relevant portion of my code:
signer1 = Keypair.fromSecretKey(Base58.decode(SIGNER_PRIVATE_KEY));
signer2 = Keypair.generate();
ProgramDerivedAddress authorityPda = PublicKey.findProgramAddress(sender_authority_seed, tokenMessengerMinter_program);
ProgramDerivedAddress messageTransmitterAccount = PublicKey.findProgramAddress(message_transmitter_seed, messageTransmitter_program);
ProgramDerivedAddress tokenMessengerAccount = PublicKey.findProgramAddress(token_messenger_seed, tokenMessengerMinter_program);
ProgramDerivedAddress remoteTokenMessengerKey = PublicKey.findProgramAddress(remote_token_messenger_seed, tokenMessengerMinter_program);
ProgramDerivedAddress tokenMinterAccount = PublicKey.findProgramAddress(token_minter_seed, tokenMessengerMinter_program);
ProgramDerivedAddress localToken = PublicKey.findProgramAddress(local_token_seed, tokenMessengerMinter_contract_address);
ProgramDerivedAddress eventAuthorityPda = PublicKey.findProgramAddress(__event_authority_seed, tokenMessengerMinter_program);
List<AccountMeta> accounts = List.of(
AccountMeta.signerAndWritable(signer1.getPublicKey()),
AccountMeta.signerAndWritable(signer1.getPublicKey()),
AccountMeta.writable(authorityPda.getPublicKey()),
AccountMeta.writable(associatedTokenAccount),
AccountMeta.writable(messageTransmitterAccount.getPublicKey()),
AccountMeta.writable(tokenMessengerAccount.getPublicKey()),
AccountMeta.writable(remoteTokenMessengerKey.getPublicKey()),
AccountMeta.writable(tokenMinterAccount.getPublicKey()),
AccountMeta.writable(localToken.getPublicKey()),
AccountMeta.writable(usdc_contract_address),
AccountMeta.signerAndWritable(signer2.getPublicKey()), // <== This is the second signer that I must include
AccountMeta.writable(messageTransmitter_contract_address),
AccountMeta.writable(tokenMessengerMinter_contract_address),
AccountMeta.writable(token_program),
AccountMeta.writable(system_program),
AccountMeta.writable(eventAuthorityPda.getPublicKey()),
AccountMeta.writable(tokenMessengerMinter_contract_address)
);
String blockHash = nodeProvider.getLatestBlockhash();
ByteBuffer instructionData = ByteBuffer.allocate(52);
data.put(getFunctionDiscriminator("deposit_for_burn"));
data.putLong(Long.reverseBytes(amount));
data.putInt(Integer.reverseBytes(destinationDomain));
data.put(mintRecipient.bytes());
Instruction instruction = new org.sol4k.instruction.BaseInstruction(
instructionData.array(),
accounts,
tokenMessengerMinter_program
);
TransactionMessage transactionMessage = TransactionMessage.newMessage(
signer1.getPublicKey(),
blockHash,
instruction
);
VersionedTransaction transaction = new VersionedTransaction(transactionMessage);
transaction.sign(signer1);
//transaction.sign(signer2);
String transactionHash = connection.sendTransaction(transaction.serialize());
//String transactionHash = connection.sendTransaction(transaction);
System.out.println("transaction Hash: " + transactionHash);Errors I have received:
SerializationException(message=Signature verification failed) at org.sol4k.VersionedTransaction.serialize(VersionedTransaction.kt:38)at lineString transactionHash = nodeProvider.sendTransaction(transaction.serialize());java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302) at java.base/java.util.Objects.checkIndex(Objects.java:365) at java.base/java.util.ArrayList.set(ArrayList.java:471) at org.sol4k.VersionedTransaction.sign(VersionedTransaction.kt:29)If I enable the linetransaction.sign(signer2);
I apologize if this is a basic question, but I am still new to Solana and Sol4K. Any guidance on the correct approach to include both required signers correctly would be greatly appreciated.
Thank you for your time and assistance!