Skip to content

Commit

Permalink
Add immutable wallet proxy hook
Browse files Browse the repository at this point in the history
  • Loading branch information
ScreamingHawk committed Dec 19, 2024
1 parent 8054556 commit 275c395
Show file tree
Hide file tree
Showing 4 changed files with 295 additions and 2 deletions.
6 changes: 5 additions & 1 deletion packages/abi/src/wallet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import * as erc6492 from './erc6492'
import * as factory from './factory'
import * as mainModule from './mainModule'
import * as mainModuleUpgradable from './mainModuleUpgradable'
import * as moduleHooks from './moduleHooks'
import * as sequenceUtils from './sequenceUtils'
import * as requireFreshSigner from './libs/requireFreshSigners'
import * as walletProxyHook from './walletProxyHook'

export const walletContracts = {
erc6492,
Expand All @@ -14,6 +16,8 @@ export const walletContracts = {
factory,
mainModule,
mainModuleUpgradable,
moduleHooks,
sequenceUtils,
requireFreshSigner
requireFreshSigner,
walletProxyHook
}
248 changes: 248 additions & 0 deletions packages/abi/src/wallet/moduleHooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
export const abi = [
{
inputs: [
{
internalType: 'bytes4',
name: '_signature',
type: 'bytes4'
}
],
name: 'HookAlreadyExists',
type: 'error'
},
{
inputs: [
{
internalType: 'bytes4',
name: '_signature',
type: 'bytes4'
}
],
name: 'HookDoesNotExist',
type: 'error'
},
{
inputs: [
{
internalType: 'address',
name: '_sender',
type: 'address'
},
{
internalType: 'address',
name: '_self',
type: 'address'
}
],
name: 'OnlySelfAuth',
type: 'error'
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: 'bytes4',
name: '_signature',
type: 'bytes4'
},
{
indexed: false,
internalType: 'address',
name: '_implementation',
type: 'address'
}
],
name: 'DefinedHook',
type: 'event'
},
{
stateMutability: 'payable',
type: 'fallback'
},
{
inputs: [
{
internalType: 'bytes4',
name: '_signature',
type: 'bytes4'
},
{
internalType: 'address',
name: '_implementation',
type: 'address'
}
],
name: 'addHook',
outputs: [],
stateMutability: 'nonpayable',
type: 'function'
},
{
inputs: [
{
internalType: 'address',
name: '',
type: 'address'
},
{
internalType: 'address',
name: '',
type: 'address'
},
{
internalType: 'uint256[]',
name: '',
type: 'uint256[]'
},
{
internalType: 'uint256[]',
name: '',
type: 'uint256[]'
},
{
internalType: 'bytes',
name: '',
type: 'bytes'
}
],
name: 'onERC1155BatchReceived',
outputs: [
{
internalType: 'bytes4',
name: '',
type: 'bytes4'
}
],
stateMutability: 'nonpayable',
type: 'function'
},
{
inputs: [
{
internalType: 'address',
name: '',
type: 'address'
},
{
internalType: 'address',
name: '',
type: 'address'
},
{
internalType: 'uint256',
name: '',
type: 'uint256'
},
{
internalType: 'uint256',
name: '',
type: 'uint256'
},
{
internalType: 'bytes',
name: '',
type: 'bytes'
}
],
name: 'onERC1155Received',
outputs: [
{
internalType: 'bytes4',
name: '',
type: 'bytes4'
}
],
stateMutability: 'nonpayable',
type: 'function'
},
{
inputs: [
{
internalType: 'address',
name: '',
type: 'address'
},
{
internalType: 'address',
name: '',
type: 'address'
},
{
internalType: 'uint256',
name: '',
type: 'uint256'
},
{
internalType: 'bytes',
name: '',
type: 'bytes'
}
],
name: 'onERC721Received',
outputs: [
{
internalType: 'bytes4',
name: '',
type: 'bytes4'
}
],
stateMutability: 'nonpayable',
type: 'function'
},
{
inputs: [
{
internalType: 'bytes4',
name: '_signature',
type: 'bytes4'
}
],
name: 'readHook',
outputs: [
{
internalType: 'address',
name: '',
type: 'address'
}
],
stateMutability: 'view',
type: 'function'
},
{
inputs: [
{
internalType: 'bytes4',
name: '_signature',
type: 'bytes4'
}
],
name: 'removeHook',
outputs: [],
stateMutability: 'nonpayable',
type: 'function'
},
{
inputs: [
{
internalType: 'bytes4',
name: '_interfaceID',
type: 'bytes4'
}
],
name: 'supportsInterface',
outputs: [
{
internalType: 'bool',
name: '',
type: 'bool'
}
],
stateMutability: 'pure',
type: 'function'
},
{
stateMutability: 'payable',
type: 'receive'
}
] as const
9 changes: 9 additions & 0 deletions packages/abi/src/wallet/walletProxyHook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const abi = [
{
type: 'function',
name: 'PROXY_getImplementation',
inputs: [],
outputs: [{ name: '', type: 'address', internalType: 'address' }],
stateMutability: 'view'
}
] as const
34 changes: 33 additions & 1 deletion packages/account/src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -402,13 +402,45 @@ export class Account {
status: AccountStatus,
chainId: ethers.BigNumberish
): Promise<commons.transaction.Transactionish> {
txs = Array.isArray(txs) ? txs : [txs]
// if onchain wallet config is not up to date
// then we should append an extra transaction that updates it
// to the latest "lazy" state
if (status.onChain.imageHash !== status.imageHash) {
const wallet = this.walletForStatus(chainId, status)
const updateConfig = await wallet.buildUpdateConfigurationTransaction(status.config)
return [Array.isArray(txs) ? txs : [txs], updateConfig.transactions].flat()
txs = [...txs, ...updateConfig.transactions]
}

// On immutable chains, we add the WalletProxyHook
if (chainId === ChainId.IMMUTABLE_ZKEVM || chainId === ChainId.IMMUTABLE_ZKEVM_TESTNET) {
const provider = this.providerFor(chainId)
if (provider) {
const hook = new ethers.Contract(this.address, walletContracts.walletProxyHook.abi, provider)
let implementation
try {
implementation = await hook.PROXY_getImplementation()
} catch (e) {
// Handle below
console.log('Error getting implementation address', e)
}
if (!implementation || implementation === ethers.ZeroAddress) {
console.log('Adding wallet proxy hook')
const hooksInterface = new ethers.Interface(walletContracts.moduleHooks.abi)
const tx: commons.transaction.Transaction = {
to: this.address,
data: hooksInterface.encodeFunctionData(hooksInterface.getFunction('addHook')!, [
'0x90611127',
'0x1f56dbAD5e8319F0DE9a323E24A31b5077dEB1a4'
]),
gasLimit: 50000, // Expected ~28k gas. Buffer added
delegateCall: false,
revertOnError: false,
value: 0
}
txs = [tx, ...txs]
}
}
}

return txs
Expand Down

0 comments on commit 275c395

Please sign in to comment.