Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9e5035b
feat: set HookMultiplexer address in EtherspotWalletAPI
kanthgithub May 29, 2025
f6454f1
feat: add hmpInitData while adding HookMultiplexer as defaultHook
kanthgithub May 29, 2025
005667c
feat: enhance adding multiple validators or modules while preparing B…
kanthgithub May 29, 2025
697aa5c
feat: example script to setup HMP and CAM on a fresh account
kanthgithub May 29, 2025
febc6e8
fixes for init code generation
nikhilkumar1612 Jun 3, 2025
223592f
fix: refactor getHookMultiplexerInitData to EtherspotWalletAPI
kanthgithub Jun 3, 2025
4310c8e
feat: bumped the package version
kanthgithub Jun 3, 2025
c4963cc
minor fixes for build issues
nikhilkumar1612 Jun 3, 2025
29c6100
changes to add resource lock validator to init code
nikhilkumar1612 Jun 4, 2025
bf042d2
feat: resourcelock-validator initiData generation for getInitCode fun…
kanthgithub Jun 9, 2025
389fe33
module install script changes
nikhilkumar1612 Jun 10, 2025
326c43b
feat: remove redundant initCode function
kanthgithub Jun 12, 2025
cc5ad45
fix: correct and set the HMP, RAL addresses for sepolia and basesepolia
kanthgithub Jun 18, 2025
126302b
update: CAM and RLV addresses for polygon, arb, op and base
nikhilkumar1612 Jun 18, 2025
3a615d6
updating CAM, RLV addresses for gnosis and bsc
nikhilkumar1612 Jun 25, 2025
037590a
fix for install modules
nikhilkumar1612 Jun 25, 2025
8ea84be
minor changes for sdk instance creation and move api key to env
nikhilkumar1612 Jun 26, 2025
70511d5
feat: resource-lock script to claim locked funds
kanthgithub Jun 27, 2025
5794cc9
feat: helper and executable script for claim-resource-lock
kanthgithub Jun 27, 2025
c75f28f
feat: helper functions to query intent and bid data via API calls to …
kanthgithub Jun 27, 2025
896c6bc
feat: validations on resource-lock release
kanthgithub Jun 27, 2025
bd367e1
feat: sepolia contract addresses updated
kanthgithub Aug 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## [7.0.0] - 2025-06-03
### Breaking Changes
- Updated HookMultiplexer, CredibleAccountModule and Bootstrap contract addresses for all chains
- getInitCode logic updated to include
- HookMultiplexer as defaultHook with CredibleAccountModule as globalHook in Multiplexer
- CredibleAccountModule to be installed as validator along with MultiSigECDSAModule
- Results in a change of precomputed modular account address.


## [6.1.0] - 2025-05-28
### Breaking Changes
- Changed contract address for Wallet Factory from `0x2A40091f044e48DEB5C0FCbc442E443F3341B451` to `0x38CC0EDdD3a944CA17981e0A19470d2298B8d43a`.
Expand Down
3 changes: 2 additions & 1 deletion examples/helpers/sdk-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export const generateModularSDKInstance = (privateKey: string, chainId: number,
{
chainId: chainId,
bundlerProvider: new EtherspotBundler(chainId, bundlerApiKey),
index: index
index: index,
accountAddress: process.env.MODULAR_ACCOUNT_ADDRESS
})

return modularSdk;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { printOp } from '../../../src/sdk/common/OperationUtils';
import * as dotenv from 'dotenv';
import { MODULE_TYPE, sleep } from '../../../src/sdk/common';
import { encodeAbiParameters, encodeFunctionData, Hex, parseAbi } from 'viem';
import { generateModularSDKInstance } from '../../helpers/sdk-helper';
import { getHookMultiPlexerInitData } from '../../pulse/utils';
import { accountAbi } from '../../../src/sdk/common/abis';
import { NetworkConfig, Networks } from '../../../src';
import { _makeBootstrapConfig } from '../../../src/sdk/base/Bootstrap';

dotenv.config();

const bundlerApiKey = process.env.API_KEY || "etherspot_public_key";

