Skip to content

Commit

Permalink
feat: allow creating with a k1 owner
Browse files Browse the repository at this point in the history
This updates the interface so a passkey isn't required and samples creating a key
  • Loading branch information
cpb8010 committed Jan 20, 2025
1 parent ba0fcdf commit cbfb7fa
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 31 deletions.
51 changes: 41 additions & 10 deletions examples/bank-demo/components/app/AddCryptoButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<script setup lang="ts">
import { createWalletClient, http, type Address, type Chain } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import { deployAccount } from "zksync-sso/client";
import { registerNewPasskey } from "zksync-sso/client/passkey";
Expand All @@ -32,9 +32,7 @@ const onClickAddCrypto = async () => {
isLoading.value = false;
};
const createCryptoAccount = async () => {
let credentialPublicKey: Uint8Array;
const getPublicPasskey = async () => {
// Create new Passkey
if (!appMeta.value || !appMeta.value.credentialPublicKey) {
try {
Expand All @@ -46,26 +44,37 @@ const createCryptoAccount = async () => {
...appMeta.value,
credentialPublicKey: u8ToString(newCredentialPublicKey),
};
credentialPublicKey = newCredentialPublicKey;
return newCredentialPublicKey;
} catch (error) {
console.error("Passkey registration failed:", error);
return;
}
} else {
credentialPublicKey = new Uint8Array(JSON.parse(appMeta.value.credentialPublicKey));
return new Uint8Array(JSON.parse(appMeta.value.credentialPublicKey));
}
};
// Configure deployer account to pay for Account creation
const getDeployerClient = async () => {
const config = useRuntimeConfig();
const deployerClient = createWalletClient({
return createWalletClient({
account: privateKeyToAccount(deployerKey as Address),
chain: config.public.network as Chain,
transport: http()
});
};
const createAccountWithPasskey = async () => {
const publicPassKey = await getPublicPasskey();
if (!publicPassKey) {
return false;
}
// Configure deployer account to pay for Account creation
const deployerClient = await getDeployerClient();
try {
const { address, transactionReceipt } = await deployAccount(deployerClient, {
credentialPublicKey,
credentialPublicKey: publicPassKey,
contracts,
});
Expand All @@ -75,10 +84,32 @@ const createCryptoAccount = async () => {
};
console.log(`Successfully created account: ${address}`);
console.log(`Transaction receipt: ${transactionReceipt.transactionHash}`);
return true;
} catch (error) {
console.error(error);
return;
return false;
}
};
const createCryptoAccount = async () => {
if (!await createAccountWithPasskey()) {
// create account with EOA owner
const privateKey = generatePrivateKey();
const account = privateKeyToAccount(privateKey);
const deployerClient = await getDeployerClient();
const { address } = await deployAccount(deployerClient, {
credentialPublicKey: new Uint8Array(),
ownerPublicKeys: [account.address],
contracts,
});
appMeta.value = {
...appMeta.value,
cryptoAccountAddress: address,
};
};
navigateTo("/crypto-account");
};
Expand Down
12 changes: 6 additions & 6 deletions examples/bank-demo/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ export default defineNuxtConfig({
aaveAddress: "0xBC989fDe9e54cAd2aB4392Af6dF60f04873A033A", // Rich Account 0
bankDemoDeployerKey: "0x3d3cbc973389cb26f657686445bcc75662b415b656078503592ac8c1abb8810e", // Rich Account 0
network: zksyncInMemoryNode,
session: "0x476F23ef274F244282252341792c8a610feF78ee",
passkey: "0x455e8d86DC6728396f8d3B740Fc893F4E20b25Dc",
accountFactory: "0x23b13d016E973C9915c6252271fF06cCA2098885",
session: "0x4Cf66C1CADcaCb14f380E347d0434479545Cbe8D",
passkey: "0xECcED2CB000f39E402B73ae868255a2a20B944c8",
accountFactory: "0x3391c36d2f5315Ff5f6f909ee9D8c58aAD7DAE06",
explorerUrl: "http://localhost:3010/",
}
},
Expand All @@ -43,9 +43,9 @@ export default defineNuxtConfig({
},
},
},
session: "0xdCdAC285612841db9Fa732098EAF04A917A71A28",
passkey: "0xCeC63BD0f35e04F3Bef1128bA3A856A7BB4D88f1",
accountFactory: "0x23b13d016E973C9915c6252271fF06cCA2098885",
session: "0x4Cf66C1CADcaCb14f380E347d0434479545Cbe8D",
passkey: "0xECcED2CB000f39E402B73ae868255a2a20B944c8",
accountFactory: "0x3391c36d2f5315Ff5f6f909ee9D8c58aAD7DAE06",
explorerUrl: "http://34.121.229.57:3010/",
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts
Submodule contracts updated 328 files
36 changes: 22 additions & 14 deletions packages/sdk/src/client/passkey/actions/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type { SessionConfig } from "../../../utils/session.js";
/* it should come from factory, not passed manually each time */
export type DeployAccountArgs = {
credentialPublicKey: Uint8Array; // Public key of the previously registered
ownerPublicKeys?: Address[]; // EOA address(es) for the account signers
paymasterAddress?: Address; // Paymaster used to pay the fees of creating accounts
paymasterInput?: Hex; // Input for paymaster (if provided)
expectedOrigin?: string; // Expected origin of the passkey
Expand Down Expand Up @@ -67,21 +68,28 @@ export const deployAccount = async <
}
}

const passkeyPublicKey = getPublicKeyBytesFromPasskeySignature(args.credentialPublicKey);
const encodedPasskeyParameters = encodePasskeyModuleParameters({
passkeyPublicKey,
expectedOrigin: origin,
});
const encodedPasskeyModuleData = encodeModuleData({
address: args.contracts.passkey,
parameters: encodedPasskeyParameters,
});
const accountId = args.uniqueAccountId || encodedPasskeyParameters;
const owners: Address[] = args.ownerPublicKeys ?? [];
const moduleData: Hex[] = [];
let accountId = args.uniqueAccountId ?? args.ownerPublicKeys?.at(0);
if (args.credentialPublicKey.length == 0 && args.ownerPublicKeys?.length == 0) {
throw new Error("No public keys provided");
} else if (args.credentialPublicKey.length != 0) {
const passkeyPublicKey = getPublicKeyBytesFromPasskeySignature(args.credentialPublicKey);
const encodedPasskeyParameters = encodePasskeyModuleParameters({
passkeyPublicKey,
expectedOrigin: origin,
});
moduleData.push(encodeModuleData({
address: args.contracts.passkey,
parameters: encodedPasskeyParameters,
}));
accountId = accountId || encodedPasskeyParameters;
}

const encodedSessionKeyModuleData = encodeModuleData({
moduleData.push(encodeModuleData({
address: args.contracts.session,
parameters: args.initialSession ? encodeSession(args.initialSession) : "0x",
});
}));

let deployProxyArgs = {
account: client.account!,
Expand All @@ -92,8 +100,8 @@ export const deployAccount = async <
args: [
toHex(args.salt),
accountId,
[encodedPasskeyModuleData, encodedSessionKeyModuleData],
[],
moduleData,
owners,
],
} as any;

Expand Down

0 comments on commit cbfb7fa

Please sign in to comment.