Skip to content
LogoLogo

usePermissions

Hook to get the current permissions for the connected account. Automatically updates when permissions change.

Type: hook

Import

import { usePermissions } from '@jaw.id/wagmi';

Signature

function usePermissions(parameters?: {
  address?: Address;
  chainId?: number;
  connector?: Connector;
  config?: Config;
  query?: UseQueryParameters;
}): UseQueryResult;

Parameters

address

Type: Address (optional)

Specific account address to get permissions for. Defaults to connected account.

chainId

Type: number (optional)

Specific chain ID. Defaults to current chain.

connector

Type: Connector (optional)

Specific connector to use. Defaults to active connector.

config

Type: Config (optional)

Wagmi config. If not provided, uses the config from WagmiProvider.

query

Type: UseQueryParameters (optional)

TanStack React Query options (excluding gcTime and staleTime which are managed internally).

Returns

Returns a TanStack React Query result:

PropertyTypeDescription
dataWalletGetPermissionsResponseArray of permissions
isLoadingbooleanWhether initial load is in progress
isFetchingbooleanWhether any fetch is in progress
isSuccessbooleanWhether query succeeded
isErrorbooleanWhether query failed
errorErrorError if query failed
refetchfunctionManually refetch permissions

data

When successful, data is an array of permissions:

type SpendPeriod = 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year' | 'forever';
 
type WalletGetPermissionsResponse = {
  /** Permission identifier (hash) */
  permissionId: string;
  /** Smart account address */
  account: string;
  /** Spender address */
  spender: string;
  /** Start timestamp (unix seconds, inclusive) */
  start: number;
  /** End timestamp (unix seconds, exclusive) */
  end: number;
  /** Salt for permission uniqueness (hex) */
  salt: `0x${string}`;
  /** Call permissions */
  calls: Array<{ target: string; selector: string; checker?: string }>;
  /** Spend limits */
  spends: Array<{ token: string; allowance: string; unit: SpendPeriod; multiplier: number }>;
}[];

Behavior

  1. Auto-enables when wallet is connected
  2. Listens for changes via permissionsChanged event
  3. Auto-refetches when permissions change on-chain
  4. Caches indefinitely until invalidated by events
  5. Returns permissions unfiltered — expired and not-yet-started permissions are included so you can render those states
  6. Validity is a function of time, not of the fetch: because the list is cached, always compare start/end against the current time at render (or before executing), never assume a cached permission is still active

Examples

Basic Usage

import { useAccount } from 'wagmi';
import { usePermissions } from '@jaw.id/wagmi';
 
function PermissionsList() {
  const { isConnected } = useAccount();
  const { data: permissions, isLoading } = usePermissions();
 
  if (!isConnected) return <p>Connect wallet to view permissions</p>;
  if (isLoading) return <p>Loading permissions...</p>;
 
  if (!permissions?.length) {
    return <p>No permissions</p>;
  }
 
  const now = Math.floor(Date.now() / 1000);
 
  return (
    <ul>
      {permissions.map((permission) => (
        <li key={permission.permissionId}>
          <p>Spender: {permission.spender}</p>
          <p>
            {permission.end <= now
              ? 'Expired — grant again to continue'
              : permission.start > now
                ? `Activates: ${new Date(permission.start * 1000).toLocaleString()}`
                : `Expires: ${new Date(permission.end * 1000).toLocaleString()}`}
          </p>
          <p>Calls: {permission.calls.length}</p>
          <p>Spends: {permission.spends.length}</p>
        </li>
      ))}
    </ul>
  );
}

For Specific Address

import { usePermissions } from '@jaw.id/wagmi';
 
function PermissionsForAddress({ address }: { address: `0x${string}` }) {
  const { data: permissions } = usePermissions({ address });
 
  // ...
}

Disable Auto-Fetch

import { usePermissions } from '@jaw.id/wagmi';
 
function ManualPermissions() {
  const { data, refetch } = usePermissions({
    query: {
      enabled: false, // Don't fetch automatically
    },
  });
 
  return (
    <div>
      <button onClick={() => refetch()}>Load Permissions</button>
      {data && <p>{data.length} permissions found</p>}
    </div>
  );
}