Skip to content

Commit 8e19e55

Browse files
committed
chore: 7702 is valid implementation code
1 parent 1f62458 commit 8e19e55

9 files changed

Lines changed: 532 additions & 662 deletions

packages/delegation-toolkit/src/actions/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ export {
2727

2828
export { isEip7702StatelessDelegatedAccount } from './isEip7702StatelessDelegatedAccount';
2929
export { isValidImplementation } from './isValidImplementation';
30+
export { isValid7702Implementation } from './isValid7702Implementation';
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import type { Client, Address, Hex } from 'viem';
2+
import { getCode } from 'viem/actions';
3+
4+
import type { DeleGatorEnvironment } from '../types';
5+
6+
// EIP-7702 delegation prefix (0xef0100)
7+
const DELEGATION_PREFIX = '0xef0100' as const;
8+
9+
/**
10+
* Parameters for checking if an account is delegated to the EIP-7702 implementation.
11+
*/
12+
export type IsValid7702ImplementationParameters = {
13+
/** The client to use for the query. */
14+
client: Client;
15+
/** The address to check for proper delegation. */
16+
accountAddress: Address;
17+
/** The DeleGator environment containing contract addresses. */
18+
environment: DeleGatorEnvironment;
19+
};
20+
21+
/**
22+
* Extracts the delegated contract address from EIP-7702 delegation code.
23+
*
24+
* @param code - The code returned from getCode for a delegated account.
25+
* @returns The delegated contract address or null if not a valid delegation.
26+
*/
27+
function extractDelegatedAddress(code: Hex | undefined): Address | null {
28+
if (!code || code.length !== 48) {
29+
// 0x (2 chars) + ef0100 (6 chars) + address (40 chars) = 48 chars
30+
return null;
31+
}
32+
33+
if (!code.startsWith(DELEGATION_PREFIX)) {
34+
return null;
35+
}
36+
37+
// Extract the 20-byte address after the delegation prefix
38+
const addressHex = code.slice(8); // Remove '0xef0100' prefix (8 chars)
39+
return `0x${addressHex}`;
40+
}
41+
42+
/**
43+
* Checks if an account is properly delegated to the EIP-7702 implementation.
44+
*
45+
* This function validates EIP-7702 delegations by checking if the EOA has a 7702
46+
* contract assigned to it and comparing the delegated address against the 7702
47+
* implementation found in the environment.
48+
*
49+
* @param params - The parameters for checking the delegation.
50+
* @param params.client - The client to use for the query.
51+
* @param params.accountAddress - The address to check for proper delegation.
52+
* @param params.environment - The DeleGator environment containing contract addresses.
53+
* @returns A promise that resolves to true if the account is properly delegated to the 7702 implementation, false otherwise.
54+
* @example
55+
* ```typescript
56+
* const isValid = await isValid7702Implementation({
57+
* client: publicClient,
58+
* accountAddress: '0x...',
59+
* environment: delegatorEnvironment,
60+
* });
61+
*
62+
* if (isValid) {
63+
* console.log('Account is properly delegated to EIP-7702 implementation');
64+
* } else {
65+
* console.log('Account is not properly delegated');
66+
* }
67+
* ```
68+
*/
69+
export async function isValid7702Implementation({
70+
client,
71+
accountAddress,
72+
environment,
73+
}: IsValid7702ImplementationParameters): Promise<boolean> {
74+
try {
75+
// Get the code at the account address
76+
const code = await getCode(client, {
77+
address: accountAddress,
78+
});
79+
80+
// Extract the delegated contract address from the EIP-7702 delegation code
81+
const delegatedAddress = extractDelegatedAddress(code);
82+
83+
// If no valid delegation found, return false
84+
if (!delegatedAddress) {
85+
return false;
86+
}
87+
88+
// Compare the delegated address with the 7702 implementation in the environment
89+
const expectedImplementation =
90+
environment.implementations.EIP7702StatelessDeleGatorImpl;
91+
if (!expectedImplementation) {
92+
return false;
93+
}
94+
95+
return (
96+
delegatedAddress.toLowerCase() === expectedImplementation.toLowerCase()
97+
);
98+
} catch (error) {
99+
// If the call fails (e.g., no code at address, network error),
100+
// then it's not properly delegated to our implementation
101+
return false;
102+
}
103+
}

packages/delegation-toolkit/src/actions/isValidImplementation.ts

Lines changed: 0 additions & 84 deletions
This file was deleted.

packages/delegation-toolkit/src/toMetaMaskSmartAccount.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
toSmartAccount,
1111
} from 'viem/account-abstraction';
1212

13-
import { isValidImplementation } from './actions/isValidImplementation';
13+
import { isValid7702Implementation } from './actions/isValid7702Implementation';
1414
import { Implementation } from './constants';
1515
import { getCounterfactualAccountData } from './counterfactualAccountData';
1616
import {
@@ -198,14 +198,19 @@ export async function toMetaMaskSmartAccount<
198198
...signatory,
199199
});
200200

201-
// Override isDeployed for all implementations to check proper implementation code
202-
return {
203-
...smartAccount,
204-
isDeployed: async () =>
205-
isValidImplementation({
206-
client,
207-
accountAddress: address,
208-
implementation,
209-
}),
210-
};
201+
// Override isDeployed only for EIP-7702 implementation to check proper delegation code
202+
if (implementation === Implementation.Stateless7702) {
203+
return {
204+
...smartAccount,
205+
isDeployed: async () =>
206+
isValid7702Implementation({
207+
client,
208+
accountAddress: address,
209+
environment,
210+
}),
211+
};
212+
}
213+
214+
// For other implementations, use the default isDeployed behavior
215+
return smartAccount;
211216
}

0 commit comments

Comments
 (0)