IPcl.contractPeriodicVolume
contractPeriodicVolume(address contractAddress, address user, bytes selector, string asset, uint64 resetPeriodSeconds, bool resolveAgentOwners) external view returns (PeriodicVolume memory) Reads the running periodic-volume counter for user under a PERIODIC_VOLUME_POLICY attached to the specific contractAddress. The lookup is narrowed by asset and resetPeriodSeconds, and optionally by function selector — pass empty bytes ("0x") to match PolicySets registered without a selector (i.e. those that apply to any call on the contract).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
contractAddress | address | ✓ | The contract the ContractPolicyConfig is registered on. |
user | address | ✓ | The address whose running volume against this contract you want to read. |
selector | bytes | ✓ | The 4-byte function selector to narrow the PolicySet lookup to. Pass empty bytes ("0x") to match PolicySets registered with an empty selector (apply-to-any-call). |
asset | string | ✓ | The denom string the policy is keyed on (for OKRW, "aokrw"). |
resetPeriodSeconds | uint64 | ✓ | Reset-period length identifying which PERIODIC_VOLUME_POLICY limit on this contract to read. |
resolveAgentOwners | bool | ✓ | If true and user is an agent wallet, aggregate the counter under the agent's owner(s) rather than the agent address itself. |
Returns
PeriodicVolume Struct { uint256 amount, uint256 maxAmount, uint64 resetPeriodSeconds, uint64 resetAt } describing the running counter, the policy limit, the period length, and the window rollover timestamp.
Examples
Check a per-contract daily OKRW cap
Reads the 24-hour OKRW volume counter for user against tokenAddress, matching any PolicySet registered without a specific selector. A typical cap on this scope is 10,000,000 OKRW/day.
import { createPublicClient, http, parseAbi, toHex } from "viem";
const PCL = "0x1000000000000000000000000000000000000005";
const pclAbi = parseAbi([
"function contractPeriodicVolume(address contractAddress, address user, bytes selector, string asset, uint64 resetPeriodSeconds, bool resolveAgentOwners) view returns ((uint256 amount, uint256 maxAmount, uint64 resetPeriodSeconds, uint64 resetAt))",
]);
const client = createPublicClient({ transport: http("https://rpc-testnet.maroo.io") });
const tokenAddress = "0x3333333333333333333333333333333333333333"; // replace before production
const user = "0x4444444444444444444444444444444444444444";
const v = await client.readContract({
address: PCL,
abi: pclAbi,
functionName: "contractPeriodicVolume",
args: [tokenAddress, user, toHex("", { size: 0 }), "aokrw", 86_400n, false],
});
// e.g. maxAmount = 10_000_000 * 10^18 aokrw (10,000,000 OKRW daily cap)
console.log(`${v.amount} / ${v.maxAmount} aokrw used, resets at ${v.resetAt}`); Narrow by function selector
When the same contract has different PERIODIC_VOLUME_POLICY PolicySets attached to different functions, pass the target function's 4-byte selector to read the correct counter.
import { encodeFunctionData, toFunctionSelector } from "viem";
// e.g. ERC20.transfer(address,uint256)
const sel = toFunctionSelector("transfer(address,uint256)");
const v = await client.readContract({
address: PCL,
abi: pclAbi,
functionName: "contractPeriodicVolume",
args: [tokenAddress, user, sel, "aokrw", 86_400n, false],
});