IPcl.contractPeriodicList
contractPeriodicList(
address contractAddress,
address user,
bytes selector,
string asset,
bool resolveAgentOwners,
PageRequest pageRequest
) external view returns (PeriodicVolume[] statuses, PageResponse pageResponse) Lists every PERIODIC_VOLUME_POLICY running counter attached to contractAddress that applies to user. Filter by asset and optionally by function selector — pass empty bytes ("0x") to match PolicySets registered without a selector. One entry per distinct reset-period bucket configured on the contract.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
contractAddress | address | ✓ | The contract whose ContractPolicyConfig you want to inspect. |
user | address | ✓ | The address to enumerate counters for. |
selector | bytes | ✓ | 4-byte function selector to narrow the lookup. Empty bytes ("0x") matches PolicySets registered without a selector. |
asset | string | ✓ | Denom filter (for OKRW, "atokrw"). |
resolveAgentOwners | bool | ✓ | If true, user is read as an agent wallet: each entry carries the largest of its agents' owners' counters (user's own when it has none). The owners' counters hold an agent wallet's transfers only when the contract's cap is wrapped in FOR_EACH_POLICY over agent owners; under a plain PERIODIC_VOLUME_POLICY, read the wallet with false. |
pageRequest | PageRequest | ✓ | Standard pagination request struct. |
Returns
(PeriodicVolume[] statuses, PageResponse pageResponse) Array of { amount, maxAmount, resetPeriodSeconds, resetAt } — one per matching contract-scoped periodic policy — plus a pagination cursor.
Examples
List all contract-scoped OKRW periodic caps for a user
Lists every contract-scoped PERIODIC_VOLUME_POLICY counter that applies to user on tokenAddress, across all reset-period buckets. Empty selector matches apply-to-any-call PolicySets.
import { createPublicClient, http, parseAbi, toHex } from "viem";
const PCL = "0x1000000000000000000000000000000000000005";
const pclAbi = parseAbi([
"function contractPeriodicList(address contractAddress, address user, bytes selector, string asset, bool resolveAgentOwners, (bytes key, uint64 offset, uint64 limit, bool countTotal, bool reverse) pageRequest) view returns ((uint256 amount, uint256 maxAmount, uint64 resetPeriodSeconds, uint64 resetAt)[] statuses, (bytes nextKey, uint64 total) pageResponse)",
]);
const client = createPublicClient({ transport: http("https://rpc-testnet.maroo.io") });
const tokenAddress = "0x6666666666666666666666666666666666666666"; // replace before production
const user = "0x7777777777777777777777777777777777777777";
const [statuses] = await client.readContract({
address: PCL,
abi: pclAbi,
functionName: "contractPeriodicList",
args: [
tokenAddress,
user,
toHex("", { size: 0 }),
"atokrw",
false,
{ key: "0x", offset: 0n, limit: 100n, countTotal: false, reverse: false },
],
});
for (const s of statuses) {
// e.g. per-contract daily cap of 10,000,000 OKRW
console.log(`period=${s.resetPeriodSeconds}s used=${s.amount}/${s.maxAmount}`);
} Read an agent wallet's owners' counters on a specific function
Narrows the lookup to the ERC20 transfer selector and reads the agent's owners' counters, the largest in each entry. That matches enforcement when the token's cap is wrapped in FOR_EACH_POLICY over agent owners, which records an agent-driven transfer under each owner. Under a plain PERIODIC_VOLUME_POLICY the transfer is on the wallet's own counter, so pass false.
import { toFunctionSelector } from "viem";
const sel = toFunctionSelector("transfer(address,uint256)");
const agentWallet = "0x8888888888888888888888888888888888888888"; // replace before production
const [statuses] = await client.readContract({
address: PCL,
abi: pclAbi,
functionName: "contractPeriodicList",
args: [
tokenAddress,
agentWallet,
sel,
"atokrw",
true, // the cap is per owner: FOR_EACH_POLICY over agent owners
{ key: "0x", offset: 0n, limit: 100n, countTotal: false, reverse: false },
],
});