Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | 28x 29x 3x 3x 14x 15x 9x 1x 10x 2x 5x 63x 63x 9x | import { encodeAbiParameters, encodePacked, parseAbiParameters } from 'viem';
import { getChainContracts } from '../constants.ts';
import type { Address, Caveat, CaveatType, Hex } from '../types.ts';
/**
* Encode caveat terms for the AllowedTargets enforcer.
* Restricts delegation to only call specific contract addresses.
*
* @param targets - The allowed target addresses.
* @returns The ABI-encoded terms.
*/
export function encodeAllowedTargets(targets: Address[]): Hex {
// AllowedTargetsEnforcer expects packed 20-byte addresses (not ABI-encoded).
return encodePacked(
targets.map(() => 'address' as const),
targets,
);
}
/**
* Encode caveat terms for the AllowedCalldata enforcer.
* Restricts a byte range of the execution calldata to an expected value.
* Commonly used to pin a function argument (e.g. a recipient address).
*
* @param options - Options for the caveat.
* @param options.dataStart - Byte offset into calldata where the check begins.
* @param options.value - The expected byte value at that offset.
* @returns The packed terms (32-byte offset ++ value bytes).
*/
export function encodeAllowedCalldata(options: {
dataStart: number;
value: Hex;
}): Hex {
const startHex = options.dataStart.toString(16).padStart(64, '0');
// Strip the 0x prefix from value and concatenate
return `0x${startHex}${options.value.slice(2)}`;
}
/**
* Encode caveat terms for the AllowedMethods enforcer.
* Restricts delegation to only call specific function selectors.
*
* @param selectors - The 4-byte function selectors.
* @returns The ABI-encoded terms.
*/
export function encodeAllowedMethods(selectors: Hex[]): Hex {
// AllowedMethodsEnforcer expects packed 4-byte selectors (not ABI-encoded).
return encodePacked(
selectors.map(() => 'bytes4' as const),
selectors,
);
}
/**
* Encode caveat terms for the ValueLte enforcer.
* Limits the ETH value that can be sent in a single call.
*
* @param maxValue - The maximum value in wei (as bigint).
* @returns The ABI-encoded terms.
*/
export function encodeValueLte(maxValue: bigint): Hex {
return encodeAbiParameters(parseAbiParameters('uint256'), [maxValue]);
}
/**
* Encode caveat terms for the NativeTokenTransferAmount enforcer.
* Limits the total cumulative ETH that can be spent across all
* transactions using this delegation (stateful, tracked on-chain).
*
* @param maxAmount - The maximum total amount in wei (as bigint).
* @returns The ABI-encoded terms.
*/
export function encodeNativeTokenTransferAmount(maxAmount: bigint): Hex {
return encodeAbiParameters(parseAbiParameters('uint256'), [maxAmount]);
}
/**
* Encode caveat terms for the ERC20TransferAmount enforcer.
* Limits the amount of an ERC-20 token that can be transferred.
*
* @param options - Options for the caveat.
* @param options.token - The ERC-20 token contract address.
* @param options.amount - The maximum amount of tokens.
* @returns The ABI-encoded terms.
*/
export function encodeErc20TransferAmount(options: {
token: Address;
amount: bigint;
}): Hex {
// ERC20TransferAmountEnforcer expects packed address (20 bytes) + uint256
// (32 bytes) = 52 bytes total.
return encodePacked(['address', 'uint256'], [options.token, options.amount]);
}
/**
* Encode caveat terms for the LimitedCalls enforcer.
* Limits the total number of calls that can be made with this delegation.
*
* @param maxCalls - The maximum number of calls.
* @returns The ABI-encoded terms.
*/
export function encodeLimitedCalls(maxCalls: number): Hex {
return encodeAbiParameters(parseAbiParameters('uint256'), [BigInt(maxCalls)]);
}
/**
* Encode caveat terms for the Timestamp enforcer.
* Restricts delegation usage to a specific time window.
*
* @param options - Options for the caveat.
* @param options.after - The earliest allowed timestamp (unix seconds).
* @param options.before - The latest allowed timestamp (unix seconds).
* @returns The ABI-encoded terms.
*/
export function encodeTimestamp(options: {
after: number;
before: number;
}): Hex {
return encodeAbiParameters(parseAbiParameters('uint128, uint128'), [
BigInt(options.after),
BigInt(options.before),
]);
}
/**
* Build a Caveat struct from a type and encoded terms.
*
* @param options - Options for the caveat.
* @param options.type - The caveat type.
* @param options.terms - The ABI-encoded terms.
* @param options.enforcerAddress - Optional override for the enforcer address.
* @param options.chainId - Optional chain ID to look up enforcer addresses.
* @returns The Caveat struct.
*/
export function makeCaveat(options: {
type: CaveatType;
terms: Hex;
enforcerAddress?: Address;
chainId?: number;
}): Caveat {
const enforcer =
options.enforcerAddress ??
getChainContracts(options.chainId).enforcers[options.type];
return {
enforcer,
terms: options.terms,
type: options.type,
};
}
/**
* Get the well-known enforcer address for a caveat type.
*
* @param caveatType - The caveat type.
* @param chainId - Optional chain ID to look up enforcer addresses.
* @returns The enforcer address.
*/
export function getEnforcerAddress(
caveatType: CaveatType,
chainId?: number,
): Address {
return getChainContracts(chainId).enforcers[caveatType];
}
|