- TONTransactionManager
TONTransactionManager implements the ITONTransactionManager interface and handles cross-chain transactions from TON to TAC.
Key Features:
- Unified Token Interface: Uses the refactored
generatePayloadmethod with object parameters across all token types (Jetton, NFT, TON) - Dependency Injection: Accepts
ISimulatorandIOperationTrackerinterfaces for improved testability - Batch Processing: Supports sending multiple cross-chain transactions simultaneously
- Fee Management: Handles protocol, executor, and forward fees with intelligent distribution
- Balance Checking: Validates sufficient TON balance before transaction execution
- Operation Tracking: Provides optional waiting mechanisms for transaction completion
- Auto Gas Limit: If
evmProxyMsg.gasLimitis not provided, it is auto-populated from the simulation result - Shard Count Logic: Internally, shardCount is computed as the number of Jettons plus NFTs (or 1 when none), which defines how many shard messages are created
new TONTransactionManager(
config: IConfiguration,
simulator: ISimulator,
operationTracker: IOperationTracker,
logger?: ILogger,
txFinalizer?: ITxFinalizer
)Creates a TONTransactionManager instance with the required dependencies.
Parameters:
config: Configuration object implementingIConfigurationsimulator: Simulator instance implementingISimulatorfor transaction simulationoperationTracker: OperationTracker instance implementingIOperationTrackerfor tracking operationslogger(optional): Logger implementingILogger(defaults toNoopLogger)txFinalizer(optional): TxFinalizer instance implementingITxFinalizerfor tracking transaction tree (defaults toTonTxFinalizer)
async sendCrossChainTransaction(
evmProxyMsg: EvmProxyMsg,
sender: SenderAbstraction,
tx: CrosschainTx
): Promise<TransactionLinkerWithOperationId>Sends a single cross-chain transaction from TON to TAC. This method prepares the transaction, checks balances, sends it to the network, and optionally waits for operation completion.
evmProxyMsg: AnEvmProxyMsgobject defining the EVM operationsender: ASenderAbstractioninstance representing the transaction sendertx:CrosschainTxcross-chain transaction data to bridge, including:options.waitOperationId(optional, default: true): Whether to wait for operation ID after sendingoptions.ensureTxExecuted(optional, default: true): Whether to validate TON transaction execution before waiting for operation IDoptions.waitOptions(optional):WaitOptionsfor operation tracking customization
Returns TransactionLinkerWithOperationId
Returns an object containing:
sendTransactionResult: Result of the transaction sending operationoperationId(optional): Operation ID if waiting was enabled- Transaction linker properties for tracking
InsufficientBalanceError: Thrown when sender has insufficient TON balanceSimulationError: Thrown when transaction simulation failsContractError: Thrown when required contracts are not deployedWalletError: Thrown when the transaction fails to send to the blockchain
async sendCrossChainTransactions(
sender: SenderAbstraction,
txs: BatchCrossChainTx[],
options?: CrossChainTransactionsOptions
): Promise<TransactionLinkerWithOperationId[]>Sends multiple cross-chain transactions in a batch from TON to TAC. This method is useful for scenarios where multiple independent operations need to be initiated simultaneously.
sender: ASenderAbstractioninstance representing the transaction sendertxs: Array ofBatchCrossChainTxobjects, each defining a single cross-chain transactionNote: Individual transactions in batch operations cannot specify
waitOperationId,waitOptions, orensureTxExecutedin their options as these are controlled at the batch level.options(optional):CrossChainTransactionsOptionscontrolling batch-level behavior:waitOperationIds(optional, default: true): Whether to wait for operation IDs for all transactions in the batchwaitOptions(optional):WaitOptionsfor customizing operation IDs waiting behavior
Returns an array of TransactionLinkerWithOperationId objects, one for each transaction sent.
async prepareCrossChainTransactionPayload(
evmProxyMsg: EvmProxyMsg,
senderAddress: string,
assets: Asset[],
options?: CrossChainTransactionOptions
): Promise<CrossChainPayloadResult[]>Prepares the transaction payloads required for a cross-chain operation without sending them to the network. This method generates all the necessary message payloads, addresses, and amounts that would be sent in a cross-chain transaction.
evmProxyMsg: AnEvmProxyMsgobject defining the EVM operationsenderAddress: TVM address string of the transaction sender (wallet address)assets: Array ofAssetinstances to be bridged in the transactionoptions(optional):CrossChainTransactionOptionsfor controlling payload generation
Returns an array of CrossChainPayloadResult objects, each containing:
body: The serialized message payload as a TON Cell, containing all transaction data and parametersdestinationAddress: Target contract address for this message (e.g., jetton wallet, NFT item, cross-chain layer)tonAmount: Amount of TON to send with this message in nanotons (for asset transfer or contract interaction)tonNetworkFee: Network fee for this specific message in nanotonstacEstimatedGas(optional): Estimated gas required for TAC-side executiontransactionLinker: Transaction linker for tracking the operation across chains
- Build transaction batching systems
- Create transaction templates for later execution
- Debug and inspect transaction payloads before sending
const payloads = await tonManager.prepareCrossChainTransactionPayload(
evmProxyMsg,
"EQD...",
[tonAsset, jettonAsset],
{ calculateRollbackFee: true }
);
// Inspect payloads before sending
payloads.forEach((payload, index) => {
console.log(`Payload ${index}:`);
console.log(` Destination: ${payload.destinationAddress}`);
console.log(` TON Amount: ${payload.tonAmount} nanotons`);
console.log(` Network Fee: ${payload.tonNetworkFee} nanotons`);
console.log(` TAC Estimated Gas: ${payload.tacEstimatedGas || 'N/A'}`);
console.log(` Transaction Linker: ${JSON.stringify(payload.transactionLinker)}`);
});TONTransactionManager is used internally by the main TacSdk class to power the main cross-chain transaction methods (sendCrossChainTransaction and sendCrossChainTransactions). The SDK automatically instantiates and manages this component, providing a unified interface while maintaining the architectural separation underneath.
The recommended way to use the TON transaction manager is through the main TacSdk class, which handles the instantiation and coordination:
import { TacSdk, Network, ConsoleLogger } from "@tonappchain/sdk";
// Create SDK instance
const sdk = await TacSdk.create({
network: Network.TESTNET
}, new ConsoleLogger());
// TON -> TAC transactions (uses TONTransactionManager internally)
const result = await sdk.sendCrossChainTransaction(
evmProxyMsg,
sender,
assets,
options,
{
timeout: 300000,
maxAttempts: 30
}
);
// Multiple TON -> TAC transactions
const results = await sdk.sendCrossChainTransactions(
sender,
[
{ evmProxyMsg: msg1, assets: [asset1] },
{ evmProxyMsg: msg2, assets: [asset2] }
],
waitOptions
);For advanced use cases, you can instantiate the TON transaction manager directly:
import {
TONTransactionManager,
Configuration,
Simulator,
OperationTracker,
ConsoleLogger,
Network
} from "@tonappchain/sdk";
// Create dependencies
const config = await Configuration.create(Network.TESTNET);
const simulator = new Simulator(config);
const operationTracker = new OperationTracker(Network.TESTNET);
const logger = new ConsoleLogger();
// Create TON Transaction Manager for TON -> TAC operations
const tonManager = new TONTransactionManager(
config,
simulator,
operationTracker,
logger,
txFinalizer // optional, defaults to TonTxFinalizer
);
// Send TON -> TAC transaction
const tx: CrosschainTx = {
assets: [tonAsset, jettonAsset],
evmProxyMsg,
options: {
tvmExecutorFee: BigInt("50000000"),
evmExecutorFee: BigInt("1000000000000000")
}
};
const result = await tonManager.sendCrossChainTransaction(
evmProxyMsg,
sender,
tx,
{ timeout: 30000 }
);The TON transaction manager includes comprehensive error handling:
try {
const result = await tonManager.sendCrossChainTransaction(
evmProxyMsg,
sender,
tx,
waitOptions
);
console.log('Transaction successful:', result.operationId);
} catch (error) {
if (error instanceof InsufficientBalanceError) {
console.error('Insufficient balance:', error.message);
} else if (error instanceof SimulationError) {
console.error('Simulation failed:', error.message);
} else if (error instanceof ContractError) {
console.error('Contract not deployed:', error.message);
} else if (error instanceof WalletError) {
console.error('Transaction send failed:', error.message);
} else {
console.error('Transaction failed:', error.message);
}
}