IPcl.globalPeriodicVolume
globalPeriodicVolume(
address user,
string calldata asset,
uint64 resetPeriodSeconds,
bool resolveAgentOwners
) external view returns (PeriodicVolume[] memory statuses) 요청한 (asset, resetPeriodSeconds) 쌍에 해당하는 모든 전역 주기 거래량 카운터를 user에 대해 반환합니다. 전역 PERIODIC_VOLUME_POLICY 중 해당 (자산, 주기) 튜플과 일치하는 정책이 없으면 빈 배열을 반환합니다. 그렇지 않으면 등록된 각 한도마다 하나씩 PeriodicVolume 항목을 담습니다. 동일한 주기에 서로 다른 maxAmount 값이 여러 개 등록될 수 있으며, 호출자가 그중 가장 엄격한 한도를 선택할 수 있도록 모두 반환합니다. resolveAgentOwners를 true로 설정하면 대신 에이전트 지갑 소유자들의 카운터를 읽어 그중 가장 큰 값을 반환합니다.
파라미터
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
user | address | ✓ | 누적 거래량을 조회할 계정 주소입니다. |
asset | string | ✓ | PeriodicVolumePolicy.tokens 배열에 선언된 자산 식별자입니다(보통 base denom, 예: "atokrw"). 서버에서 정규화됩니다. |
resetPeriodSeconds | uint64 | ✓ | 조회할 카운터를 식별하는 초 단위 주기 길이입니다(예: 24시간 윈도는 86400). 등록된 주기가 이 값과 정확히 일치하는 항목만 반환됩니다. |
resolveAgentOwners | bool | ✓ | true이면 user를 에이전트 지갑으로 보고 그 에이전트 소유자들의 카운터(소유자가 없으면 user 자신의 카운터)를 읽어 가장 큰 값을 반환합니다. 에이전트 지갑의 전송이 소유자들의 카운터에 기록되는 것은 상한을 에이전트 소유자를 순회하는 FOR_EACH_POLICY로 감쌌을 때뿐입니다. maroo-testnet-1의 전역 일일 한도가 이렇게 감싸여 있으므로, 테스트넷에서는 true가 상한에 가장 가까운 소유자의 값을 반환합니다. false이면 user 자신의 카운터만 조회합니다. |
반환값
타입:
PeriodicVolume[] PeriodicVolume { uint256 amount; uint256 maxAmount; uint64 resetPeriodSeconds; uint64 resetAt; } 배열입니다. (자산, 주기) 튜플과 일치하는 등록 한도마다 하나씩 항목이 담깁니다. 빈 배열은 해당 튜플에 등록된 정책이 없다는 뜻입니다.
예제
사용자에게 적용되는 모든 전역 일일 OKRW 한도 조회
동일한 (자산, 주기) 튜플에 여러 한도가 공존할 수 있으므로, 단일 레코드를 가정하지 말고 반환 배열을 순회하여 결합해야 합니다. 보통은 남은 여유(remaining headroom)의 최솟값을 취합니다.
import { createPublicClient, http } from "viem";
const PCL = "0x1000000000000000000000000000000000000005" as const;
const pclAbi = [{
name: "globalPeriodicVolume", type: "function", stateMutability: "view",
inputs: [
{ name: "user", type: "address" },
{ 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") });
// TODO: replace with the real end-user address before production.
const statuses = await client.readContract({
address: PCL,
abi: pclAbi,
functionName: "globalPeriodicVolume",
args: ["0x8F3ac2B1d9E74c05A6B18FE27Dc4913e5A0F7b62", "atokrw", 86_400n, false],
});
if (statuses.length === 0) {
console.log("no periodic-volume policy is currently registered for this (asset, period)");
} else {
// Pick the tightest applicable cap — remaining headroom is min(maxAmount - amount) across entries.
// `amount` can pass `maxAmount`: the testnet records volume for attested senders too, who are not held to the cap.
const left = (s: (typeof statuses)[number]) => (s.amount >= s.maxAmount ? 0n : s.maxAmount - s.amount);
const headroom = statuses.reduce<bigint>((min, s) => (left(s) < min ? left(s) : min), left(statuses[0]));
console.log(`tightest remaining headroom: ${headroom} atokrw`);
} Solidity에서 동일한 카운터 조회
Solidity view가 메모리 배열을 반환하므로, 컨트랙트가 추가 RPC 호출 없이 순회하며 가장 엄격한 한도를 선택할 수 있습니다.
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.28;
import "@maroo-chain/contracts/precompiles/pcl/IPcl.sol";
contract HeadroomView {
IPcl constant pcl = IPcl(0x1000000000000000000000000000000000000005);
/// @return tightest Minimum remaining headroom across every registered
/// global periodic-volume limit for the (atokrw, 24h) counter.
function remainingDailyHeadroom(address user) external view returns (uint256 tightest) {
PeriodicVolume[] memory rows =
pcl.globalPeriodicVolume(user, "atokrw", 86_400, false);
if (rows.length == 0) {
return type(uint256).max; // no policy → unbounded
}
tightest = type(uint256).max;
for (uint256 i = 0; i < rows.length; ++i) {
// amount can pass maxAmount (attested senders are recorded but not held to the cap)
uint256 left = rows[i].amount >= rows[i].maxAmount ? 0 : rows[i].maxAmount - rows[i].amount;
if (left < tightest) tightest = left;
}
}
}