Skip to content

Commit aabaed8

Browse files
authored
Merge pull request #91 from cometh-hq/develop
Develop
2 parents 8ff95b0 + b4f921d commit aabaed8

File tree

8 files changed

+112
-19
lines changed

8 files changed

+112
-19
lines changed

bun.lockb

832 Bytes
Binary file not shown.

packages/sdk/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"name": "yoanslvy"
77
}
88
],
9-
"version": "1.0.13",
9+
"version": "1.0.14",
1010
"description": "SDK Cometh Connect 4337",
1111
"repository": "https://github.com/cometh-hq/connect-sdk-4337.git",
1212
"keywords": [
@@ -45,7 +45,7 @@
4545
"build": "tsup --splitting"
4646
},
4747
"peerDependencies": {
48-
"viem": "^2.22.23",
48+
"viem": "^2.31.1",
4949
"wagmi": "^2"
5050
},
5151
"devDependencies": {

packages/sdk/src/constants.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const SENTINEL_MODULES =
1111
const SAFE_7579_ADDRESS: Address = "0x7579EE8307284F293B1927136486880611F20002";
1212
const LAUNCHPAD_ADDRESS: Address = "0x7579011aB74c46090561ea277Ba79D510c6C00ff";
1313

14-
const add7579FunctionSelector = "0xd78343d9";
1514
const hardcodeVerificationGasLimit7579 = 1000000n;
1615
const FALLBACK_TARGET_FLAG =
1716
"0x0000000000000000000000000000000000000001" as Address;
@@ -35,7 +34,6 @@ export {
3534
FALLBACK_TARGET_FLAG,
3635
FALLBACK_TARGET_SELECTOR_FLAG_PERMITTED_TO_CALL_SMARTSESSION,
3736
customChains,
38-
add7579FunctionSelector,
3937
hardcodeVerificationGasLimit7579,
4038
defaultClientConfig,
4139
};

packages/sdk/src/core/accounts/safe/createSafeSmartAccount.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import {
3838
getSafeInitializer,
3939
} from "./services/safe";
4040

41-
import { SAFE_7579_ADDRESS, add7579FunctionSelector } from "@/constants";
41+
import { SAFE_7579_ADDRESS } from "@/constants";
4242
import { MethodNotSupportedError } from "@/errors";
4343
import { isSmartAccountDeployed } from "permissionless";
4444
import type { ToSafeSmartAccountReturnType } from "permissionless/accounts";
@@ -325,7 +325,6 @@ export async function createSafeSmartAccount<
325325
async signMessage({ message }) {
326326
return safeSigner.signMessage({ message });
327327
},
328-
329328
async signTypedData() {
330329
throw new MethodNotSupportedError();
331330
},
@@ -379,12 +378,12 @@ export async function createSafeSmartAccount<
379378
}
380379

381380
// set fallback 7579 in delegateCall
382-
const modifiedCalls = calls.map((call) => ({
381+
// biome-ignore lint/suspicious/noExplicitAny: to Allow nested delegatecalls
382+
const modifiedCalls = calls.map((call: any) => ({
383383
...call,
384384
data: call.data ?? "0x",
385385
value: call.value ?? BigInt(0),
386-
operation:
387-
call.data?.slice(0, 10) === add7579FunctionSelector ? 1 : 0,
386+
operation: call.operation ?? 0,
388387
}));
389388

390389
if (hasMultipleCalls) {
@@ -417,7 +416,7 @@ export async function createSafeSmartAccount<
417416
modifiedCalls[0].to,
418417
modifiedCalls[0].value,
419418
modifiedCalls[0].data,
420-
modifiedCalls[0].operation,
419+
modifiedCalls[0].operation ?? 0,
421420
],
422421
});
423422
},

packages/sdk/src/core/actions/accounts/7579/setFallbackTo7579.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ export async function setFallbackTo7579<
118118
],
119119
}),
120120
value: BigInt(0),
121+
operation: 1,
121122
},
122123
];
123124