// tsx examples/modules/credible-account-modules/credible-account-ecosystem-install.ts
async function main() {

const chainId = Number(process.env.CHAIN_ID);

// Init SDK
const modularSdk = generateModularSDKInstance(
process.env.WALLET_PRIVATE_KEY as string,
chainId,
bundlerApiKey,
);

const networkConfig : NetworkConfig = Networks[chainId];

const HOOK_MULTIPLEXER_ADDRESS = networkConfig.contracts.hookMultiPlexer as Hex;
const RESOURCE_LOCK_VALIDATOR_ADDRESS = networkConfig.contracts.resourceLockValidator as Hex;
const CREDIBLE_ACCOUNT_MODULE_ADDRESS = networkConfig.contracts.credibleAccountModule as Hex;

// Get counterfactual of ModularEtherspotWallet...
const address: Hex = (await modularSdk.getCounterFactualAddress()) as Hex;
console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet address: ${address}`);
// Get native balance
const balance = await modularSdk.getNativeBalance();
console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet native balance: ${balance}`);
// Clear existing UserOps from batch
await modularSdk.clearUserOpsFromBatch();

/*//////////////////////////////////////////////////////////////
INSTALL HOOK MULTIPLEXER WITH CREDIBLE ACCOUNT MODULE - AS HOOK
//////////////////////////////////////////////////////////////*/

//Get HookMultiPlexer init data with CredibleAccountHook as global subhook
let hmpInitData = getHookMultiPlexerInitData([CREDIBLE_ACCOUNT_MODULE_ADDRESS]);
const config = _makeBootstrapConfig(HOOK_MULTIPLEXER_ADDRESS, hmpInitData);
console.log('\x1b[33m%s\x1b[0m', `Credible-Setup -> HmpInitData: ${hmpInitData}`);
const hmpInstallCalldata = encodeFunctionData({
abi: parseAbi(accountAbi),
functionName: 'installModule',
args: [BigInt(MODULE_TYPE.HOOK), HOOK_MULTIPLEXER_ADDRESS, config.data],
});
console.log('\x1b[33m%s\x1b[0m', `Credible-Setup -> HmpInstallCalldata: ${hmpInstallCalldata}`);
// Add UserOp to batch
await modularSdk.addUserOpsToBatch({ to: address, data: hmpInstallCalldata });

/*//////////////////////////////////////////////////////////////
INSTALL CREDIBLE ACCOUNT MODULE - AS VALIDATOR
//////////////////////////////////////////////////////////////*/

//Get CredibleAccountValidator init data
let cavInitData = encodeAbiParameters([{ type: 'uint256' }], [BigInt(MODULE_TYPE.VALIDATOR)]);
console.log('\x1b[33m%s\x1b[0m', `Credible-Setup -> CavInitData: ${cavInitData}`);
const cavInstallCalldata = encodeFunctionData({
abi: parseAbi(accountAbi),
functionName: 'installModule',
args: [BigInt(MODULE_TYPE.VALIDATOR), CREDIBLE_ACCOUNT_MODULE_ADDRESS, cavInitData],
});
console.log('\x1b[33m%s\x1b[0m', `Credible-Setup -> cavInstallCalldata: ${cavInstallCalldata}`);
//Add UserOp to batch
await modularSdk.addUserOpsToBatch({ to: address, data: cavInstallCalldata });

/*//////////////////////////////////////////////////////////////
INSTALL RESOURCE LOCK VALIDATOR
//////////////////////////////////////////////////////////////*/

// Get ResourceLockValidator init data
let rlvInitData = encodeAbiParameters([{ type: 'address' }], [modularSdk.getEOAAddress()]);
console.log('\x1b[33m%s\x1b[0m', `Credible-Setup -> RlvInitData: ${rlvInitData}`);
const rlvInstallCalldata = encodeFunctionData({
abi: parseAbi(accountAbi),
functionName: 'installModule',
args: [BigInt(MODULE_TYPE.VALIDATOR), RESOURCE_LOCK_VALIDATOR_ADDRESS, rlvInitData],
});
console.log('\x1b[33m%s\x1b[0m', `Credible-Setup -> RlvInstallCalldata: ${rlvInstallCalldata}`);
// Add UserOp to batch
await modularSdk.addUserOpsToBatch({ to: address, data: rlvInstallCalldata });

/*//////////////////////////////////////////////////////////////
ESTIMATE/SEND USER OP
//////////////////////////////////////////////////////////////*/

