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
  ],
});
ESC
검색어를 입력하세요