Standard Commission Calls
The standard commissionCall is the bread and butter of the protocol. It allows you to wrap a batch of transactions and attach a commission.
WHEN TO USE
Use this for simple, independent actions.
- Example: "Deposit 100 USDC into Aave"
- Example: "Buy 1 ETH NFT on OpenSea"
Do not use if you need the output of step 1 to be the input of step 2.
The Flow
- Fund: User sends ETH/Tokens to CommissionRoad.
- Execute: CommissionRoad executes the calls as
msg.sender. - Sweep: CommissionRoad sends the results back to the user.
Implementation
1. Encode your calls (including the Sweep!)
Since CommissionRoad performs the action, it usually receives the output tokens. You must instruct it to send them back to the user.
typescript
import { encodeFunctionData, parseEther } from "viem";
// A. The Action (e.g., Swap on Uniswap)
// Note: 'recipient' in the swap data should be CommissionRoad address (or user if supported)
const swapData = encodeFunctionData({ ... });
// B. The Sweep (Get tokens back to user)
const sweepData = encodeFunctionData({
abi: commissionRoadAbi,
functionName: "sweepERC20Token",
args: [outputTokenAddress, userAddress]
});
const batchCallData = [
{ target: swapRouter, callData: swapData, value: 0n },
{ target: commissionRoadAddress, callData: sweepData, value: 0n } // Critical!
];2. Calculate Commission and Call
typescript
await commissionRoad.write.commissionCall([
batchCallData,
nftId,
ethAddress,
commission,
], { value: totalEthNeeded });Permit2 Integration
CommissionRoad works natively with Permit2, allowing you to pay commissions in any token and handle approvals efficiently.
WHY IT'S NICE
- Single Approval: Users approve the
Permit2contract once per token. - Any Token: Pay commissions in USDC, DAI, or the token being swapped.
To use Permit2, simply include the permitTransferFrom call as the first call in your batchCallData.
typescript
// 1. Sign Permit
const signature = await signPermit2(user, permit, commissionRoadAddress);
// 2. Add as First Call
const permitCall = encodeFunctionData({
abi: permit2Abi,
functionName: "permitTransferFrom",
args: [permit, transferDetails, userAddress, signature]
});
batchCallData.unshift({
target: permit2Address,
callData: permitCall,
value: 0n
});⚠️ Gotchas
- Context: The target contract sees
CommissionRoadas themsg.sender, not the user. - No Chaining: You cannot use the result of Call A in Call B.