// Estimate UserOp
const op = await modularSdk.estimate();
console.log(`Estimate UserOp: ${await printOp(op)}`);
// Send UserOp
const uoHash = await modularSdk.send(op);
console.log(`UserOpHash: ${uoHash}`);
// Await transaction hash
console.log('Waiting for transaction...');
let userOpsReceipt = null;
const timeout = Date.now() + 1200000; // 1 minute timeout
while (userOpsReceipt == null && Date.now() < timeout) {
await sleep(2);
userOpsReceipt = await modularSdk.getUserOpReceipt(uoHash);
}
console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt);
}

main()
.catch(console.error)
.finally(() => process.exit());
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { EtherspotBundler, ModularSdk } from '../../../src';
import * as dotenv from 'dotenv';
import { getViemAccount } from '../../../src/sdk/common/utils';
import { generateModularSDKInstance } from '../../helpers/sdk-helper';

dotenv.config();

// tsx examples/modules/credible-account-modules/hook-multiplexer-has-hook.ts
async function main() {
const bundlerApiKey = 'etherspot_public_key';

// initializating sdk...
const modularSdk = generateModularSDKInstance(
process.env.WALLET_PRIVATE_KEY as string,
Number(process.env.CHAIN_ID), bundlerApiKey);

// get address of EtherspotWallet
const address: string = await modularSdk.getCounterFactualAddress();

console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet address: ${address}`);

const moduleInfo = await modularSdk.getAllModules();
console.log(`moduleInfo: ${JSON.stringify(moduleInfo)}`);
}

main()
.catch(console.error)
.finally(() => process.exit());
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as dotenv from 'dotenv';
import { MODULE_TYPE, sleep } from '../../../src/sdk/common';
import { generateModularSDKInstance } from '../../helpers/sdk-helper';
import { encodeAbiParameters } from 'viem';
import { NetworkConfig, Networks } from '../../../src';

dotenv.config();

// tsx examples/modules/credible-account-modules/install-credible-account-module.ts
async function main() {
const bundlerApiKey = 'etherspot_public_key';
const chainId = Number(process.env.CHAIN_ID);

// initializating sdk...
const modularSdk = generateModularSDKInstance(
process.env.WALLET_PRIVATE_KEY as string,
chainId, bundlerApiKey);

// get address of EtherspotWallet
const address: string = await modularSdk.getCounterFactualAddress();

console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet address: ${address}`);

let cavInitData = encodeAbiParameters([{ type: 'uint256' }], [BigInt(MODULE_TYPE.VALIDATOR)]);
console.log('\x1b[33m%s\x1b[0m', `CavInitData: ${cavInitData}`);

const networkConfig : NetworkConfig = Networks[chainId];
const uoHash = await modularSdk.installModule(MODULE_TYPE.VALIDATOR, networkConfig.contracts.credibleAccountModule, cavInitData);
console.log(`UserOpHash: ${uoHash}`);

// get transaction hash...
console.log('Waiting for transaction...');
let userOpsReceipt = null;
const timeout = Date.now() + 60000; // 1 minute timeout
while ((userOpsReceipt == null) && (Date.now() < timeout)) {
await sleep(2);
userOpsReceipt = await modularSdk.getUserOpReceipt(uoHash);
}
console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt);
}

main()
.catch(console.error)
.finally(() => process.exit());
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as dotenv from 'dotenv';
import { MODULE_TYPE, sleep } from '../../../src/sdk/common';
import { generateModularSDKInstance } from '../../helpers/sdk-helper';
import { encodeAbiParameters, Hex } from 'viem';
import { NetworkConfig, Networks } from '../../../src';
import { getHookMultiPlexerInitData } from '../../pulse/utils';

dotenv.config();

