Skip to content

Commit 9701078

Browse files
committed
fix: manual testing works
needs some better page pathing
1 parent 48960d9 commit 9701078

File tree

9 files changed

+123
-15
lines changed

9 files changed

+123
-15
lines changed

packages/auth-server/components/account-recovery/passkey-generation-flow/Step3ConfirmNow.vue

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
<script setup lang="ts">
7979
import { useAppKitAccount } from "@reown/appkit/vue";
8080
import { type Address, isAddressEqual } from "viem";
81+
import { getPasskeySignatureFromPublicKeyBytes } from "zksync-sso-4337/client/passkey";
8182
8283
import type { RegisterNewPasskeyReturnType } from "~/composables/usePasskeyRegister";
8384
@@ -141,11 +142,17 @@ const handleConfirmRecovery = async () => {
141142
client = await getWalletClient({ chainId: defaultChain.id });
142143
}
143144
145+
// Convert {x, y} public key format to Uint8Array (COSE format)
146+
const credentialPublicKeyBytes = getPasskeySignatureFromPublicKeyBytes([
147+
props.newPasskey.credentialPublicKey.x,
148+
props.newPasskey.credentialPublicKey.y,
149+
]);
150+
144151
await initRecovery({
145152
client,
146153
accountToRecover: props.accountAddress,
147-
credentialPublicKey: props.newPasskey.credentialPublicKey,
148-
accountId: props.newPasskey.credentialId,
154+
credentialPublicKey: credentialPublicKeyBytes,
155+
credentialId: props.newPasskey.credentialIdBase64url,
149156
});
150157
confirmGuardianErrorMessage.value = null;
151158
emit("next");

packages/auth-server/composables/usePasskeyRegister.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { createWebAuthnCredential } from "zksync-sso-4337/client";
44
// Return type matching what components expect
55
export type RegisterNewPasskeyReturnType = {
66
credentialId: Hex;
7+
credentialIdBase64url: string;
78
credentialPublicKey: { x: Hex; y: Hex };
89
};
910

@@ -25,6 +26,7 @@ export const usePasskeyRegister = () => {
2526

2627
return {
2728
credentialId: result.credentialId,
29+
credentialIdBase64url: result.credentialIdBase64url,
2830
credentialPublicKey: result.publicKey,
2931
};
3032
});

packages/auth-server/composables/useRecoveryGuardian.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Account, Address, Chain, Hex, Transport, WalletClient } from "viem";
2-
import { encodeAbiParameters, keccak256, parseAbiParameters, toHex } from "viem";
2+
import { encodeAbiParameters, keccak256, pad, parseAbiParameters, toHex } from "viem";
33
import { waitForTransactionReceipt } from "viem/actions";
44
import { base64urlToUint8Array, getPublicKeyBytesFromPasskeySignature } from "zksync-sso-4337/utils";
55

packages/auth-server/pages/recovery/google/index.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
</template>
1313

