Skip to content

use7702Authorization

The use7702Authorization hook enables signing of EIP-7702 authorization payloads, allowing Externally Owned Accounts (EOAs) to temporarily behave like smart contract accounts. This unlocks features like gasless transactions, batch operations, and enhanced security for regular wallets.

Import

import { use7702Authorization } from '@openfort/openfort-react';

Usage

import { use7702Authorization } from '@openfort/openfort-react';
import { usePublicClient } from 'wagmi';
import { sepolia } from 'viem/chains';
 
function Authorize7702() {
  const { signAuthorization } = use7702Authorization();
  const publicClient = usePublicClient();
 
  const handleAuthorization = async () => {
    try {
      // Get the current nonce for the account
      const nonce = await publicClient.getTransactionCount({
        address: '0x...', // Your EOA address
      });
 
      // Sign the authorization
      const signedAuth = await signAuthorization({
        contractAddress: '0xe6Cae83BdE06E4c305530e199D7217f42808555B', // Implementation contract
        chainId: sepolia.id,
        nonce,
      });
 
      console.log('Authorization signed:', signedAuth);
      // Use signedAuth in your transaction
    } catch (error) {
      console.error('Failed to sign authorization:', error);
    }
  };
 
  return (
    <button onClick={handleAuthorization}>
      Sign Authorization
    </button>
  );
}

Parameters

signAuthorization Parameters

PropertyTypeRequiredDescription
contractAddressAddressYesThe smart contract implementation address to authorize
chainIdnumberYesThe chain ID where the authorization will be used
noncenumberYesThe current transaction count for the account

Options (Optional)

PropertyTypeDefaultDescription
hashMessagebooleanfalseWhether to hash the message before signing
arrayifyMessagebooleanfalseWhether to arrayify the message before signing

Return Value

signAuthorization Function

Returns a Promise<SignedAuthorization> with the following structure:

PropertyTypeDescription
addressAddressThe contract address that was authorized
chainIdnumberThe chain ID for the authorization
noncenumberThe nonce used in the authorization
rHexThe r component of the signature
sHexThe s component of the signature
vbigintThe v component of the signature
yParitynumberThe y parity of the signature

Examples

Complete EIP-7702 Flow with Pimlico

import { use7702Authorization } from '@openfort/openfort-react';
import { usePublicClient, useWalletClient } from 'wagmi';
import { sepolia } from 'viem/chains';
import { toSimpleSmartAccount } from 'permissionless/accounts';
import { createSmartAccountClient } from 'permissionless';
import { createPimlicoClient } from 'permissionless/clients/pimlico';
 
function Send7702Transaction() {
  const { signAuthorization } = use7702Authorization();
  const publicClient = usePublicClient();
  const { data: walletClient } = useWalletClient();
 
  const sendGaslessTransaction = async () => {
    if (!walletClient) return;
 
    // 1. Create smart account
    const simpleSmartAccount = await toSimpleSmartAccount({
      owner: walletClient,
      client: publicClient,
      address: walletClient.account.address,
      entryPoint: {
        address: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
        version: '0.8',
      },
    });
 
    // 2. Sign EIP-7702 authorization
    const nonce = await publicClient.getTransactionCount({
      address: walletClient.account.address,
    });
 
    const authorization = await signAuthorization({
      contractAddress: '0xe6Cae83BdE06E4c305530e199D7217f42808555B',
      chainId: sepolia.id,
      nonce,
    });
 
    // 3. Create Pimlico client
    const pimlicoClient = createPimlicoClient({
      transport: http(`https://api.pimlico.io/v2/sepolia/rpc?apikey=${apiKey}`),
      entryPoint: {
        address: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
        version: '0.8',
      },
    });
 
    // 4. Create smart account client
    const smartAccountClient = createSmartAccountClient({
      account: simpleSmartAccount,
      chain: sepolia,
      bundlerTransport: http(`https://api.pimlico.io/v2/sepolia/rpc?apikey=${apiKey}`),
      paymaster: pimlicoClient,
      userOperation: {
        estimateFeesPerGas: async () => {
          return (await pimlicoClient.getUserOperationGasPrice()).fast;
        },
      },
    });
 
    // 5. Send gasless transaction
    const txHash = await smartAccountClient.sendTransaction({
      calls: [
        {
          to: '0x0000000000000000000000000000000000000000',
          data: '0x',
          value: BigInt(0),
        },
      ],
      factory: '0x7702',
      factoryData: '0x',
      authorization,
      paymasterContext: {
        sponsorshipPolicyId: process.env.NEXT_PUBLIC_SPONSORSHIP_POLICY_ID,
      },
    });
 
    console.log('Transaction sent:', txHash);
  };
 
  return (
    <button onClick={sendGaslessTransaction}>
      Send Gasless Transaction
    </button>
  );
}

