getPendingRevocationEtas
Read the Instant Layer’s scheduled revocation ETA for each of a delegate’s selectors — the only on-chain signal that a revocation is in flight.
import { getPendingRevocationEtas, getSessionKeySelectors } from "@symmio/trading-core";
const selectors = getSessionKeySelectors(config, { chainId });
const etas = await getPendingRevocationEtas(config, {
delegator: { addr: subAccount, isPartyB: false },
delegate: sessionKeyAddress,
selectors,
});
const now = BigInt(Math.floor(Date.now() / 1000));
const isRevoking = [...etas.values()].some((eta) => eta > now);Nothing else reveals a pending revocation.
initiateRevokeDelegation does not clear the grant — it stamps
pendingRevocationEta = block.timestamp + revocationCooldown and the contract keeps enforcing the delegation until
that ETA passes. getIsDelegationActive and
getActiveDelegations therefore keep answering “active” for the whole
cooldown — correctly, because the key really can still sign. A UI that renders only those reads shows a reassuring
“ready” right through a revocation.
Probe the granted selectors, not the active ones
Pass the set the key was granted — the output of getSessionKeySelectors, the same list handed to getActiveDelegations.
It is tempting to feed getActiveDelegations’ matched selectors back in here, but that list empties out at exactly the wrong moment: enforcement stops the instant the ETA passes, while the schedule survives until someone finalizes. Probe the active set and a finalize button goes dark precisely when finalizing becomes possible.
A revocation is per selector
initiateRevokeDelegation schedules only the selectors it was handed, so a partial revoke leaves the rest untouched and the result covers a subset of what you probed. The reads are bundled into multicalls of batchSize (default 10).
Parameters
delegatorInstantLayerAccountrequiredThe account the delegation is enforced under. Pass exactly the account that was handed to
initiateRevokeDelegation.
delegateAddressrequiredThe delegated signer whose pending revocations are read.
selectorsreadonly Hex[]requiredSelectors to probe — the granted set.
batchSizenumberoptionalHow many pendingRevocationEta reads to bundle per multicall. Defaults to 10.
chainIdnumberoptionalOptional chain override.
Returns
ReadonlyMap<Hex, bigint>Scheduled revocations keyed by selector, as Unix timestamps in seconds. A probed selector with no scheduled revocation
is absent from the map rather than present with 0n, so map.size === 0 means nothing is being revoked. Keys are
the selectors exactly as they were passed in.
Reading the result
Three states, and they are not the same:
| Condition | Meaning |
|---|---|
map.size === 0 | No revocation scheduled. |
some eta > now | Revoking — the key still signs until that ETA. |
map.size > 0, every eta <= now | Authority already gone; finalizeRevokeDelegation will now go through. |
Finalizing while any scheduled ETA is still in the future reverts with RevocationCooldownNotOver.
This read does not canonicalize. It keys the mapping on delegator.addr verbatim — exactly what
initiateRevokeDelegation and isDelegationActive do. That is unlike
getActiveDelegations, which resolves a virtual account to its parent
sub-account, so a VA address answers here only if the revocation was scheduled against that VA.
Query options
import { getPendingRevocationEtasQueryOptions } from "@symmio/trading-core";
import { useQuery } from "@tanstack/react-query";
useQuery(getPendingRevocationEtasQueryOptions(config, { delegator, delegate, selectors }));The React binding is usePendingRevocation, which pairs this read with a ticking clock so “is it over yet?” answers itself.