Suggested Params Configuration
Description
Section titled “Description”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
Section titled “Prerequisites”- LocalNet running (via
algokit localnet start)
Run This Example
Section titled “Run This Example”From the repository root:
cd examplesnpm run example algorand_client/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);});Other examples in Algorand Client
Section titled “Other examples in Algorand Client”- Client Instantiation
- AlgoAmount Utility
- Signer Configuration
- Suggested Params Configuration
- Account Manager
- Send Payment
- Send Asset Operations
- Send Application Operations
- Create Transaction (Unsigned Transactions)
- Transaction Composer (Atomic Transaction Groups)
- Asset Manager
- App Manager
- App Deployer
- Client Manager
- Error Transformers
- Transaction Leases