Skip to content

Commit 041c7be

Browse files
committed
wip
1 parent 6847852 commit 041c7be

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

src/wallet.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2764,3 +2764,108 @@ pub fn encode_usdc_paymaster_data(
27642764

27652765
data
27662766
}
2767+
2768+
/// Creates the ABI-encoded calldata for an ERC20 `permit` call.
2769+
/// This is used when the TBA needs to call permit on-chain (since TBAs can't sign off-chain)
2770+
///
2771+
/// # Arguments
2772+
/// * `owner` - The address that owns the tokens (the TBA in this case)
2773+
/// * `spender` - The address to grant allowance to (e.g., the paymaster)
2774+
/// * `value` - The amount of tokens to approve
2775+
/// * `deadline` - The deadline timestamp for the permit
2776+
///
2777+
/// # Returns
2778+
/// A `Vec<u8>` containing the ABI-encoded calldata for the permit function
2779+
pub fn create_erc20_permit_calldata(
2780+
owner: EthAddress,
2781+
spender: EthAddress,
2782+
value: U256,
2783+
deadline: U256,
2784+
) -> Vec<u8> {
2785+
// For on-chain permit calls by the TBA, we don't need nonce, v, r, s
2786+
// The TBA will call permit() directly as the owner
2787+
// This creates calldata for: permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
2788+
// But for TBA on-chain calls, v=0, r=0, s=0 works because the TBA IS the owner
2789+
2790+
use alloy_sol_types::SolCall;
2791+
2792+
// Define the permit function call
2793+
// Note: Using the standard ERC20Permit interface
2794+
sol! {
2795+
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s);
2796+
}
2797+
2798+
let call = permitCall {
2799+
owner,
2800+
spender,
2801+
value,
2802+
deadline,
2803+
v: 0, // Dummy values for on-chain call
2804+
r: B256::ZERO,
2805+
s: B256::ZERO,
2806+
};
2807+
2808+
call.abi_encode()
2809+
}
2810+
2811+
/// Creates a multicall calldata that combines permit + another operation
2812+
/// This is useful for TBAs to approve and use tokens in a single transaction
2813+
pub fn create_multicall_permit_and_execute(
2814+
token_address: EthAddress,
2815+
permit_spender: EthAddress,
2816+
permit_amount: U256,
2817+
permit_deadline: U256,
2818+
execute_target: EthAddress,
2819+
execute_calldata: Vec<u8>,
2820+
execute_value: U256,
2821+
) -> Vec<u8> {
2822+
// Create permit calldata
2823+
let permit_calldata = create_erc20_permit_calldata(
2824+
EthAddress::ZERO, // Will be replaced by TBA address when executed
2825+
permit_spender,
2826+
permit_amount,
2827+
permit_deadline,
2828+
);
2829+
2830+
// For TBA execute, we need to create two execute calls:
2831+
// 1. Execute permit on token contract
2832+
// 2. Execute the actual operation
2833+
2834+
// This would need to be wrapped in a multicall or batch execute
2835+
// The exact implementation depends on the TBA's interface
2836+
2837+
// For now, return just the permit calldata
2838+
// In practice, this would be combined with the execute calldata
2839+
permit_calldata
2840+
}
2841+
2842+
/// Encode paymaster data for USDC payment with on-chain permit (for TBAs)
2843+
/// This version doesn't include a permit signature since TBAs will call permit on-chain
2844+
pub fn encode_usdc_paymaster_data_for_tba(
2845+
paymaster: EthAddress,
2846+
token_address: EthAddress,
2847+
max_cost: U256,
2848+
) -> Vec<u8> {
2849+
// Start with paymaster address (20 bytes)
2850+
let mut data = Vec::new();
2851+
data.extend_from_slice(paymaster.as_slice());
2852+
2853+
// Add paymaster-specific data for Circle's TokenPaymaster v0.8
2854+
// For TBAs, we might need a different mode or the paymaster needs to support on-chain permits
2855+
2856+
// Mode byte (1 for on-chain approval mode, if supported)
2857+
// Note: This depends on Circle's paymaster implementation
2858+
// Mode 0 = permit signature mode (for EOAs)
2859+
// Mode 1 = assume pre-existing approval (for smart contracts)
2860+
data.push(1u8);
2861+
2862+
// Token address (USDC)
2863+
data.extend_from_slice(token_address.as_slice());
2864+
2865+
// Max cost amount
2866+
data.extend_from_slice(&max_cost.to_be_bytes::<32>());
2867+
2868+
// No signature needed for on-chain approval mode
2869+
2870+
data
2871+
}

0 commit comments

Comments
 (0)