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