Basic Authorization Signing

const { signAuthorization } = use7702Authorization();
 
// Sign authorization for a specific contract
const authorization = await signAuthorization({
  contractAddress: '0xe6Cae83BdE06E4c305530e199D7217f42808555B',
  chainId: 11155111, // Sepolia
  nonce: 0,
});
 
console.log('Signed authorization:', {
  address: authorization.address,
  chainId: authorization.chainId,
  signature: {
    r: authorization.r,
    s: authorization.s,
    v: authorization.v,
  },
});

With Custom Options

const authorization = await signAuthorization(
  {
    contractAddress: '0xe6Cae83BdE06E4c305530e199D7217f42808555B',
    chainId: 11155111,
    nonce: 0,
  },
  {
    hashMessage: false,
    arrayifyMessage: false,
  }
);

What is EIP-7702?

EIP-7702 is an Ethereum Improvement Proposal that allows Externally Owned Accounts (EOAs) to temporarily adopt smart contract functionality. By signing an authorization, your regular wallet can:

  • Execute gasless transactions - Let a paymaster cover gas fees
  • Batch multiple operations - Execute multiple transactions atomically
  • Use custom transaction logic - Add validation rules and permissions
  • Access smart account features - Without deploying a new contract

The authorization is temporary and only valid for specific transactions, maintaining the security model of EOAs while unlocking smart account capabilities.

Error Handling

The hook throws OpenfortError with specific types:

import { OpenfortErrorType } from '@openfort/openfort-react';
 
try {
  const authorization = await signAuthorization({
    contractAddress: '0x...',
    chainId: 11155111,
    nonce: 0,
  });
} catch (error) {
  if (error.type === OpenfortErrorType.CONFIGURATION_ERROR) {
    console.error('Openfort client not initialized');
  } else if (error.type === OpenfortErrorType.VALIDATION_ERROR) {
    console.error('Missing contract address');
  } else if (error.type === OpenfortErrorType.WALLET_ERROR) {
    console.error('Failed to sign authorization');
  }
}

Common Error Types

Error TypeDescriptionSolution
CONFIGURATION_ERROROpenfort client not initializedEnsure OpenfortProvider is properly set up
VALIDATION_ERRORMissing or invalid contract addressVerify contractAddress parameter is provided
WALLET_ERRORFailed to sign the authorizationCheck wallet connection and permissions

Use Cases

Gasless Onboarding

Allow new users to interact with your dApp without needing ETH for gas fees.

Batch Operations

Execute multiple transactions (like approving and swapping tokens) in a single operation.

Enhanced Security

Add custom validation logic or spending limits to regular wallets.

Session Keys

Grant temporary permissions for specific operations without full wallet access.

Notes

  • The authorization is valid only for the specific chain and nonce provided
  • Each authorization can only be used once due to the nonce
  • The signature is generated using your embedded Openfort wallet
  • Private key management is handled securely by the Openfort SDK
  • EIP-7702 is currently supported on select networks (check network compatibility)

Related