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이면 대신 에이전트 지갑 소유자들의 카운터를 읽어 가장 큰 값을 반환합니다.

파라미터

이름 타입 필수 설명
contractAddress address ✓ 주기 거래량 정책을 담고 있는 ContractPolicyConfig가 등록된 컨트랙트 주소입니다.
user address ✓ 누적 거래량을 조회할 계정 주소입니다.
selector bytes ✓ 정책이 바인딩된 4바이트 함수 selector를 bytes로 인코딩한 값입니다. selector 범위 없이("모든 호출에 적용") 등록된 정책을 조회하려면 빈 바이트("")를 전달합니다.
asset string ✓ PeriodicVolumePolicy.tokens 배열에 선언된 자산 식별자입니다. 서버에서 정규화됩니다.
resetPeriodSeconds uint64 ✓ 조회할 카운터를 식별하는 초 단위 주기 길이입니다. 등록된 주기가 이 값과 정확히 일치하는 항목만 반환됩니다.
resolveAgentOwners bool ✓ true이면 user를 에이전트 지갑으로 보고 그 에이전트 소유자들의 카운터(소유자가 없으면 user 자신의 카운터)를 읽어 가장 큰 값을 반환합니다. 에이전트 지갑의 전송이 소유자들의 카운터에 기록되는 것은 컨트랙트의 상한을 에이전트 소유자를 순회하는 FOR_EACH_POLICY로 감쌌을 때뿐이며, 이때 가장 큰 값이 상한에 가장 가까운 소유자의 값입니다. 일반 PERIODIC_VOLUME_POLICY에서는 전송이 지갑 자신의 카운터에 기록되므로 false로 지갑을 조회합니다. false이면 user 자신의 카운터만 조회합니다.

반환값

타입: PeriodicVolume[]

PeriodicVolume { uint256 amount; uint256 maxAmount; uint64 resetPeriodSeconds; uint64 resetAt; } 배열입니다. 튜플과 일치하는 컨트랙트 범위 한도마다 하나씩 항목이 담깁니다. 빈 배열은 일치하는 정책이 없다는 뜻입니다.

에러

코드 이름 설명
InvalidSelector InvalidSelector selector가 비어 있지 않은데 정확히 4바이트가 아닐 때 revert됩니다. 빈 바이트는 유효하며 "이 컨트랙트의 모든 호출"을 의미합니다.

예제

특정 전송 함수에 겹친 모든 컨트랙트 일일 한도 조회

동일한 (자산, 주기) 쌍에 여러 한도가 동시에 존재할 수 있으므로(예: 기본 사용자별 일일 한도와, 특정 selector에만 더 엄격하게 적용되는 한도가 함께 있는 경우), 사용자에게 남은 여유를 표시하기 전에 모든 항목을 순회하여 평가해야 합니다.

import { createPublicClient, http, toFunctionSelector } 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 = toFunctionSelector("transfer(address,uint256)"); // 0xa9059cbb

// 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,
    "atokrw",
    86_400n,
    false,
  ],
});

for (const s of statuses) {
  console.log(`used ${s.amount} / ${s.maxAmount} atokrw, resets at ${s.resetAt}`);
}

빈 selector — 함수 범위 없이 등록된 카운터

빈 바이트 selector는 "모든 호출에 적용" 버킷을 조회합니다. resolveAgentOwners = true와 에이전트 지갑을 user로 함께 사용하면 그 지갑 소유자들의 카운터 중 가장 큰 값을 반환합니다. 컨트랙트가 상한을 에이전트 소유자를 순회하는 FOR_EACH_POLICY로 감쌌다면 이 값이 상한에 가장 가까운 소유자의 값입니다. 일반 PERIODIC_VOLUME_POLICY라면 지갑의 전송이 지갑 자신의 카운터에 기록되므로 false를 전달합니다.

// 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",
    "atokrw",
    86_400n,
    true, // the cap is per owner: FOR_EACH_POLICY over agent owners
  ],
});
ESC
검색어를 입력하세요