Skip to content

Commit

Permalink
chore: enable prettier for ts files
Browse files Browse the repository at this point in the history
Found this in another branch and decided to split it out to it's own
change to avoid unrelated changes

chore: fix era-test-node version

chore: attempt latest era-test-node

Later versions have breaking changes to failed transactions, so trying
this version before attempting test changes
  • Loading branch information
cpb8010 committed Dec 31, 2024
1 parent 8a14c35 commit 846c287
Show file tree
Hide file tree
Showing 8 changed files with 289 additions and 210 deletions.
1 change: 0 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ deployments-zk
# Disable prettier for files if VSCode settings are ignored
**/*.vue
**/*.js
**/*.ts
**/*.jsx
**/*.tsx
**/*.mjs
Expand Down
4 changes: 2 additions & 2 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const config: HardhatUserConfig = {
},
},
zksolc: {
version: "1.5.7",
version: "1.5.8",
settings: {
// https://era.zksync.io/docs/tools/hardhat/hardhat-zksync-solc.html#configuration
// Native AA calls an internal system contract, so it needs extra permissions
Expand All @@ -56,7 +56,7 @@ const config: HardhatUserConfig = {
version: "0.8.28",
settings: {
evmVersion: "cancun",
}
},
},
};

Expand Down
1 change: 0 additions & 1 deletion scripts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ async function deploy(name: string, deployer: Wallet, proxy: boolean, args?: any
return proxyAddress;
}


