Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions src/abstractionkit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export {
} from "./account/Safe/modules/AllowanceModule";
export { SafeAccountV0_2_0 } from "./account/Safe/SafeAccountV0_2_0";
export { SafeAccountV0_3_0 } from "./account/Safe/SafeAccountV0_3_0";
export { SafeAccountV1_5_0_M_0_3_0 } from "./account/Safe/SafeAccountV1_5_0_M_0_3_0";

export { SendUseroperationResponse } from "./account/SendUseroperationResponse";

Expand Down
16 changes: 8 additions & 8 deletions src/account/Safe/SafeAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import {
BaseInitOverrides,
WebauthnDummySignerSignaturePair,
WebauthnPublicKey,
SafeAccountSingleton,
} from "./types";
import { decodeMultiSendCallData, encodeMultiSendCallData } from "./multisend";
import { AbstractionKitError, ensureError } from "src/errors";
Expand All @@ -67,8 +68,6 @@ import { SafeAccountFactory } from "src/factory/SafeAccountFactory";
import { getSafeMessageEip712Data, SafeMessageTypedDataDomain, SafeMessageTypedMessageValue } from "./safeMessage";

export class SafeAccount extends SmartAccount {
static readonly DEFAULT_SAFE_SINGLETON = Safe_L2_V1_4_1;

static readonly DEFAULT_WEB_AUTHN_SHARED_SIGNER: string =
"0xfD90FAd33ee8b58f32c00aceEad1358e4AFC23f9";
static readonly DEFAULT_WEB_AUTHN_SIGNER_SINGLETON: string =
Expand Down Expand Up @@ -110,6 +109,7 @@ export class SafeAccount extends SmartAccount {
protected x: bigint | null = null;
protected y: bigint | null = null;

readonly safeAccountSingleton:SafeAccountSingleton;
readonly entrypointAddress: string;
readonly safe4337ModuleAddress: string;
protected factoryAddress: string | null;
Expand All @@ -124,6 +124,7 @@ export class SafeAccount extends SmartAccount {
overrides: {
onChainIdentifierParams?: OnChainIdentifierParamsType;
onChainIdentifier?: string;
safeAccountSingleton?: SafeAccountSingleton;
} = {}
) {
super(accountAddress);
Expand Down Expand Up @@ -160,6 +161,7 @@ export class SafeAccount extends SmartAccount {
}else{
this.onChainIdentifier = null;
}
this.safeAccountSingleton = overrides.safeAccountSingleton?? Safe_L2_V1_4_1;
}

/**
Expand All @@ -172,7 +174,7 @@ export class SafeAccount extends SmartAccount {
* SafeAccountFactory.DEFAULT_FACTORY_ADDRESS
* @param overrides.singletonInitHash - a hash that includes the singleton address and thr proxy bytecode
* keccak256(solidityPacked(["bytes", "bytes"], [proxyByteCode, abiCoder.encode(["uint256"], [singletonAddress])]))
* defaults to SafeAccount.DEFAULT_SAFE_SINGLETON.singletonInitHash
* defaults to SafeAccount.safeAccountSingleton.singletonInitHash
* @returns proxy/account address
*/
public static createProxyAddress(
Expand All @@ -191,8 +193,7 @@ export class SafeAccount extends SmartAccount {
overrides.safeFactoryAddress ??
SafeAccountFactory.DEFAULT_FACTORY_ADDRESS;
const singletonInitHash =
overrides.singletonInitHash ??
SafeAccount.DEFAULT_SAFE_SINGLETON.singletonInitHash;
overrides.singletonInitHash ?? Safe_L2_V1_4_1.singletonInitHash;
const salt = keccak256(
solidityPacked(
["bytes32", "uint256"],
Expand Down Expand Up @@ -914,9 +915,8 @@ export class SafeAccount extends SmartAccount {
} else {
safeAccountFactory = new SafeAccountFactory();
}

const safeSingleton =
overrides.safeAccountSingleton ?? SafeAccount.DEFAULT_SAFE_SINGLETON;
overrides.safeAccountSingleton ?? Safe_L2_V1_4_1;
const sender = this.createProxyAddress(initializerCallData, {
c2Nonce: overrides.c2Nonce ?? 0n,
safeFactoryAddress: safeAccountFactory.address,
Expand Down Expand Up @@ -1118,7 +1118,7 @@ export class SafeAccount extends SmartAccount {
}

const safeSingleton =
overrides.safeAccountSingleton ?? SafeAccount.DEFAULT_SAFE_SINGLETON;
overrides.safeAccountSingleton ?? Safe_L2_V1_4_1;

const generatorFunctionInputParameters = [
safeSingleton.singletonAddress,
Expand Down
12 changes: 9 additions & 3 deletions src/account/Safe/SafeAccountV0_3_0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import {
CreateUserOperationV7Overrides,
SafeUserOperationTypedDataDomain,
SafeUserOperationV7TypedMessageValue,
SafeAccountSingleton,
} from "./types";

import { UserOperationV7, MetaTransaction, OnChainIdentifierParamsType } from "../../types";
import { ENTRYPOINT_V7 } from "src/constants";
import { ENTRYPOINT_V7, Safe_L2_V1_4_1 } from "src/constants";

export class SafeAccountV0_3_0 extends SafeAccount {
static readonly DEFAULT_ENTRYPOINT_ADDRESS = ENTRYPOINT_V7;
Expand All @@ -24,6 +25,7 @@ export class SafeAccountV0_3_0 extends SafeAccount {
entrypointAddress?: string;
onChainIdentifierParams?: OnChainIdentifierParamsType;
onChainIdentifier?: string
safeAccountSingleton?: SafeAccountSingleton;
} = {},
) {
const safe4337ModuleAddress =
Expand All @@ -37,7 +39,8 @@ export class SafeAccountV0_3_0 extends SafeAccount {
accountAddress, safe4337ModuleAddress, entrypointAddress,
{
onChainIdentifierParams: overrides.onChainIdentifierParams,
onChainIdentifier: overrides.onChainIdentifier
onChainIdentifier: overrides.onChainIdentifier,
safeAccountSingleton: overrides.safeAccountSingleton
}
);
}
Expand Down Expand Up @@ -100,7 +103,7 @@ export class SafeAccountV0_3_0 extends SafeAccount {
}
}
const [accountAddress, factoryAddress, factoryData] =
SafeAccountV0_3_0.createAccountAddressAndFactoryAddressAndData(
SafeAccount.createAccountAddressAndFactoryAddressAndData(
owners,
overrides,
overrides.safe4337ModuleAddress ??
Expand Down Expand Up @@ -298,3 +301,6 @@ export class SafeAccountV0_3_0 extends SafeAccount {
return userOperationV7;
}
}

export class SafeAccountV1_4_1_M_0_3_0 extends SafeAccountV0_3_0 {
}
105 changes: 105 additions & 0 deletions src/account/Safe/SafeAccountV1_5_0_M_0_3_0.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { OnChainIdentifierParamsType } from "src/types";
import { SafeAccountV0_3_0 } from "./SafeAccountV0_3_0";
import { Signer, InitCodeOverrides } from "./types";
import { Safe_L2_V1_5_0 } from "src/constants";
import { AbiCoder, keccak256, solidityPacked } from "ethers";
import { SafeAccount } from "./SafeAccount";

export class SafeAccountV1_5_0_M_0_3_0 extends SafeAccountV0_3_0 {
constructor(
accountAddress: string,
overrides: {
safe4337ModuleAddress?: string;
entrypointAddress?: string;
onChainIdentifierParams?: OnChainIdentifierParamsType;
onChainIdentifier?: string
} = {},
) {
super(
accountAddress,
{
onChainIdentifierParams: overrides.onChainIdentifierParams,
onChainIdentifier: overrides.onChainIdentifier,
safeAccountSingleton: Safe_L2_V1_5_0
}
);
}

public static createProxyAddress(
initializerCallData: string,
overrides: {
c2Nonce?: bigint;
safeFactoryAddress?: string;
singletonInitHash?: string;
} = {},
): string {
const modOverrides = overrides;
modOverrides.singletonInitHash =
overrides.singletonInitHash??Safe_L2_V1_5_0.singletonInitHash;
return SafeAccountV0_3_0.createProxyAddress(
initializerCallData,
modOverrides
);
}

/**
* To create and initialize a SafeAccount object from its
* initial owners
* @remarks
* initializeNewAccount only needed when the smart account
* have not been deployed yet and the account address is unknown.
* @param owners - list of account owners signers
* @param overrides - override values to change the initialization default values
* @returns a SafeAccount object
*/
public static initializeNewAccount(
owners: Signer[],
overrides: InitCodeOverrides = {},
): SafeAccountV1_5_0_M_0_3_0 {
const modOverrides = overrides;
modOverrides.safeAccountSingleton =
overrides.safeAccountSingleton??Safe_L2_V1_5_0;
return SafeAccountV0_3_0.initializeNewAccount(
owners,
overrides
);
}

/**
* calculate account addressfrom initial owners signers
* @param owners - list of account owners addresses
* @param overrides - override values to change the initialization default values
* @returns account address
*/
public static createAccountAddress(
owners: Signer[],
overrides: InitCodeOverrides = {},
): string {
const modOverrides = overrides;
modOverrides.safeAccountSingleton =
overrides.safeAccountSingleton??Safe_L2_V1_5_0;
return SafeAccountV0_3_0.createAccountAddress(
owners,
modOverrides
);
}

/**
* create account factory address and factory data
* @param owners - list of account owners signers
* @param overrides - override values to change the initialization default values
* @returns factoryAddress and factoryData
*/
public static createFactoryAddressAndData(
owners: Signer[],
overrides: InitCodeOverrides = {},
): [string, string] {
const modOverrides = overrides;
modOverrides.safeAccountSingleton =
overrides.safeAccountSingleton??Safe_L2_V1_5_0;
return SafeAccountV0_3_0.createFactoryAddressAndData(
owners,
overrides
);
}
}
6 changes: 6 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ export const ENTRYPOINT_V8 = "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108";
export const ENTRYPOINT_V7 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
export const ENTRYPOINT_V6 = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789";

export const Safe_L2_V1_5_0: SafeAccountSingleton = {
singletonAddress: "0xEdd160fEBBD92E350D4D398fb636302fccd67C7e",
singletonInitHash:
"0x1b94aebb5a7df6dff11d93589204a6bbc99b4b8c9014bf1d386d006c2c17a881",
};

export const Safe_L2_V1_4_1: SafeAccountSingleton = {
singletonAddress: "0x29fcB43b46531BcA003ddC8FCB67FFE91900C762",
singletonInitHash:
Expand Down