1414
<script setup lang="ts">
15-
const { enabled } = useOidcConfig();
15+
// const { enabled } = useOidcConfig();
16+
const enabled = false;
1617
1718
if (!enabled) {
1819
await navigateTo("/");

packages/auth-server/pages/recovery/index.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,6 @@
4646
</template>
4747

4848
<script setup lang="ts">
49-
const { enabled: oidcEnabled } = useOidcConfig();
49+
// const { enabled: oidcEnabled } = useOidcConfig();
50+
const oidcEnabled = false;
5051
</script>

packages/auth-server/stores/local-node.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
"rpcUrl": "http://localhost:8545",
33
"chainId": 1337,
44
"deployer": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
5-
"eoaValidator": "0x7a313d9Ff9797d7b0F299A9c7F6d325ED4e175C7",
6-
"sessionValidator": "0xBf344DA0c5847266B9D7a8fcFcbb9449fc804B6B",
7-
"webauthnValidator": "0x2C94D758140037d36c139409c2380Bd4AC3f082b",
8-
"guardianExecutor": "0x7fB73973d71dA68b5B7b9D29AEc7d278A16aA661",
9-
"accountImplementation": "0x48B16b015F0495a637A18B133D18156524CF10cC",
10-
"beacon": "0x1edB03d812A15782143E05ac212CC74baD076a43",
11-
"factory": "0x3Cb6Ce4F4733420Ca17dAaC6B11c74a392d7EB10",
12-
"testPaymaster": "0x21efE34a462B1c2af645D515738480A3fE0F483b",
13-
"mockPaymaster": "0x21efE34a462B1c2af645D515738480A3fE0F483b",
5+
"eoaValidator": "0x6cFA08b105a8674B3249CaA3B4405783A0D8a58B",
6+
"sessionValidator": "0x7079ade5d4C71aE7868E6AC8553148FfC3D8d660",
7+
"webauthnValidator": "0xE619369f26285FEd402bd0c3526aEb1faf2BE2C0",
8+
"guardianExecutor": "0x85ed36BD17265a4eb2f6d87FAd3E6277066986f0",
9+
"accountImplementation": "0xE604bd7C1d6dde44Ebe434d3BE6FD5fD9145C860",
10+
"beacon": "0xb3b3496CC339d80b2182a3985FeF5EBE60bc896C",
11+
"factory": "0x197072f17a5e1A35C1909999e6f3cFEDe5A42BB8",
12+
"testPaymaster": "0xfE88Fdf39d345eD27a600852962A51f9EC6Ee3f4",
13+
"mockPaymaster": "0xfE88Fdf39d345eD27a600852962A51f9EC6Ee3f4",
1414
"entryPoint": "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
1515
"bundlerUrl": "http://localhost:4337"
1616
}

packages/sdk-4337/src/client/passkey/cose.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Buffer } from "buffer";
2+
import type { Hex } from "viem";
23

34
enum COSEKEYS {
45
kty = 1, // Key Type
@@ -80,6 +81,71 @@ function decodeValue(buffer: Buffer, offset: number): [number | Buffer, number]
8081
}
8182
}
8283

