diff --git a/src/README.md b/src/README.md index 7e370eb..dbfddba 100644 --- a/src/README.md +++ b/src/README.md @@ -11,17 +11,17 @@ The Module SDK allows you to: - **Interact with** and **use** modules using a simple and consistent API - Can be used **alongside existing account SDKs** such as [permissionless.js](https://www.npmjs.com/package/permissionless), [Biconomy](https://www.npmjs.com/package/@biconomy/account), [Zerodev](https://www.npmjs.com/package/@zerodevapp/sdk) and many more - **Use core modules**, such as: - - AutoSavings Executor: Automatically save a percentage of incoming funds - - ColdStorage Hook: Prevent funds from being withdrawn without a timelock - - Deadman Switch Validator: Prevent funds from being locked forever + - Auto Savings: Automatically allocate a set percentage of any incoming token to a target vault + - ColdStorage Hook: Restrict all transactions with a timelock and only allow funds to be sent to a single address + - Deadman Switch: Recover an account after a specified inactive period - Hook Multiplexer: Combine multiple hooks into one with fine-grained control over when they are called - - MultiFactor Validator: Use multiple validators in combination as a multi-factor authentication system + - Multi Factor: Use multiple validators in combination as a multi-factor authentication system - Ownable Executor: Allow an account to control a subaccount and pay for its transaction fees - Ownable Validator: Authenticate on your account with multiple ECDSA keys - Registry Hook: Query the Module Registry before installing and using modules - - Scheduled Orders Executor: Execute swaps on a specified schedule - - Scheduled Transfers Executor: Transfer funds on a specified schedule - - Social Recovery Validator: Recover your account using a set of guardians + - Scheduled Orders: Execute swaps on a specified schedule + - Scheduled Transfers: Transfer funds on a specified schedule + - Social Recovery: Recover your account using a set of guardians In-depth documentation is available at [docs.rhinestone.wtf](https://docs.rhinestone.wtf/module-sdk/). @@ -56,7 +56,7 @@ import { getModule, getAccount, getClient, - getInstallMultiFactorValidator, + getMultiFactorValidator, } from '@rhinestone/module-sdk' // Create a client for the current network @@ -72,7 +72,7 @@ const moduleToInstall = getModule({ }) // Or use one of the existing modules -moduleToInstall = getInstallMultiFactorValidator({ +moduleToInstall = getMultiFactorValidator({ threshold: 2, validators: [ { diff --git a/src/account/erc7579-implementation/api/installModule.ts b/src/account/erc7579-implementation/api/installModule.ts index 05a6fb4..1e24c48 100644 --- a/src/account/erc7579-implementation/api/installModule.ts +++ b/src/account/erc7579-implementation/api/installModule.ts @@ -52,7 +52,7 @@ const _installModule = async ({ args: [ BigInt(moduleTypeIds[module.type]), module.module, - module.data || '0x', + module.initData || '0x', ], }), }) @@ -89,7 +89,7 @@ async function installFallback({ module.module, encodePacked( ['bytes4', 'bytes1', 'bytes'], - [module.selector!, module.callType!, module.data ?? '0x'], + [module.selector!, module.callType!, module.initData ?? '0x'], ), ], }), diff --git a/src/account/erc7579-implementation/api/uninstallModule.ts b/src/account/erc7579-implementation/api/uninstallModule.ts index 789b2e3..24934d7 100644 --- a/src/account/erc7579-implementation/api/uninstallModule.ts +++ b/src/account/erc7579-implementation/api/uninstallModule.ts @@ -50,7 +50,7 @@ const _uninstallModule = async ({ const isInstalled = await isModuleInstalled({ client, account, module }) if (isInstalled) { - let moduleData = module.data || '0x' + let moduleData = module.initData || '0x' if (module.type === 'validator' || module.type === 'executor') { const prev = await getPreviousModule({ client, account, module }) moduleData = encodeAbiParameters( @@ -109,7 +109,7 @@ const _uninstallFallback = async ({ module.module, encodePacked( ['bytes4', 'bytes'], - [module.selector!, module.data ?? '0x'], + [module.selector!, module.initData ?? '0x'], ), ], }), diff --git a/src/account/kernel/api/installModule.ts b/src/account/kernel/api/installModule.ts index 5a87088..9e6c7ea 100644 --- a/src/account/kernel/api/installModule.ts +++ b/src/account/kernel/api/installModule.ts @@ -69,11 +69,11 @@ const _installModule = async ({ module.hook!, encodeAbiParameters( [{ type: 'bytes' }, { type: 'bytes' }], - [module.data || '0x', '0x'], + [module.initData || '0x', '0x'], ), ], ) - : module.data || '0x', + : module.initData || '0x', ], }), }) @@ -124,7 +124,7 @@ async function installFallback({ [ encodePacked( ['bytes1', 'bytes'], - [module.callType, module.data || '0x'], + [module.callType, module.initData || '0x'], ), '0x', ], diff --git a/src/account/kernel/api/isModuleInstalled.ts b/src/account/kernel/api/isModuleInstalled.ts index 8570f5c..b55a8fd 100644 --- a/src/account/kernel/api/isModuleInstalled.ts +++ b/src/account/kernel/api/isModuleInstalled.ts @@ -41,7 +41,7 @@ const _isModuleInstalled = async ({ address: account.address, abi: parseAbi(accountAbi), functionName: 'isModuleInstalled', - args: [kernelModuleTypeIds[module.type], module.module, module.data], + args: [kernelModuleTypeIds[module.type], module.module, module.initData], })) as boolean } diff --git a/src/account/kernel/api/uninstallModule.ts b/src/account/kernel/api/uninstallModule.ts index 1cf87eb..fff588a 100644 --- a/src/account/kernel/api/uninstallModule.ts +++ b/src/account/kernel/api/uninstallModule.ts @@ -55,7 +55,7 @@ const _uninstallModule = async ({ args: [ BigInt(kernelModuleTypeIds[module.type]), module.module, - module.data || '0x', + module.initData || '0x', ], }), }) @@ -79,7 +79,7 @@ const _uninstallFallback = async ({ account, module: { ...module, - data: + initData: encodeAbiParameters( [{ name: 'functionSignature', type: 'bytes4' }], [module.selector!], @@ -99,7 +99,7 @@ const _uninstallFallback = async ({ module.module, encodePacked( ['bytes4', 'bytes'], - [module.selector!, module.data || '0x'], + [module.selector!, module.initData || '0x'], ), ], }), diff --git a/src/account/kernel/types.ts b/src/account/kernel/types.ts index 39f9d31..3947e44 100644 --- a/src/account/kernel/types.ts +++ b/src/account/kernel/types.ts @@ -3,7 +3,7 @@ import { Address, Hex } from 'viem' export type KernelModule = { module: Address - data?: Hex + initData?: Hex additionalContext?: Hex type: KernelModuleType hook?: Address diff --git a/src/account/safe/api/installModule.ts b/src/account/safe/api/installModule.ts index 0b5dd99..be19470 100644 --- a/src/account/safe/api/installModule.ts +++ b/src/account/safe/api/installModule.ts @@ -77,20 +77,20 @@ const getModuleCalldata = (module: Module): Hex => { switch (module.type) { case 'validator': case 'executor': - return module.data || '0x' + return module.initData || '0x' case 'hook': return encodeAbiParameters( parseAbiParameters( 'uint8 hookType, bytes4 selector, bytes memory initData', ), - [module.hookType!, module.selector!, module.data || '0x'], + [module.hookType!, module.selector!, module.initData || '0x'], ) case 'fallback': return encodeAbiParameters( parseAbiParameters( 'bytes4 functionSig, bytes1 calltype, bytes memory initData', ), - [module.functionSig!, module.callType!, module.data || '0x'], + [module.functionSig!, module.callType!, module.initData || '0x'], ) default: throw new Error(`Unknown module type ${module.type}`) diff --git a/src/account/safe/api/uninstallModule.ts b/src/account/safe/api/uninstallModule.ts index 17769a8..ab23bd3 100644 --- a/src/account/safe/api/uninstallModule.ts +++ b/src/account/safe/api/uninstallModule.ts @@ -89,18 +89,18 @@ const getModuleCalldata = (module: Module): Hex => { switch (module.type) { case 'validator': case 'executor': - return module.data || '0x' + return module.initData || '0x' case 'hook': return encodeAbiParameters( parseAbiParameters( 'uint8 hookType, bytes4 selector, bytes memory initData', ), - [module.hookType!, module.selector!, module.data || '0x'], + [module.hookType!, module.selector!, module.initData || '0x'], ) case 'fallback': return encodeAbiParameters( parseAbiParameters('bytes4 functionSig, bytes memory moduleDeInitData'), - [module.functionSig!, module.data || '0x'], + [module.functionSig!, module.initData || '0x'], ) default: throw new Error(`Unknown module type ${module.type}`) diff --git a/src/common/queries/account.ts b/src/common/queries/account.ts index 3aa43a9..a9900e0 100644 --- a/src/common/queries/account.ts +++ b/src/common/queries/account.ts @@ -37,7 +37,9 @@ export const getInstalledModules = async ({ return responseBody.data.moduleQueries.map((module: any) => module.module) } else { throw new Error( - `Error: ${responseBody.errors.map((error: any) => error.message).join(', ')}`, + `Error: ${responseBody.errors + .map((error: any) => error.message) + .join(', ')}`, ) } } diff --git a/src/common/queries/registry.ts b/src/common/queries/registry.ts index 55b70e2..d9e705f 100644 --- a/src/common/queries/registry.ts +++ b/src/common/queries/registry.ts @@ -28,7 +28,9 @@ export const getRegistryModules = async (): Promise => { return responseBody.data.moduleRegistrations } else { throw new Error( - `Error: ${responseBody.errors.map((error: any) => error.message).join(', ')}`, + `Error: ${responseBody.errors + .map((error: any) => error.message) + .join(', ')}`, ) } } diff --git a/src/index.ts b/src/index.ts index e962cdf..8dbbcd4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,69 +12,70 @@ export type { Account, AccountType, Execution, InitialModules } from './account' export { getModule, MULTI_FACTOR_VALIDATOR_ADDRESS, - getInstallMultiFactorValidator, + getMultiFactorValidator, getSetMFAThresholdAction, getSetMFAValidatorAction, getRemoveMFAValidatorAction, isMFASubValidator, getMFAValidatorMockSignature, OWNABLE_VALIDATOR_ADDRESS, - getInstallOwnableValidator, + getOwnableValidator, getAddOwnableValidatorOwnerAction, getRemoveOwnableValidatorOwnerAction, getSetOwnableValidatorThresholdAction, getOwnableValidatorOwners, + getOwnableValidatorThreshold, getOwnableValidatorMockSignature, SCHEDULED_ORDERS_EXECUTER_ADDRESS, - getInstallScheduledOrdersExecutor, + getScheduledOrdersExecutor, getCreateScheduledOrderAction, getSwapOrderData, SCHEDULED_TRANSFERS_EXECUTER_ADDRESS, - getInstallScheduledTransfersExecutor, + getScheduledTransfersExecutor, getCreateScheduledTransferAction, - getScheduledTransactionData, + getScheduledTransferData, WEBAUTHN_VALIDATOR_ADDRESS, - getInstallWebAuthnValidator, + getWebAuthnValidator, getWebauthnValidatorSignature, getWebauthnValidatorMockSignature, SOCIAL_RECOVERY_ADDRESS, - getInstallSocialRecoveryValidator, + getSocialRecoveryValidator, getAddSocialRecoveryGuardianAction, getSocialRecoveryGuardians, getRemoveSocialRecoveryGuardianAction, getSetSocialRecoveryThresholdAction, getSocialRecoveryMockSignature, DEADMAN_SWITCH_ADDRESS, - getInstallDeadmanSwitch, + getDeadmanSwitch, getDeadmanSwitchConfig, getDeadmanSwitchValidatorMockSignature, OWNABLE_EXECUTER_ADDRESS, - getInstallOwnableExecuter, + getOwnableExecuter, getAddOwnableExecutorOwnerAction, getRemoveOwnableExecutorOwnerAction, getOwnableExecutorOwners, getExecuteOnOwnedAccountAction, getExecuteBatchOnOwnedAccountAction, AUTO_SAVINGS_ADDRESS, - getInstallAutoSavingsExecutor, + getAutoSavingsExecutor, getSetAutoSavingConfigAction, getAutoSavingAccountTokenConfig, getDeleteAutoSavingConfigAction, getAutoSaveAction, getAutoSavingTokens, REGISTRY_HOOK_ADDRESS, - getInstallRegistryHook, + getRegistryHook, getSetRegistryAction, HOOK_MULTI_PLEXER_ADDRESS, - getInstallHookMultiPlexer, + getHookMultiPlexer, getAddHookAction, getRemoveHookAction, getHooks, HookType, COLD_STORAGE_HOOK_ADDRESS, COLD_STORAGE_FLASHLOAN_ADDRESS, - getInstallColdStorageHook, - getInstallAllowedCallbackSenders, + getColdStorageHook, + getAllowedCallbackSenders, getColdStorageSetWaitPeriodAction, getRequestTimelockedExecution, getRequestTimelockedModuleConfigExecution, diff --git a/src/module/api/getModule.ts b/src/module/api/getModule.ts index acc2ba8..3ca7806 100644 --- a/src/module/api/getModule.ts +++ b/src/module/api/getModule.ts @@ -4,7 +4,8 @@ import { SafeHookType } from '../../account/safe/types' export const getModule = ({ module, - data = '0x', + initData = '0x', + deInitData = '0x', type, additionalContext, hook, @@ -14,7 +15,8 @@ export const getModule = ({ hookType, }: { module: Address - data?: Hex + initData?: Hex + deInitData?: Hex type: ModuleType additionalContext?: Hex @@ -32,7 +34,8 @@ export const getModule = ({ }): Module => { return { module, - data, + initData, + deInitData, type, additionalContext: additionalContext || '0x', hook, diff --git a/src/module/auto-savings/index.ts b/src/module/auto-savings/index.ts index 7e3c99a..a84d2c0 100644 --- a/src/module/auto-savings/index.ts +++ b/src/module/auto-savings/index.ts @@ -1,5 +1,5 @@ export { AUTO_SAVINGS_ADDRESS } from './constants' -export { getInstallAutoSavingsExecutor } from './installation' +export { getAutoSavingsExecutor } from './installation' export { getSetAutoSavingConfigAction, getAutoSavingAccountTokenConfig, diff --git a/src/module/auto-savings/installation.ts b/src/module/auto-savings/installation.ts index 04663cf..b4e05b3 100644 --- a/src/module/auto-savings/installation.ts +++ b/src/module/auto-savings/installation.ts @@ -12,14 +12,14 @@ type Params = { hook?: Address } -export const getInstallAutoSavingsExecutor = ({ +export const getAutoSavingsExecutor = ({ tokens, configs, hook, }: Params): Module => { return { module: AUTO_SAVINGS_ADDRESS, - data: encodeAbiParameters( + initData: encodeAbiParameters( [ { internalType: 'address[]', name: '_tokens', type: 'address[]' }, { @@ -39,6 +39,7 @@ export const getInstallAutoSavingsExecutor = ({ ], [tokens, configs], ), + deInitData: '0x', additionalContext: '0x', type: 'executor', hook, diff --git a/src/module/cold-storage/index.ts b/src/module/cold-storage/index.ts index 14798f0..3c462e0 100644 --- a/src/module/cold-storage/index.ts +++ b/src/module/cold-storage/index.ts @@ -2,10 +2,7 @@ export { COLD_STORAGE_HOOK_ADDRESS, COLD_STORAGE_FLASHLOAN_ADDRESS, } from './constants' -export { - getInstallColdStorageHook, - getInstallAllowedCallbackSenders, -} from './installation' +export { getColdStorageHook, getAllowedCallbackSenders } from './installation' export { getColdStorageSetWaitPeriodAction, getRequestTimelockedExecution, diff --git a/src/module/cold-storage/installation.ts b/src/module/cold-storage/installation.ts index 1922c45..647bfd8 100644 --- a/src/module/cold-storage/installation.ts +++ b/src/module/cold-storage/installation.ts @@ -23,7 +23,7 @@ type Params = { hook?: Address } -export const getInstallColdStorageHook = async ({ +export const getColdStorageHook = async ({ account, client, waitPeriod, @@ -33,13 +33,13 @@ export const getInstallColdStorageHook = async ({ }: Params): Promise => { const installedModules = await getInstalledModules({ account, client }) - const data = installedModules.includes(COLD_STORAGE_HOOK_ADDRESS) + const initData = installedModules.includes(COLD_STORAGE_HOOK_ADDRESS) ? '0x' : encodePacked(['uint128', 'address'], [BigInt(waitPeriod), owner]) return { module: COLD_STORAGE_HOOK_ADDRESS, - data, + initData, additionalContext: '0x', type: moduleType, hook, @@ -54,7 +54,7 @@ type FlashloanParams = { hook?: Address } -export const getInstallAllowedCallbackSenders = ({ +export const getAllowedCallbackSenders = ({ addresses, functionSig, callType, @@ -63,10 +63,11 @@ export const getInstallAllowedCallbackSenders = ({ }: FlashloanParams): Module => { return { module: COLD_STORAGE_FLASHLOAN_ADDRESS, - data: encodeAbiParameters( + initData: encodeAbiParameters( [{ internalType: 'address[]', name: 'addresses', type: 'address[]' }], [addresses], ), + deInitData: '0x', functionSig, selector, hook, diff --git a/src/module/deadman-switch/abi.ts b/src/module/deadman-switch/abi.ts index 3ed836c..49223b5 100644 --- a/src/module/deadman-switch/abi.ts +++ b/src/module/deadman-switch/abi.ts @@ -10,4 +10,13 @@ export const abi = [ stateMutability: 'view', type: 'function', }, + { + inputs: [ + { internalType: 'address', name: 'smartAccount', type: 'address' }, + ], + name: 'isInitialized', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, ] diff --git a/src/module/deadman-switch/index.ts b/src/module/deadman-switch/index.ts index 630726e..437f9cb 100644 --- a/src/module/deadman-switch/index.ts +++ b/src/module/deadman-switch/index.ts @@ -1,5 +1,5 @@ export { DEADMAN_SWITCH_ADDRESS } from './constants' -export { getInstallDeadmanSwitch } from './installation' +export { getDeadmanSwitch } from './installation' export { getDeadmanSwitchConfig, getDeadmanSwitchValidatorMockSignature, diff --git a/src/module/deadman-switch/installation.ts b/src/module/deadman-switch/installation.ts index c077cd3..546bcff 100644 --- a/src/module/deadman-switch/installation.ts +++ b/src/module/deadman-switch/installation.ts @@ -1,21 +1,37 @@ -import { Address, encodePacked } from 'viem' +import { Address, encodePacked, PublicClient } from 'viem' import { Module } from '../types' import { DEADMAN_SWITCH_ADDRESS } from './constants' +import { abi } from './abi' +import { Account } from '../../account' -export const getInstallDeadmanSwitch = ({ +export const getDeadmanSwitch = async ({ moduleType, nominee, timeout, hook, + account, + client, }: { nominee: Address timeout: number moduleType: 'hook' | 'validator' hook?: Address -}): Module => { + account: Account + client: PublicClient +}): Promise => { + const isInitialized = (await client.readContract({ + address: DEADMAN_SWITCH_ADDRESS, + abi, + functionName: 'isInitialized', + args: [account.address], + })) as boolean + return { module: DEADMAN_SWITCH_ADDRESS, - data: encodePacked(['address', 'uint48'], [nominee, timeout]), + initData: isInitialized + ? '0x' + : encodePacked(['address', 'uint48'], [nominee, timeout]), + deInitData: '0x', additionalContext: '0x', type: moduleType, hook, diff --git a/src/module/hook-multi-plexer/index.ts b/src/module/hook-multi-plexer/index.ts index 06a9716..0cb9eb6 100644 --- a/src/module/hook-multi-plexer/index.ts +++ b/src/module/hook-multi-plexer/index.ts @@ -1,5 +1,5 @@ export { HOOK_MULTI_PLEXER_ADDRESS } from './constants' -export { getInstallHookMultiPlexer } from './installation' +export { getHookMultiPlexer } from './installation' export { getAddHookAction, getRemoveHookAction, getHooks } from './usage' export { HookType } from './types' export type { SigHookInit } from './types' diff --git a/src/module/hook-multi-plexer/installation.ts b/src/module/hook-multi-plexer/installation.ts index 7f67a58..862f356 100644 --- a/src/module/hook-multi-plexer/installation.ts +++ b/src/module/hook-multi-plexer/installation.ts @@ -13,7 +13,7 @@ type Params = { hookType?: number } -export const getInstallHookMultiPlexer = ({ +export const getHookMultiPlexer = ({ globalHooks, valueHooks, delegatecallHooks, @@ -24,7 +24,7 @@ export const getInstallHookMultiPlexer = ({ }: Params): Module => { return { module: HOOK_MULTI_PLEXER_ADDRESS, - data: encodeAbiParameters( + initData: encodeAbiParameters( [ { internalType: 'address[]', name: 'globalHooks', type: 'address[]' }, { internalType: 'address[]', name: 'valueHooks', type: 'address[]' }, @@ -52,6 +52,7 @@ export const getInstallHookMultiPlexer = ({ ], [globalHooks, valueHooks, delegatecallHooks, sigHooks, targetHooks], ), + deInitData: '0x', additionalContext: '0x', type: 'hook', selector, diff --git a/src/module/index.ts b/src/module/index.ts index c0d022d..b346434 100644 --- a/src/module/index.ts +++ b/src/module/index.ts @@ -2,7 +2,7 @@ export { getModule } from './api' export { MULTI_FACTOR_VALIDATOR_ADDRESS, - getInstallMultiFactorValidator, + getMultiFactorValidator, getSetMFAThresholdAction, getSetMFAValidatorAction, getRemoveMFAValidatorAction, @@ -12,38 +12,39 @@ export { export { OWNABLE_VALIDATOR_ADDRESS, - getInstallOwnableValidator, + getOwnableValidator, getAddOwnableValidatorOwnerAction, getRemoveOwnableValidatorOwnerAction, getSetOwnableValidatorThresholdAction, getOwnableValidatorOwners, + getOwnableValidatorThreshold, getOwnableValidatorMockSignature, } from './ownable-validator' export { SCHEDULED_ORDERS_EXECUTER_ADDRESS, - getInstallScheduledOrdersExecutor, + getScheduledOrdersExecutor, getCreateScheduledOrderAction, getSwapOrderData, } from './scheduled-orders' export { SCHEDULED_TRANSFERS_EXECUTER_ADDRESS, - getInstallScheduledTransfersExecutor, + getScheduledTransfersExecutor, getCreateScheduledTransferAction, - getScheduledTransactionData, + getScheduledTransferData, } from './scheduled-transfers' export { WEBAUTHN_VALIDATOR_ADDRESS, - getInstallWebAuthnValidator, + getWebAuthnValidator, getWebauthnValidatorSignature, getWebauthnValidatorMockSignature, } from './webauthn-validator' export { SOCIAL_RECOVERY_ADDRESS, - getInstallSocialRecoveryValidator, + getSocialRecoveryValidator, getAddSocialRecoveryGuardianAction, getSocialRecoveryGuardians, getRemoveSocialRecoveryGuardianAction, @@ -53,14 +54,14 @@ export { export { DEADMAN_SWITCH_ADDRESS, - getInstallDeadmanSwitch, + getDeadmanSwitch, getDeadmanSwitchConfig, getDeadmanSwitchValidatorMockSignature, } from './deadman-switch' export { OWNABLE_EXECUTER_ADDRESS, - getInstallOwnableExecuter, + getOwnableExecuter, getAddOwnableExecutorOwnerAction, getRemoveOwnableExecutorOwnerAction, getOwnableExecutorOwners, @@ -70,7 +71,7 @@ export { export { AUTO_SAVINGS_ADDRESS, - getInstallAutoSavingsExecutor, + getAutoSavingsExecutor, getSetAutoSavingConfigAction, getAutoSavingAccountTokenConfig, getDeleteAutoSavingConfigAction, @@ -80,13 +81,13 @@ export { export { REGISTRY_HOOK_ADDRESS, - getInstallRegistryHook, + getRegistryHook, getSetRegistryAction, } from './registry-hook' export { HOOK_MULTI_PLEXER_ADDRESS, - getInstallHookMultiPlexer, + getHookMultiPlexer, getAddHookAction, getRemoveHookAction, getHooks, @@ -103,8 +104,8 @@ export { getFlashloanAddAddressAction, getFlashloanRemoveAddressAction, getFlashloanWhitelist, - getInstallAllowedCallbackSenders, - getInstallColdStorageHook, + getAllowedCallbackSenders, + getColdStorageHook, } from './cold-storage' export { fetchRegistryModules, REGISTRY_ADDRESS } from './registry' diff --git a/src/module/mfa-validator/installation.ts b/src/module/mfa-validator/installation.ts index 4ea9b97..0f69d7f 100644 --- a/src/module/mfa-validator/installation.ts +++ b/src/module/mfa-validator/installation.ts @@ -14,11 +14,13 @@ export const getMFAValidator = ({ const subValidators: Address[] = validators.map( (validator) => validator.module, ) - const initDatas: Hex[] = validators.map((validator) => validator.data ?? '0x') + const initDatas: Hex[] = validators.map( + (validator) => validator.initData ?? '0x', + ) return { module: MFA_VALIDATOR_ADDRESS, - data: encodeAbiParameters( + initData: encodeAbiParameters( [ { name: 'subValidators', type: 'address[]' }, { name: 'deInitDatas', type: 'bytes[]' }, @@ -27,6 +29,7 @@ export const getMFAValidator = ({ ], [subValidators, deInitDatas, initDatas, threshold], ), + deInitData: '0x', additionalContext: '0x', type: 'validator', } diff --git a/src/module/multi-factor-validator/index.ts b/src/module/multi-factor-validator/index.ts index 3503898..ffda30f 100644 --- a/src/module/multi-factor-validator/index.ts +++ b/src/module/multi-factor-validator/index.ts @@ -1,5 +1,5 @@ export { MULTI_FACTOR_VALIDATOR_ADDRESS } from './constants' -export { getInstallMultiFactorValidator } from './installation' +export { getMultiFactorValidator } from './installation' export { getSetMFAThresholdAction, getRemoveMFAValidatorAction, diff --git a/src/module/multi-factor-validator/installation.ts b/src/module/multi-factor-validator/installation.ts index ab88e1a..fd1d623 100644 --- a/src/module/multi-factor-validator/installation.ts +++ b/src/module/multi-factor-validator/installation.ts @@ -3,7 +3,7 @@ import { Module } from '../types' import { MULTI_FACTOR_VALIDATOR_ADDRESS } from './constants' import { Validator } from './types' -export const getInstallMultiFactorValidator = ({ +export const getMultiFactorValidator = ({ threshold, validators, hook, @@ -14,7 +14,7 @@ export const getInstallMultiFactorValidator = ({ }): Module => { return { module: MULTI_FACTOR_VALIDATOR_ADDRESS, - data: encodePacked( + initData: encodePacked( ['uint8', 'bytes'], [ threshold, @@ -37,6 +37,7 @@ export const getInstallMultiFactorValidator = ({ ), ], ), + deInitData: '0x', additionalContext: '0x', type: 'validator', hook, diff --git a/src/module/ownable-executer/index.ts b/src/module/ownable-executer/index.ts index 92097f2..8452d97 100644 --- a/src/module/ownable-executer/index.ts +++ b/src/module/ownable-executer/index.ts @@ -1,5 +1,5 @@ export { OWNABLE_EXECUTER_ADDRESS } from './constants' -export { getInstallOwnableExecuter } from './installation' +export { getOwnableExecuter } from './installation' export { getAddOwnableExecutorOwnerAction, getRemoveOwnableExecutorOwnerAction, diff --git a/src/module/ownable-executer/installation.ts b/src/module/ownable-executer/installation.ts index 1a12d94..47f6e69 100644 --- a/src/module/ownable-executer/installation.ts +++ b/src/module/ownable-executer/installation.ts @@ -2,7 +2,7 @@ import { Address, encodePacked } from 'viem' import { Module } from '../types' import { OWNABLE_EXECUTER_ADDRESS } from './constants' -export const getInstallOwnableExecuter = ({ +export const getOwnableExecuter = ({ owner, hook, }: { @@ -11,7 +11,8 @@ export const getInstallOwnableExecuter = ({ }): Module => { return { module: OWNABLE_EXECUTER_ADDRESS, - data: encodePacked(['address'], [owner]), + initData: encodePacked(['address'], [owner]), + deInitData: '0x', additionalContext: '0x', type: 'executor', hook, diff --git a/src/module/ownable-executer/usage.ts b/src/module/ownable-executer/usage.ts index 9705753..7c368b2 100644 --- a/src/module/ownable-executer/usage.ts +++ b/src/module/ownable-executer/usage.ts @@ -12,11 +12,23 @@ import { SENTINEL_ADDRESS } from '../../common/constants' import { OWNABLE_EXECUTER_ADDRESS } from './constants' import { Account } from '../../account' -export const getAddOwnableExecutorOwnerAction = ({ +export const getAddOwnableExecutorOwnerAction = async ({ owner, + client, + account, }: { owner: Address -}): Execution => { + client: PublicClient + account: Account +}): Promise => { + const owners = await getOwnableExecutorOwners({ account, client }) + + const currentOwnerIndex = owners.findIndex((o: Address) => o === owner) + + if (currentOwnerIndex !== -1) { + throw new Error('Owner already exists') + } + return { target: OWNABLE_EXECUTER_ADDRESS, value: BigInt(0), diff --git a/src/module/ownable-validator/index.ts b/src/module/ownable-validator/index.ts index 012a7fa..7447d39 100644 --- a/src/module/ownable-validator/index.ts +++ b/src/module/ownable-validator/index.ts @@ -1,9 +1,10 @@ export { OWNABLE_VALIDATOR_ADDRESS } from './constants' -export { getInstallOwnableValidator } from './installation' +export { getOwnableValidator } from './installation' export { getSetOwnableValidatorThresholdAction, getAddOwnableValidatorOwnerAction, getRemoveOwnableValidatorOwnerAction, getOwnableValidatorOwners, getOwnableValidatorMockSignature, + getOwnableValidatorThreshold, } from './usage' diff --git a/src/module/ownable-validator/installation.ts b/src/module/ownable-validator/installation.ts index c878bc8..876e617 100644 --- a/src/module/ownable-validator/installation.ts +++ b/src/module/ownable-validator/installation.ts @@ -2,7 +2,7 @@ import { Address, encodeAbiParameters } from 'viem' import { Module } from '../types' import { OWNABLE_VALIDATOR_ADDRESS } from './constants' -export const getInstallOwnableValidator = ({ +export const getOwnableValidator = ({ threshold, owners, hook, @@ -13,13 +13,14 @@ export const getInstallOwnableValidator = ({ }): Module => { return { module: OWNABLE_VALIDATOR_ADDRESS, - data: encodeAbiParameters( + initData: encodeAbiParameters( [ { name: 'threshold', type: 'uint256' }, { name: 'owners', type: 'address[]' }, ], [BigInt(threshold), owners], ), + deInitData: '0x', additionalContext: '0x', hook, type: 'validator', diff --git a/src/module/ownable-validator/usage.ts b/src/module/ownable-validator/usage.ts index 137d30e..4c6436b 100644 --- a/src/module/ownable-validator/usage.ts +++ b/src/module/ownable-validator/usage.ts @@ -27,11 +27,23 @@ export const getSetOwnableValidatorThresholdAction = ({ } } -export const getAddOwnableValidatorOwnerAction = ({ +export const getAddOwnableValidatorOwnerAction = async ({ owner, + client, + account, }: { owner: Address -}): Execution => { + client: PublicClient + account: Account +}): Promise => { + const owners = await getOwnableValidatorOwners({ account, client }) + + const currentOwnerIndex = owners.findIndex((o: Address) => o === owner) + + if (currentOwnerIndex !== -1) { + throw new Error('Owner already exists') + } + return { target: OWNABLE_VALIDATOR_ADDRESS, value: BigInt(0), @@ -98,6 +110,27 @@ export const getOwnableValidatorOwners = async ({ } } +export const getOwnableValidatorThreshold = async ({ + account, + client, +}: { + account: Account + client: PublicClient +}): Promise => { + try { + const threshold = (await client.readContract({ + address: OWNABLE_VALIDATOR_ADDRESS, + abi, + functionName: 'threshold', + args: [account.address], + })) as number + + return Number(threshold) + } catch { + throw new Error('Failed to get threshold') + } +} + export const getOwnableValidatorMockSignature = (): Hex => { return '0xe8b94748580ca0b4993c9a1b86b5be851bfc076ff5ce3a1ff65bf16392acfcb800f9b4f1aef1555c7fce5599fffb17e7c635502154a0333ba21f3ae491839af51c' } diff --git a/src/module/registry-hook/index.ts b/src/module/registry-hook/index.ts index 4b6861f..78b7342 100644 --- a/src/module/registry-hook/index.ts +++ b/src/module/registry-hook/index.ts @@ -1,3 +1,3 @@ export { REGISTRY_HOOK_ADDRESS } from './constants' -export { getInstallRegistryHook } from './installation' +export { getRegistryHook } from './installation' export { getSetRegistryAction } from './usage' diff --git a/src/module/registry-hook/installation.ts b/src/module/registry-hook/installation.ts index 58748d2..df8e9d2 100644 --- a/src/module/registry-hook/installation.ts +++ b/src/module/registry-hook/installation.ts @@ -2,14 +2,15 @@ import { Address, encodePacked } from 'viem' import { Module } from '../types' import { REGISTRY_HOOK_ADDRESS } from './constants' -export const getInstallRegistryHook = ({ +export const getRegistryHook = ({ registryAddress, }: { registryAddress: Address }): Module => { return { module: REGISTRY_HOOK_ADDRESS, - data: encodePacked(['address'], [registryAddress]), + initData: encodePacked(['address'], [registryAddress]), + deInitData: '0x', additionalContext: '0x', type: 'hook', } diff --git a/src/module/scheduled-orders/index.ts b/src/module/scheduled-orders/index.ts index 3f74c24..424c38e 100644 --- a/src/module/scheduled-orders/index.ts +++ b/src/module/scheduled-orders/index.ts @@ -1,4 +1,4 @@ export { SCHEDULED_ORDERS_EXECUTER_ADDRESS } from './constants' -export { getInstallScheduledOrdersExecutor } from './installation' +export { getScheduledOrdersExecutor } from './installation' export { getCreateScheduledOrderAction, getSwapOrderData } from './usage' export * from './types' diff --git a/src/module/scheduled-orders/installation.ts b/src/module/scheduled-orders/installation.ts index baa8b42..07bf071 100644 --- a/src/module/scheduled-orders/installation.ts +++ b/src/module/scheduled-orders/installation.ts @@ -10,7 +10,7 @@ type Params = { hook?: Address } -export const getInstallScheduledOrdersExecutor = ({ +export const getScheduledOrdersExecutor = ({ executeInterval, numberOfExecutions, startDate, @@ -20,10 +20,11 @@ export const getInstallScheduledOrdersExecutor = ({ return { module: SCHEDULED_ORDERS_EXECUTER_ADDRESS, type: 'executor', - data: encodePacked( + initData: encodePacked( ['uint48', 'uint16', 'uint48', 'bytes'], [executeInterval, numberOfExecutions, startDate, executionData], ), + deInitData: '0x', hook, } } diff --git a/src/module/scheduled-transfers/index.ts b/src/module/scheduled-transfers/index.ts index 329756f..744700c 100644 --- a/src/module/scheduled-transfers/index.ts +++ b/src/module/scheduled-transfers/index.ts @@ -1,6 +1,6 @@ export { SCHEDULED_TRANSFERS_EXECUTER_ADDRESS } from './constants' -export { getInstallScheduledTransfersExecutor } from './installation' +export { getScheduledTransfersExecutor } from './installation' export { getCreateScheduledTransferAction, - getScheduledTransactionData, + getScheduledTransferData, } from './usage' diff --git a/src/module/scheduled-transfers/installation.ts b/src/module/scheduled-transfers/installation.ts index 52bbdad..4bc19be 100644 --- a/src/module/scheduled-transfers/installation.ts +++ b/src/module/scheduled-transfers/installation.ts @@ -10,7 +10,7 @@ type Params = { hook?: Address } -export const getInstallScheduledTransfersExecutor = ({ +export const getScheduledTransfersExecutor = ({ executeInterval, numberOfExecutions, startDate, @@ -20,10 +20,11 @@ export const getInstallScheduledTransfersExecutor = ({ return { module: SCHEDULED_TRANSFERS_EXECUTER_ADDRESS, type: 'executor', - data: encodePacked( + initData: encodePacked( ['uint48', 'uint16', 'uint48', 'bytes'], [executeInterval, numberOfExecutions, startDate, executionData], ), + deInitData: '0x', hook, } } diff --git a/src/module/scheduled-transfers/types.ts b/src/module/scheduled-transfers/types.ts index af3e685..aaafbf6 100644 --- a/src/module/scheduled-transfers/types.ts +++ b/src/module/scheduled-transfers/types.ts @@ -1,7 +1,7 @@ import { Address } from 'viem' import { ERC20Token, Schedule } from '../scheduled-orders/types' -export type ScheduledTransaction = Schedule & { +export type ScheduledTransfer = Schedule & { token?: ERC20Token amount: number recipient: Address diff --git a/src/module/scheduled-transfers/usage.ts b/src/module/scheduled-transfers/usage.ts index 9c37d9c..208376f 100644 --- a/src/module/scheduled-transfers/usage.ts +++ b/src/module/scheduled-transfers/usage.ts @@ -6,21 +6,21 @@ import { encodePacked, erc20Abi, } from 'viem' -import { ScheduledTransaction } from './types' +import { ScheduledTransfer } from './types' import { Execution } from '../../account/types' import { SCHEDULED_TRANSFERS_EXECUTER_ADDRESS } from './constants' import { abi } from './abi' type Params = { - scheduledTransaction: ScheduledTransaction + scheduledTransfer: ScheduledTransfer } -export const getScheduledTransactionData = ({ - scheduledTransaction, +export const getScheduledTransferData = ({ + scheduledTransfer, }: Params): Hex => { const amount = BigInt( - Number(scheduledTransaction.amount) * - 10 ** (scheduledTransaction.token?.decimals || 18), + Number(scheduledTransfer.amount) * + 10 ** (scheduledTransfer.token?.decimals || 18), ) return encodeAbiParameters( @@ -30,28 +30,28 @@ export const getScheduledTransactionData = ({ { name: 'callData', type: 'bytes' }, ], [ - scheduledTransaction.token - ? (scheduledTransaction.token.token_address as Address) - : (scheduledTransaction.recipient as Address), - scheduledTransaction.token ? BigInt(0) : amount, - scheduledTransaction.token + scheduledTransfer.token + ? (scheduledTransfer.token.token_address as Address) + : (scheduledTransfer.recipient as Address), + scheduledTransfer.token ? BigInt(0) : amount, + scheduledTransfer.token ? encodeFunctionData({ functionName: 'transfer', abi: erc20Abi, - args: [scheduledTransaction.recipient as Address, amount], + args: [scheduledTransfer.recipient as Address, amount], }) : '0x', ], ) } -type CreateScheduledTransactionExecutionParams = { - scheduledTransaction: ScheduledTransaction +type CreateScheduledTransferExecutionParams = { + scheduledTransfer: ScheduledTransfer } export const getCreateScheduledTransferAction = ({ - scheduledTransaction, -}: CreateScheduledTransactionExecutionParams): Execution => { + scheduledTransfer, +}: CreateScheduledTransferExecutionParams): Execution => { return { target: SCHEDULED_TRANSFERS_EXECUTER_ADDRESS, value: BigInt(0), @@ -62,10 +62,10 @@ export const getCreateScheduledTransferAction = ({ encodePacked( ['uint48', 'uint16', 'uint48', 'bytes'], [ - scheduledTransaction.repeatEvery, - scheduledTransaction.numberOfRepeats, - scheduledTransaction.startDate, - getScheduledTransactionData({ scheduledTransaction }), + scheduledTransfer.repeatEvery, + scheduledTransfer.numberOfRepeats, + scheduledTransfer.startDate, + getScheduledTransferData({ scheduledTransfer }), ], ), ], diff --git a/src/module/social-recovery/installation.ts b/src/module/social-recovery/installation.ts index 3b4e4dc..465d947 100644 --- a/src/module/social-recovery/installation.ts +++ b/src/module/social-recovery/installation.ts @@ -2,7 +2,7 @@ import { Address, encodeAbiParameters } from 'viem' import { Module } from '../types' import { SOCIAL_RECOVERY_ADDRESS } from './constants' -export const getInstallSocialRecoveryValidator = ({ +export const getSocialRecoveryValidator = ({ threshold, guardians, hook, @@ -13,13 +13,14 @@ export const getInstallSocialRecoveryValidator = ({ }): Module => { return { module: SOCIAL_RECOVERY_ADDRESS, - data: encodeAbiParameters( + initData: encodeAbiParameters( [ { name: 'threshold', type: 'uint256' }, { name: 'guardians', type: 'address[]' }, ], [BigInt(threshold), guardians], ), + deInitData: '0x', additionalContext: '0x', type: 'validator', hook, diff --git a/src/module/types.ts b/src/module/types.ts index f47d199..fcd2eb6 100644 --- a/src/module/types.ts +++ b/src/module/types.ts @@ -5,7 +5,8 @@ export type ModuleType = 'validator' | 'executor' | 'fallback' | 'hook' export type Module = { module: Address - data?: Hex + initData?: Hex + deInitData?: Hex additionalContext?: Hex type: ModuleType diff --git a/src/module/webauthn-validator/index.ts b/src/module/webauthn-validator/index.ts index ab10f31..6bba274 100644 --- a/src/module/webauthn-validator/index.ts +++ b/src/module/webauthn-validator/index.ts @@ -1,5 +1,5 @@ export { WEBAUTHN_VALIDATOR_ADDRESS } from './constants' -export { getInstallWebAuthnValidator } from './installation' +export { getWebAuthnValidator } from './installation' export { getWebauthnValidatorSignature, getWebauthnValidatorMockSignature, diff --git a/src/module/webauthn-validator/installation.ts b/src/module/webauthn-validator/installation.ts index 0007047..28c8a97 100644 --- a/src/module/webauthn-validator/installation.ts +++ b/src/module/webauthn-validator/installation.ts @@ -9,12 +9,12 @@ export type WebauthnCredential = { hook?: Address } -export const getInstallWebAuthnValidator = ( +export const getWebAuthnValidator = ( webAuthnCredential: WebauthnCredential, ): Module => { return { module: WEBAUTHN_VALIDATOR_ADDRESS, - data: encodeAbiParameters( + initData: encodeAbiParameters( [ { components: [ @@ -42,6 +42,7 @@ export const getInstallWebAuthnValidator = ( keccak256(toHex(webAuthnCredential.authenticatorId)), ], ), + deInitData: '0x', hook: webAuthnCredential.hook, additionalContext: '0x', type: 'validator', diff --git a/src/package.json b/src/package.json index b24ead8..d4a3601 100644 --- a/src/package.json +++ b/src/package.json @@ -1,6 +1,6 @@ { "name": "@rhinestone/module-sdk", - "version": "0.1.5", + "version": "0.1.6", "description": "A TypeScript library for using Smart Account Modules in Applications", "author": { "name": "Rhinestone", diff --git a/test/e2e/infra/installModuleActions.ts b/test/e2e/infra/installModuleActions.ts index 4e2b372..378b899 100644 --- a/test/e2e/infra/installModuleActions.ts +++ b/test/e2e/infra/installModuleActions.ts @@ -1,9 +1,9 @@ import { installModule } from 'src/account' import { - getInstallOwnableValidator, - getInstallWebAuthnValidator, - getInstallScheduledOrdersExecutor, - getInstallScheduledTransfersExecutor, + getOwnableValidator, + getWebAuthnValidator, + getScheduledOrdersExecutor, + getScheduledTransfersExecutor, } from 'src/module' import { Account } from 'src/account' import { Address, encodePacked, Hex, PublicClient, zeroAddress } from 'viem' @@ -11,16 +11,16 @@ import { CallType } from 'src/module/types' import { validators } from 'test/utils/userOps/constants/validators' import { REGISTRY_ADDRESS } from 'src/module/registry' import { SafeHookType } from 'src/account/safe/types' -import { getInstallOwnableExecuter } from 'src/module/ownable-executer' -import { getInstallSocialRecoveryValidator } from 'src/module/social-recovery/installation' -import { getInstallAutoSavingsExecutor } from 'src/module/auto-savings' +import { getOwnableExecuter } from 'src/module/ownable-executer' +import { getSocialRecoveryValidator } from 'src/module/social-recovery/installation' +import { getAutoSavingsExecutor } from 'src/module/auto-savings' import { - getInstallAllowedCallbackSenders, - getInstallColdStorageHook, + getAllowedCallbackSenders, + getColdStorageHook, } from 'src/module/cold-storage' -import { getInstallHookMultiPlexer } from 'src/module/hook-multi-plexer' -import { getInstallDeadmanSwitch } from 'src/module/deadman-switch' -import { getInstallMultiFactorValidator } from 'src/module/multi-factor-validator' +import { getHookMultiPlexer } from 'src/module/hook-multi-plexer' +import { getDeadmanSwitch } from 'src/module/deadman-switch' +import { getMultiFactorValidator } from 'src/module/multi-factor-validator' type Params = { account: Account @@ -49,56 +49,60 @@ export const getInstallModuleActions = async ({ account, client }: Params) => { const installOwnableValidatorAction = await installModule({ client, account, - module: getInstallOwnableValidator(ownableValidator), + module: getOwnableValidator(ownableValidator), }) // install webauthn validator const installWebAuthnValidatorAction = await installModule({ client, account, - module: getInstallWebAuthnValidator(webAuthnValidator), + module: getWebAuthnValidator(webAuthnValidator), }) // install ownable executor const installOwnableExecutorAction = await installModule({ client, account, - module: getInstallOwnableExecuter(ownableExecuter), + module: getOwnableExecuter(ownableExecuter), }) // install social recovery const installSocialRecoveryAction = await installModule({ client, account, - module: getInstallSocialRecoveryValidator(socialRecoveryValidator), + module: getSocialRecoveryValidator(socialRecoveryValidator), }) // install auto savings executor const installAutoSavingsExecutorAction = await installModule({ client, account, - module: getInstallAutoSavingsExecutor(autoSavingExecutor), + module: getAutoSavingsExecutor(autoSavingExecutor), }) // install deadman switch validator const installDeadmanSwitchValidatorAction = await installModule({ client, account, - module: getInstallDeadmanSwitch(deadmanSwitchValidator), + module: await getDeadmanSwitch({ + ...deadmanSwitchValidator, + account, + client, + }), }) // install multi factor validator const installMultiFactorValidatorAction = await installModule({ client, account, - module: getInstallMultiFactorValidator(multiFactorValidator), + module: getMultiFactorValidator(multiFactorValidator), }) // install virtual code storage hook const installVirtualCodeStorageExecutorAction = await installModule({ client, account, - module: await getInstallColdStorageHook({ + module: await getColdStorageHook({ account, client, ...virtualCodeStorageExecutor, @@ -109,28 +113,28 @@ export const getInstallModuleActions = async ({ account, client }: Params) => { const installCallbackSendersAction = await installModule({ client, account, - module: getInstallAllowedCallbackSenders(allowedCallbackSendersFallback), + module: getAllowedCallbackSenders(allowedCallbackSendersFallback), }) // install scheduled orders executor const installScheduledOrdersExecutorAction = await installModule({ client, account, - module: getInstallScheduledOrdersExecutor(scheduledOrdersExecutor), + module: getScheduledOrdersExecutor(scheduledOrdersExecutor), }) // install scheduled transfers executor const installScheduledTransfersExecutorAction = await installModule({ client, account, - module: getInstallScheduledTransfersExecutor(scheduledTransfersExecutor), + module: getScheduledTransfersExecutor(scheduledTransfersExecutor), }) // install hook multi plexer const installHookMultiplexerAction = await installModule({ client, account, - module: getInstallHookMultiPlexer(hookMultiPlexer), + module: getHookMultiPlexer(hookMultiPlexer), }) return [ diff --git a/test/e2e/modules/ownableExecutor.ts b/test/e2e/modules/ownableExecutor.ts index 4ab0c1b..65d67ea 100644 --- a/test/e2e/modules/ownableExecutor.ts +++ b/test/e2e/modules/ownableExecutor.ts @@ -54,8 +54,10 @@ export const testOwnableExecutor = async ({ account, client: publicClient, }) - const addNewOwnerAction = getAddOwnableExecutorOwnerAction({ + const addNewOwnerAction = await getAddOwnableExecutorOwnerAction({ owner: newOwner, + account, + client: publicClient, }) await sendUserOp({ account, actions: [addNewOwnerAction] }) diff --git a/test/e2e/modules/ownableValidator.ts b/test/e2e/modules/ownableValidator.ts index 4cc9f85..8db47ed 100644 --- a/test/e2e/modules/ownableValidator.ts +++ b/test/e2e/modules/ownableValidator.ts @@ -53,9 +53,11 @@ export const testOwnableValidator = async ({ account, client: publicClient, }) - const addNewOwnerAction = getAddOwnableValidatorOwnerAction({ + const addNewOwnerAction = (await getAddOwnableValidatorOwnerAction({ owner: newOwner, - }) + account, + client: publicClient, + })) as Execution await sendUserOp({ account, actions: [addNewOwnerAction] }) diff --git a/test/e2e/modules/scheduledTransfersExecutor.ts b/test/e2e/modules/scheduledTransfersExecutor.ts index 7229a31..aab23d8 100644 --- a/test/e2e/modules/scheduledTransfersExecutor.ts +++ b/test/e2e/modules/scheduledTransfersExecutor.ts @@ -39,7 +39,7 @@ export const testScheduledTransfersExecutor = async ({ } const scheduledOrderAction = getCreateScheduledTransferAction({ - scheduledTransaction: { + scheduledTransfer: { token, amount: 100, recipient: '0x0Cb7EAb54EB751579a82D80Fe2683687deb918f3', diff --git a/test/unit/module/autoSavings/autoSavings.test.ts b/test/unit/module/autoSavings/autoSavings.test.ts index 06bbc80..3f7ec42 100644 --- a/test/unit/module/autoSavings/autoSavings.test.ts +++ b/test/unit/module/autoSavings/autoSavings.test.ts @@ -1,5 +1,4 @@ -import { getInstallAutoSavingsExecutor } from 'src' -import { AUTO_SAVINGS_ADDRESS } from 'src' +import { AUTO_SAVINGS_ADDRESS, getAutoSavingsExecutor } from 'src/module' import { Address, zeroAddress } from 'viem' import { getSetAutoSavingConfigAction, @@ -27,13 +26,13 @@ describe('Auto Savings Module', () => { ] it('should get install auto savings module', async () => { - const installAutoSavingsModule = getInstallAutoSavingsExecutor({ + const installAutoSavingsModule = getAutoSavingsExecutor({ tokens, configs, }) expect(installAutoSavingsModule.module).toEqual(AUTO_SAVINGS_ADDRESS) - expect(installAutoSavingsModule.data).toBeDefined() + expect(installAutoSavingsModule.initData).toBeDefined() expect(installAutoSavingsModule.type).toEqual('executor') }) diff --git a/test/unit/module/coldStorage/coldStorage.test.ts b/test/unit/module/coldStorage/coldStorage.test.ts index 2d3b387..b606f20 100644 --- a/test/unit/module/coldStorage/coldStorage.test.ts +++ b/test/unit/module/coldStorage/coldStorage.test.ts @@ -14,10 +14,7 @@ import { getClient } from 'src' import { MockClient } from '../../../utils/mocks/client' import { getAccount } from 'src' import { MockAccountDeployed } from '../../../utils/mocks/account' -import { - getInstallColdStorageHook, - getInstallAllowedCallbackSenders, -} from 'src' +import { getColdStorageHook, getAllowedCallbackSenders } from 'src/module' import { CallType } from 'src/module/types' describe('Cold storage Module', () => { @@ -28,7 +25,7 @@ describe('Cold storage Module', () => { const executionHash = toHex('test_hash', { size: 32 }) it('should get install cold storage hook module', async () => { - const installColdStorageModule = await getInstallColdStorageHook({ + const installColdStorageModule = await getColdStorageHook({ account, client, moduleType: 'hook', @@ -37,12 +34,12 @@ describe('Cold storage Module', () => { }) expect(installColdStorageModule.module).toEqual(COLD_STORAGE_HOOK_ADDRESS) - expect(installColdStorageModule.data).toBeDefined() + expect(installColdStorageModule.initData).toBeDefined() expect(installColdStorageModule.type).toEqual('hook') }) it('should get install cold storage flashloan module', async () => { - const installColdStorageFlashloanModule = getInstallAllowedCallbackSenders({ + const installColdStorageFlashloanModule = getAllowedCallbackSenders({ addresses, selector: '0x00000000', callType: CallType.CALLTYPE_SINGLE, @@ -51,7 +48,7 @@ describe('Cold storage Module', () => { expect(installColdStorageFlashloanModule.module).toEqual( COLD_STORAGE_FLASHLOAN_ADDRESS, ) - expect(installColdStorageFlashloanModule.data).toBeDefined() + expect(installColdStorageFlashloanModule.initData).toBeDefined() expect(installColdStorageFlashloanModule.type).toEqual('fallback') }) diff --git a/test/unit/module/deadmanSwitch/deadmanSwitch.test.ts b/test/unit/module/deadmanSwitch/deadmanSwitch.test.ts index a34ce52..bb82c78 100644 --- a/test/unit/module/deadmanSwitch/deadmanSwitch.test.ts +++ b/test/unit/module/deadmanSwitch/deadmanSwitch.test.ts @@ -1,6 +1,6 @@ import { DEADMAN_SWITCH_ADDRESS, getDeadmanSwitchConfig } from 'src' import { Address, zeroAddress } from 'viem' -import { getInstallDeadmanSwitch } from 'src' +import { getDeadmanSwitch } from 'src/module' import { getClient } from 'src' import { MockClient } from 'test/utils/mocks/client' import { getAccount } from 'src' @@ -13,30 +13,34 @@ describe('Deadman switch Module', () => { const account = getAccount(MockAccountDeployed) it('should get install deadman switch hook module', async () => { - const installDeadmanSwitchHookModule = getInstallDeadmanSwitch({ + const installDeadmanSwitchHookModule = await getDeadmanSwitch({ nominee, timeout: 3, moduleType: 'hook', + account, + client, }) expect(installDeadmanSwitchHookModule.module).toEqual( DEADMAN_SWITCH_ADDRESS, ) - expect(installDeadmanSwitchHookModule.data).toBeDefined() + expect(installDeadmanSwitchHookModule.initData).toBeDefined() expect(installDeadmanSwitchHookModule.type).toEqual('hook') }) it('should get install deadman switch validator module', async () => { - const installDeadmanSwitchValidatorModule = getInstallDeadmanSwitch({ + const installDeadmanSwitchValidatorModule = await getDeadmanSwitch({ nominee, timeout: 3, moduleType: 'validator', + account, + client, }) expect(installDeadmanSwitchValidatorModule.module).toEqual( DEADMAN_SWITCH_ADDRESS, ) - expect(installDeadmanSwitchValidatorModule.data).toBeDefined() + expect(installDeadmanSwitchValidatorModule.initData).toBeDefined() expect(installDeadmanSwitchValidatorModule.type).toEqual('validator') }) diff --git a/test/unit/module/getModule.test.ts b/test/unit/module/getModule.test.ts index 7a2cbcf..c9a9685 100644 --- a/test/unit/module/getModule.test.ts +++ b/test/unit/module/getModule.test.ts @@ -4,14 +4,14 @@ import { getModule } from 'src' describe('Get Module implementation', () => { // Setup const address = slice(keccak256(toHex('address')), 0, 20) - const data = keccak256(toHex('data')) + const initData = keccak256(toHex('initData')) const type = 'validator' it('should get and return an object with the passed arguments', async () => { - const module = getModule({ module: address, data, type }) + const module = getModule({ module: address, initData, type }) expect(module.module).toEqual(address) - expect(module.data).toEqual(data) + expect(module.initData).toEqual(initData) expect(module.type).toEqual(type) }) }) diff --git a/test/unit/module/hookMultiPlexer/hookMultiPlexer.test.ts b/test/unit/module/hookMultiPlexer/hookMultiPlexer.test.ts index fe01889..a984808 100644 --- a/test/unit/module/hookMultiPlexer/hookMultiPlexer.test.ts +++ b/test/unit/module/hookMultiPlexer/hookMultiPlexer.test.ts @@ -3,7 +3,7 @@ import { getClient } from 'src' import { MockClient } from '../../../utils/mocks/client' import { getAccount } from 'src' import { MockAccountDeployed } from '../../../utils/mocks/account' -import { getInstallHookMultiPlexer, HOOK_MULTI_PLEXER_ADDRESS } from 'src' +import { getHookMultiPlexer, HOOK_MULTI_PLEXER_ADDRESS } from 'src/module' import { getAddHookAction, getHooks, getRemoveHookAction } from 'src' import { HookType } from 'src' import { SigHookInit } from 'src/module' @@ -34,12 +34,12 @@ describe('Hook MultiPlexer Module', () => { } it('should get install hook multi plexer module', async () => { - const installHookMultiPlexerModule = getInstallHookMultiPlexer(hooks) + const installHookMultiPlexerModule = getHookMultiPlexer(hooks) expect(installHookMultiPlexerModule.module).toEqual( HOOK_MULTI_PLEXER_ADDRESS, ) - expect(installHookMultiPlexerModule.data).toBeDefined() + expect(installHookMultiPlexerModule.initData).toBeDefined() expect(installHookMultiPlexerModule.type).toEqual('hook') }) diff --git a/test/unit/module/multiFactorValidator/multiFactorValidator.test.ts b/test/unit/module/multiFactorValidator/multiFactorValidator.test.ts index 5d6b94a..9f7a33d 100644 --- a/test/unit/module/multiFactorValidator/multiFactorValidator.test.ts +++ b/test/unit/module/multiFactorValidator/multiFactorValidator.test.ts @@ -4,11 +4,11 @@ import { getAccount } from 'src' import { MockAccountDeployed } from '../../../utils/mocks/account' import { MULTI_FACTOR_VALIDATOR_ADDRESS, - getInstallMultiFactorValidator, + getMultiFactorValidator, getRemoveMFAValidatorAction, getSetMFAValidatorAction, isMFASubValidator, -} from 'src' +} from 'src/module' import { getSetMFAThresholdAction } from 'src' import { Validator } from 'src/module' import { Address, Hex, slice } from 'viem' @@ -37,12 +37,12 @@ describe('MultiFactor Validator Module', () => { } it('should get install multi factor module', async () => { - const installHookMultiPlexerModule = getInstallMultiFactorValidator(mfaData) + const installHookMultiPlexerModule = getMultiFactorValidator(mfaData) expect(installHookMultiPlexerModule.module).toEqual( MULTI_FACTOR_VALIDATOR_ADDRESS, ) - expect(installHookMultiPlexerModule.data).toBeDefined() + expect(installHookMultiPlexerModule.initData).toBeDefined() expect(installHookMultiPlexerModule.type).toEqual('validator') }) diff --git a/test/unit/module/ownableExecuter/ownableExecuter.test.ts b/test/unit/module/ownableExecuter/ownableExecuter.test.ts index 1db45ab..f6cd632 100644 --- a/test/unit/module/ownableExecuter/ownableExecuter.test.ts +++ b/test/unit/module/ownableExecuter/ownableExecuter.test.ts @@ -1,4 +1,4 @@ -import { getInstallOwnableExecuter } from 'src' +import { getOwnableExecuter } from 'src/module' import { OWNABLE_EXECUTER_ADDRESS } from 'src' import { Address } from 'viem' import { @@ -24,19 +24,21 @@ describe('Ownable Executer Module', () => { ] as Address[] it('should get install ownable executer module', async () => { - const installOwnableExecuterModule = getInstallOwnableExecuter({ + const installOwnableExecuterModule = getOwnableExecuter({ owner: owners[0], }) expect(installOwnableExecuterModule.module).toEqual( OWNABLE_EXECUTER_ADDRESS, ) - expect(installOwnableExecuterModule.data).toBeDefined() + expect(installOwnableExecuterModule.initData).toBeDefined() expect(installOwnableExecuterModule.type).toEqual('executor') }) it('Should get addOwnerExecution action', async () => { - const addOwnerExecution = getAddOwnableExecutorOwnerAction({ + const addOwnerExecution = await getAddOwnableExecutorOwnerAction({ + client, + account, owner: owners[0], }) diff --git a/test/unit/module/ownableValidator/ownableValidator.test.ts b/test/unit/module/ownableValidator/ownableValidator.test.ts index 1761813..b041a17 100644 --- a/test/unit/module/ownableValidator/ownableValidator.test.ts +++ b/test/unit/module/ownableValidator/ownableValidator.test.ts @@ -1,4 +1,4 @@ -import { getInstallOwnableValidator } from 'src' +import { getOwnableValidator } from 'src/module' import { OWNABLE_VALIDATOR_ADDRESS } from 'src' import { Address } from 'viem' import { @@ -11,6 +11,8 @@ import { getClient } from 'src' import { MockClient } from 'test/utils/mocks/client' import { getAccount } from 'src' import { MockAccountDeployed } from 'test/utils/mocks/account' +import { getOwnableValidatorThreshold } from 'src/module' +import { Execution } from 'src/account' describe('Ownable Validator Module', () => { // Setup @@ -23,7 +25,7 @@ describe('Ownable Validator Module', () => { ] as Address[] it('should get install ownable validator module', async () => { - const installOwnableValidatorModule = getInstallOwnableValidator({ + const installOwnableValidatorModule = getOwnableValidator({ threshold: 3, owners, }) @@ -31,7 +33,7 @@ describe('Ownable Validator Module', () => { expect(installOwnableValidatorModule.module).toEqual( OWNABLE_VALIDATOR_ADDRESS, ) - expect(installOwnableValidatorModule.data).toBeDefined() + expect(installOwnableValidatorModule.initData).toBeDefined() expect(installOwnableValidatorModule.type).toEqual('validator') }) @@ -46,9 +48,11 @@ describe('Ownable Validator Module', () => { }) it('Should get addOwnerExecution action', async () => { - const addOwnerExecution = getAddOwnableValidatorOwnerAction({ + const addOwnerExecution = (await getAddOwnableValidatorOwnerAction({ + client, + account, owner: owners[0], - }) + })) as Execution expect(addOwnerExecution.target).toEqual(OWNABLE_VALIDATOR_ADDRESS) expect(addOwnerExecution.value).toEqual(BigInt(0)) @@ -72,4 +76,13 @@ describe('Ownable Validator Module', () => { }) expect(allOwners.length).toEqual(0) }) + + it('should return ownable validator threshold', async () => { + const threshold = await getOwnableValidatorThreshold({ + client, + account, + }) + + expect(threshold).toEqual(0) + }) }) diff --git a/test/unit/module/registryHook/registryHook.test.ts b/test/unit/module/registryHook/registryHook.test.ts index b92dd08..298e9a1 100644 --- a/test/unit/module/registryHook/registryHook.test.ts +++ b/test/unit/module/registryHook/registryHook.test.ts @@ -1,4 +1,4 @@ -import { getInstallRegistryHook } from 'src' +import { getRegistryHook } from 'src/module' import { REGISTRY_HOOK_ADDRESS } from 'src' import { Address } from 'viem' import { getSetRegistryAction } from 'src' @@ -9,12 +9,12 @@ describe('Registry hook Module', () => { '0x0Cb7EAb54EB751579a82D80Fe2683687deb918f3' as Address it('should get install registry hook module', async () => { - const installOwnableExecuterModule = getInstallRegistryHook({ + const installOwnableExecuterModule = getRegistryHook({ registryAddress, }) expect(installOwnableExecuterModule.module).toEqual(REGISTRY_HOOK_ADDRESS) - expect(installOwnableExecuterModule.data).toBeDefined() + expect(installOwnableExecuterModule.initData).toBeDefined() expect(installOwnableExecuterModule.type).toEqual('hook') }) diff --git a/test/unit/module/scheduledOrders/scheduledOrders.test.ts b/test/unit/module/scheduledOrders/scheduledOrders.test.ts index 1671d7d..8f3ce19 100644 --- a/test/unit/module/scheduledOrders/scheduledOrders.test.ts +++ b/test/unit/module/scheduledOrders/scheduledOrders.test.ts @@ -1,4 +1,4 @@ -import { getInstallScheduledOrdersExecutor } from 'src' +import { getScheduledOrdersExecutor } from 'src/module' import { SCHEDULED_ORDERS_EXECUTER_ADDRESS } from 'src' import { getCreateScheduledOrderAction } from 'src' import { ERC20Token } from 'src' @@ -16,7 +16,7 @@ describe('ScheduledOrders Module', () => { } it('should get install scheduled orders module', async () => { - const installScheduledOrdersModule = getInstallScheduledOrdersExecutor({ + const installScheduledOrdersModule = getScheduledOrdersExecutor({ numberOfExecutions: 1, executeInterval: 10, startDate: new Date().getTime(), @@ -26,7 +26,7 @@ describe('ScheduledOrders Module', () => { expect(installScheduledOrdersModule.module).toEqual( SCHEDULED_ORDERS_EXECUTER_ADDRESS, ) - expect(installScheduledOrdersModule.data).toBeDefined() + expect(installScheduledOrdersModule.initData).toBeDefined() expect(installScheduledOrdersModule.type).toEqual('executor') }) diff --git a/test/unit/module/scheduledTransfers/scheduledTransfers.test.ts b/test/unit/module/scheduledTransfers/scheduledTransfers.test.ts index 368bdeb..3881341 100644 --- a/test/unit/module/scheduledTransfers/scheduledTransfers.test.ts +++ b/test/unit/module/scheduledTransfers/scheduledTransfers.test.ts @@ -1,6 +1,6 @@ -import { getInstallScheduledTransfersExecutor } from 'src' +import { getScheduledTransfersExecutor } from 'src/module' import { SCHEDULED_TRANSFERS_EXECUTER_ADDRESS } from 'src' -import { getCreateScheduledTransferAction } from 'src' +import { getCreateScheduledTransferAction } from 'src/module' import { ERC20Token } from 'src' describe('ScheduledTransfers Module', () => { @@ -11,24 +11,23 @@ describe('ScheduledTransfers Module', () => { } it('should get install scheduled transfers module', async () => { - const installScheduledTransfersModule = - getInstallScheduledTransfersExecutor({ - numberOfExecutions: 1, - executeInterval: 10, - startDate: new Date().getTime(), - executionData: '0x', - }) + const installScheduledTransfersModule = getScheduledTransfersExecutor({ + numberOfExecutions: 1, + executeInterval: 10, + startDate: new Date().getTime(), + executionData: '0x', + }) expect(installScheduledTransfersModule.module).toEqual( SCHEDULED_TRANSFERS_EXECUTER_ADDRESS, ) - expect(installScheduledTransfersModule.data).toBeDefined() + expect(installScheduledTransfersModule.initData).toBeDefined() expect(installScheduledTransfersModule.type).toEqual('executor') }) it('Should get createScheduledTransferExecution action', async () => { const createScheduledTransferExecution = getCreateScheduledTransferAction({ - scheduledTransaction: { + scheduledTransfer: { token, amount: 100, recipient: '0x0Cb7EAb54EB751579a82D80Fe2683687deb918f3', diff --git a/test/unit/module/socialRecovery/socialRecovery.test.ts b/test/unit/module/socialRecovery/socialRecovery.test.ts index e150a35..c047f68 100644 --- a/test/unit/module/socialRecovery/socialRecovery.test.ts +++ b/test/unit/module/socialRecovery/socialRecovery.test.ts @@ -1,4 +1,4 @@ -import { getInstallSocialRecoveryValidator } from 'src/module/social-recovery/installation' +import { getSocialRecoveryValidator } from 'src/module/social-recovery/installation' import { SOCIAL_RECOVERY_ADDRESS } from 'src/module/social-recovery/constants' import { Address } from 'viem' import { @@ -23,13 +23,13 @@ describe('Social Recovery Module', () => { ] as Address[] it('should get install social recovery module', async () => { - const installSocialRecoveryModule = getInstallSocialRecoveryValidator({ + const installSocialRecoveryModule = getSocialRecoveryValidator({ threshold: 3, guardians, }) expect(installSocialRecoveryModule.module).toEqual(SOCIAL_RECOVERY_ADDRESS) - expect(installSocialRecoveryModule.data).toBeDefined() + expect(installSocialRecoveryModule.initData).toBeDefined() expect(installSocialRecoveryModule.type).toEqual('validator') }) diff --git a/test/unit/module/webauthnValidator/webauthnValidator.test.ts b/test/unit/module/webauthnValidator/webauthnValidator.test.ts index 1040702..d36f09f 100644 --- a/test/unit/module/webauthnValidator/webauthnValidator.test.ts +++ b/test/unit/module/webauthnValidator/webauthnValidator.test.ts @@ -1,6 +1,6 @@ import { WEBAUTHN_VALIDATOR_ADDRESS, - getInstallWebAuthnValidator, + getWebAuthnValidator, getWebauthnValidatorSignature, } from 'src/module' import { toHex } from 'viem' @@ -14,7 +14,7 @@ describe('Webauthn Validator Module', () => { } it('should get install webauthn validator module', async () => { - const installWebauthnValidatorModule = getInstallWebAuthnValidator({ + const installWebauthnValidatorModule = getWebAuthnValidator({ pubKeyX: credentials.pubKeyX, pubKeyY: credentials.pubKeyY, authenticatorId: credentials.authenticatorId, @@ -23,7 +23,7 @@ describe('Webauthn Validator Module', () => { expect(installWebauthnValidatorModule.module).toEqual( WEBAUTHN_VALIDATOR_ADDRESS, ) - expect(installWebauthnValidatorModule.data).toBeDefined() + expect(installWebauthnValidatorModule.initData).toBeDefined() expect(installWebauthnValidatorModule.type).toEqual('validator') }) diff --git a/test/utils/mocks/module.ts b/test/utils/mocks/module.ts index 5ff261c..f26cca0 100644 --- a/test/utils/mocks/module.ts +++ b/test/utils/mocks/module.ts @@ -2,27 +2,27 @@ import { CallType, Module } from 'src/module/types' export const MockValidator: Module = { module: '0x58e7d1cc62482891d902f0a7b255bac6cd001ac6', - data: '0x', + initData: '0x', type: 'validator', hook: '0x73cC9a599d853D4e5a9Bc092578ef3DB7e063179', } export const MockExecutor: Module = { module: '0x73cC9a599d853D4e5a9Bc092578ef3DB7e063179', - data: '0x', + initData: '0x', type: 'executor', hook: '0x73cC9a599d853D4e5a9Bc092578ef3DB7e063179', } export const MockHook: Module = { module: '0x688499e4b783375703d7e60c262b62bf40511523', - data: '0x', + initData: '0x', type: 'hook', } export const MockFallback: Module = { module: '0x510dfc5a624e9dd8518a52271c16063228efe314', - data: '0x150b7a02', + initData: '0x150b7a02', type: 'fallback', hook: '0x73cC9a599d853D4e5a9Bc092578ef3DB7e063179', selector: '0x150b7a02', @@ -33,7 +33,7 @@ export const MockFallback: Module = { export const MockSafeFallback: Module = { module: '0x510dfc5a624e9dd8518a52271c16063228efe314', - data: '0x150b7a02', + initData: '0x150b7a02', type: 'fallback', callType: CallType.CALLTYPE_SINGLE, functionSig: '0x150b7a02', @@ -42,7 +42,7 @@ export const MockSafeFallback: Module = { export const MockSafeHook: Module = { module: '0x688499e4b783375703d7e60c262b62bf40511523', - data: '0x', + initData: '0x', type: 'hook', hookType: 0, selector: '0x150b7a02',