Skip to content

Commit 05dd049

Browse files
SDK upgrade to 6.1.0 version with the EtherspotWalletFactory contracts (on all chains) with latest IHook (#65)
* Updated contracts and changelog - Updated factory, bootstrap and MOECDSA validator contract addresses. - Updated CHANGLOG.md with changes. - Bumped version from 5.1.2 to 6.0.0. * feat: credible-account module installation test script * feat: credible account module installation script - updated with module addresses * feat: remove obselete reference scripts * feat: add isModuleInitialised function and update the example scripts * feat: constant file with address enhancements and changeLog * feat: upgrade package version from 6.0.1 to 7.0.0 * feat: scripts and AccountAPI updates * fix: example scripts to contain public-api-key * feat: update change-log and package versioning to 6.1.0 --------- Co-authored-by: cryptonoyaiba <[email protected]>
1 parent a18a627 commit 05dd049

File tree

12 files changed

+322
-164
lines changed

12 files changed

+322
-164
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## [6.1.0] - 2025-05-28
4+
### Breaking Changes
5+
- Changed contract address for Wallet Factory from `0x2A40091f044e48DEB5C0FCbc442E443F3341B451` to `0x38CC0EDdD3a944CA17981e0A19470d2298B8d43a`.
6+
- Changed contract address for Bootstrap from `0x0D5154d7751b6e2fDaa06F0cC9B400549394C8AA` to `0xCF2808eA7d131d96E5C73Eb0eCD8Dc84D33905C7`.
7+
- Changed contract address for Multiple Owner ECDSA Validator from `0x0740Ed7c11b9da33d9C80Bd76b826e4E90CC1906` to `0x0eA25BF9F313344d422B513e1af679484338518E`.
8+
- Added support for HookMultiPlexer at address `0xDcA918dd23456d321282DF9507F6C09A50522136`.
9+
- Results in a change of precomputed modular account address.
10+
311
## [6.0.1] - 2025-05-28
412
### Fix
513
- revert 6.0.0 to the older version of the sdk

examples/basics/custom-chain.ts

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,42 +12,39 @@ const bundlerApiKey = 'etherspot_public_key';
1212
const bundlerUrl = 'https://testnet-rpc.etherspot.io/v2/84532'; // bundler url
1313
const chainId = 84532; // chain id
1414
const entryPointAddress = '0x0000000071727De22E5E9d8BAf0edAc6f37da032'; // entry point address
15-
const walletFactoryAddress = '0x2A40091f044e48DEB5C0FCbc442E443F3341B451'; // wallet factory address
16-
const bootstrapAddress = '0x0D5154d7751b6e2fDaa06F0cC9B400549394C8AA'; // bootstrap address
17-
const multipleOwnerECDSAValidatorAddress = '0x0740Ed7c11b9da33d9C80Bd76b826e4E90CC1906'; // multi owner ECDSA validator factory address
15+
const walletFactoryAddress = '0x38CC0EDdD3a944CA17981e0A19470d2298B8d43a'; // wallet factory address
16+
const bootstrapAddress = '0xCF2808eA7d131d96E5C73Eb0eCD8Dc84D33905C7'; // bootstrap address
17+
const multipleOwnerECDSAValidatorAddress = '0x0eA25BF9F313344d422B513e1af679484338518E'; // multi owner ECDSA validator factory address
1818

1919
// tsx examples/basics/custom-chain.ts
2020
async function main() {
2121
// for custom chains, you can use the following code to create a chain object
2222
const chain = defineChain({
2323
id: chainId,
24-
name: "Base sepolia Testnet",
24+
name: 'Base sepolia Testnet',
2525
nativeCurrency: {
2626
decimals: 18,
2727
name: 'ETH',
28-
symbol: 'ETH'
28+
symbol: 'ETH',
2929
},
3030
rpcUrls: {
3131
default: {
32-
http: ['https://sepolia.base.org'] // RPC URL
33-
}
34-
}
35-
})
32+
http: ['https://sepolia.base.org'], // RPC URL
33+
},
34+
},
35+
});
3636
// initializating sdk...
37-
const modularSdk = new ModularSdk(
38-
process.env.WALLET_PRIVATE_KEY as string,
39-
{
40-
chain: chain,
41-
chainId: chainId,
42-
bundlerProvider: new EtherspotBundler(chainId, bundlerApiKey, bundlerUrl),
43-
index: 0,
44-
entryPointAddress,
45-
walletFactoryAddress,
46-
bootstrapAddress,
47-
multipleOwnerECDSAValidatorAddress,
48-
rpcProviderUrl: bundlerUrl,
49-
})
50-
37+
const modularSdk = new ModularSdk(process.env.WALLET_PRIVATE_KEY as string, {
38+
chain: chain,
39+
chainId: chainId,
40+
bundlerProvider: new EtherspotBundler(chainId, bundlerApiKey, bundlerUrl),
41+
index: 0,
42+
entryPointAddress,
43+
walletFactoryAddress,
44+
bootstrapAddress,
45+
multipleOwnerECDSAValidatorAddress,
46+
rpcProviderUrl: bundlerUrl,
47+
});
5148