// tsx examples/modules/credible-account-modules/install-hook-multiplexer.ts
async function main() {
const bundlerApiKey = 'etherspot_public_key';
const chainId = Number(process.env.CHAIN_ID);

// initializating sdk...
const modularSdk = generateModularSDKInstance(
process.env.WALLET_PRIVATE_KEY as string,
chainId, bundlerApiKey);

// get address of EtherspotWallet
const address: string = await modularSdk.getCounterFactualAddress();

console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet address: ${address}`);

const networkConfig : NetworkConfig = Networks[chainId];

let hmpInitData = getHookMultiPlexerInitData([networkConfig.contracts.credibleAccountModule as Hex]);
const uoHash = await modularSdk.installModule(MODULE_TYPE.HOOK, networkConfig.contracts.credibleAccountModule, hmpInitData);
console.log(`UserOpHash: ${uoHash}`);

// get transaction hash...
console.log('Waiting for transaction...');
let userOpsReceipt = null;
const timeout = Date.now() + 60000; // 1 minute timeout
while ((userOpsReceipt == null) && (Date.now() < timeout)) {
await sleep(2);
userOpsReceipt = await modularSdk.getUserOpReceipt(uoHash);
}
console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt);
}

main()
.catch(console.error)
.finally(() => process.exit());
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as dotenv from 'dotenv';
import { MODULE_TYPE, sleep } from '../../../src/sdk/common';
import { generateModularSDKInstance } from '../../helpers/sdk-helper';
import { encodeAbiParameters } from 'viem';
import { NetworkConfig, Networks } from '../../../src';

dotenv.config();

// tsx examples/modules/credible-account-modules/install-resource-lock-validator.ts
async function main() {
const bundlerApiKey = 'etherspot_public_key';
const chainId = Number(process.env.CHAIN_ID);

// initializating sdk...
const modularSdk = generateModularSDKInstance(
process.env.WALLET_PRIVATE_KEY as string,
chainId, bundlerApiKey);

// get address of EtherspotWallet
const address: string = await modularSdk.getCounterFactualAddress();

console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet address: ${address}`);

let rlvInitData = encodeAbiParameters([{ type: 'address' }], [modularSdk.getEOAAddress()]);

const networkConfig : NetworkConfig = Networks[chainId];
const uoHash = await modularSdk.installModule(MODULE_TYPE.VALIDATOR, networkConfig.contracts.resourceLockValidator, rlvInitData);
console.log(`UserOpHash: ${uoHash}`);

// get transaction hash...
console.log('Waiting for transaction...');
let userOpsReceipt = null;
const timeout = Date.now() + 60000; // 1 minute timeout
while ((userOpsReceipt == null) && (Date.now() < timeout)) {
await sleep(2);
userOpsReceipt = await modularSdk.getUserOpReceipt(uoHash);
}
console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt);
}

main()
.catch(console.error)
.finally(() => process.exit());
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import * as dotenv from 'dotenv';
import { MODULE_TYPE, sleep } from '../../../src/sdk/common';
import { generateModularSDKInstance } from '../../helpers/sdk-helper';
import { encodeAbiParameters, Hex } from 'viem';
import { NetworkConfig, Networks } from '../../../src';

dotenv.config();

// tsx examples/modules/credible-account-modules/uninstall-credible-account-module.ts
async function main() {
const bundlerApiKey = 'etherspot_public_key';

const chainId = Number(process.env.CHAIN_ID);

// initializating sdk...
const modularSdk = generateModularSDKInstance(
process.env.WALLET_PRIVATE_KEY as string,
chainId, bundlerApiKey);

// get address of EtherspotWallet
const etherspotWalletAddress: string = await modularSdk.getCounterFactualAddress();

console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet address: ${etherspotWalletAddress}`);

const networkConfig : NetworkConfig = Networks[chainId];

//this should be previous node address of the module to be uninstalled and the deinit data
//deinit data is the data that is passed to the module to be uninstalled
// here we need to call the function which can find out the address of previous node of the module to be uninstalled
// and the deinit data can be 0x00 as default value
const deInitDataDefault = encodeAbiParameters([{ type: 'uint256' }, { type: 'address' }],
[BigInt(MODULE_TYPE.VALIDATOR), etherspotWalletAddress as Hex]);

//generate deinit data...
const deInitData = await modularSdk.generateModuleDeInitData(
MODULE_TYPE.VALIDATOR,
networkConfig.contracts.credibleAccountModule,
deInitDataDefault);

console.log(`deinitData: ${deInitData}`);

const uoHash = await modularSdk.uninstallModule(MODULE_TYPE.VALIDATOR,
networkConfig.contracts.credibleAccountModule, deInitData);
console.log(`UserOpHash: ${uoHash}`);

// get transaction hash...
console.log('Waiting for transaction...');
let userOpsReceipt = null;
const timeout = Date.now() + 60000; // 1 minute timeout
while ((userOpsReceipt == null) && (Date.now() < timeout)) {
await sleep(2);
userOpsReceipt = await modularSdk.getUserOpReceipt(uoHash);
}
console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt);
}

main()
.catch(console.error)
.finally(() => process.exit());
Loading