Class TransactionBuilder
Constructors
constructor
Parameters
Optionalprovider: IProvider
Returns TransactionBuilder
Methods
addContract
Add a contract using ContractRequestData Routes to the appropriate builder method based on contractType. This is a generic method that automatically calls the correct specialized method.
Contract Types:
- 0: Transfer
- 1: CreateAsset
- 2: CreateValidator
- 4: Freeze
- 5: Unfreeze
- 6: Delegate
- 7: Undelegate
- 8: Withdraw
- 9: Claim
- 14: Vote
- 63: SmartContract
Parameters
- contract: ContractRequestData
Contract request data with contractType
Returns this
This builder instance for chaining
build
Build transaction using node endpoint (requires provider) This is the recommended method for most use cases as the node handles complex operations.
Node-Assisted Building: The node automatically handles:
- Nonce fetching (gets current account nonce)
- Fee calculation (computes optimal kAppFee and bandwidthFee)
- Proto encoding (creates valid proto bytes)
- Validation (ensures transaction is valid)
When to Use:
- Standard wallet applications
- When you have internet connectivity
- When you want automatic fee calculation
- When you don't need to control every parameter
Comparison with buildProto():
- build() = Online, automatic, easy (requires provider)
- buildProto() = Offline, manual, flexible (no network needed)
Returns Promise<Transaction>
Transaction object with proto bytes from node, ready to sign
Example
// Simple node-assisted build
const provider = new KleverProvider({ network: 'mainnet' })
const tx = await TransactionBuilder.create(provider)
.sender('klv1xyz...')
.transfer({ receiver: 'klv1abc...', amount: '1000000' })
.build()
// Node automatically fetches nonce and calculates fees
await tx.sign(privateKey)
const hash = await provider.sendRawTransaction(tx.toHex())
// Build with multiple contracts
const tx = await TransactionBuilder.create(provider)
.sender('klv1xyz...')
.transfer({ receiver: 'klv1abc...', amount: '1000000' })
.freeze({ amount: '5000000' })
.delegate({ receiver: 'klv1validator...' })
.build()
// Override specific parameters
const tx = await TransactionBuilder.create(provider)
.sender('klv1xyz...')
.nonce(150) // Override automatic nonce
.transfer({ receiver: 'klv1abc...', amount: '1000000' })
.build()
buildProto
Build proto transaction offline (client-side, no network required) This method creates a transaction entirely on the client side without contacting the node. You must provide all required parameters (sender, nonce, fees) either via builder state or options.
Offline Mode Benefits:
- No network latency
- Works without internet connection
- Full control over transaction parameters
- Ideal for hardware wallets and air-gapped signing
Fee Calculation: When building offline, fees must be provided manually or estimated:
- KAppFee: Base fee for the contract type (typically 500000-1000000)
- BandwidthFee: Fee based on transaction size (typically 100000-500000)
- KDAFee: Optional - pay fees in custom KDA instead of KLV
Parameters
- options: BuildCallOptions = {}
Build options (sender, nonce, fees, etc.)
Build call options All fields are optional - will use builder's state if not provided
OptionalchainId?: stringChain ID for offline transaction building
Optionaldata?: string[]Transaction data (for smart contract calls)
Optionalfees?: { bandwidthFee: number; kAppFee: number }Fees for offline transaction building
OptionalkdaFee?: { amount: AmountLike; kda: string }KDA fee for offline transaction building
Optionalnonce?: numberNonce for offline transaction building
OptionalpermissionId?: numberPermission ID for the transaction
Optionalsender?: stringSender address
Optionalvalue?: Record<string, bigint>Value to send with transaction (e.g., { KLV: parseKLV('1') })
Returns Transaction
Transaction object with proto bytes ready to sign
Example
// Offline build with all parameters in options
const tx = TransactionBuilder.create()
.transfer({ receiver: 'klv1abc...', amount: '1000000' })
.buildProto({
sender: 'klv1xyz...',
nonce: 123,
chainId: '100',
fees: {
kAppFee: 500000,
bandwidthFee: 100000
}
})
await tx.sign(privateKey)
const hex = tx.toHex()
// Offline build using builder state
const tx = TransactionBuilder.create()
.sender('klv1xyz...')
.nonce(123)
.setChainId('100')
.transfer({ receiver: 'klv1abc...', amount: '1000000' })
.buildProto({
fees: { kAppFee: 500000, bandwidthFee: 100000 }
})
// Offline build with KDA fee (pay fees in custom token)
const tx = TransactionBuilder.create()
.sender('klv1xyz...')
.nonce(123)
.transfer({ receiver: 'klv1abc...', amount: '1000000' })
.buildProto({
chainId: '100',
fees: { kAppFee: 0, bandwidthFee: 0 },
kdaFee: { kda: 'MYTOKEN-ABCD', amount: '1000000' }
})
buildRequest
Build transaction request object for node endpoint Creates a request object that can be sent to the node's /transaction/build endpoint The node will handle nonce fetching, fee calculation, and proto encoding
Returns BuildTransactionRequest
Request object ready to send to node's /transaction/build endpoint
callOptions
Add multiple build options at once Convenience method to set multiple builder options in a single call. This is particularly useful when working with smart contracts or offline building.
Note: The
valueoption is not supported here - set callValue directly in smartContract()Parameters
- options: BuildCallOptions
Build options object
Build call options All fields are optional - will use builder's state if not provided
OptionalchainId?: stringChain ID for offline transaction building
Optionaldata?: string[]Transaction data (for smart contract calls)
Optionalfees?: { bandwidthFee: number; kAppFee: number }Fees for offline transaction building
OptionalkdaFee?: { amount: AmountLike; kda: string }KDA fee for offline transaction building
Optionalnonce?: numberNonce for offline transaction building
OptionalpermissionId?: numberPermission ID for the transaction
Optionalsender?: stringSender address
Optionalvalue?: Record<string, bigint>Value to send with transaction (e.g., { KLV: parseKLV('1') })
Returns this
This builder instance for chaining
- options: BuildCallOptions
claim
Add claim contract to claim rewards or allocations Used for claiming staking rewards, airdrops, or other claimable amounts
Parameters
- params: ClaimRequest
Claim parameters
Returns this
This builder instance for chaining
Example
// Claim staking rewards
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.claim({
claimType: 0 // Staking rewards
})
.build()
// Claim specific allocation
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.claim({
claimType: 1,
id: 'allocation-id-123'
})
.build()- params: ClaimRequest
createAsset
Add create asset contract to create a new token or NFT collection Creates fungible tokens (FTs), non-fungible tokens (NFTs), or other asset types
Parameters
- params: CreateAssetRequest
Asset creation parameters
OptionaladminAddress?: stringOptionalattributes?: AttributesInfoOptionalinitialSupply?: AmountLikeOptionallogo?: stringmaxSupply: AmountLike
name: string
ownerAddress: string
precision: number
Optionalproperties?: PropertiesInfoOptionalroles?: RolesInfo[]Optionalroyalties?: RoyaltiesInfoOptionalstaking?: StakingInfoticker: string
type: number
Optionaluris?: Record<string, string>
Returns this
This builder instance for chaining
Example
// Create fungible token
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.createAsset({
type: 0,
name: 'My Token',
ticker: 'MTK',
ownerAddress: 'klv1...',
precision: 6,
maxSupply: '1000000000000',
initialSupply: '100000000000'
})
.build()
// Create NFT collection
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.createAsset({
type: 1,
name: 'My NFT Collection',
ticker: 'MYNFT',
ownerAddress: 'klv1...',
precision: 0,
maxSupply: 0,
royalties: { address: 'klv1...', percentage: 5 }
})
.build()- params: CreateAssetRequest
createValidator
Add create validator contract to register a new validator node Validators participate in consensus and earn rewards for securing the network
Parameters
- params: CreateValidatorRequest
Validator creation parameters
blsPublicKey: string
OptionalcanDelegate?: booleancommission: number
Optionallogo?: stringOptionalmaxDelegationAmount?: AmountLikeOptionalname?: stringownerAddress: string
OptionalrewardAddress?: stringOptionaluris?: Record<string, string>
Returns this
This builder instance for chaining
Example
// Create validator node
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.createValidator({
blsPublicKey: '0xabcd1234...',
ownerAddress: 'klv1...',
commission: 10, // 10% commission
canDelegate: true,
name: 'My Validator',
logo: 'https://example.com/logo.png',
uris: {
website: 'https://validator.example.com',
twitter: 'https://twitter.com/myvalidator'
}
})
.build()- params: CreateValidatorRequest
data
Set transaction data for smart contract calls Data is used primarily for smart contract interactions, where it contains:
- Function name (first element)
- Function arguments (remaining elements)
Important:
- Data is automatically base64 encoded when building with buildRequest()
- For offline building with buildProto(), provide UTF-8 strings
Parameters
- data: string[]
Array of strings containing function name and arguments
Returns this
This builder instance for chaining
Example
// Smart contract call with arguments
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.smartContract({ address: 'klv1contract...', scType: 1 })
.data(['transfer', 'klv1receiver...', '1000000'])
.build()
// Multiple data fields
const tx = TransactionBuilder.create()
.sender('klv1...')
.smartContract({ address: 'klv1contract...', scType: 1 })
.data(['functionName', 'arg1', 'arg2', 'arg3'])
.buildProto({ nonce: 1, chainId: '100', fees: { kAppFee: 500000, bandwidthFee: 100000 } })
delegate
Add delegate contract to assign a frozen bucket to a validator Delegation allows validators to use your staked KLV for consensus and earn rewards
Parameters
- params: DelegateRequest
Delegate parameters
Returns this
This builder instance for chaining
Example
// Delegate specific bucket to validator
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.delegate({
receiver: 'klv1validator123...',
bucketId: 'bucket-hash-123'
})
.build()
// Delegate all available buckets
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.delegate({
receiver: 'klv1validator123...'
})
.build()- params: DelegateRequest
freeze
Add freeze (stake) contract to lock KLV or KDA assets Freezing creates a bucket that can be delegated to validators or used for governance
Parameters
- params: FreezeRequest
Freeze parameters
amount: AmountLike
Optionalkda?: string
Returns this
This builder instance for chaining
Example
// Freeze KLV for staking
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.freeze({
amount: '5000000' // 5 KLV
})
.build()
// Freeze custom KDA token
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.freeze({
amount: '1000000',
kda: 'MYTOKEN-ABCD'
})
.build()- params: FreezeRequest
getProvider
Get the provider instance
Returns undefined | IProvider
kdaFee
Set KDA fee to pay transaction fees in a custom KDA asset instead of KLV By default, transactions pay fees in KLV (kAppFee + bandwidthFee). This method allows paying fees in a different asset.
Important:
- Cannot use 'KLV' as kdaFee (KLV is the default fee asset)
- The asset must support being used as a fee payment option
Parameters
- fee: { amount: AmountLike; kda: string }
KDA fee configuration
amount: AmountLike
Fee amount in smallest units of the KDA asset
kda: string
Asset ID to use for fee payment (cannot be 'KLV')
Returns this
This builder instance for chaining
nonce
Set nonce manually for offline transaction building The nonce is a sequential counter that prevents transaction replay attacks. Each account has its own nonce that increments with every transaction.
When to use:
- Offline transaction building (required with buildProto())
- Manual nonce management for batch transactions
- Testing or debugging specific scenarios
Getting current nonce: Use
provider.getAccount(address)to get the current nonce from the networkParameters
- nonce: number
Transaction nonce (must be non-negative)
Returns this
This builder instance for chaining
Example
// Manual nonce for offline building
const tx = TransactionBuilder.create()
.sender('klv1...')
.nonce(123)
.transfer({ receiver: 'klv1...', amount: '1000000' })
.buildProto({
chainId: '100',
fees: { kAppFee: 500000, bandwidthFee: 100000 }
})
// Get nonce from provider first
const account = await provider.getAccount('klv1...')
const tx = TransactionBuilder.create()
.sender('klv1...')
.nonce(account.nonce)
.transfer({ receiver: 'klv1...', amount: '1000000' })
.buildProto({ chainId: '100', fees: { kAppFee: 500000, bandwidthFee: 100000 } })
permissionId
Set permission ID for multi-signature transactions Permission IDs enable complex account structures with multiple signers and permissions.
Use cases:
- Multi-signature wallets requiring multiple approvals
- Corporate accounts with different permission levels
- Smart contract interactions with specific permissions
Parameters
- id: number
Permission ID number
Returns this
This builder instance for chaining
reset
Reset builder state to initial values Clears all contracts and builder configuration, allowing reuse of the builder instance
What gets reset:
- All added contracts
- Sender address
- Nonce
- KDA fee
- Permission ID
- Transaction data
What persists:
- Provider (if set)
- Chain ID (if set)
Returns this
This builder instance for chaining
Example
const builder = TransactionBuilder.create(provider)
// Build first transaction
const tx1 = await builder
.sender('klv1...')
.transfer({ receiver: 'klv1abc...', amount: '1000000' })
.build()
// Reset and build second transaction
const tx2 = await builder
.reset()
.sender('klv1...')
.freeze({ amount: '5000000' })
.build()
sender
Set sender address for the transaction
Parameters
- address: string
Bech32 encoded Klever address (e.g., "klv1...")
Returns this
This builder instance for chaining
- address: string
setChainId
Set chain ID (overrides provider's network if set) The chain ID identifies which Klever network to use (e.g., "100" for mainnet)
Parameters
- chainId: string
Chain ID string (e.g., "100" for mainnet, "101" for testnet)
Returns this
This builder instance for chaining
- chainId: string
setProvider
smartContract
Add smart contract call to interact with deployed contracts Enables calling functions on smart contracts deployed on the Klever blockchain
Contract Call Types (scType):
- 0: Deploy contract
- 1: Invoke contract function
- 2: Upgrade contract
Important:
- Use
.data()to specify function name and arguments - callValue allows sending KLV or KDA tokens with the call
- Contract address must be valid bech32 format
Parameters
- params: SmartContractRequest
Smart contract parameters
address: string
OptionalcallValue?: Record<string, AmountLike>scType: number
Returns this
This builder instance for chaining
Example
// Invoke contract function
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.smartContract({
address: 'klv1contract...',
scType: 1, // Invoke
callValue: { KLV: '1000000' } // Send 1 KLV
})
.data(['transfer', 'klv1receiver...', '500000'])
.build()
// Call contract without sending value
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.smartContract({
address: 'klv1contract...',
scType: 1
})
.data(['getValue'])
.build()
transfer
Add transfer contract to send KLV or KDA assets
Parameters
- params: TransferRequest
Transfer parameters
amount: AmountLike
Optionalkda?: stringOptionalkdaRoyalties?: AmountLikeOptionalklvRoyalties?: AmountLikereceiver: string
Returns this
This builder instance for chaining
Example
// Transfer KLV
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.transfer({
receiver: 'klv1abc123...',
amount: '1000000' // 1 KLV
})
.build()
// Transfer custom KDA token
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.transfer({
receiver: 'klv1abc123...',
amount: '5000000',
kda: 'MYTOKEN-ABCD'
})
.build()
// Transfer with royalties (for NFTs)
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.transfer({
receiver: 'klv1abc123...',
amount: '1',
kda: 'NFT-COLLECTION/NONCE-1',
kdaRoyalties: '100000',
klvRoyalties: '50000'
})
.build()- params: TransferRequest
undelegate
Add undelegate contract to remove delegation from a validator Undelegation returns the bucket to your control but keeps it frozen
Parameters
- params: UndelegateRequest
Undelegate parameters
Returns this
This builder instance for chaining
- params: UndelegateRequest
unfreeze
Add unfreeze (unstake) contract to unlock frozen assets Unfreezing initiates the unlocking process - assets become available after the unlock period
Parameters
- params: UnfreezeRequest
Unfreeze parameters
Returns this
This builder instance for chaining
Example
// Unfreeze KLV bucket
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.unfreeze({
kda: 'KLV',
bucketId: 'bucket-hash-123'
})
.build()
// Unfreeze custom KDA token
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.unfreeze({
kda: 'MYTOKEN-ABCD'
})
.build()- params: UnfreezeRequest
vote
Add vote contract to participate in governance proposals Voting allows token holders to participate in network governance decisions
Parameters
- params: VoteRequest
Vote parameters
Optionalamount?: AmountLikeproposalId: number
type: number
Returns this
This builder instance for chaining
Example
// Vote yes on proposal
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.vote({
proposalId: 5,
type: 1, // Yes
amount: '1000000' // Optional voting weight
})
.build()
// Vote no on proposal
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.vote({
proposalId: 5,
type: 2 // No
})
.build()- params: VoteRequest
withdraw
Add withdraw contract to retrieve available funds Used to withdraw staking rewards, unlocked frozen assets, or other withdrawable amounts
Parameters
- params: WithdrawRequest
Withdraw parameters
Optionalamount?: AmountLikeOptionalcurrencyID?: stringOptionalkda?: stringwithdrawType: number
Returns this
This builder instance for chaining
Example
// Withdraw staking rewards
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.withdraw({
withdrawType: 0 // Staking rewards
})
.build()
// Withdraw specific KDA amount
const tx = await TransactionBuilder.create(provider)
.sender('klv1...')
.withdraw({
withdrawType: 0,
kda: 'MYTOKEN-ABCD',
amount: '1000000'
})
.build()- params: WithdrawRequest
Staticcreate
Create a new TransactionBuilder with provider (static factory) Provides a cleaner API for chainable transaction building
Parameters
Optionalprovider: IProvider
Returns TransactionBuilder
TransactionBuilder - Fluent API for building Klever blockchain transactions
Supports three build modes:
Example