When we do sendTransactionAsync at frontend it asks for a signature to perform the transaction. Now in my predicate code i am recovering the sender address with ec_recover_address but it throws OutOfGas error as i am not able to recover the address because the sendTransactionAsync did not add any witness. When we log the transaction request there is only one witness of [0,0,0,0,0,0,0,0,0] which breaks the transaction.
To reproduce: Just do verify_signature in a predicate and do the transaction using either sendTransaction or sendTransactionAsync.
Hi @Akash could you provide some more context on what you are trying to accomplish here? The sender of a transaction normally signs that transaction themselves and thus proves the authenticity of the transaction.
If the wallet is unlocked then of course you can add an account witness yourself (although you shouldn’t need to) but I suspect you are interacting with a locked wallet.
yes you are right i am using a locked wallet. fuel wallet extension to be precise. when im doing any transaction from frontend side i want to verify the signature of the transaction to recover the wallet address of the transactor in predicate and verify with one of my configurables which is in my case an authorized user address and only he should be able to make the transaction. thats why i need to add a signature for the transaction but i think the wallet should add it itself while signing the transaction request. any insights on this?
It seems to me that you may be doing things in a rather obtuse manner, if you are using the wallet connector why not just retrieve the wallet address of the transactor via getAddress
and then pass it to the predicate that way?
To interact with a locked wallet via connectors and pass the wallet address to the predicate, you can follow these steps:
- Connect to the wallet using a connector.
- Retrieve the wallet address.
- Pass the wallet address to the predicate.
Here’s an example of how you can achieve this:
Step 1: Connect to the Wallet Using a Connector
First, ensure you have set up the connector and connected to the wallet.
import { Provider, Wallet, WalletLocked, Predicate } from 'fuels-ts';
import { Connector } from 'fuels-ts/wallets/connectors';
// Setup the provider
const provider = await Provider.create('https://testnet.fuel.network');
// Initialize the connector (example using a hypothetical connector)
const connector = new Connector(provider);
await connector.connect();
// Get the locked wallet
const lockedWallet = new WalletLocked(connector);
Step 2: Retrieve the Wallet Address
Retrieve the address of the connected wallet.
const walletAddress = await lockedWallet.getAddress();
console.log('Wallet Address:', walletAddress);
Step 3: Pass the Wallet Address to the Predicate
Use the retrieved wallet address as a parameter for the predicate.
const validSenderAddress = walletAddress;
// Define the predicate with the configurable constant
const configurable = { VALID_SENDER: validSenderAddress };
const predicate = new Predicate<[string]>({
bytecode: ValidSenderPredicate.bytecode,
provider: lockedWallet.provider,
abi: ValidSenderPredicate.abi,
data: [configurable.VALID_SENDER],
configurableConstants: configurable,
});
// Transfer funds to the predicate
const tx1 = await lockedWallet.transfer(predicate.address, 200_000, provider.getBaseAssetId(), {
gasLimit: 1000,
});
await tx1.waitForResult();
const destinationWallet = WalletUnlocked.generate({
provider: lockedWallet.provider,
});
const amountToTransfer = 100;
// Transfer funds from the predicate to the destination if the predicate returns true
const tx2 = await predicate.transfer(
destinationWallet.address,
amountToTransfer,
provider.getBaseAssetId(),
{
gasLimit: 1000,
}
);
await tx2.waitForResult();
This code connects to a locked wallet using a connector, retrieves the wallet address, and passes it to the predicate for validation.
For more information on connectors, you can refer to the Connectors documentation.