@rainbow-me/delegation
v0.3.2
Published
EIP-7702 batch transaction executor with smart delegation detection
Downloads
1,583
Readme
Rainbow Delegation
EIP-7702 delegation utilities for batched execution, delegation status checks, and delegation lifecycle management.
Installation
yarn add @rainbow-me/delegation
# or
npm install @rainbow-me/delegation
# or
pnpm add @rainbow-me/delegationPeer Dependencies:
yarn add viem@^2.38.0 @storesjs/stores@^0.8.6Optional peer dependencies:
react— required only if using hooks (useDelegations,useDelegationDisabled,useWillDelegate)ethers— required only if using ethers client inputs
Configuration
Call configure once before using actions/hooks.
import { configure } from '@rainbow-me/delegation';
configure({
platformClient,
logger,
getCurrentAddress,
// optional
storeOptions,
});Required services:
platformClient: HTTP client withget<T>(url, opts).logger: logger withdebug/info/warn/error.getCurrentAddress: reactive current-address getter for store prefetch.
Optional services:
storeOptions: storage/sync/shouldEnable options for persisted query stores.
Delegation Contract Support
New delegation/switch decisions use the contract mapping in
src/contract/addresses.ts:
| Chain | Chain ID | Delegation Contract |
| ---------------- | -------- | -------------------------------------------- |
| Ethereum Mainnet | 1 | 0x612373D7003d694220f7800EeaF8E3924c0951D3 |
| Optimism | 10 | 0x612373D7003d694220f7800EeaF8E3924c0951D3 |
| BSC | 56 | 0x612373D7003d694220f7800EeaF8E3924c0951D3 |
| Gnosis Chain | 100 | 0x612373D7003d694220f7800EeaF8E3924c0951D3 |
| Unichain | 130 | 0x612373D7003d694220f7800EeaF8E3924c0951D3 |
| Polygon | 137 | 0x612373D7003d694220f7800EeaF8E3924c0951D3 |
| Base | 8453 | 0x612373D7003d694220f7800EeaF8E3924c0951D3 |
| Arbitrum | 42161 | 0x612373D7003d694220f7800EeaF8E3924c0951D3 |
| Celo | 42220 | 0x612373D7003d694220f7800EeaF8E3924c0951D3 |
| Ink | 57073 | 0x612373D7003d694220f7800EeaF8E3924c0951D3 |
| Berachain | 80094 | 0x612373D7003d694220f7800EeaF8E3924c0951D3 |
| Katana | 747474 | 0x612373D7003d694220f7800EeaF8E3924c0951D3 |
- If a chain is not mapped, the library will not create/switch delegation on that chain
supportsDelegationmay still return supported when the address is already delegated (existingeip1559path)
Client Inputs
Bound transaction actions accept either client shape:
- viem:
{ walletClient, publicClient, ... } - ethers:
{ signer, provider, chainId, ... }
When using ethers inputs, clients are normalized internally to viem clients.
Ethers input requirements:
signermust be wallet-like and exposeprivateKeyprovidermust expose an RPC URL
Recommended Flow
Use supportsDelegation to check whether delegation requirements for
executeBatchedTransaction are satisfied. Execution
actions still revalidate at signing time and may throw if state changes.
import {
supportsDelegation,
willDelegate,
prepareBatchedTransaction,
executeBatchedTransaction,
UnsupportedReason,
} from '@rainbow-me/delegation';
const support = await supportsDelegation({ address, chainId });
if (!support.supported) {
if (support.reason === UnsupportedReason.USER_DISABLED) {
// fallback path
}
// fallback path when delegation requirements are not satisfied
}
const warning = await willDelegate({ address, chainId });
if (warning.willDelegate) {
// show "this transaction will include a delegation authorization"
}
const nonce = await publicClient.getTransactionCount({ address });
const simulationTx = await prepareBatchedTransaction({
from: address,
calls,
chainId,
nonce,
});
const result = await executeBatchedTransaction({
walletClient,
publicClient,
chainId,
calls,
nonce,
transactionOptions: {
maxFeePerGas,
maxPriorityFeePerGas,
gasLimit: null,
},
});
console.log(result.hash, result.type); // type is 'eip1559' | 'eip7702'API Reference
configure({ platformClient, logger, getCurrentAddress, storeOptions? })
Initializes services and store wiring for the library.
- Must be called before actions/hooks.
supportsDelegation({ address, chainId, requireFreshStatus? })
Returns:
{ supported: true, reason: null }{ supported: false, reason: UnsupportedReason.USER_DISABLED | UnsupportedReason.NOT_AVAILABLE }
UI helper only. executeBatchedTransaction still performs fresh checks.
supported: true means delegation is enabled for this address and either:
- the account is already Rainbow delegated on the chain, or
- the account can authorize delegation on the chain now.
Set requireFreshStatus: true to bypass cache and fetch the latest chain status.
willDelegate({ address, chainId, requireFreshStatus? })
Returns:
{ willDelegate: true, delegation: { chainId, contractAddress } }{ willDelegate: false, delegation: null }
UI helper indicating whether executeBatchedTransaction would include an authorization.
Set requireFreshStatus: true to bypass cache and fetch the latest chain status.
Already delegated accounts return willDelegate: false, including upgrade-available states.
prepareBatchedTransaction({ from, calls, chainId, nonce })
Prepares transaction data for simulation.
Returns Transaction with optional authorization_list when a new delegation is needed.
executeBatchedTransaction({ walletClient|signer, publicClient|provider, chainId, calls, transactionOptions, nonce, value? })
Executes batched calls:
- uses
eip1559path when already delegated - uses
eip7702path when authorization is needed and allowed
Returns:
{ hash, type: 'eip1559' | 'eip7702' }
Throws when delegation requirements are not satisfied for the address/chain.
executeDelegation({ walletClient|signer, publicClient|provider, chainId, calldata, transactionOptions, nonce, value? })
Low-level delegation execution action.
Performs fresh delegation checks before signing authorization and sending transaction.
Returns:
{ hash, type: 'eip7702' }
executeRevokeDelegation({ walletClient|signer, publicClient|provider, chainId, transactionOptions, nonce })
Signs zero-address authorization and revokes delegation. Revokes delegation state on the chain regardless of provider classification (Rainbow or third-party).
Use shouldRevokeDelegation to determine if revocation is currently needed.
Returns:
{ hash, type: 'eip7702' }
getDelegations({ address })
Fetches delegation state and returns only active delegations:
DelegationStatus.RAINBOW_DELEGATEDDelegationStatus.THIRD_PARTY_DELEGATED
shouldRevokeDelegation({ address })
Returns:
shouldRevoke: booleanrevokes: { address, chainId }[]
true when delegated to Rainbow with revoke reasons (VULNERABILITY, BUG, UNSPECIFIED).
resetCache()
Clears delegation status query cache.
Does not clear per-address delegation preference (enableDelegation /
disableDelegation state).
Hooks & Preference Helpers
Hooks require react as a peer dependency.
useDelegations(address)
Returns:
DelegationWithChainId[]
Subscribes to active delegations and keeps status fresh for the address (30s refresh window).
useDelegationDisabled(address)
Returns true when delegation is disabled for that address.
useWillDelegate(address, chainId)
Returns true when current store state indicates the next batched transaction
would include a delegation authorization.
Subscribes to chain-specific delegation decision state and keeps status fresh (15s refresh window).
Preference actions
enableDelegation(address)disableDelegation(address)isDelegationEnabled(address)
Exported Types & Enums
The package exports store/action state types and enums, including:
DelegationStatusUnsupportedReasonRevokeReasonUpdateReasonDelegationStateChainDelegationStateDelegationWithChainIdActiveDelegations
Notes
- This package is designed for integration with a platform API via
platformClient. - Delegation contract addresses are chain-specific and validated against local mapping + backend state.
configure()must be called before any action/hook usage.