task("deploy", "Deploys ZKsync SSO contracts")
.addOptionalParam("only", "name of a specific contract to deploy")
.addFlag("noProxy", "do not deploy transparent proxies for factory and modules")
Expand Down
2 changes: 1 addition & 1 deletion scripts/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ task("upgrade", "Upgrades ZKsync SSO contracts")
const tx = await proxy.upgradeTo(await newImpl.getAddress());
await tx.wait();
console.log("Proxy upgraded successfully");
});
});
57 changes: 39 additions & 18 deletions test/BasicTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,30 @@ describe("Basic tests", function () {
assert(aaFactoryContract != null, "No AA Factory deployed");

const factoryAddress = await aaFactoryContract.getAddress();
expect(factoryAddress, "the factory address").to.equal(await fixtures.getAaFactoryAddress(), "factory address match");
expect(factoryAddress, "the factory address").to.equal(
await fixtures.getAaFactoryAddress(),
"factory address match",
);

const bytecodeHash = await aaFactoryContract.beaconProxyBytecodeHash();
const deployedAccountContract = await fixtures.getAccountProxyContract();
const deployedAccountContractCode = await deployedAccountContract.getDeployedCode();
assert(deployedAccountContractCode != null, "No account code deployed");
const ssoBeaconBytecodeHash = ethers.hexlify(utils.hashBytecode(deployedAccountContractCode));
expect(bytecodeHash, "deployed account bytecode hash").to.equal(ssoBeaconBytecodeHash, "deployed account code doesn't match");
expect(bytecodeHash, "deployed account bytecode hash").to.equal(
ssoBeaconBytecodeHash,
"deployed account code doesn't match",
);

const args = await aaFactoryContract.getEncodedBeacon();
const deployedBeaconAddress = new ethers.AbiCoder().encode(["address"], [await fixtures.getBeaconAddress()]);
expect(args, "the beacon address").to.equal(deployedBeaconAddress, "the deployment beacon");

const randomSalt = randomBytes(32);
const standardCreate2Address = utils.create2Address(factoryAddress, bytecodeHash, randomSalt, args) ;
const standardCreate2Address = utils.create2Address(factoryAddress, bytecodeHash, randomSalt, args);

const preDeployAccountCode = await fixtures.wallet.provider.getCode(standardCreate2Address);
expect(preDeployAccountCode , "expected deploy location").to.equal("0x", "nothing deployed here (yet)");
expect(preDeployAccountCode, "expected deploy location").to.equal("0x", "nothing deployed here (yet)");

const deployTx = await aaFactoryContract.deployProxySsoAccount(
randomSalt,
Expand All @@ -69,7 +75,10 @@ describe("Basic tests", function () {
expect(postDeployAccountCode, "expected deploy location").to.not.equal("0x", "deployment didn't match create2!");

expect(proxyAccountAddress, "the proxy account location via logs").to.not.equal(ZeroAddress, "be a valid address");
expect(proxyAccountAddress, "the proxy account location").to.equal(standardCreate2Address, "be what create2 returns");
expect(proxyAccountAddress, "the proxy account location").to.equal(
standardCreate2Address,
"be what create2 returns",
);

const account = SsoAccount__factory.connect(proxyAccountAddress, provider);
assert(await account.k1IsOwner(fixtures.wallet.address));
Expand All @@ -81,16 +90,19 @@ describe("Basic tests", function () {

const balanceBefore = await provider.getBalance(proxyAccountAddress);

const smartAccount = new SmartAccount({
address: proxyAccountAddress,
secret: fixtures.wallet.privateKey,
}, provider);
const smartAccount = new SmartAccount(
{
address: proxyAccountAddress,
secret: fixtures.wallet.privateKey,
},
provider,
);

const value = parseEther("0.01");
const target = Wallet.createRandom().address;

const aaTx = {
...await aaTxTemplate(),
...(await aaTxTemplate()),
to: target,
value,
gasLimit: 300_000n,
Expand All @@ -103,15 +115,21 @@ describe("Basic tests", function () {
const tx = await provider.broadcastTransaction(signedTransaction);
const receipt = await tx.wait();
const fee = receipt.gasUsed * aaTx.gasPrice;
expect(await provider.getBalance(proxyAccountAddress)).to.equal(balanceBefore - value - fee, "invalid final balance");
expect(await provider.getBalance(proxyAccountAddress)).to.equal(
balanceBefore - value - fee,
"invalid final balance",
);
expect(await provider.getBalance(target)).to.equal(value, "invalid final balance");
});

it("should execute a multicall", async () => {
const smartAccount = new SmartAccount({
address: proxyAccountAddress,
secret: fixtures.wallet.privateKey,
}, provider);
const smartAccount = new SmartAccount(
{
address: proxyAccountAddress,
secret: fixtures.wallet.privateKey,
},
provider,
);

const balanceBefore = await provider.getBalance(proxyAccountAddress);
const value = parseEther("0.01");
Expand All @@ -136,7 +154,7 @@ describe("Basic tests", function () {
const account = SsoAccount__factory.connect(proxyAccountAddress, provider);

const aaTx = {
...await aaTxTemplate(),
...(await aaTxTemplate()),
to: proxyAccountAddress,
data: account.interface.encodeFunctionData("batchCall", [calls]),
value: value * 2n,
Expand All @@ -152,7 +170,10 @@ describe("Basic tests", function () {
const receipt = await tx.wait();
const fee = receipt.gasUsed * aaTx.gasPrice;

expect(await provider.getBalance(proxyAccountAddress)).to.equal(balanceBefore - value * 2n - fee, "invalid final own balance");
expect(await provider.getBalance(proxyAccountAddress)).to.equal(
balanceBefore - value * 2n - fee,
"invalid final own balance",
);
expect(await provider.getBalance(target1)).to.equal(value, "invalid final target-1 balance");
expect(await provider.getBalance(target2)).to.equal(value, "invalid final target-2 balance");
});
Expand Down
56 changes: 25 additions & 31 deletions test/PasskeyModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,14 @@ import { getWallet, LOCAL_RICH_WALLETS, RecordedResponse } from "./utils";
* @param buffer Value to decode from base64
* @param to (optional) The decoding to use, in case it's desirable to decode from base64 instead
*/
export function toBuffer(
base64urlString: string,
from: "base64" | "base64url" = "base64url",
): Uint8Array {
export function toBuffer(base64urlString: string, from: "base64" | "base64url" = "base64url"): Uint8Array {
const _buffer = toArrayBuffer(base64urlString, from === "base64url");
return new Uint8Array(_buffer);
}

async function deployValidator(
wallet: Wallet,
): Promise<WebAuthValidator> {
async function deployValidator(wallet: Wallet): Promise<WebAuthValidator> {
const deployer: Deployer = new Deployer(hre, wallet);
const passkeyValidatorArtifact = await deployer.loadArtifact(
"WebAuthValidator",
);
const passkeyValidatorArtifact = await deployer.loadArtifact("WebAuthValidator");

const validator = await deployer.deploy(passkeyValidatorArtifact, []);
return WebAuthValidator__factory.connect(await validator.getAddress(), wallet);
Expand Down Expand Up @@ -118,10 +111,7 @@ export function decodeFirst<Type>(input: Uint8Array): Type {
return first;
}

export function fromBuffer(
buffer: Uint8Array,
to: "base64" | "base64url" = "base64url",
): string {
export function fromBuffer(buffer: Uint8Array, to: "base64" | "base64url" = "base64url"): string {
return fromArrayBuffer(buffer, to === "base64url");
}

Expand Down Expand Up @@ -199,9 +189,7 @@ function shouldRemoveLeadingZero(bytes: Uint8Array): boolean {
* Returns hash digest of the given data, using the given algorithm when provided. Defaults to using
* SHA-256.
*/
export async function toHash(
data: Uint8Array | string,
): Promise<Uint8Array> {
export async function toHash(data: Uint8Array | string): Promise<Uint8Array> {
if (typeof data === "string") {
data = new TextEncoder().encode(data);
}
Expand All @@ -214,7 +202,8 @@ async function rawVerify(
authenticatorData: string,
clientData: string,
b64SignedChallange: string,
publicKeyEs256Bytes: Uint8Array) {
publicKeyEs256Bytes: Uint8Array,
) {
const authDataBuffer = toBuffer(authenticatorData);
const clientDataHash = await toHash(toBuffer(clientData));
const hashedData = await toHash(concat([authDataBuffer, clientDataHash]));
Expand All @@ -232,22 +221,24 @@ describe("Passkey validation", function () {

// 37 bytes
const authenticatorData = "SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MFAAAABQ";
const clientData = "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiZFhPM3ctdWdycS00SkdkZUJLNDFsZFk1V2lNd0ZORDkiLCJvcmlnaW4iOiJodHRwOi8vbG9jYWxob3N0OjUxNzMiLCJjcm9zc09yaWdpbiI6ZmFsc2UsIm90aGVyX2tleXNfY2FuX2JlX2FkZGVkX2hlcmUiOiJkbyBub3QgY29tcGFyZSBjbGllbnREYXRhSlNPTiBhZ2FpbnN0IGEgdGVtcGxhdGUuIFNlZSBodHRwczovL2dvby5nbC95YWJQZXgifQ";
const b64SignedChallange = "MEUCIQCYrSUCR_QUPAhvRNUVfYiJC2JlOKuqf4gx7i129n9QxgIgaY19A9vAAObuTQNs5_V9kZFizwRpUFpiRVW_dglpR2A";
const clientData =
"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiZFhPM3ctdWdycS00SkdkZUJLNDFsZFk1V2lNd0ZORDkiLCJvcmlnaW4iOiJodHRwOi8vbG9jYWxob3N0OjUxNzMiLCJjcm9zc09yaWdpbiI6ZmFsc2UsIm90aGVyX2tleXNfY2FuX2JlX2FkZGVkX2hlcmUiOiJkbyBub3QgY29tcGFyZSBjbGllbnREYXRhSlNPTiBhZ2FpbnN0IGEgdGVtcGxhdGUuIFNlZSBodHRwczovL2dvby5nbC95YWJQZXgifQ";
const b64SignedChallange =
"MEUCIQCYrSUCR_QUPAhvRNUVfYiJC2JlOKuqf4gx7i129n9QxgIgaY19A9vAAObuTQNs5_V9kZFizwRpUFpiRVW_dglpR2A";

// this is a binary object formatted by @simplewebauthn that contains the alg type and public key
const publicKeyEs256Bytes = new Uint8Array([
165, 1, 2, 3, 38, 32, 1, 33, 88, 32, 167, 69,
109, 166, 67, 163, 110, 143, 71, 60, 77, 232, 220, 7,
121, 156, 141, 24, 71, 28, 210, 116, 124, 90, 115, 166,
213, 190, 89, 4, 216, 128, 34, 88, 32, 193, 67, 151,
85, 245, 24, 139, 246, 220, 204, 228, 76, 247, 65, 179,
235, 81, 41, 196, 37, 216, 117, 201, 244, 128, 8, 73,
37, 195, 20, 194, 9,
165, 1, 2, 3, 38, 32, 1, 33, 88, 32, 167, 69, 109, 166, 67, 163, 110, 143, 71, 60, 77, 232, 220, 7, 121, 156, 141,
24, 71, 28, 210, 116, 124, 90, 115, 166, 213, 190, 89, 4, 216, 128, 34, 88, 32, 193, 67, 151, 85, 245, 24, 139,
246, 220, 204, 228, 76, 247, 65, 179, 235, 81, 41, 196, 37, 216, 117, 201, 244, 128, 8, 73, 37, 195, 20, 194, 9,
]);
const verifyMessage = await rawVerify(
passkeyValidator,
authenticatorData, clientData, b64SignedChallange, publicKeyEs256Bytes);
authenticatorData,
clientData,
b64SignedChallange,
publicKeyEs256Bytes,
);

assert(verifyMessage == true, "valid sig");
});
Expand All @@ -260,21 +251,24 @@ describe("Passkey validation", function () {
ethersResponse.authenticatorData,
ethersResponse.clientData,
ethersResponse.b64SignedChallenge,
ethersResponse.passkeyBytes);
ethersResponse.passkeyBytes,
);

assert(verifyMessage == true, "test sig is valid");
});

it("should fail when signature is bad", async function () {
const passkeyValidator = await deployValidator(wallet);

const b64SignedChallenge = "MEUCIQCYrSUCR_QUPAhvRNUVfYiJC2JlOKuqf4gx7i129n9QxgIgaY19A9vAAObuTQNs5_V9kZFizwRpUFpiRVW_dglpR2A";
const b64SignedChallenge =
"MEUCIQCYrSUCR_QUPAhvRNUVfYiJC2JlOKuqf4gx7i129n9QxgIgaY19A9vAAObuTQNs5_V9kZFizwRpUFpiRVW_dglpR2A";
const verifyMessage = await rawVerify(
passkeyValidator,
ethersResponse.authenticatorData,
ethersResponse.clientData,
b64SignedChallenge,
ethersResponse.passkeyBytes);
ethersResponse.passkeyBytes,
);

assert(verifyMessage == false, "bad sig should be false");
});
Expand Down
Loading

0 comments on commit 846c287

Please sign in to comment.