84+
// Encode an integer in CBOR format
85+
function encodeInt(int: number): Buffer {
86+
if (int >= 0 && int <= 23) {
87+
// Small positive integer (0–23)
88+
return Buffer.from([int]);
89+
} else if (int >= 24 && int <= 255) {
90+
// 1-byte positive integer
91+
return Buffer.from([0x18, int]);
92+
} else if (int >= 256 && int <= 65535) {
93+
// 2-byte positive integer
94+
const buf = Buffer.alloc(3);
95+
buf[0] = 0x19;
96+
buf.writeUInt16BE(int, 1);
97+
return buf;
98+
} else if (int < 0 && int >= -24) {
99+
// Small negative integer (-1 to -24)
100+
return Buffer.from([0x20 - (int + 1)]);
101+
} else if (int < -24 && int >= -256) {
102+
// 1-byte negative integer
103+
return Buffer.from([0x38, -int - 1]);
104+
} else if (int < -256 && int >= -65536) {
105+
// 2-byte negative integer
106+
const buf = Buffer.alloc(3);
107+
buf[0] = 0x39;
108+
buf.writeUInt16BE(-int - 1, 1);
109+
return buf;
110+
} else {
111+
throw new Error("Unsupported integer range");
112+
}
113+
}
114+
115+
// Encode a byte array in CBOR format
116+
function encodeBytes(bytes: Buffer): Buffer {
117+
if (bytes.length <= 23) {
118+
return Buffer.concat([Buffer.from([0x40 + bytes.length]), bytes]); // Byte array with small length
119+
} else if (bytes.length < 256) {
120+
return Buffer.concat([Buffer.from([0x58, bytes.length]), bytes]); // Byte array with 1-byte length prefix
121+
} else {
122+
throw new Error("Unsupported byte array length");
123+
}
124+
}
125+
126+
// Encode a map in CBOR format
127+
function encodeMap(map: COSEPublicKeyMap): Buffer {
128+
const encodedItems: Buffer[] = [];
129+
130+
// CBOR map header, assuming the map size fits within small integer encoding
131+
const mapHeader = 0xA0 | map.size;
132+
encodedItems.push(Buffer.from([mapHeader]));
133+
134+
map.forEach((value, key) => {
135+
// Encode the key
136+
encodedItems.push(encodeInt(key));
137+
138+
// Encode the value based on its type (Buffer or number)
139+
if (Buffer.isBuffer(value)) {
140+
encodedItems.push(encodeBytes(value));
141+
} else {
142+
encodedItems.push(encodeInt(value));
143+
}
144+
});
145+
146+
return Buffer.concat(encodedItems);
147+
}
148+
83149
/**
84150
* Decodes a CBOR-encoded COSE public key (from WebAuthn credential) and returns the x,y coordinates.
85151
* @param publicPasskey - CBOR-encoded COSE public key as Uint8Array
@@ -92,3 +158,25 @@ export const getPublicKeyBytesFromPasskeySignature = (publicPasskey: Uint8Array)
92158

93159
return [Buffer.from(x), Buffer.from(y)];
94160
};
161+
162+
/**
163+
* Encodes x,y hex coordinates into a CBOR-encoded COSE public key format.
164+
* This is the inverse of getPublicKeyBytesFromPasskeySignature.
165+
* @param coordinates - Tuple of [x, y] coordinates as hex strings
166+
* @returns CBOR-encoded COSE public key as Uint8Array
167+
*/
168+
export const getPasskeySignatureFromPublicKeyBytes = (coordinates: readonly [Hex, Hex]): Uint8Array => {
169+
const [xHex, yHex] = coordinates;
170+
const x = Buffer.from(xHex.slice(2), "hex");
171+
const y = Buffer.from(yHex.slice(2), "hex");
172+
173+
const cosePublicKey: COSEPublicKeyMap = new Map();
174+
cosePublicKey.set(COSEKEYS.kty, 2); // Type 2 for EC keys
175+
cosePublicKey.set(COSEKEYS.alg, -7); // -7 for ES256 algorithm
176+
cosePublicKey.set(COSEKEYS.crv, 1); // Curve ID (1 for P-256)
177+
cosePublicKey.set(COSEKEYS.x, x);
178+
cosePublicKey.set(COSEKEYS.y, y);
179+
180+
const encodedPublicKey = encodeMap(cosePublicKey);
181+
return new Uint8Array(encodedPublicKey);
182+
};

packages/sdk-4337/src/client/passkey/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ export {
88
type PasskeyClientActions,
99
passkeyClientActions,
1010
} from "./client-actions.js";
11-
export { getPublicKeyBytesFromPasskeySignature } from "./cose.js";
11+
export {
12+
getPasskeySignatureFromPublicKeyBytes,
13+
getPublicKeyBytesFromPasskeySignature,
14+
} from "./cose.js";
1215
export {
1316
base64urlToUint8Array,
1417
type CreateCredentialOptions,

packages/sdk-4337/src/client/passkey/webauthn.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,11 @@ export interface WebAuthnCredential {
246246
*/
247247
credentialId: Hex;
248248

249+
/**
250+
* Raw credential ID (base64url encoded string)
251+
*/
252+
credentialIdBase64url: string;
253+
249254
publicKey: {
250255
/**
251256
* X coordinate of P-256 public key (32 bytes, hex string with 0x prefix)
@@ -391,6 +396,7 @@ export async function createWebAuthnCredential(options: CreateCredentialOptions)
391396

392397
return {
393398
credentialId: bytesToHex(credId),
399+
credentialIdBase64url: credential.id,
394400
publicKey: {
395401
x: bytesToHex(xBuffer),
396402
y: bytesToHex(yBuffer),

0 commit comments

Comments
 (0)