Set Custom Gas Params¶
This guide shows how to calculate and set custom gas params in DataHaven. The StorageHub SDK already dynamically computes the necessary gas params, but you can set custom values if needed. The createBucket method will be used as an example, but the same approach applies to any SDK method that involves an on-chain transaction.
Prerequisites¶
- Node.js v22+ installed
-
A TypeScript project
Need a starter project?
If you don't have an existing project, follow these steps to create a TypeScript project you can use to follow the guides in this section:
-
Create a new project folder by executing the following command in the terminal:
-
Initialize a
package.jsonfile using the correct command for your package manager: -
Add the TypeScript and Node type definitions to your projects using the correct command for your package manager:
-
Create a
tsconfig.jsonfile in the root of your project and paste the following configuration: -
Initialize the
srcdirectory:
-
-
Implemented the
createBuckethelper method from the Create a Bucket guide
Initialize the Script¶
Create an index.ts file if you haven't already. Its run method will orchestrate all the logic in this guide. By now, your services folder (including the MSP and client helper services) should already be created, along with the operations folder containing bucket operations helper methods, which means you should already have the createBucket helper method implemented. If not, see the Get Started guide and the Create a bucket guide.
Add the following code to your index.ts file:
import '@storagehub/api-augment';
import { initWasm } from '@storagehub-sdk/core';
import { polkadotApi } from './services/clientService.js';
import { createBucket } from './operations/bucketOperations.js';
async function run() {
// For anything from @storagehub-sdk/core to work, initWasm() is required
// on top of the file
await initWasm();
// --- Bucket creating logic ---
// Create a bucket
const bucketName = 'init-bucket';
const { bucketId, txReceipt } = await createBucket(bucketName);
console.log(`Created Bucket ID: ${bucketId}`);
console.log(`createBucket() txReceipt: ${txReceipt}`);
// Disconnect the Polkadot API at the very end
await polkadotApi.disconnect();
}
await run();
In this code, the createBucket helper method from bucketOperations.ts is called. Once all params are ready within this method, the SDK's storageHubClient.createBucket method is called:
...
// Create bucket on chain
const txHash: `0x${string}` | undefined = await storageHubClient.createBucket(
mspId as `0x${string}`,
bucketName,
isPrivate,
valuePropId
);
...
Through this method, an on-chain transaction is executed with a gas amount dynamically set by the SDK. To pass custom values, an extra gasTxOpts param, of type EvmWriteOptions (imported from @storagehub-sdk/core), can be passed at the end of the param list, like so:
...
// Create bucket on chain
const txHash: `0x${string}` | undefined = await storageHubClient.createBucket(
mspId as `0x${string}`,
bucketName,
isPrivate,
valuePropId,
gasTxOpts
);
...
The EvmWriteOptions type has the following structure:
type EvmWriteOptions = {
// Explicit gas limit. If omitted, the SDK will estimate and multiply.
// It's computed with an estimation from the contract call and a multiplier.
gas?: bigint;
// Multiplier applied over the SDK gas estimate when `gas` is not supplied.
// Defaults to 5.
gasMultiplier?: number;
// Deprecated - do not use - Legacy gas price (wei)
// StorageHub SDK is moving to EIP-1559 only. This field is ignored by the SDK.
// Use `maxFeePerGas` and `maxPriorityFeePerGas` instead.
gasPrice?: bigint;
// EIP-1559: max fee per gas (wei). Use with `maxPriorityFeePerGas`.
// maxFeePerGas = baseFeePerGas * safeMarginMultiplier + maxPriorityFeePerGas
maxFeePerGas?: bigint;
// EIP-1559: max priority fee per gas (wei).
// The tip paid to validators and should be increased under network congestion.
maxPriorityFeePerGas?: bigint;
};
In the following section, you will learn how to set and calculate these gas values within the EvmWriteOptions type.
Add Method to Set Gas Fees¶
To create the buildGasTxOpts helper method, follow these steps:
-
Create a
txOperations.tsfile within theoperationsfolder. -
Add the following code:
txOperations.tsimport { EvmWriteOptions } from '@storagehub-sdk/core'; import { publicClient } from '../services/clientService.js'; // Build custom gas transaction options export async function buildGasTxOpts(): Promise<EvmWriteOptions> { const gas = BigInt('1500000'); // EIP-1559 fees based on latest block const latestBlock = await publicClient.getBlock({ blockTag: 'latest' }); const baseFeePerGas = latestBlock.baseFeePerGas; if (baseFeePerGas == null) { throw new Error( 'RPC did not return baseFeePerGas for the latest block. Cannot build EIP-1559 fees.', ); } const maxPriorityFeePerGas = BigInt('1500000000'); // 1.5 gwei // maxFeePerGas = baseFeePerGas * safeMarginMultiplier + maxPriorityFeePerGas // safeMarginMultiplier should be some value that protects you from fee spikes (e.g., 1.5x or 2x) const maxFeePerGas = baseFeePerGas * BigInt(2) + maxPriorityFeePerGas; return { gas, maxFeePerGas, maxPriorityFeePerGas }; }
Update Create Bucket Method¶
To update your existing createBucket helper method within your bucketOperations.ts file to include the gasTxOpts calculation, follow these steps:
-
Add this line to your imports:
-
Trigger the
buildGasTxOptsmethod right before calling the SDK'sstorageHubClient.createBucketmethod and add thegasTxOptsparam at the end of the param list, like so:
View complete bucketOperations.ts file
import {
storageHubClient,
address,
publicClient,
polkadotApi,
} from '../services/clientService.js';
import { getMspInfo, getValueProps } from '../services/mspService.js';
import { buildGasTxOpts } from './txOperations.js';
export async function createBucket(bucketName: string) {
// Get basic MSP information from the MSP including its ID
const { mspId } = await getMspInfo();
// Choose one of the value props retrieved from the MSP through the helper function
const valuePropId = await getValueProps();
console.log(`Value Prop ID: ${valuePropId}`);
// Derive bucket ID
const bucketId = (await storageHubClient.deriveBucketId(
address,
bucketName,
)) as string;
console.log(`Derived bucket ID: ${bucketId}`);
// Check that the bucket doesn't exist yet
const bucketBeforeCreation =
await polkadotApi.query.providers.buckets(bucketId);
console.log('Bucket before creation is empty', bucketBeforeCreation.isEmpty);
if (!bucketBeforeCreation.isEmpty) {
throw new Error(`Bucket already exists: ${bucketId}`);
}
const isPrivate = false;
const gasTxOpts = await buildGasTxOpts();
// Create bucket on chain
const txHash: `0x${string}` | undefined = await storageHubClient.createBucket(
mspId as `0x${string}`,
bucketName,
isPrivate,
valuePropId,
gasTxOpts,
);
console.log('createBucket() txHash:', txHash);
if (!txHash) {
throw new Error('createBucket() did not return a transaction hash');
}
// Wait for transaction receipt
const txReceipt = await publicClient.waitForTransactionReceipt({
hash: txHash,
});
if (txReceipt.status !== 'success') {
throw new Error(`Bucket creation failed: ${txHash}`);
}
return { bucketId, txReceipt };
}
Run Create Bucket Script¶
Execute the createBucket method by running the script:
Upon successful execution, it should return an expected bucket-creation response like this:
Next Steps¶
| Created: January 29, 2026