Documentation Index Fetch the complete documentation index at: https://docs.tac.build/llms.txt
Use this file to discover all available pages before exploring further.
The Agnostic Proxy enables building complex DeFi operations with dynamic value replacement capabilities. It moves business logic from proxy contracts to your application code, making development more reactive and eliminating the need for custom proxy contract audits.
Agnostic Proxy Documentation
Overview
The AgnosticProxy SDK allows you to:
Chain multiple DeFi operations with interdependent values
Replace parameter values dynamically with token balances at execution time
Build complex strategies without writing custom proxy contracts
Visualize and debug operation chains with built-in tools
Key Features
Dynamic Value Replacement : Automatically replace parameters with actual token balances
Efficient Hook System : Custom, FullBalanceApprove, and FullBalanceTransfer hooks
Complex Operations : Chain multiple DeFi operations seamlessly
Visualization Tools : Human-readable chain visualization and debugging
Type Safety : Full TypeScript support
Quickstart
import { AgnosticProxySDK , Network } from "@tonappchain/sdk" ;
import { ethers } from "ethers" ;
// Create SDK instance
const sdk = new AgnosticProxySDK ( Network . TESTNET );
// Add contract interfaces
sdk . addContractInterface ( ROUTER_ADDRESS , ROUTER_ABI );
sdk . addContractInterface ( STAKING_ADDRESS , STAKING_ABI );
// Get agnostic call parameters
const agnosticCallParams = sdk . getAgnosticCallParams ();
// Create hooks for your strategy
const hooks = [
sdk . createFullBalanceApproveHook ( TOKEN_IN , ROUTER_ADDRESS , true ),
sdk . createCustomHook ( ROUTER_ADDRESS , "swapExactTokensForTokens" , [
ethers . parseEther ( "100" ), // amount in
ethers . parseEther ( "90" ), // min amount out
[ TOKEN_IN , TOKEN_OUT ],
SMART_ACCOUNT_ADDRESS ,
Math . floor ( Date . now () / 1000 ) + 3600 ,
]),
];
// Build and encode the operation
const zapCall = sdk . buildZapCall ( hooks , [ TOKEN_OUT ], []);
const encodedCall = sdk . encodeZapCall ( zapCall );
// Visualize the operation chain
sdk . visualizeZapCall ( zapCall );
Core Concepts
Hook Types
The SDK supports three types of hooks:
1. Custom Hook
Execute arbitrary contract calls with optional dynamic value replacement:
const hook = sdk . createCustomHook (
CONTRACT_ADDRESS ,
"functionName" ,
[ param1 , param2 , param3 ],
{
isFromSAPerspective: true , // Execute from Smart Account perspective
value: 0 n , // ETH value to send
dynamicReplacements: [ replacement ], // Dynamic value replacements
}
);
2. FullBalanceApprove Hook
Approve the full balance of a token to a spender:
const approveHook = sdk . createFullBalanceApproveHook (
TOKEN_ADDRESS ,
SPENDER_ADDRESS ,
true // isFromSAPerspective
);
3. FullBalanceTransfer Hook
Transfer the full balance of a token to a recipient:
const transferHook = sdk . createFullBalanceTransferHook (
TOKEN_ADDRESS ,
RECIPIENT_ADDRESS ,
false // isFromSAPerspective
);
Dynamic Value Replacement
Replace parameter values at execution time with actual token balances:
// Create a dynamic amount replacement
const replacement = sdk . createAmountReplacement (
0 , // parameter index to replace
TOKEN_ADDRESS , // token to get balance of
BALANCE_ADDRESS // address to check balance for
);
// Use in a custom hook
const hook = sdk . createCustomHook (
CONTRACT_ADDRESS ,
"stake" ,
[ 0 n ], // This 0 will be replaced with actual balance
{
dynamicReplacements: [ replacement ],
}
);
Complete Example with TacSDK
import {
TacSdk ,
AgnosticProxySDK ,
SenderFactory ,
Network ,
} from "@tonappchain/sdk" ;
import { TonConnectUI } from "@tonconnect/ui" ;
import { ethers } from "ethers" ;
async function executeCompleteStrategy () {
// Initialize TacSDK
const tacSdk = await TacSdk . create ({ network: Network . TESTNET });
// Initialize sender
const tonConnectUI = new TonConnectUI ({
manifestUrl: "https://example.com/tonconnect-manifest.json" ,
});
const sender = await SenderFactory . getSender ({ tonConnect: tonConnectUI });
const tvmWalletAddress = sender . getSenderAddress ();
// Initialize AgnosticProxy SDK
const agnosticSdk = new AgnosticProxySDK ( Network . TESTNET );
const agnosticCallParams = agnosticSdk . getAgnosticCallParams ();
// Register contract interfaces
agnosticSdk . addContractInterface ( UNISWAP_ROUTER , UNISWAP_ROUTER_ABI );
agnosticSdk . addContractInterface ( STAKING_CONTRACT , STAKING_ABI );
// Get smart account address
const smartAccountAddress = await tacSdk . getSmartAccountAddressForTvmWallet (
tvmWalletAddress ,
agnosticCallParams . evmTargetAddress
);
// Build strategy: USDC → WETH → Stake
const hooks = [];
// Transfer incoming USDC to smart account
hooks . push (
agnosticSdk . createFullBalanceTransferHook (
TOKENS . USDC ,
smartAccountAddress ,
false
)
);
// Approve USDC for Uniswap
hooks . push (
agnosticSdk . createFullBalanceApproveHook ( TOKENS . USDC , UNISWAP_ROUTER , true )
);
// Swap USDC to WETH
hooks . push (
agnosticSdk . createCustomHook (
UNISWAP_ROUTER ,
"swapExactTokensForTokens" ,
[
ethers . parseUnits ( "2000" , 6 ), // 2000 USDC
ethers . parseEther ( "1" ), // min 1 WETH
[ TOKENS . USDC , TOKENS . WETH ],
smartAccountAddress ,
Math . floor ( Date . now () / 1000 ) + 3600 ,
],
{ isFromSAPerspective: true }
)
);
// Approve WETH for staking
hooks . push (
agnosticSdk . createFullBalanceApproveHook (
TOKENS . WETH ,
STAKING_CONTRACT ,
true
)
);
// Stake WETH with dynamic amount
const replacement = agnosticSdk . createAmountReplacement (
0 ,
TOKENS . WETH ,
smartAccountAddress
);
hooks . push (
agnosticSdk . createCustomHook (
STAKING_CONTRACT ,
"stake" ,
[ 0 n ], // Will be replaced with actual WETH balance
{
dynamicReplacements: [ replacement ],
isFromSAPerspective: true ,
}
)
);
// Build ZapCall
const zapCall = agnosticSdk . buildZapCall (
hooks ,
[ TOKENS . STAKE_SHARE_TOKEN ], // Bridge tokens after operation
[] // No NFTs to bridge
);
// Visualize the strategy
console . log ( "📋 Strategy Visualization:" );
agnosticSdk . visualizeZapCall ( zapCall );
// Get analytics
const breakdown = agnosticSdk . getZapCallBreakdown ( zapCall );
console . log ( " \n 📈 Strategy Analytics:" );
console . log ( ` Total Operations: ${ breakdown . totalHooks } ` );
console . log ( ` Estimated Gas: ${ breakdown . gasEstimate . toLocaleString () } ` );
console . log ( ` Encoded Size: ${ breakdown . encodedSize } bytes` );
// Encode for transaction
const encodedCall = agnosticSdk . encodeZapCall ( zapCall );
// Execute via TacSDK
const evmProxyMsg = {
evmTargetAddress: agnosticCallParams . evmTargetAddress ,
methodName: agnosticCallParams . methodName ,
encodedParameters: encodedCall ,
};
const assets = [
{
address: USDCTvmAddress ,
amount: 2000 ,
},
];
await tacSdk . sendCrossChainTransaction ( evmProxyMsg , sender , assets );
}
Best Practices
Always add contract interfaces before creating hooks
Use dynamic replacements for interdependent operations
Add appropriate approvals before token operations
Visualize strategies before execution to verify logic
Test with small amounts first on testnet
Learn more in the thorough Agnostic Proxy GitHub page .