Documentation Index
Fetch the complete documentation index at: https://docs.tedprotocol.io/llms.txt
Use this file to discover all available pages before exploring further.
How to integrate TED Protocol into your application.
Overview
TED Protocol integration methods:
| Method | Complexity | Status |
|---|
| Direct contract calls | Medium | Available |
| SDK | Low | Coming soon |
| Embeddable widget | Lowest | Coming soon |
This guide covers direct contract integration.
Prerequisites
- Web3 library (ethers.js, web3.js, or viem)
- TED Protocol addresses from the Contract Addresses page
- Contract ABIs
Setup
Initialize your connection to TED Protocol:
import { ethers } from 'ethers';
// Contract addresses (example - verify on contract-addresses page)
const DIAMOND_ADDRESS = "0x..."; // Network-specific
// Combined ABI (includes all facets)
const TED_ABI = [
// IFXSwap
"function swap(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, uint256 deadline) returns (uint256)",
"function getQuote(address tokenIn, address tokenOut, uint256 amountIn) view returns (tuple(uint256 amountOut, uint256 priceImpact, address[] route, uint256 gasEstimate))",
// ICrossChainSwap
"function crossChainSwap(tuple(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, uint32 srcChainId, uint32 dstChainId, address recipient, uint256 deadline, bytes bridgeOptions)) payable returns (bytes32)",
"function estimateFees(tuple(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, uint32 srcChainId, uint32 dstChainId, address recipient, uint256 deadline, bytes bridgeOptions)) view returns (uint256, uint256)",
// Events
"event Swap(address indexed sender, address indexed tokenIn, address indexed tokenOut, uint256 amountIn, uint256 amountOut, address dex)",
"event CrossChainSwapInitiated(bytes32 indexed messageId, address indexed sender, uint32 srcChainId, uint32 dstChainId, address tokenIn, address tokenOut, uint256 amountIn)"
];
// Initialize
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const tedProtocol = new ethers.Contract(DIAMOND_ADDRESS, TED_ABI, signer);
Same-Chain Swap
Execute a swap on a single chain:
- Approve tokens
- Get a quote
- Calculate minimum output with slippage
- Execute swap
async function executeSwap(tokenIn, tokenOut, amountIn, slippageBps = 50) {
// 1. Approve tokens (if not already approved)
const tokenContract = new ethers.Contract(tokenIn, ERC20_ABI, signer);
const allowance = await tokenContract.allowance(userAddress, DIAMOND_ADDRESS);
if (allowance < amountIn) {
const approveTx = await tokenContract.approve(DIAMOND_ADDRESS, amountIn);
await approveTx.wait();
}
// 2. Get quote
const quote = await tedProtocol.getQuote(tokenIn, tokenOut, amountIn);
// 3. Calculate minimum output with slippage
const minAmountOut = quote.amountOut * (10000n - BigInt(slippageBps)) / 10000n;
// 4. Execute swap
const deadline = Math.floor(Date.now() / 1000) + 600; // 10 minutes
const tx = await tedProtocol.swap(
tokenIn,
tokenOut,
amountIn,
minAmountOut,
deadline
);
const receipt = await tx.wait();
// 5. Parse events for confirmation
const swapEvent = receipt.logs.find(log => {
try {
return tedProtocol.interface.parseLog(log)?.name === 'Swap';
} catch { return false; }
});
if (swapEvent) {
const parsed = tedProtocol.interface.parseLog(swapEvent);
return {
amountIn: parsed.args.amountIn,
amountOut: parsed.args.amountOut,
txHash: receipt.hash
};
}
}
Cross-Chain Swap
Execute swaps across different blockchains:
async function executeCrossChainSwap(params) {
const {
tokenIn,
tokenOut,
amountIn,
srcChainId,
dstChainId,
recipient,
slippageBps = 100
} = params;
// 1. Approve tokens
const tokenContract = new ethers.Contract(tokenIn, ERC20_ABI, signer);
const approveTx = await tokenContract.approve(DIAMOND_ADDRESS, amountIn);
await approveTx.wait();
// 2. Estimate fees
const crossChainParams = {
tokenIn,
tokenOut,
amountIn,
minAmountOut: 0n, // Will calculate after quote
srcChainId,
dstChainId,
recipient,
deadline: Math.floor(Date.now() / 1000) + 3600,
bridgeOptions: "0x"
};
const [nativeFee, bridgeFee] = await tedProtocol.estimateFees(crossChainParams);
// 3. Get expected output and set minimum
const quote = await tedProtocol.getQuote(tokenIn, tokenOut, amountIn);
crossChainParams.minAmountOut = quote.amountOut * (10000n - BigInt(slippageBps)) / 10000n;
// 4. Execute cross-chain swap
const tx = await tedProtocol.crossChainSwap(crossChainParams, {
value: nativeFee
});
const receipt = await tx.wait();
// 5. Get message ID for tracking
const event = receipt.logs.find(log => {
try {
return tedProtocol.interface.parseLog(log)?.name === 'CrossChainSwapInitiated';
} catch { return false; }
});
if (event) {
const parsed = tedProtocol.interface.parseLog(event);
return {
messageId: parsed.args.messageId,
txHash: receipt.hash
};
}
}
Tracking Cross-Chain Transfers
Monitor transfer status using the LayerZero Scan API:
async function trackTransfer(messageId) {
const response = await fetch(
`https://api.layerzeroscan.com/tx/${messageId}`
);
const data = await response.json();
return {
status: data.status, // 'INFLIGHT', 'DELIVERED', 'FAILED'
srcTxHash: data.srcTxHash,
dstTxHash: data.dstTxHash
};
}
Token Approvals
Standard Approval
Grants the protocol permission to spend your tokens:
async function approveToken(tokenAddress, amount) {
const token = new ethers.Contract(tokenAddress, ERC20_ABI, signer);
const tx = await token.approve(DIAMOND_ADDRESS, amount);
await tx.wait();
}
Permit (Gasless Approval)
Supported by TEDP and some stablecoins via ERC-2612.
- Sign approval off-chain
- Include in your swap transaction
- Save gas on separate approval transaction
See the API Reference for permit implementation details.
Error Handling
Always simulate transactions before executing and handle custom errors:
async function safeSwap(tokenIn, tokenOut, amountIn) {
try {
// Simulate first
await tedProtocol.swap.staticCall(
tokenIn,
tokenOut,
amountIn,
0n, // Will fail if there's an issue
Math.floor(Date.now() / 1000) + 600
);
// Execute if simulation passes
return await executeSwap(tokenIn, tokenOut, amountIn);
} catch (error) {
// Parse custom errors
if (error.data) {
const iface = new ethers.Interface([
"error InsufficientOutput(uint256 expected, uint256 actual)",
"error DeadlineExpired(uint256 deadline, uint256 timestamp)",
"error UnsupportedToken(address token)",
"error ProtocolPaused()"
]);
try {
const decoded = iface.parseError(error.data);
console.error(`Error: ${decoded.name}`, decoded.args);
} catch {
console.error("Unknown error:", error);
}
}
throw error;
}
}
Best Practices
Always Get Fresh Quotes
Quotes are valid for a short time. Execute immediately after quoting.
Set Appropriate Slippage
| Swap Type | Recommended Slippage |
|---|
| Stablecoin pairs | 0.1-0.5% |
| Cross-chain swaps | 0.5-1% |
| Large amounts | Use lower values |
Handle Network Switching
Ensure users are on the correct network before executing transactions:
async function ensureCorrectNetwork(requiredChainId) {
const currentChainId = await provider.getNetwork().then(n => n.chainId);
if (currentChainId !== requiredChainId) {
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: ethers.toQuantity(requiredChainId) }]
});
}
}
Implement Retry Logic
Network issues can cause temporary failures. Retrying with exponential backoff improves reliability.
Support