Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
5153cd6
chore: adds wip of webauthn client tests
linnall Apr 24, 2025
c25704c
chore: updates webauthn test to use mocked window.credentials.get res…
linnall Apr 29, 2025
6cfbae2
chore: adds credential and mock response from self generated credenti…
linnall Apr 29, 2025
2e39c73
fix: rename webAuthnCredentials to webAuthnAccountParams
linnall Apr 30, 2025
72b971a
chore: adds to do
linnall Apr 30, 2025
4beb371
feat: add ability to create a webauthn ModularAccountV2 without a signer
linnall May 6, 2025
1124c0e
chore: removes unused code
linnall May 6, 2025
7925ded
fix: ensures presence of signer is explicit
linnall May 7, 2025
60f0f5e
fix: refactor to not destructure
linnall May 7, 2025
eec1736
feat: adds account functions for webauthn
linnall May 8, 2025
9e0696b
feat: add webauthn gas estimator
howydev Apr 29, 2025
2b028e7
chore: fix lint, change to use type narrowing instead
howydev May 1, 2025
b3c1c3c
feat: add webauthn signer
howydev Apr 28, 2025
803ca66
chore: update dummy sig
howydev Apr 29, 2025
9fdcbe2
feat: modifies mav2 smart account client and mav2 client tests to wor…
linnall May 11, 2025
b8d0d55
fix: add documenting comment for webauthn gas estimator usage
linnall May 12, 2025
225c1be
fix: adds documentation comment for webauthnGasEstimator usage
linnall May 12, 2025
b52d014
chore: wip deploy webauthn account then sign message
linnall May 13, 2025
409707b
fix: prepend signatures with 0xff
linnall May 15, 2025
af790a9
fix: prepend signature regardless of deferred actions data presence
linnall May 15, 2025
d86e283
chore: wip debugging
linnall May 19, 2025
03a5fb4
fix: debug
howydev May 19, 2025
fc502fa
chore: adds updated mock authenticator response
linnall May 19, 2025
60856a1
fix: prefixes signature with offset
linnall May 20, 2025
97991a9
chore: update credentials and mocked authenticator response
linnall May 20, 2025
378c121
chore: updates credentials and authenticator response
linnall May 22, 2025
5b9879f
chore: fix merge issues with main
linnall May 27, 2025
ab8f4e3
test: update tests using mock webauthn device (#1639)
moldy530 May 27, 2025
1de9126
chore: wip format message to be EIP-712 and add lint fixes
linnall May 28, 2025
c786483
fix: inline documentation
linnall May 28, 2025
5ccba79
chore: removes debugging statements and linting fixes
linnall May 28, 2025
5d4c0d5
chore: rename types
linnall May 28, 2025
69204ef
fix: refactor
linnall May 28, 2025
809dcf7
chore: remove debug statement
linnall May 28, 2025
0e434ba
fix: update return type
linnall May 28, 2025
01fdde3
fix: adds strongly typed errors
linnall May 28, 2025
64d47ef
chore: removes debug statements
linnall May 28, 2025
7d8c780
fix: fixes example in docs
linnall May 28, 2025
0a42ce8
chore: add todo comment, removes debug statement
linnall May 29, 2025
2bdb611
chore: remove lint warnings
linnall May 29, 2025
c375b00
refactor: encode sign parameters as a struct
linnall May 30, 2025
c9b9e82
feat: enables installValidation to take a Modular Account with no sig…
linnall Jun 6, 2025
e490ee8
chore: lint
linnall Jun 6, 2025
4ba28ff
Merge branch 'main' into linna/webauth-tests
linnall Jun 6, 2025
8592aa6
feat: export WebAuthnValidationModule
linnall Jun 9, 2025
db6c8ce
Merge branch 'main' into linna/webauth-tests
linnall Jun 9, 2025
10bf11f
fix: typing for install validation decorator
moldy530 Jun 9, 2025
40b9932
fix: typing on creation of clients to support alchemy configs
moldy530 Jun 9, 2025
976778d
fix: updates tests to retry transaction, updates hook with new Instal…
linnall Jun 9, 2025
12083d4
chore: removes unused import
linnall Jun 9, 2025
92bc665
fix: uses session key provider
linnall Jun 9, 2025
9517d21
fix: narrow account type to a modular account v2
linnall Jun 10, 2025
01aec4c
Merge branch 'main' into linna/webauth-tests
linnall Jun 10, 2025
a511372
Merge branch 'main' into linna/webauth-tests
linnall Jun 13, 2025
80b1e11
chore: adds wip of webauthn client tests
linnall Apr 24, 2025
4a31074
chore: updates webauthn test to use mocked window.credentials.get res…
linnall Apr 29, 2025
db4082d
chore: adds credential and mock response from self generated credenti…
linnall Apr 29, 2025
10bdfb4
fix: rename webAuthnCredentials to webAuthnAccountParams
linnall Apr 30, 2025
27c16a4
chore: adds to do
linnall Apr 30, 2025
1015a44
feat: add ability to create a webauthn ModularAccountV2 without a signer
linnall May 6, 2025
eaca5d3
chore: removes unused code
linnall May 6, 2025
f89caac
fix: ensures presence of signer is explicit
linnall May 7, 2025
1a714c1
fix: refactor to not destructure
linnall May 7, 2025
f4fce6e
feat: adds account functions for webauthn
linnall May 8, 2025
6fef890
feat: add webauthn gas estimator
howydev Apr 29, 2025
aef8ab6
chore: fix lint, change to use type narrowing instead
howydev May 1, 2025
43cd540
feat: add webauthn signer
howydev Apr 28, 2025
dbed1f5
chore: update dummy sig
howydev Apr 29, 2025
bae0dd4
feat: modifies mav2 smart account client and mav2 client tests to wor…
linnall May 11, 2025
d39c857
fix: add documenting comment for webauthn gas estimator usage
linnall May 12, 2025
968d3f2
fix: adds documentation comment for webauthnGasEstimator usage
linnall May 12, 2025
12df485
chore: wip deploy webauthn account then sign message
linnall May 13, 2025
25c586e
fix: prepend signatures with 0xff
linnall May 15, 2025
ac5ccb7
fix: prepend signature regardless of deferred actions data presence
linnall May 15, 2025
b1db3f8
chore: wip debugging
linnall May 19, 2025
33b99a6
fix: debug
howydev May 19, 2025
5374d09
chore: adds updated mock authenticator response
linnall May 19, 2025
9b1746b
fix: prefixes signature with offset
linnall May 20, 2025
db25235
chore: update credentials and mocked authenticator response
linnall May 20, 2025
e09190c
chore: updates credentials and authenticator response
linnall May 22, 2025
f32de73
chore: fix merge issues with main
linnall May 27, 2025
d4b7755
test: update tests using mock webauthn device (#1639)
moldy530 May 27, 2025
ec69fc2
chore: wip format message to be EIP-712 and add lint fixes
linnall May 28, 2025
95c1a3b
fix: inline documentation
linnall May 28, 2025
8cbe5f8
chore: removes debugging statements and linting fixes
linnall May 28, 2025
602ade8
chore: rename types
linnall May 28, 2025
7b682c7
fix: refactor
linnall May 28, 2025
ce67fe6
chore: remove debug statement
linnall May 28, 2025
e7f1f03
fix: update return type
linnall May 28, 2025
d74cf3d
fix: adds strongly typed errors
linnall May 28, 2025
85a0a93
chore: removes debug statements
linnall May 28, 2025
b6f3259
fix: fixes example in docs
linnall May 28, 2025
3729c8e
chore: add todo comment, removes debug statement
linnall May 29, 2025
4c85c6c
chore: remove lint warnings
linnall May 29, 2025
8a83a38
refactor: encode sign parameters as a struct
linnall May 30, 2025
806fc68
feat: export WebAuthnValidationModule
linnall Jun 9, 2025
402aba9
fix: typing on creation of clients to support alchemy configs
moldy530 Jun 9, 2025
65c24e0
fix: cleans up tests
linnall Jun 13, 2025
de71a93
chore: removes unused import
linnall Jun 13, 2025
83afbfa
fix: webauthn session key test
linnall Jun 16, 2025
3ecb290
Merge branch 'main' into linna/webauth-tests
linnall Jun 17, 2025
09f7c16
Merge branch 'linna/webauthn-account-sdk' into linna/webauth-tests
linnall Jun 17, 2025
114a620
fix: removes duplicate identifier
linnall Jun 17, 2025
63d8b53
fix: remove unnecessary arg
linnall Jun 17, 2025
21237b8
chore: merges in main
linnall Jun 17, 2025
897a484
chore: merges in main
linnall Jun 17, 2025
6b76785
chore: removes to do comment
linnall Jun 18, 2025
a4236ee
chore: removes unnecessary account type check
linnall Jun 18, 2025
bf40fec
chore: merges in main
linnall Jun 18, 2025
bbbdbea
chore: updates yarn.lock and docs.yml
linnall Jun 18, 2025
e98e304
fix: add back necessary account type checks
linnall Jun 18, 2025
22d4899
Merge branch 'main' into linna/webauth-tests
linnall Jun 18, 2025
637ec19
fix: restore yarn.lock file
linnall Jun 19, 2025
2c39ce0
fix: adds more granular errors
linnall Jun 24, 2025
e222383
chore: updates error docs
linnall Jun 24, 2025
682383d
Merge branch 'main' into linna/webauth-tests
linnall Jun 24, 2025
4400a87
fix: refactor
linnall Jun 24, 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
14 changes: 14 additions & 0 deletions aa-sdk/core/src/errors/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ export class AccountNotFoundError extends BaseError {
}
}

/**
* This error is thrown when an account is not a Modular Account V2
*/

export class NotAModularAccountV2Error extends BaseError {
override name = "NotAModularAccountV2Error";
/**
* Constructor for initializing an error message indicating that the account is not a Modular Account V2.
*/
constructor() {
super("This is not a Modular Account V2 account.");
}
}

/**
* Represents an error that is thrown when no default factory is defined for a specific account type on a given chain and entry point version.
* This error suggests providing an override via the `factoryAddress` parameter when creating an account.
Expand Down
1 change: 1 addition & 0 deletions aa-sdk/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export {
export type * from "./entrypoint/types.js";
export {
AccountNotFoundError,
NotAModularAccountV2Error,
AccountRequiresOwnerError,
BatchExecutionNotSupportedError,
DefaultFactoryNotDefinedError,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
import {
createBundlerClient,
getEntryPoint,
InvalidDeferredActionNonce,
InvalidEntityIdError,
InvalidNonceKeyError,
InvalidDeferredActionNonce,
toSmartContractAccount,
type AccountOp,
type SmartAccountSigner,
type SmartContractAccount,
type SmartContractAccountWithSigner,
type ToSmartContractAccountParams,
type SmartContractAccount,
} from "@aa-sdk/core";
import { DEFAULT_OWNER_ENTITY_ID, parseDeferredAction } from "../../utils.js";
import {
type Hex,
type Address,
type Chain,
type Transport,
concatHex,
encodeFunctionData,
maxUint32,
zeroAddress,
getContract,
concatHex,
maxUint152,
maxUint32,
zeroAddress,
type Address,
type Chain,
type Hex,
type Transport,
} from "viem";
import type { ToWebAuthnAccountParameters } from "viem/account-abstraction";
import { modularAccountAbi } from "../../abis/modularAccountAbi.js";
import { serializeModuleEntity } from "../../actions/common/utils.js";
import { nativeSMASigner } from "../nativeSMASigner.js";
import { singleSignerMessageSigner } from "../../modules/single-signer-validation/signer.js";
import type { ToWebAuthnAccountParameters } from "viem/account-abstraction";
import { webauthnSigningFunctions } from "../../modules/webauthn-validation/signingMethods.js";
import { DEFAULT_OWNER_ENTITY_ID, parseDeferredAction } from "../../utils.js";
import { nativeSMASigner } from "../nativeSMASigner.js";

export const executeUserOpSelector: Hex = "0x8DD7712F";

export type ModularAccountsV2 = ModularAccountV2 | WebauthnModularAccountV2;

export type SignerEntity = {
isGlobalValidation: boolean;
entityId: number;
Expand Down Expand Up @@ -358,3 +360,9 @@ export async function createMAv2Base<
encodeCallData,
} as ModularAccountV2<TSigner>; // TO DO: figure out when this breaks! we shouldn't have to cast
}

export function isModularAccountV2(
account: SmartContractAccount,
): account is ModularAccountV2 | WebauthnModularAccountV2 {
return account.source === "ModularAccountV2";
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,44 @@
import {
AccountNotFoundError,
IncompatibleClientError,
isSmartAccountClient,
NotAModularAccountV2Error,
EntityIdOverrideError,
type GetAccountParameter,
type GetEntryPointFromAccount,
IncompatibleClientError,
type SendUserOperationResult,
type UserOperationOverridesParameter,
type SmartAccountSigner,
isSmartAccountClient,
isSmartAccountWithSigner,
} from "@aa-sdk/core";
import {
type Address,
type Chain,
type Client,
type Hex,
encodeFunctionData,
type Transport,
concatHex,
encodeFunctionData,
zeroAddress,
} from "viem";

import { semiModularAccountBytecodeAbi } from "../../abis/semiModularAccountBytecodeAbi.js";
import type { HookConfig, ValidationConfig } from "../common/types.js";
import {
serializeValidationConfig,
serializeHookConfig,
serializeModuleEntity,
serializeValidationConfig,
} from "../common/utils.js";

import { type ModularAccountV2Client } from "../../client/client.js";
import { type ModularAccountV2 } from "../../account/common/modularAccountV2Base.js";
import {
type ModularAccountsV2,
isModularAccountV2,
} from "../../account/common/modularAccountV2Base.js";
import { DEFAULT_OWNER_ENTITY_ID } from "../../utils.js";

export type InstallValidationParams<
TSigner extends SmartAccountSigner = SmartAccountSigner,
TAccount extends ModularAccountsV2 | undefined =
| ModularAccountsV2
| undefined,
> = {
validationConfig: ValidationConfig;
selectors: Hex[];
Expand All @@ -38,38 +47,38 @@ export type InstallValidationParams<
hookConfig: HookConfig;
initData: Hex;
}[];
account?: ModularAccountV2<TSigner> | undefined;
} & UserOperationOverridesParameter<
GetEntryPointFromAccount<ModularAccountV2<TSigner>>
>;
} & UserOperationOverridesParameter<GetEntryPointFromAccount<TAccount>> &
GetAccountParameter<TAccount>;

export type UninstallValidationParams<
TSigner extends SmartAccountSigner = SmartAccountSigner,
TAccount extends ModularAccountsV2 | undefined =
| ModularAccountsV2
| undefined,
> = {
moduleAddress: Address;
entityId: number;
uninstallData: Hex;
hookUninstallDatas: Hex[];
account?: ModularAccountV2<TSigner> | undefined;
} & UserOperationOverridesParameter<
GetEntryPointFromAccount<ModularAccountV2<TSigner>>
>;
} & UserOperationOverridesParameter<GetEntryPointFromAccount<TAccount>> &
GetAccountParameter<TAccount>;

export type InstallValidationActions<
TSigner extends SmartAccountSigner = SmartAccountSigner,
TAccount extends ModularAccountsV2 | undefined =
| ModularAccountsV2
| undefined,
> = {
installValidation: (
args: InstallValidationParams<TSigner>,
args: InstallValidationParams<TAccount>,
) => Promise<SendUserOperationResult>;
encodeInstallValidation: (
// TODO: omit the user op sending related parameters from this type
args: InstallValidationParams<TSigner>,
args: InstallValidationParams<TAccount>,
) => Promise<Hex>;
uninstallValidation: (
args: UninstallValidationParams<TSigner>,
args: UninstallValidationParams<TAccount>,
) => Promise<SendUserOperationResult>;
encodeUninstallValidation: (
args: UninstallValidationParams<TSigner>,
args: UninstallValidationParams<TAccount>,
) => Promise<Hex>;
};

Expand Down Expand Up @@ -117,23 +126,32 @@ export type InstallValidationActions<
* @param {object} client - The client instance which provides account and sendUserOperation functionality.
* @returns {object} - An object containing two methods, `installValidation` and `uninstallValidation`.
*/
export const installValidationActions: <
TSigner extends SmartAccountSigner = SmartAccountSigner,
export function installValidationActions<
TTransport extends Transport = Transport,
TChain extends Chain | undefined = Chain | undefined,
TAccount extends ModularAccountsV2 | undefined =
| ModularAccountsV2
| undefined,
>(
client: ModularAccountV2Client<TSigner>,
) => InstallValidationActions<TSigner> = (client) => {
client: Client<TTransport, TChain, TAccount>,
): InstallValidationActions<TAccount> {
const encodeInstallValidation = async ({
validationConfig,
selectors,
installData,
hooks,
account = client.account,
}: InstallValidationParams) => {
}: InstallValidationParams<TAccount>) => {
if (!account) {
throw new AccountNotFoundError();
}

if (!isSmartAccountClient(client)) {
if (!isModularAccountV2(account)) {
throw new NotAModularAccountV2Error();
}

if (isSmartAccountWithSigner(account) && !isSmartAccountClient(client)) {
// if we don't differentiate between WebauthnModularAccountV2Client and ModularAccountV2Client, passing client to isSmartAccountClient complains
throw new IncompatibleClientError(
"SmartAccountClient",
"installValidation",
Expand Down Expand Up @@ -171,12 +189,17 @@ export const installValidationActions: <
uninstallData,
hookUninstallDatas,
account = client.account,
}: UninstallValidationParams) => {
}: UninstallValidationParams<TAccount>) => {
if (!account) {
throw new AccountNotFoundError();
}

if (!isSmartAccountClient(client)) {
if (!isModularAccountV2(account)) {
throw new NotAModularAccountV2Error();
}

if (isSmartAccountWithSigner(account) && !isSmartAccountClient(client)) {
// if we don't differentiate between WebauthnModularAccountV2Client and ModularAccountV2Client, passing client to isSmartAccountClient complains
throw new IncompatibleClientError(
"SmartAccountClient",
"uninstallValidation",
Expand Down Expand Up @@ -210,7 +233,19 @@ export const installValidationActions: <
hooks,
account = client.account,
overrides,
}) => {
}: InstallValidationParams<TAccount>) => {
if (!isSmartAccountClient(client)) {
throw new IncompatibleClientError(
"SmartAccountClient",
"installValidation",
client,
);
}

if (!account) {
throw new AccountNotFoundError();
}

const callData = await encodeInstallValidation({
validationConfig,
selectors,
Expand All @@ -233,8 +268,20 @@ export const installValidationActions: <
hookUninstallDatas,
account = client.account,
overrides,
}) => {
const callData = await encodeUninstallValidation({
}: UninstallValidationParams<TAccount>) => {
if (!account) {
throw new AccountNotFoundError();
}

if (!isSmartAccountClient(client)) {
throw new IncompatibleClientError(
"SmartAccountClient",
"uninstallValidation",
client,
);
}

const callData: Hex = await encodeUninstallValidation({
moduleAddress,
entityId,
uninstallData,
Expand All @@ -249,4 +296,4 @@ export const installValidationActions: <
});
},
};
};
}
Loading
Loading