5249
// get address of EtherspotWallet...
5350
const address: string = await modularSdk.getCounterFactualAddress();
@@ -77,7 +74,7 @@ async function main() {
7774
console.log('Waiting for transaction...');
7875
let userOpsReceipt: string | null = null;
7976
const timeout = Date.now() + 1200000; // 1 minute timeout
80-
while ((userOpsReceipt == null) && (Date.now() < timeout)) {
77+
while (userOpsReceipt == null && Date.now() < timeout) {
8178
await sleep(2);
8279
userOpsReceipt = await modularSdk.getUserOpReceipt(uoHash);
8380
}
@@ -86,4 +83,4 @@ async function main() {
8683

8784
main()
8885
.catch(console.error)
89-
.finally(() => process.exit());
86+
.finally(() => process.exit());

examples/basics/get-address.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ dotenv.config();
66
// tsx examples/basics/get-address.ts
77
async function main() {
88
const bundlerApiKey = 'etherspot_public_key';
9-
const customBundlerUrl = '';
109

1110
// initializating sdk...
1211
const modularSdk = generateModularSDKInstance(

examples/basics/transfer-erc20.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ dotenv.config();
1313
// add/change these values
1414
const recipient = '0x80a1874E1046B1cc5deFdf4D3153838B72fF94Ac'; // recipient wallet address
1515
const value = '0.1'; // transfer value
16-
const tokenAddress = process.env.TOKEN_ADDRESS as string; // token address
16+
const tokenAddress = '0xDeDf3B40f8c44b1fF195F37F35c6b8199C7ee443'; // token address
1717
const bundlerApiKey = 'etherspot_public_key';
1818

1919
// tsx examples/basics/transfer-erc20.ts

examples/modules/install-hook.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { printOp } from '../../src/sdk/common/OperationUtils';
2+
import * as dotenv from 'dotenv';
3+
import { MODULE_TYPE, sleep } from '../../src/sdk/common';
4+
import { encodeAbiParameters, encodeFunctionData, Hex, parseAbi } from 'viem';
5+
import { generateModularSDKInstance } from '../helpers/sdk-helper';
6+
import { getHookMultiPlexerInitData } from '../pulse/utils';
7+
import { accountAbi } from '../../src/sdk/common/abis';
8+
9+
dotenv.config();
10+
11+
const bundlerApiKey = 'etherspot_public_key';
12+
const CHAIN_ID = '1';
13+
const HOOK_MULTIPLEXER_ADDRESS = '0xDcA918dd23456d321282DF9507F6C09A50522136';
14+
15+
// tsx examples/modules/install-hook.ts
16+
async function main() {
17+
// Init SDK
18+
const modularSdk = generateModularSDKInstance(
19+
process.env.WALLET_PRIVATE_KEY as string,
20+
Number(CHAIN_ID),
21+
bundlerApiKey,
22+
);
23+
24+
// Get counterfactual of ModularEtherspotWallet...
25+
const address: Hex = (await modularSdk.getCounterFactualAddress()) as Hex;
26+
console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet address: ${address}`);
27+
// Get native balance
28+
const balance = await modularSdk.getNativeBalance();
29+
console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet native balance: ${balance}`);
30+
// Clear existing UserOps from batch
31+
await modularSdk.clearUserOpsFromBatch();
32+
33+
/*//////////////////////////////////////////////////////////////
34+
INSTALL HOOK MULTIPLEXER WITH CREDIBLE ACCOUNT MODULE - AS HOOK
35+
//////////////////////////////////////////////////////////////*/
36+
37+
//Get HookMultiPlexer init data with CredibleAccountHook as global subhook
38+
let hmpInitData = getHookMultiPlexerInitData([]);
39+
const hmpInstallCalldata = encodeFunctionData({
40+
abi: parseAbi(accountAbi),
41+
functionName: 'installModule',
42+
args: [BigInt(MODULE_TYPE.HOOK), HOOK_MULTIPLEXER_ADDRESS, hmpInitData],
43+
});
44+
// // Add UserOp to batch
45+
await modularSdk.addUserOpsToBatch({ to: address, data: hmpInstallCalldata });
46+
47+
/*//////////////////////////////////////////////////////////////
48+
ESTIMATE/SEND USER OP
49+
//////////////////////////////////////////////////////////////*/
50+
51+
// Estimate UserOp
52+
const op = await modularSdk.estimate();
53+
console.log(`Estimate UserOp: ${await printOp(op)}`);
54+
// Send UserOp
55+
const uoHash = await modularSdk.send(op);
56+
console.log(`UserOpHash: ${uoHash}`);
57+
// Await transaction hash
58+
console.log('Waiting for transaction...');
59+
let userOpsReceipt = null;
60+
const timeout = Date.now() + 1200000; // 1 minute timeout
61+
while (userOpsReceipt == null && Date.now() < timeout) {
62+
await sleep(2);
63+
userOpsReceipt = await modularSdk.getUserOpReceipt(uoHash);
64+
}
65+
console.log('\x1b[33m%s\x1b[0m', `Transaction Receipt: `, userOpsReceipt);
66+
}
67+
68+
main()
69+
.catch(console.error)
70+
.finally(() => process.exit());
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import * as dotenv from 'dotenv';
2+
import { MODULE_TYPE } from '../../src/sdk/common';
3+
import { generateModularSDKInstance } from '../helpers/sdk-helper';
4+
5+
dotenv.config();
6+
7+
// tsx examples/modules/is-module-installed.ts
8+
async function main() {
9+
const bundlerApiKey = 'etherspot_public_key';
10+
11+
console.log(`inside is-module-installed script:`);
12+
13+
// initializating sdk for index 0...
14+
const modularSdk = generateModularSDKInstance(
15+
process.env.WALLET_PRIVATE_KEY,
16+
Number(process.env.CHAIN_ID),
17+
bundlerApiKey
18+
);// Testnets dont need apiKey on bundlerProvider
19+
20+
// get address of EtherspotWallet
21+
const address: string = await modularSdk.getCounterFactualAddress();
22+
23+
console.log('\x1b[33m%s\x1b[0m', `EtherspotWallet address: ${address}`);
24+
25+
const isModuleInstalled = await modularSdk.isModuleInstalled(MODULE_TYPE.VALIDATOR, '0xFE14F6d4e407850b24D160B9ACfBb042D32BE492');
26+
console.log(`isModuleInstalled: ${isModuleInstalled}`);
27+
}
28+
29+
main()
30+
.catch(console.error)
31+
.finally(() => process.exit());

examples/modules/uninstall-module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ async function main() {
2727
//generate deinit data...
2828
const deInitData = await modularSdk.generateModuleDeInitData(
2929
MODULE_TYPE.VALIDATOR,
30-
'0xF4CDE8B11500ca9Ea108c5838DD26Ff1a4257a0c',
30+
'0x9509aae8990bfA12BE09130BB822C37F3086863E',
3131
deInitDataDefault);
3232

3333
console.log(`deinitData: ${deInitData}`);
@@ -36,7 +36,7 @@ async function main() {
3636
// 0x22A55192a663591586241D42E603221eac49ed09
3737
// 0xF4CDE8B11500ca9Ea108c5838DD26Ff1a4257a0c
3838
const uoHash = await modularSdk.uninstallModule(MODULE_TYPE.VALIDATOR,
39-
'0xF4CDE8B11500ca9Ea108c5838DD26Ff1a4257a0c', deInitData);
39+
'0x9509aae8990bfA12BE09130BB822C37F3086863E', deInitData);
4040
console.log(`UserOpHash: ${uoHash}`);
4141

4242
// get transaction hash...

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@etherspot/modular-sdk",
3-
"version": "6.0.1",
3+
"version": "6.1.0",
44
"description": "Etherspot Modular SDK - build with ERC-7579 smart accounts modules",
55
"keywords": [
66
"ether",

src/sdk/base/BaseAccountAPI.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { TransactionDetailsForUserOp } from './TransactionDetailsForUserOp.js';
22
import { PaymasterAPI } from './PaymasterAPI.js';
3-
import { ErrorSubject, Exception, getUserOpHash, NotPromise, packUserOp, UserOperation } from '../common/index.js';
3+
import { AddressZero, ErrorSubject, Exception, getUserOpHash, NotPromise, packUserOp, UserOperation } from '../common/index.js';
44
import { calcPreVerificationGas, GasOverheads } from './calcPreVerificationGas.js';
55
import { Factory, Network, NetworkNames, NetworkService, SdkOptions, SignMessageDto, validateDto } from '../index.js';
66
import { Context } from '../context.js';
@@ -56,6 +56,7 @@ export abstract class BaseAccountAPI {
5656
factoryUsed: Factory;
5757
factoryAddress?: string;
5858
validatorAddress?: string;
59+
hookMultiplexerAddress?: string;
5960
wallet: WalletProviderLike;
6061
publicClient: PublicClient;
6162

@@ -96,6 +97,7 @@ export abstract class BaseAccountAPI {
9697
this.factoryAddress = params.factoryAddress;
9798
this.publicClient = params.publicClient;
9899
this.validatorAddress = params.optionsLike?.multipleOwnerECDSAValidatorAddress ?? Networks[params.optionsLike.chainId]?.contracts?.multipleOwnerECDSAValidator ?? DEFAULT_MULTIPLE_OWNER_ECDSA_VALIDATOR_ADDRESS;
100+
this.hookMultiplexerAddress = Networks[params.optionsLike.chainId]?.contracts?.hookMultiPlexer || AddressZero;
99101
}
100102

101103
get error$(): ErrorSubject {

src/sdk/base/EtherspotWalletAPI.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,18 @@ export class EtherspotWalletAPI extends BaseAccountAPI {
7676
return response as boolean;
7777
}
7878

79+
async isModuleInitialised(moduleTypeId: MODULE_TYPE, module: string, initData = '0x'): Promise<boolean> {
80+
const accountAddress = await this.getAccountAddress();
81+
if (!accountAddress) throw new Error('Account address not found');
82+
const response = await this.publicClient.readContract({
83+
address: accountAddress as Hex,
84+
abi: parseAbi(accountAbi),
85+
functionName: 'isModuleInstalled',
86+
args: [moduleTypeId, module, initData]
87+
});
88+
return response as boolean;
89+
}
90+
7991
async installModule(moduleTypeId: MODULE_TYPE, module: string, initData = '0x'): Promise<string> {
8092
const accountAddress = await this.getAccountAddress();
8193
if (!accountAddress) throw new Error('Account address not found');

0 commit comments

Comments
 (0)