What is Redelegation?
Redelegation is the process of updating an existing wallet delegation with new parameters. This replaces the previous delegation for that wallet address with a new one.
Redelegation follows the exact same 3-step process as initial delegation. The new delegation completely replaces the previous one for the same wallet address.
When to Redelegate
1. Allowance Adjustment
Scenario : User needs to increase or decrease spending limit
Increase Allowance
Decrease Allowance
Reset Allowance
When : User’s current allowance is running low or depletedExample :
Current allowance: 5,000 USDC
Remaining: 500 USDC
Want to increase to: 10,000 USDC
Action : Redelegate with new amount (10,000 USDC)When : User wants to reduce risk or limit spendingExample :
Current allowance: 10,000 USDC
Remaining: 8,000 USDC
Want to decrease to: 2,000 USDC
Action : Redelegate with lower amount (2,000 USDC)The new allowance replaces the old one entirely, regardless of remaining balance.
When : Allowance exhausted and needs replenishmentExample :
Current allowance: 5,000 USDC
Remaining: 0 USDC
Transactions failing due to insufficient allowance
Action : Redelegate to restore spending capability
2. Contract Upgrades
Scenario : Platform upgrades smart contracts with new features or security improvements
Platform will notify users when contract upgrades require redelegation. This is the most critical redelegation scenario.
When It Happens :
Platform deploys new smart contract versions
Security patches or improvements implemented
New features added to delegation contracts
Network-specific contract updates
What You Need to Do :
Monitor platform notifications for upgrade announcements
Inform users of the upgrade and its benefits
Guide users through redelegation process
Set reasonable deadline for migration
Provide fallback for users who don’t migrate promptly
Example Notification Flow :
interface ContractUpgradeNotification {
upgradeId : string ;
effectiveDate : string ;
deadline : string ;
affectedNetworks : string [];
reason : string ;
changes : string [];
}
async function notifyUsersOfContractUpgrade (
upgrade : ContractUpgradeNotification
) {
// Send email/push notification to all users with delegated wallets
// on affected networks
const affectedUsers = await getUsersWithWalletsOnNetworks (
upgrade . affectedNetworks
);
for ( const user of affectedUsers ) {
await sendNotification ( user , {
title: 'Action Required: Wallet Redelegation Needed' ,
message: `Our smart contracts have been upgraded. Please redelegate your wallets by ${ upgrade . deadline } .` ,
action: {
label: 'Redelegate Now' ,
url: '/settings/wallets/redelegate'
}
});
}
}
3. Network Migration
Scenario : User wants to move delegation to a different blockchain
Example Use Cases :
Switch from Ethereum to Linea for lower gas fees
Move from Linea to Solana for faster transactions
Consolidate multiple network wallets to single network
Process :
Delegate new wallet on target network
Update priority to prefer new network
Optionally revoke old delegation (by setting allowance to 0)
Network Migration Example
async function migrateToLinea (
userId : string ,
ethereumWalletAddress : string ,
lineaWalletAddress : string
) {
console . log ( 'Step 1: Delegate new Linea wallet' );
await completeDelegationFlow (
userId ,
'linea' ,
'usdc' ,
'10000' ,
lineaWalletAddress
);
console . log ( 'Step 2: Update priority to prefer Linea' );
const wallets = await getCurrentPriority ( userId );
const lineaWallet = wallets . find ( w => w . address === lineaWalletAddress );
const ethereumWallet = wallets . find ( w => w . address === ethereumWalletAddress );
if ( lineaWallet && ethereumWallet ) {
await updatePriority ( userId , [
{ id: lineaWallet . id , priority: 1 },
{ id: ethereumWallet . id , priority: 2 }
]);
}
console . log ( 'Step 3: Optional - Revoke Ethereum delegation' );
// User can manually revoke in their wallet or leave as backup
}
4. Wallet Address Change
Scenario : User wants to use a different wallet address for the same network
Common Reasons :
Upgraded to hardware wallet
Changed wallet provider
Security concerns with old wallet
Using different wallet for organizational reasons
Process :
Delegate new wallet address
Verify new wallet works
Remove or deprioritize old wallet
You can have multiple wallets on the same network with different addresses. Use priority to control which is used first.
5. Security Events
Scenario : Wallet potentially compromised or security best practices
When to Redelegate Immediately :
Private key exposure suspected
Wallet used on untrusted device
Suspicious transaction activity
Periodic security rotation (best practice)
Emergency Redelegation Process :
Revoke Current Delegation
Set allowance to 0 on potentially compromised wallet using user’s wallet interface (not API)
Delegate New Wallet
Complete delegation flow with new, secure wallet
Verify Security
Ensure old wallet has zero allowance and new wallet is functioning
Monitor
Watch for any unauthorized transactions on old wallet
Redelegation Process
Redelegation uses the exact same 3-step workflow as initial delegation:
Step-by-Step Redelegation
Request New Delegation Token
Frontend Wallet Interaction
User approves new blockchain transaction with updated parameters:
Same wallet address (for allowance update)
New spending limit (if changing allowance)
New spender address (if contract upgraded)
The new delegation completely replaces the previous one. There is no “additive” mode - you must specify the full new allowance, not just the additional amount.
Implementation Examples
Increase Allowance
Increase Allowance
Decrease Allowance
async function increaseAllowance (
userId : string ,
walletAddress : string ,
currentAllowance : number ,
additionalAmount : number
) : Promise < void > {
const newAllowance = currentAllowance + additionalAmount ;
console . log ( `Increasing allowance from ${ currentAllowance } to ${ newAllowance } ` );
const wallet = await getExternalWallets ( userId );
const targetWallet = wallet . find ( w => w . address === walletAddress );
if ( ! targetWallet ) {
throw new Error ( 'Wallet not found' );
}
await completeDelegationFlow (
userId ,
targetWallet . network as any ,
targetWallet . currency as any ,
newAllowance . toString (),
walletAddress
);
console . log ( '✅ Allowance increased successfully' );
}
Contract Upgrade Migration
Contract Upgrade Redelegation
interface ContractUpgrade {
network : 'linea' | 'ethereum' | 'solana' ;
newSpenderAddress : string ;
newTokenAddress ?: string ;
effectiveDate : Date ;
}
async function migrateToNewContract (
userId : string ,
walletAddress : string ,
upgrade : ContractUpgrade
) : Promise < void > {
const wallets = await getExternalWallets ( userId );
const wallet = wallets . find ( w =>
w . address === walletAddress && w . network === upgrade . network
);
if ( ! wallet ) {
throw new Error ( 'Wallet not found for migration' );
}
console . log ( 'Starting contract upgrade migration...' );
console . log ( `Network: ${ upgrade . network } ` );
console . log ( `New spender: ${ upgrade . newSpenderAddress } ` );
await completeDelegationFlow (
userId ,
wallet . network as any ,
wallet . currency as any ,
wallet . allowance ,
walletAddress ,
{
spenderAddress: upgrade . newSpenderAddress ,
tokenAddress: upgrade . newTokenAddress
}
);
console . log ( '✅ Migration to new contract complete' );
const updated = await getExternalWallets ( userId );
const updatedWallet = updated . find ( w => w . address === walletAddress );
console . log ( 'Updated wallet:' , updatedWallet );
}
Batch Redelegation
For users with multiple wallets needing updates:
async function batchRedelegate (
userId : string ,
updates : Array <{
address : string ;
newAllowance : string ;
}>
) : Promise <{
successful : string [];
failed : Array <{ address : string ; error : string }>;
}> {
const results = {
successful: [] as string [],
failed: [] as Array <{ address : string ; error : string }>
};
const wallets = await getExternalWallets ( userId );
for ( const update of updates ) {
try {
const wallet = wallets . find ( w => w . address === update . address );
if ( ! wallet ) {
throw new Error ( 'Wallet not found' );
}
await completeDelegationFlow (
userId ,
wallet . network as any ,
wallet . currency as any ,
update . newAllowance ,
update . address
);
results . successful . push ( update . address );
console . log ( `✅ Redelegated ${ update . address } ` );
} catch ( error : any ) {
results . failed . push ({
address: update . address ,
error: error . message
});
console . error ( `❌ Failed to redelegate ${ update . address } :` , error );
}
await new Promise ( resolve => setTimeout ( resolve , 1000 ));
}
return results ;
}
UI/UX Considerations
Allowance Warning
Contract Upgrade Notice
Redelegation Flow
Prompt users when allowance is running low: function AllowanceWarning ({ wallet } : { wallet : ExternalWallet }) {
const remaining = parseFloat ( wallet . allowance );
const original = parseFloat ( wallet . balance );
const percentRemaining = ( remaining / original ) * 100 ;
if ( percentRemaining > 20 ) return null ;
return (
< div className = "warning" >
< AlertIcon />
< div >
< h4 > Low Allowance Warning </ h4 >
< p >
Only { remaining } { wallet . currency . toUpperCase () } remaining.
Redelegate to increase your spending limit.
</ p >
< button onClick = { () => startRedelegation ( wallet ) } >
Increase Allowance
</ button >
</ div >
</ div >
);
}
Display contract upgrade requirements: function ContractUpgradeNotice ({ upgrade } : {
upgrade : ContractUpgradeNotification
}) {
return (
< div className = "upgrade-notice" >
< h3 > Action Required: Contract Upgrade </ h3 >
< p > { upgrade . reason } </ p >
< ul >
< h4 > What's New: </ h4 >
{ upgrade . changes . map ( change => (
< li key = { change } > { change } </ li >
)) }
</ ul >
< div className = "deadline" >
< strong > Deadline: </ strong > { upgrade . deadline }
</ div >
< button onClick = { () => startMigration ( upgrade ) } >
Redelegate Now
</ button >
</ div >
);
}
Guide users through redelegation: function RedelegationWizard ({ wallet } : { wallet : ExternalWallet }) {
const [ step , setStep ] = useState ( 1 );
const [ newAmount , setNewAmount ] = useState ( wallet . allowance );
return (
< div className = "redelegation-wizard" >
< h2 > Update Wallet Delegation </ h2 >
< ProgressSteps current = { step } total = { 3 } />
{ step === 1 && (
< div >
< h3 > Current Delegation </ h3 >
< p > Allowance: { wallet . allowance } { wallet . currency } </ p >
< p > Remaining: { wallet . balance } { wallet . currency } </ p >
< h3 > New Allowance </ h3 >
< input
type = "number"
value = { newAmount }
onChange = { ( e ) => setNewAmount ( e . target . value ) }
/>
< button onClick = { () => setStep ( 2 ) } > Continue </ button >
</ div >
) }
{ step === 2 && (
< WalletConnectionStep
wallet = { wallet }
newAmount = { newAmount }
onComplete = { () => setStep ( 3 ) }
/>
) }
{ step === 3 && (
< div >
< h3 > ✅ Redelegation Complete! </ h3 >
< p > New allowance: { newAmount } { wallet . currency } </ p >
< button onClick = { () => window . location . reload () } >
Done
</ button >
</ div >
) }
</ div >
);
}
Best Practices
Proactive Redelegation
Set up automated monitoring to alert users before allowance runs out: async function checkAllowanceStatus ( userId : string ) {
const wallets = await getExternalWallets ( userId );
for ( const wallet of wallets ) {
const percentRemaining =
( parseFloat ( wallet . balance ) / parseFloat ( wallet . allowance )) * 100 ;
if ( percentRemaining < 20 ) {
await sendNotification ( userId , {
type: 'low_allowance' ,
wallet: wallet . address ,
remaining: wallet . balance ,
currency: wallet . currency
});
}
}
}
Scheduled Contract Checks
Regularly check for contract upgrades: async function checkForContractUpgrades () : Promise < ContractUpgrade []> {
const response = await fetch ( '/api/platform/contract-upgrades' );
return await response . json ();
}
// Run daily
setInterval ( async () => {
const upgrades = await checkForContractUpgrades ();
if ( upgrades . length > 0 ) {
await notifyAffectedUsers ( upgrades );
}
}, 24 * 60 * 60 * 1000 );
Educate users about when and why to redelegate:
Include redelegation info in onboarding
Provide in-app tooltips and guides
Send periodic reminders about allowance status
Explain benefits of proactive management
Handle scenarios where redelegation hasn’t occurred:
Maintain multiple wallet support for failover
Prompt users at checkout if allowance insufficient
Provide clear error messages with actionable steps
Allow alternative payment methods during migration periods
Testing Redelegation
Always test redelegation flows before production:
describe ( 'Redelegation' , () => {
it ( 'should increase allowance successfully' , async () => {
const initialAllowance = 5000 ;
const additionalAmount = 5000 ;
const expectedNew = 10000 ;
await increaseAllowance (
userId ,
walletAddress ,
initialAllowance ,
additionalAmount
);
const wallets = await getExternalWallets ( userId );
const wallet = wallets . find ( w => w . address === walletAddress );
expect ( wallet ?. allowance ). toBe ( expectedNew . toString ());
});
it ( 'should handle contract upgrade migration' , async () => {
const upgrade : ContractUpgrade = {
network: 'linea' ,
newSpenderAddress: '0xNewSpender...' ,
effectiveDate: new Date ()
};
await migrateToNewContract ( userId , walletAddress , upgrade );
// Verify new contract is being used
const wallets = await getExternalWallets ( userId );
const wallet = wallets . find ( w => w . address === walletAddress );
expect ( wallet ). toBeDefined ();
// Additional verification that new spender is active
});
it ( 'should batch redelegate multiple wallets' , async () => {
const updates = [
{ address: wallet1 , newAllowance: '10000' },
{ address: wallet2 , newAllowance: '5000' }
];
const results = await batchRedelegate ( userId , updates );
expect ( results . successful ). toHaveLength ( 2 );
expect ( results . failed ). toHaveLength ( 0 );
});
});
Troubleshooting
Redelegation Not Reflecting New Allowance
Symptom : API shows old allowance after redelegationCauses :
Blockchain transaction not confirmed
Wrong transaction hash submitted
Cached data in API
Solutions :
Wait for blockchain confirmation (check block explorer)
Verify transaction hash is correct
Retry fetching wallet data after 30 seconds
User Can't Complete Redelegation
Symptom : Transaction fails during Step 2Causes :
Insufficient gas/SOL for transaction
Wrong network selected in wallet
Wallet connection lost
Solutions :
Ensure user has gas funds (ETH/SOL)
Verify correct network selected
Reconnect wallet and retry
Contract Upgrade Breaking Changes
Symptom : Old delegation still working after supposed upgradeCauses :
Upgrade not yet effective
Gradual rollout in progress
Network-specific timing
Solutions :
Check upgrade effective date
Contact platform support for rollout status
Complete redelegation proactively regardless
Monitoring & Analytics
Track redelegation metrics for your application:
interface RedelegationMetrics {
totalRedelegations : number ;
redelegationsByReason : {
allowanceIncrease : number ;
allowanceDecrease : number ;
contractUpgrade : number ;
networkMigration : number ;
security : number ;
};
averageNewAllowance : number ;
redelegationSuccessRate : number ;
}
async function trackRedelegation (
userId : string ,
reason : string ,
oldAllowance : number ,
newAllowance : number ,
success : boolean
) {
await analytics . track ( 'wallet_redelegation' , {
userId ,
reason ,
oldAllowance ,
newAllowance ,
change: newAllowance - oldAllowance ,
changePercent: (( newAllowance - oldAllowance ) / oldAllowance ) * 100 ,
success ,
timestamp: new Date ()
});
}
Next Steps