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

Type: 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],
});
ESC
Type to search