packages/sdk/src/core/actions/accounts/retrieveAccountAddressFromPasskey.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,34 @@ import {
33
retrieveSmartAccountAddressFromPasskey,
44
retrieveSmartAccountAddressFromPasskeyId,
55
} from "@/core/signers/passkeys/passkeyService";
6-
import type { Address, Chain } from "viem";
6+
import type { Address, Chain, PublicClient } from "viem";
77

88
/**
99
* Function used to retrieve an account address from passkeys
1010
* @param apiKey
1111
* @param chain
1212
* @param fullDomainSelected
1313
*/
14-
export const retrieveAccountAddressFromPasskeys = async (
15-
apiKey: string,
16-
chain: Chain,
14+
export const retrieveAccountAddressFromPasskeys = async ({
15+
apiKey,
16+
chain,
1717
fullDomainSelected = false,
18-
baseUrl?: string
19-
): Promise<Address> => {
18+
baseUrl,
19+
publicClient,
20+
}: {
21+
apiKey: string;
22+
chain: Chain;
23+
fullDomainSelected: boolean;
24+
baseUrl?: string;
25+
publicClient?: PublicClient;
26+
}): Promise<Address> => {
2027
const api = new API(apiKey, baseUrl);
2128

2229
return await retrieveSmartAccountAddressFromPasskey(
2330
api,
2431
chain,
25-
fullDomainSelected
32+
fullDomainSelected,
33+
publicClient
2634
);
2735
};
2836

@@ -39,12 +47,14 @@ export const retrieveAccountAddressFromPasskeyId = async ({
3947
chain,
4048
fullDomainSelected = false,
4149
baseUrl,
50+
publicClient,
4251
}: {
4352
apiKey: string;
4453
id: string;
4554
chain: Chain;
4655
fullDomainSelected: boolean;
4756
baseUrl?: string;
57+
publicClient?: PublicClient;
4858
}): Promise<Address> => {
4959
const api = new API(apiKey, baseUrl);
5060

@@ -53,5 +63,6 @@ export const retrieveAccountAddressFromPasskeyId = async ({
5363
id,
5464
chain,
5565
fullDomainSelected,
66+
publicClient,
5667
});
5768
};

packages/sdk/src/core/modules/sessionKey/decorators/grantPermission.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export async function grantPermission<
6060
to: preparedPermission.action.target,
6161
data: preparedPermission.action.callData,
6262
value: BigInt(0),
63+
operation: 0,
6364
},
6465
];
6566

@@ -117,6 +118,7 @@ export async function grantPermission<
117118
],
118119
}),
119120
value: BigInt(0),
121+
operation: 1,
120122
});
121123
}
122124

