Skip to content
Algorand Developer Portal

Suggested Params Configuration

← Back to Algorand Client

This example demonstrates how to configure suggested transaction parameters:

  • setDefaultValidityWindow() to set the number of rounds a transaction is valid
  • setSuggestedParamsCache() to enable/disable caching
  • setSuggestedParamsCacheTimeout() to set cache duration in milliseconds
  • getSuggestedParams() to manually fetch suggested params
  • Performance benefits of caching when sending multiple transactions
  • LocalNet running (via algokit localnet start)

From the repository root:

Terminal window
cd examples
npm run example algorand_client/04-params-config.ts

View source on GitHub

04-params-config.ts
/**
* Example: Suggested Params Configuration
*
* This example demonstrates how to configure suggested transaction parameters:
* - setDefaultValidityWindow() to set the number of rounds a transaction is valid
* - setSuggestedParamsCache() to enable/disable caching
* - setSuggestedParamsCacheTimeout() to set cache duration in milliseconds
* - getSuggestedParams() to manually fetch suggested params
* - Performance benefits of caching when sending multiple transactions
*
* Prerequisites:
* - LocalNet running (via `algokit localnet start`)
*/
import { AlgorandClient, algo } from '@algorandfoundation/algokit-utils';
import {
printError,
printHeader,
printInfo,
printStep,
printSuccess,
shortenAddress,
} from '../shared/utils.js';
async function main() {
printHeader('Suggested Params Configuration Example');
// Initialize client and verify LocalNet is running
const algorand = AlgorandClient.defaultLocalNet();
try {
await algorand.client.algod.status();
printSuccess('Connected to LocalNet');
} catch (error) {
printError(
`Failed to connect to LocalNet: ${error instanceof Error ? error.message : String(error)}`,
);
printInfo('Make sure LocalNet is running (e.g., algokit localnet start)');
return;
}
// Step 1: Understanding suggested params
printStep(1, 'Understanding suggested params');
printInfo('Suggested params contain network information needed for transactions:');
printInfo(' - firstValid: The first round the transaction is valid');
printInfo(' - lastValid: The last round the transaction is valid (set during tx building)');
printInfo(' - genesisHash: The hash of the genesis block');
printInfo(' - genesisId: The network identifier (e.g., "localnet-v1")');
printInfo(' - fee: The minimum transaction fee');
printInfo(' - minFee: The minimum fee per byte');
const params = await algorand.getSuggestedParams();
printInfo(`\nCurrent suggested params from LocalNet:`);
printInfo(` firstValid: ${params.firstValid}`);
printInfo(` genesisId: ${params.genesisId}`);
printInfo(` fee: ${params.fee} microALGO`);
printInfo(` minFee: ${params.minFee} microALGO`);
printSuccess('Retrieved suggested params from LocalNet');
// Step 2: Default validity window behavior
printStep(2, 'Understand default validity window behavior');
printInfo('The validity window determines: lastValid = firstValid + validityWindow');
printInfo('Default is 10 rounds, but LocalNet uses 1000 rounds for convenience');
printInfo('This is set during transaction building, not in suggested params');
// Create accounts for demonstrating transactions
const dispenser = await algorand.account.dispenserFromEnvironment();
const sender = algorand.account.random();
const receiver = algorand.account.random();
// Fund the sender
await algorand.send.payment({
sender: dispenser.addr,
receiver: sender.addr,
amount: algo(10),
});
printInfo(`\nSender: ${shortenAddress(sender.addr.toString())}`);
printInfo(`Receiver: ${shortenAddress(receiver.addr.toString())}`);
// Send a transaction and inspect its validity window
const txResult = await algorand.send.payment({
sender: sender.addr,
receiver: receiver.addr,
amount: algo(0.1),
note: 'Transaction 1',
});
// Access the transaction directly from the result
const tx = txResult.transactions[0];
printInfo(`\nTransaction built with LocalNet default:`);
printInfo(` firstValid: ${tx.firstValid}`);
printInfo(` lastValid: ${tx.lastValid}`);
printInfo(` Validity window: ${Number(tx.lastValid - tx.firstValid)} rounds (LocalNet default)`);
printSuccess('Demonstrated default validity window');
// Step 3: Set custom validity window
printStep(3, 'Demonstrate setDefaultValidityWindow()');
printInfo('Use setDefaultValidityWindow() to override the default validity window');
printInfo('This affects all transactions built by this client');
// Create a new client with custom validity window
const algorandCustom = AlgorandClient.defaultLocalNet().setDefaultValidityWindow(50);
algorandCustom.setSignerFromAccount(sender);
const txResultCustom = await algorandCustom.send.payment({
sender: sender.addr,
receiver: receiver.addr,
amount: algo(0.1),
note: 'Transaction with custom validity',
});
// Access the transaction directly from the result
const txCustom = txResultCustom.transactions[0];
printInfo(`\nTransaction built with setDefaultValidityWindow(50):`);
printInfo(` firstValid: ${txCustom.firstValid}`);
printInfo(` lastValid: ${txCustom.lastValid}`);
printInfo(` Validity window: ${Number(txCustom.lastValid - txCustom.firstValid)} rounds`);
printSuccess('Demonstrated custom validity window');
// Step 4: When to use different validity windows
printStep(4, 'When to use longer vs shorter validity windows');
printInfo('');
printInfo('Shorter validity windows (5-10 rounds):');
printInfo(' - High-frequency trading applications');
printInfo(' - When you want quick transaction expiration');
printInfo(' - Reduces risk of delayed/stale transactions being confirmed');
printInfo('');
printInfo('Longer validity windows (100-1000 rounds):');
printInfo(' - Batch operations with many transactions');
printInfo(' - When network congestion is expected');
printInfo(' - When user confirmation takes time');
printInfo(' - Offline signing scenarios');
printSuccess('Explained validity window use cases');
// Step 5: Suggested params caching basics
printStep(5, 'Demonstrate getSuggestedParams() caching');
printInfo('getSuggestedParams() caches results to avoid repeated network calls');
printInfo('Default cache timeout is 3 seconds (3000ms)');
// Create a fresh client to demonstrate caching
const algorandCache = AlgorandClient.defaultLocalNet();
// Demonstrate that the cache is working
printInfo('\nFetching params twice in quick succession...');
const startTime1 = Date.now();
await algorandCache.getSuggestedParams();
const duration1 = Date.now() - startTime1;
const startTime2 = Date.now();
await algorandCache.getSuggestedParams();
const duration2 = Date.now() - startTime2;
printInfo(` First call: ~${duration1}ms (includes network fetch)`);
printInfo(` Second call: ~${duration2}ms (from cache)`);
printSuccess('Demonstrated params caching');
// Step 6: Configure cache timeout
printStep(6, 'Demonstrate setSuggestedParamsCacheTimeout()');
printInfo('Use setSuggestedParamsCacheTimeout() to set how long params are cached');
printInfo('Value is in milliseconds');
// Create a client with longer cache timeout
const algorandLongCache = AlgorandClient.defaultLocalNet().setSuggestedParamsCacheTimeout(60_000);
printInfo('\nWith setSuggestedParamsCacheTimeout(60_000): 60 second cache');
printInfo('Good for: High-throughput apps sending many transactions quickly');
// Create a client with shorter cache timeout
const algorandShortCache = AlgorandClient.defaultLocalNet().setSuggestedParamsCacheTimeout(500);
printInfo('With setSuggestedParamsCacheTimeout(500): 0.5 second cache');
printInfo('Good for: Apps that need the most current round information');
// Fetch to demonstrate they work
await algorandLongCache.getSuggestedParams();
await algorandShortCache.getSuggestedParams();
printSuccess('Demonstrated cache timeout configuration');
// Step 7: Manual cache control with setSuggestedParamsCache()
printStep(7, 'Demonstrate setSuggestedParamsCache()');
printInfo('Use setSuggestedParamsCache() to manually set cached params');
printInfo('Useful when you already have params from another source');
// Get params and set them in a new client
const cachedParams = await algorand.getSuggestedParams();
const algorandCached = AlgorandClient.defaultLocalNet();
// Set cache with explicit expiry
const cacheExpiry = new Date(Date.now() + 30_000); // 30 seconds from now
algorandCached.setSuggestedParamsCache(cachedParams, cacheExpiry);
printInfo(`\nSet cached params with expiry: ${cacheExpiry.toISOString()}`);
printInfo('Now getSuggestedParams() will return cached value without network call');
// Verify the cache is being used
const startCached = Date.now();
const fromCache = await algorandCached.getSuggestedParams();
const durationCached = Date.now() - startCached;
printInfo(`Retrieved from cache in ~${durationCached}ms`);
printInfo(`Cached firstValid: ${fromCache.firstValid}`);
printSuccess('Demonstrated manual cache setting');
// Step 8: Performance benefit with multiple transactions
printStep(8, 'Show performance benefit of caching with multiple transactions');
printInfo('When sending many transactions, caching reduces network calls');
printInfo('Each transaction needs suggested params to set validity window');
// Send 5 transactions with unique notes and measure time
const numTransactions = 5;
printInfo(`\nSending ${numTransactions} transactions with caching enabled (default)...`);
const startWithCache = Date.now();
for (let i = 0; i < numTransactions; i++) {
await algorand.send.payment({
sender: sender.addr,
receiver: receiver.addr,
amount: algo(0.01),
note: `Performance test transaction ${i + 1} at ${Date.now()}`,
});
}
const durationWithCache = Date.now() - startWithCache;
printInfo(` Total time: ${durationWithCache}ms`);
printInfo(` Average per transaction: ${(durationWithCache / numTransactions).toFixed(0)}ms`);
printInfo(' Note: Params are fetched once and cached for subsequent transactions');
printSuccess('Demonstrated caching performance benefit');
// Step 9: Method chaining
printStep(9, 'Method chaining - Configure params fluently');
printInfo('All configuration methods return the AlgorandClient for chaining');
const configuredClient = AlgorandClient.defaultLocalNet()
.setDefaultValidityWindow(25)
.setSuggestedParamsCacheTimeout(10_000)
.setSignerFromAccount(sender);
printInfo(`\nConfigured client with:`);
printInfo(` .setDefaultValidityWindow(25)`);
printInfo(` .setSuggestedParamsCacheTimeout(10_000)`);
printInfo(` .setSignerFromAccount(sender)`);
// Send a transaction to verify the configuration
const chainedTxResult = await configuredClient.send.payment({
sender: sender.addr,
receiver: receiver.addr,
amount: algo(0.01),
note: 'Chained config test',
});
// Access the transaction directly from the result
const chainedTx = chainedTxResult.transactions[0];
printInfo(
`\nResulting transaction validity window: ${Number(chainedTx.lastValid - chainedTx.firstValid)} rounds`,
);
printSuccess('Demonstrated method chaining');
// Step 10: Summary
printStep(10, 'Summary');
printInfo('Suggested params configuration methods:');
printInfo('');
printInfo('getSuggestedParams():');
printInfo(' - Returns cached params or fetches from network');
printInfo(' - Automatically manages cache expiry');
printInfo(' - Use for manual param inspection or custom transactions');
printInfo('');
printInfo('setDefaultValidityWindow(rounds):');
printInfo(' - Sets how many rounds a transaction stays valid');
printInfo(' - Default is 10 rounds (1000 for LocalNet)');
printInfo(' - Affects lastValid = firstValid + validityWindow');
printInfo('');
printInfo('setSuggestedParamsCacheTimeout(milliseconds):');
printInfo(' - Sets how long params are cached before refresh');
printInfo(' - Default is 3000ms (3 seconds)');
printInfo(' - Longer = fewer network calls, possibly stale data');
printInfo(' - Shorter = more network calls, fresher data');
printInfo('');
printInfo('setSuggestedParamsCache(params, until?):');
printInfo(' - Manually sets cached params');
printInfo(' - Optional expiry date (defaults to timeout)');
printInfo(' - Useful when you have params from another source');
printInfo('');
printInfo('Best practices:');
printInfo(' - Use default settings for most applications');
printInfo(' - Increase cache timeout for high-throughput apps');
printInfo(' - Use shorter validity windows for time-sensitive transactions');
printInfo(' - Use longer validity windows for batch operations');
printSuccess('Suggested Params Configuration example completed!');
}
main().catch(error => {
printError(`Unhandled error: ${error instanceof Error ? error.message : String(error)}`);
process.exit(1);
});