Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

useRevokePermissions

Hook to revoke an active permission by its ID. This permanently disables the permission, preventing the spender from executing any further calls.

Type: hook

Import

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

Signature

function useRevokePermissions(parameters?: {
  config?: Config;
  mutation?: UseMutationParameters;
}): UseMutationResult

Parameters

config

Type: Config (optional)

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

mutation

Type: UseMutationParameters (optional)

TanStack React Query mutation options.

Returns

Returns a TanStack React Query mutation result:

PropertyTypeDescription
mutatefunctionFunction to revoke permission
mutateAsyncfunctionAsync version of mutate
dataRevokePermissionApiResponseRevocation result
isPendingbooleanWhether revocation is in progress
isSuccessbooleanWhether revocation succeeded
isErrorbooleanWhether revocation failed
errorErrorError if revocation failed

data

When successful, data contains:

interface RevokePermissionApiResponse {
  /** Indicates if the permission was revoked successfully */
  success: boolean;
}

Mutation Variables

When calling mutate(), pass an object with the following properties:

id (required)

Type: Hex (e.g., `0x${string}`)

The permission ID (hash) to revoke. You can obtain this from:

  • The permissionId field returned when granting a permission
  • The permissionId field from permissions returned by usePermissions()
// From grant response
const { data } = useGrantPermissions();
const permissionId = data.permissionId; // '0x1234...'
 
// From permissions list
const { data: permissions } = usePermissions();
const permissionId = permissions[0].permissionId; // '0x1234...'

address (optional)

Type: Address

Specific account address to revoke the permission for. Defaults to the connected account.

revoke({
  id: '0x1234...',
  address: '0xSpecificAccount...', // Optional: specify which account
});

chainId (optional)

Type: number

Target chain ID where the permission exists. Defaults to the connected chain.

revoke({
  id: '0x1234...',
  chainId: 8453, // Revoke on Base
});

connector (optional)

Type: Connector

Specific connector to use. Defaults to the active connector.

capabilities (optional)

Type: RequestCapabilities

Optional capabilities for the revocation transaction, such as paymaster service for sponsored (gasless) revocation.

interface RequestCapabilities {
  /** Paymaster service for sponsored transactions */
  paymasterService?: {
    /** URL of the paymaster service (ERC-7677 compliant) */
    url: string;
    /** Optional context for the paymaster */
    context?: Record<string, unknown>;
  };
}
// Sponsored revocation (gasless)
revoke({
  id: '0x1234...',
  capabilities: {
    paymasterService: {
      url: 'https://paymaster.example.com',
    },
  },
});

Examples

Basic Usage

import { useRevokePermissions } from '@jaw.id/wagmi';
 
function RevokeButton({ permissionId }: { permissionId: `0x${string}` }) {
  const { mutate: revoke, isPending } = useRevokePermissions();
 
  return (
    <button
      onClick={() => revoke({ id: permissionId })}
      disabled={isPending}
    >
      {isPending ? 'Revoking...' : 'Revoke Permission'}
    </button>
  );
}

With Confirmation Dialog

import { useState } from 'react';
import { useRevokePermissions } from '@jaw.id/wagmi';
 
function RevokeWithConfirmation({ permission }) {
  const { mutate: revoke, isPending } = useRevokePermissions();
  const [showConfirm, setShowConfirm] = useState(false);
 
  const handleRevoke = () => {
    revoke(
      { id: permission.permissionId },
      {
        onSuccess: () => {
          setShowConfirm(false);
          // Permission list will auto-update via usePermissions
        },
      }
    );
  };
 
  if (showConfirm) {
    return (
      <div className="confirm-dialog">
        <p>Revoke permission for {permission.spender}?</p>
        <p className="warning">This action cannot be undone.</p>
        <button onClick={handleRevoke} disabled={isPending}>
          {isPending ? 'Revoking...' : 'Confirm Revoke'}
        </button>
        <button onClick={() => setShowConfirm(false)}>Cancel</button>
      </div>
    );
  }
 
  return <button onClick={() => setShowConfirm(true)}>Revoke</button>;
}

With Callbacks

import { useRevokePermissions } from '@jaw.id/wagmi';
import { toast } from 'sonner';
 
function RevokeWithCallbacks() {
  const { mutate: revoke } = useRevokePermissions({
    mutation: {
      onSuccess: () => {
        toast.success('Permission revoked successfully');
      },
      onError: (error) => {
        toast.error(`Failed to revoke: ${error.message}`);
      },
    },
  });
 
  // ...
}

Full Permissions Manager

import { usePermissions, useRevokePermissions } from '@jaw.id/wagmi';
 
function PermissionsManager() {
  const { data: permissions, isLoading } = usePermissions();
  const { mutate: revoke, isPending, variables } = useRevokePermissions();
 
  if (isLoading) return <p>Loading permissions...</p>;
  if (!permissions?.length) return <p>No active permissions</p>;
 
  return (
    <div>
      <h2>Active Permissions</h2>
      {permissions.map((permission) => {
        const isRevoking = isPending && variables?.id === permission.permissionId;
 
        return (
          <div key={permission.permissionId} className="permission-card">
            <div className="permission-info">
              <p><strong>Spender:</strong> {permission.spender}</p>
              <p><strong>Expires:</strong> {new Date(permission.end * 1000).toLocaleDateString()}</p>
              <p><strong>Call Permissions:</strong> {permission.calls.length}</p>
              <p><strong>Spend Limits:</strong> {permission.spends.length}</p>
            </div>
            <button
              onClick={() => revoke({ id: permission.permissionId })}
              disabled={isPending}
            >
              {isRevoking ? 'Revoking...' : 'Revoke'}
            </button>
          </div>
        );
      })}
    </div>
  );
}

Revoke on Specific Chain

import { useRevokePermissions } from '@jaw.id/wagmi';
import { base } from 'wagmi/chains';
 
function RevokeOnBase({ permissionId }) {
  const { mutate: revoke, isPending } = useRevokePermissions();
 
  const handleRevoke = () => {
    revoke({
      id: permissionId,
      chainId: base.id, // Revoke on Base chain
    });
  };
 
  return (
    <button onClick={handleRevoke} disabled={isPending}>
      Revoke Permission on Base
    </button>
  );
}

Sponsored Revocation (Gasless)

import { useRevokePermissions } from '@jaw.id/wagmi';
 
function SponsoredRevoke({ permissionId }) {
  const { mutate: revoke, isPending } = useRevokePermissions();
 
  const handleRevoke = () => {
    revoke({
      id: permissionId,
      capabilities: {
        paymasterService: {
          url: 'https://your-paymaster.com/api',
        },
      },
    });
  };
 
  return (
    <button onClick={handleRevoke} disabled={isPending}>
      Revoke (Gasless)
    </button>
  );
}

Important Notes

Related