The TAC SDK makes it possible to create hybrid dApps that let TON users interact directly with EVM smart contracts without needing to manage multiple wallets or understand the complexities of cross-chain messaging.
For full documentation and examples, please visit TAC SDK Documentation.
npm install @tonappchain/sdk
or
yarn add @tonappchain/sdk
The TAC SDK enables you to create frontends that:
- Connect to TON wallets like Tonkeeper or Tonhub
- Send transactions from TON to your EVM contracts
- Track cross-chain transaction status in real-time
- Handle tokens across both chains
- Create a seamless user experience for TON users
-
TacSdk
: The main class for interacting with the TAC protocol.create
: Initializes the SDK instance.sendCrossChainTransaction
: Sends a cross-chain transaction from TON to TAC.getEVMTokenAddress
: Gets the TAC address for a TON token.getTVMTokenAddress
: Gets the TON address for a TAC token.getTransactionSimulationInfo
: Performs a complete simulation of a crosschain transaction to estimate fees and gather execution-related metadata.getUserJettonBalance
: Gets a user's Jetton balance (raw).getUserJettonBalanceExtended
: Gets extended Jetton balance info (including decimals).getUserJettonWalletAddress
: Calculates a user's Jetton wallet address.nativeTONAddress (getter)
: Placeholder address for native TON.nativeTACAddress (getter)
: Gets the native asset address on the TAC chain.- (See file for more...)
-
OperationTracker
: Tools for monitoring cross-chain operation status.constructor
: Creates a tracker instance.getOperationId
: Retrieves the Operation ID from aTransactionLinker
.getStageProfiling
: Gets detailed timing and status for all stages of an operation.getSimplifiedOperationStatus
: Gets a simplified overall status (Pending, Successful, Failed, Not Found).- (See file for more...)
-
Senders
: Handles signing and sending TON transactions.TonConnectSender
: Implements sending via TonConnect UI.RawSender
: Implements sending using a raw private key.
-
Utilities
: Helper functions and interfaces.startTracking
: Utility function to poll and log operation status to the console.
-
Enums
: Key enumerations used by the SDK.Network
:TESTNET
orMAINNET
.SimplifiedStatuses
:PENDING
,FAILED
,SUCCESSFUL
,OPERATION_ID_NOT_FOUND
.OperationType
: Detailed operation types (PENDING
,TON_TAC_TON
,ROLLBACK
, etc.).StageName
: Identifiers for tracking stages (COLLECTED_IN_TAC
,EXECUTED_IN_TAC
, etc.).
-
Structs
: Core data structures.AssetBridgingData
: Specifies assets to bridge (TON or Jettons).EvmProxyMsg
: Defines the target EVM call details.TransactionLinker
: Identifies a cross-chain operation.- (See file for more...)
Navigate through the linked files for full details on parameters, return types, examples, and more.
Note: The TAC protocol only knows how to send data to contracts that inherit from a TacProxy (TacProxyV1) contract. Such a contract must have a strictly defined signature of its methods. It is specified below:
function myProxyFunction(bytes calldata tacHeader, bytes calldata arguments) external onlyTacCCL {
// Function implementation
}
Note: methodName in
evmProxyMsg
must be either a simple method name or a signature of the form MethodName(bytes,bytes)
The first argument of methods must always be TACHeader. It is sent by protocol, augmented with data from executor.
bytes tacHeader
: Encoded structure TacHeaderV1, containing:uint64 shardsKey
: ID you can specify for yourself an inside message to the TVM contract on the TON network.uint256 timestamp
: The block timestamp on TON where the user's message was created.bytes32 operationId
: Unique identifier for the message created by the TAC infrastructure.string tvmCaller
: The TON user's wallet address that sent the message.bytes extraData
: Untrusted extra data, provided by executor with the current message if needed. Otherwise, it's an empty bytes array.
You need to specify all the remaining data you need in tuple (bytes) in arguments. For example this is how arguments for addLiquidity method in UniswapV2 (a special proxy contract for it) will look like:
const abi = new ethers.AbiCoder();
const encodedParameters = abi.encode(
['tuple(address,address,uint256,uint256,uint256,uint256,address,uint256)'],
[
[
EVM_TOKEN_A_ADDRESS,
EVM_TOKEN_B_ADDRESS,
amountA,
amountB,
amountAMin,
amountBMin,
UNISWAPV2_PROXY_ADDRESS,
deadline
]
]
);
More details in sendAddLiquidity.ts and in other tests.
import { TacSdk } from '@tonappchain/sdk';
import { TonConnectUI } from '@tonconnect/ui';
import { ethers } from 'ethers';
// Create EVM payload for DappProxy
const abi = new ethers.AbiCoder();
const encodedParameters = abi.encode(
['tuple(uint256,uint256,address[],address)'],
[
[
tokenAAmount,
tokenBAmount,
[EVMtokenAAddress, EVMtokenBAddress],
proxyDapp
]
]
);
const evmProxyMsg: EvmProxyMsg = {
evmTargetAddress: DappProxyAddress,
methodName: 'addLiquidity',
encodedParameters
};
// Create jetton transfer messages corresponding to EVM tokens, e.g., two tokens for adding liquidity to a pool
const assets: AssetBridgingData[] = [
{
address: TVMtokenAAddress,
amount: tokenAAmount,
type: AssetType.FT,
},
{
address: TVMtokenBAddress,
amount: tokenBAmount,
type: AssetType.FT,
}
];
const sdkParams: SDKParams = {
network: Network.TESTNET
};
const tacSdk = await TacSdk.create(sdkParams);
//Send transaction via tonConnect or mnemonic
const tonConnectUI = new TonConnectUI({
manifestUrl: config.tonconnectManifestUrl as string
});
const sender = await SenderFactory.getSender({
tonConnect: tonConnectUI
});
await tacSdk.sendCrossChainTransaction(evmProxyMsg, sender, assets);
tacSdk.closeConnections();
For a detailed example, see test/sendSwap.ts
or test/sendRemoveLiquidity.ts
, which demonstrates swapping tokens and removing liquidity on Uniswap and tracking the transaction status.
MIT