packages/sdk/src/core/signers/passkeys/passkeyService.ts

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1+
import { SafeAbi } from "@/core/accounts/safe/abi/safe";
2+
import { SafeWebAuthnSharedSignerAbi } from "@/core/accounts/safe/abi/sharedWebAuthnSigner";
13
import { isSafeOwner } from "@/core/accounts/safe/services/safe";
24
import type { API } from "@/core/services/API";
35
import { parseAuthenticatorData } from "@simplewebauthn/server/helpers";
46
import CBOR from "cbor-js";
57
import elliptic from "elliptic";
8+
import { isSmartAccountDeployed } from "permissionless";
69
import psl from "psl";
710
import type { ParsedDomain } from "psl";
811
import {
12+
http,
913
type Address,
1014
type Chain,
1115
type Hex,
1216
type PublicClient,
17+
createPublicClient,
1318
encodeAbiParameters,
19+
getContract,
1420
hashMessage,
1521
keccak256,
1622
toBytes,
@@ -406,7 +412,8 @@ const getPasskeySigner = async ({
406412
const retrieveSmartAccountAddressFromPasskey = async (
407413
API: API,
408414
chain: Chain,
409-
fullDomainSelected: boolean
415+
fullDomainSelected: boolean,
416+
publicClient?: PublicClient
410417
): Promise<Address> => {
411418
let publicKeyId: Hex;
412419

@@ -435,6 +442,15 @@ const retrieveSmartAccountAddressFromPasskey = async (
435442
const { smartAccountAddress, publicKeyX, publicKeyY, signerAddress } =
436443
webAuthnSignerForGivenChain;
437444

445+
await _checkIfOwner({
446+
smartAccountAddress: smartAccountAddress as Address,
447+
signerAddress: signerAddress as Address,
448+
publicKeyX: publicKeyX as Hex,
449+
publicKeyY: publicKeyY as Hex,
450+
chain,
451+
publicClient: publicClient as PublicClient,
452+
});
453+
438454
setPasskeyInStorage(
439455
smartAccountAddress as Address,
440456
publicKeyId,
@@ -451,11 +467,13 @@ const retrieveSmartAccountAddressFromPasskeyId = async ({
451467
id,
452468
chain,
453469
fullDomainSelected,
470+
publicClient,
454471
}: {
455472
API: API;
456473
id: string;
457474
chain: Chain;
458475
fullDomainSelected: boolean;
476+
publicClient?: PublicClient;
459477
}): Promise<Address> => {
460478
const publicKeyCredentials = [
461479
{
@@ -488,10 +506,18 @@ const retrieveSmartAccountAddressFromPasskeyId = async ({
488506
);
489507
if (!webAuthnSignerForGivenChain)
490508
throw new NoPasskeySignerFoundForGivenChain();
491-
492509
const { smartAccountAddress, publicKeyX, publicKeyY, signerAddress } =
493510
webAuthnSignerForGivenChain;
494511

512+
await _checkIfOwner({
513+
chain,
514+
smartAccountAddress: smartAccountAddress as Address,
515+
signerAddress: signerAddress as Address,
516+
publicKeyX: publicKeyX as Hex,
517+
publicKeyY: publicKeyY as Hex,
518+
publicClient: publicClient as PublicClient,
519+
});
520+
495521
setPasskeyInStorage(
496522
smartAccountAddress as Address,
497523
publicKeyId,
@@ -503,6 +529,62 @@ const retrieveSmartAccountAddressFromPasskeyId = async ({
503529
return smartAccountAddress as Address;
504530
};
505531

532+
const _checkIfOwner = async ({
533+
chain,
534+
smartAccountAddress,
535+
signerAddress,
536+
publicKeyX,
537+
publicKeyY,
538+
publicClient,
539+
}: {
540+
chain: Chain;
541+
smartAccountAddress: Address;
542+
signerAddress: Address;
543+
publicKeyX: Hex;
544+
publicKeyY: Hex;
545+
publicClient: PublicClient;
546+
}) => {
547+
const _publicClient =
548+
publicClient ??
549+
createPublicClient({
550+
chain,
551+
transport: http(),
552+
});
553+
554+
const safe = getContract({
555+
address: smartAccountAddress as Address,
556+
abi: SafeAbi,
557+
client: _publicClient,
558+
});
559+
560+
const sharedWebAuthnSigner = getContract({
561+
address: signerAddress as Address,
562+
abi: SafeWebAuthnSharedSignerAbi,
563+
client: _publicClient,
564+
});
565+
566+
const isSafeDeployed = await isSmartAccountDeployed(
567+
_publicClient,
568+
smartAccountAddress as Address
569+
);
570+
if (!isSafeDeployed) return;
571+
572+
const [isSignerOwner, sharedWebAuthnSignerConfiguration] =
573+
await Promise.all([
574+
await safe.read.isOwner([signerAddress]),
575+
await sharedWebAuthnSigner.read.getConfiguration([
576+
smartAccountAddress as Address,
577+
]),
578+
]);
579+
580+
if (!isSignerOwner) throw new SignerNotOwnerError();
581+
582+
if (
583+
sharedWebAuthnSignerConfiguration.x !== BigInt(publicKeyX) ||
584+
sharedWebAuthnSignerConfiguration.y !== BigInt(publicKeyY)
585+
)
586+
throw new SignerNotOwnerError();
587+
};
506588
export {
507589
createPasskeySigner,
508590
getPasskeyInStorage,

0 commit comments

Comments
 (0)