IPcl.contractPeriodicVolume
contractPeriodicVolume(
address contractAddress,
address user,
bytes calldata selector,
string calldata asset,
uint64 resetPeriodSeconds,
bool resolveAgentOwners
) external view returns (PeriodicVolume[] memory statuses) contractAddress에서 user에 대해 요청한 (selector, asset, resetPeriodSeconds) 튜플과 일치하는 모든 컨트랙트 범위 주기 거래량 카운터를 반환합니다. 동일한 주기에 서로 다른 maxAmount 한도가 여러 개 등록될 수 있으므로(예: 함수별 상한 아래에 지갑 등급 상한이 겹쳐 있는 경우), 호출자는 단일 레코드를 가정하지 말고 반환 배열을 순회하여 결합해야 합니다. 빈 배열은 해당 튜플에 컨트랙트 정책이 등록되어 있지 않다는 뜻입니다. 함수 selector 범위 없이 등록된 카운터를 조회하려면 빈 selector를 전달합니다. resolveAgentOwners = true이면 user가 소유한 모든 에이전트의 거래량을 합산합니다.
파라미터
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
contractAddress | address | ✓ | 주기 거래량 정책을 담고 있는 ContractPolicyConfig가 등록된 컨트랙트 주소입니다. |
user | address | ✓ | 누적 거래량을 조회할 계정 주소입니다. |
selector | bytes | ✓ | 정책이 바인딩된 4바이트 함수 selector를 bytes로 인코딩한 값입니다. selector 범위 없이("모든 호출에 적용") 등록된 정책을 조회하려면 빈 바이트("")를 전달합니다. |
asset | string | ✓ | PeriodicVolumePolicy.tokens 배열에 선언된 자산 식별자입니다. 서버에서 정규화됩니다. |
resetPeriodSeconds | uint64 | ✓ | 조회할 카운터를 식별하는 초 단위 주기 길이입니다. 등록된 주기가 이 값과 정확히 일치하는 항목만 반환됩니다. |
resolveAgentOwners | bool | ✓ | true이면 소유자가 user인 모든 에이전트의 거래량을 합산합니다. false이면 user 자신의 카운터만 조회합니다. |
반환값
PeriodicVolume[] PeriodicVolume { uint256 amount; uint256 maxAmount; uint64 resetPeriodSeconds; uint64 resetAt; } 배열입니다. 튜플과 일치하는 컨트랙트 범위 한도마다 하나씩 항목이 담깁니다. 빈 배열은 일치하는 정책이 없다는 뜻입니다.
에러
| 코드 | 이름 | 설명 |
|---|---|---|
InvalidSelector | InvalidSelector | selector가 비어 있지 않은데 정확히 4바이트가 아닐 때 revert됩니다. 빈 바이트는 유효하며 "이 컨트랙트의 모든 호출"을 의미합니다. |
예제
특정 전송 함수에 겹친 모든 컨트랙트 일일 한도 조회
동일한 (자산, 주기) 쌍에 여러 한도가 동시에 존재할 수 있으므로(예: 기본 사용자별 일일 한도와, 특정 selector에만 더 엄격하게 적용되는 한도가 함께 있는 경우), 사용자에게 남은 여유를 표시하기 전에 모든 항목을 순회하여 평가해야 합니다.
import { createPublicClient, http, toHex, keccak256, toBytes } from "viem";
const PCL = "0x1000000000000000000000000000000000000005" as const;
const pclAbi = [{
name: "contractPeriodicVolume", type: "function", stateMutability: "view",
inputs: [
{ name: "contractAddress", type: "address" },
{ name: "user", type: "address" },
{ name: "selector", type: "bytes" },
{ name: "asset", type: "string" },
{ name: "resetPeriodSeconds", type: "uint64" },
{ name: "resolveAgentOwners", type: "bool" },
],
outputs: [{
type: "tuple[]",
components: [
{ name: "amount", type: "uint256" },
{ name: "maxAmount", type: "uint256" },
{ name: "resetPeriodSeconds", type: "uint64" },
{ name: "resetAt", type: "uint64" },
],
}],
}] as const;
const client = createPublicClient({ transport: http("https://rpc-testnet.maroo.io") });
// 4-byte selector for transfer(address,uint256).
const transferSelector = toHex(keccak256(toBytes("transfer(address,uint256)")).slice(0, 4));
// TODO: replace with the real contract + user addresses before production.
const statuses = await client.readContract({
address: PCL,
abi: pclAbi,
functionName: "contractPeriodicVolume",
args: [
"0x8f3aC2b1D9e74C05a6B18Fe27dC4913E5A0f7b62",
"0x2d1e4A98F0Cc78bC3d5FA47a6E1B927dE04B85b1",
transferSelector,
"aokrw",
86_400n,
false,
],
});
for (const s of statuses) {
console.log(`used ${s.amount} / ${s.maxAmount} aokrw, resets at ${s.resetAt}`);
} 빈 selector — 함수 범위 없이 등록된 카운터
빈 바이트 selector는 "모든 호출에 적용" 버킷을 조회합니다. resolveAgentOwners = true와 함께 사용하면 소유한 하위 에이전트가 있을 때 소유자가 바라보는 상한을 반환합니다.
// A PolicySet registered with selector = "" applies to every call on the target.
// Pass empty bytes to read that counter class.
const statuses = await client.readContract({
address: PCL,
abi: pclAbi,
functionName: "contractPeriodicVolume",
args: [
"0x8f3aC2b1D9e74C05a6B18Fe27dC4913E5A0f7b62",
"0x2d1e4A98F0Cc78bC3d5FA47a6E1B927dE04B85b1",
"0x",
"aokrw",
86_400n,
true, // include agent owners
],
});