Skip to content

Commit

Permalink
feat: setup key encryption
Browse files Browse the repository at this point in the history
still need key export, but has an idea
  • Loading branch information
cpb8010 committed Jan 20, 2025
1 parent cbfb7fa commit bc531eb
Showing 1 changed file with 88 additions and 16 deletions.
104 changes: 88 additions & 16 deletions examples/bank-demo/components/app/AddCryptoButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,32 @@
<span v-if="!isLoading">Add Crypto account</span>
<CommonSpinner v-else class="h-6"/>
</ZkButton>
<div>
<div v-if="showModal" class="modal-overlay">
<div class="modal-content">
<h2>Enter PIN/Password</h2>
<input v-model="enteredPin" type="password" >
<button @click="checkPin">Confirm</button>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { createWalletClient, http, type Address, type Chain } from "viem";
import type { PrivateKeyAccount, Address, Chain, Hex } from "viem";
import { createWalletClient, http } from "viem";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import { deployAccount } from "zksync-sso/client";
import { registerNewPasskey } from "zksync-sso/client/passkey";
const { appMeta, userDisplay, userId, contracts, deployerKey } = useAppMeta();
const isLoading = ref(false);
const showModal = ref(false);
const enteredPin = ref("");
const account = ref<PrivateKeyAccount>();
const privateKey = ref<Hex>();
// Convert Uin8Array to string
const u8ToString = (input: Uint8Array): string => {
const str = JSON.stringify(Array.from ? Array.from(input) : [].map.call(input, (v => v)));
Expand Down Expand Up @@ -91,26 +106,83 @@ const createAccountWithPasskey = async () => {
}
};
async function encryptMessage(cryptoPrivateKey: string) {
if (!enteredPin.value) {
console.warn("Pin not set");
return;
}
const keyEncryptionKey = await window.crypto.subtle.generateKey(
{
name: "AES-CBC",
length: 256,
},
true,
["encrypt", "decrypt"],
);
const encoded = new TextEncoder().encode(cryptoPrivateKey);
// TODO: get a fixed salt from the backend here
const hashedPin = await window.crypto.subtle.digest("SHA-512", new TextEncoder().encode(enteredPin.value));
const iv = new Uint8Array(hashedPin.slice(0, 16));
const encryptedKey = await window.crypto.subtle.encrypt(
{
name: "AES-CBC",
iv: iv,
},
keyEncryptionKey,
encoded,
);
return { encryptedKey, keyEncryptionKey, iv: iv };
}
async function decryptMessage(encryptedKey: ArrayBuffer, key: CryptoKey, iv: Uint8Array) {
const decryptedBytes = await window.crypto.subtle.decrypt({ name: "AES-CBC", iv }, key, encryptedKey);
return new TextDecoder().decode(decryptedBytes);
}
async function checkPin() {
if (!privateKey.value) {
console.warn("Private key not set");
return;
}
const encrypted = await encryptMessage(privateKey.value);
if (!encrypted) {
console.error("Encryption failed", privateKey.value);
return;
}
const testDecrypted = await decryptMessage(encrypted.encryptedKey, encrypted.keyEncryptionKey, encrypted.iv);
if (privateKey.value != testDecrypted) {
console.error("Decryption failed", privateKey.value, testDecrypted);
return;
}
console.log("Decryption success", encrypted);
// export the encrypted key
const deployerClient = await getDeployerClient();
const { address } = await deployAccount(deployerClient, {
credentialPublicKey: new Uint8Array(),
ownerPublicKeys: [account.value?.address],
contracts,
});
appMeta.value = {
...appMeta.value,
cryptoAccountAddress: address,
};
showModal.value = true;
navigateTo("/crypto-account");
}
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,
};
privateKey.value = generatePrivateKey();
account.value = privateKeyToAccount(privateKey.value);
showModal.value = true;
} else {
navigateTo("/crypto-account");
};
navigateTo("/crypto-account");
};
</script>

0 comments on commit bc531eb

Please sign in to comment.