Skip to content

Commit

Permalink
feat: add fallback to get installed modules
Browse files Browse the repository at this point in the history
  • Loading branch information
kopy-kat committed Oct 22, 2024
1 parent 25f26b2 commit 2c5e011
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 17 deletions.
49 changes: 43 additions & 6 deletions src/account/erc7579-implementation/api/getInstalledModules.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Address, PublicClient } from 'viem'
import { Address, parseAbi, PublicClient, zeroAddress } from 'viem'
import { Account } from '../../types'

import { getInstalledModules as getInstalledModulesQuery } from '../../../common/queries/account'
import { accountAbi } from '../constants/abis'
import { SENTINEL_ADDRESS } from '../../../common/constants'

export const getInstalledModules = async ({
account,
Expand All @@ -10,8 +11,44 @@ export const getInstalledModules = async ({
account: Account
client: PublicClient
}): Promise<Address[]> => {
return getInstalledModulesQuery({
account,
client,
})
let installedModules: Address[] = []
try {
installedModules = await getInstalledModulesQuery({
account,
client,
})
} catch (e) {}
if (installedModules.length === 0) {
const installedValidators = (await client.readContract({
address: account.address,
abi: parseAbi(accountAbi),
functionName: 'getValidatorsPaginated',
args: [SENTINEL_ADDRESS, 100],
})) as Address[]
for (const validator of installedValidators) {
installedModules.push(validator)
}

const installedExecutors = (await client.readContract({
address: account.address,
abi: parseAbi(accountAbi),
functionName: 'getExecutorsPaginated',
args: [SENTINEL_ADDRESS, 100],
})) as Address[]

for (const executor of installedExecutors) {
installedModules.push(executor)
}

const installedHook = (await client.readContract({
address: account.address,
abi: parseAbi(accountAbi),
functionName: 'getActiveHook',
})) as Address

if (installedHook != zeroAddress) {
installedModules.push(installedHook)
}
}
return installedModules
}
2 changes: 1 addition & 1 deletion src/account/erc7579-implementation/constants/abis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const bootstrapAbi = [

export const accountAbi = [
'function getActiveHook() external view returns (address hook)',
'function getValidatorPaginated(address cursor,uint256 size) returns (address[] memory, address)',
'function getValidatorsPaginated(address cursor,uint256 size) returns (address[] memory, address)',
'function getExecutorsPaginated(address cursor,uint256 size) returns (address[] memory, address)',
'function installModule(uint256 moduleTypeId,address module,bytes calldata initData)',
'function uninstallModule(uint256 moduleTypeId,address module,bytes calldata deInitData)',
Expand Down
49 changes: 43 additions & 6 deletions src/account/nexus/api/getInstalledModules.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Address, PublicClient } from 'viem'
import { Address, parseAbi, PublicClient, zeroAddress } from 'viem'
import { Account } from '../../types'

import { getInstalledModules as getInstalledModulesQuery } from '../../../common/queries/account'
import { accountAbi } from '../constants/abis'
import { SENTINEL_ADDRESS } from '../../../common/constants'

export const getInstalledModules = async ({
account,
Expand All @@ -10,8 +11,44 @@ export const getInstalledModules = async ({
account: Account
client: PublicClient
}): Promise<Address[]> => {
return getInstalledModulesQuery({
account,
client,
})
let installedModules: Address[] = []
try {
installedModules = await getInstalledModulesQuery({
account,
client,
})
} catch (e) {}
if (installedModules.length === 0) {
const installedValidators = (await client.readContract({
address: account.address,
abi: parseAbi(accountAbi),
functionName: 'getValidatorsPaginated',
args: [SENTINEL_ADDRESS, 100],
})) as Address[]
for (const validator of installedValidators) {
installedModules.push(validator)
}

const installedExecutors = (await client.readContract({
address: account.address,
abi: parseAbi(accountAbi),
functionName: 'getExecutorsPaginated',
args: [SENTINEL_ADDRESS, 100],
})) as Address[]

for (const executor of installedExecutors) {
installedModules.push(executor)
}

const installedHook = (await client.readContract({
address: account.address,
abi: parseAbi(accountAbi),
functionName: 'getActiveHook',
})) as Address

if (installedHook != zeroAddress) {
installedModules.push(installedHook)
}
}
return installedModules
}
45 changes: 43 additions & 2 deletions src/account/safe/api/getInstalledModules.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Address, PublicClient } from 'viem'
import { Address, parseAbi, PublicClient, zeroAddress } from 'viem'
import { Account } from '../../types'
import { getInstalledModules as getInstalledModulesQuery } from '../../../common/queries'
import { accountAbi } from '../constants/abis'
import { SENTINEL_ADDRESS } from '../../../common/constants'

export const getInstalledModules = async ({
account,
Expand All @@ -9,5 +11,44 @@ export const getInstalledModules = async ({
account: Account
client: PublicClient
}): Promise<Address[]> => {
return getInstalledModulesQuery({ account, client })
let installedModules: Address[] = []
try {
installedModules = await getInstalledModulesQuery({
account,
client,
})
} catch (e) {}
if (installedModules.length === 0) {
const installedValidators = (await client.readContract({
address: account.address,
abi: parseAbi(accountAbi),
functionName: 'getValidatorsPaginated',
args: [SENTINEL_ADDRESS, 100],
})) as Address[]
for (const validator of installedValidators) {
installedModules.push(validator)
}

const installedExecutors = (await client.readContract({
address: account.address,
abi: parseAbi(accountAbi),
functionName: 'getExecutorsPaginated',
args: [SENTINEL_ADDRESS, 100],
})) as Address[]

for (const executor of installedExecutors) {
installedModules.push(executor)
}

const installedHook = (await client.readContract({
address: account.address,
abi: parseAbi(accountAbi),
functionName: 'getActiveHook',
})) as Address

if (installedHook != zeroAddress) {
installedModules.push(installedHook)
}
}
return installedModules
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getAccount, getInstalledModules } from 'src'
import { getClient } from 'src'
import { MockAccountDeployed } from 'test/utils/mocks/account'
import { MockClient } from 'test/utils/mocks/client'

describe('Get installed modules', () => {
// Setup
const client = getClient(MockClient)
const account = getAccount(MockAccountDeployed)

it('Should return the installed modules', async () => {
const installedModules = await getInstalledModules({
client,
account,
})

expect(installedModules.length).toBeGreaterThan(0)
})
})
19 changes: 19 additions & 0 deletions test/unit/account/account-types/safe/getInstalledModules.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getAccount, getInstalledModules } from 'src'
import { getClient } from 'src'
import { MockSafeAccountDeployed } from 'test/utils/mocks/account'
import { MockClient } from 'test/utils/mocks/client'

describe('Get installed modules', () => {
// Setup
const client = getClient(MockClient)
const account = getAccount(MockSafeAccountDeployed)

it('Should return the installed modules', async () => {
const installedModules = await getInstalledModules({
client,
account,
})

expect(installedModules.length).toBeGreaterThan(0)
})
})
5 changes: 3 additions & 2 deletions test/utils/mocks/account.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Account } from 'src/account/types'

export const MockAccountDeployed: Account = {
address: '0x7227dcfb0c5ec7a5f539f97b18be261c49687ed6',
// address: '0x7227dcfb0c5ec7a5f539f97b18be261c49687ed6',
address: '0x0579bCB9b3B9678A991F553531c27f4ea4863bE4',
deployedOnChains: [11155111],
type: 'erc7579-implementation',
}
Expand All @@ -13,7 +14,7 @@ export const MockKernelAccountDeployed: Account = {
}

export const MockSafeAccountDeployed: Account = {
address: '0xc2b17e73603dccc195118a36f3203134fd7985f5',
address: '0x2b22106d8Aade2C3E546749bC027D5a21195FfED',
deployedOnChains: [11155111],
type: 'safe',
}
Expand Down

0 comments on commit 2c5e011

Please sign in to comment.