Skip to content

Commit

Permalink
Revert "Revert "revert MUD ID""
Browse files Browse the repository at this point in the history
This reverts commit f785166.
  • Loading branch information
holic committed Nov 9, 2024
1 parent 56c3f96 commit 3c83157
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 126 deletions.
34 changes: 16 additions & 18 deletions packages/entrykit/src/passkey/createPasskey.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
import { cache } from "./cache";
import { createBridge, PasskeyCredential } from "@latticexyz/id/internal";
import { MUDChain } from "@latticexyz/common/chains";
import { PasskeyCredential } from "@latticexyz/id/internal";
import { createCredential } from "webauthn-p256";

export async function createPasskey(chain: MUDChain): Promise<PasskeyCredential> {
const bridge = await createBridge({ url: chain.mudIdUrl, message: "Creating account…" });
try {
const credential = await bridge.request("create");
console.log("created passkey", credential);
export async function createPasskey(): Promise<PasskeyCredential> {
const credential = await createCredential({ name: "MUD Account" });
console.log("created passkey", credential);

cache.setState((state) => ({
activeCredential: credential.credentialId,
publicKeys: {
...state.publicKeys,
[credential.credentialId]: credential.publicKey,
},
}));
cache.setState((state) => ({
activeCredential: credential.id,
publicKeys: {
...state.publicKeys,
[credential.id]: credential.publicKey,
},
}));

return credential;
} finally {
bridge.close();
}
return {
credentialId: credential.id,
publicKey: credential.publicKey,
};
}
5 changes: 2 additions & 3 deletions packages/entrykit/src/passkey/getAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { Chain, Client, Transport } from "viem";
import { cache } from "./cache";
import { P256Credential } from "webauthn-p256";
import { toCoinbaseSmartAccount, ToCoinbaseSmartAccountReturnType } from "@latticexyz/common/accounts";
import { toWebAuthnAccount } from "./toWebAuthnAccount";
import { MUDChain } from "@latticexyz/common/chains";
import { toWebAuthnAccount } from "viem/account-abstraction";

export async function getAccount(
client: Client<Transport, Chain>,
Expand All @@ -17,7 +16,7 @@ export async function getAccount(
throw new Error("No public key found for passkey credential.");
}

const passkey = toWebAuthnAccount({ credential: { id, publicKey }, bridgeUrl: (client.chain as MUDChain).mudIdUrl });
const passkey = toWebAuthnAccount({ credential: { id, publicKey } });
const owners = [passkey];

return await toCoinbaseSmartAccount({ client, owners });
Expand Down
6 changes: 3 additions & 3 deletions packages/entrykit/src/passkey/passkeyConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ export function passkeyConnector({ chainId }: PasskeyConnectorOptions): CreatePa
// supportsSimulation: true,

async createPasskey() {
const { credentialId } = await createPasskey(chain);
const { credentialId } = await createPasskey();
const account = await getAccount(client, credentialId);
this.onAccountsChanged([account.address]);
this.onConnect?.({ chainId: numberToHex(chainId) });
},
async reusePasskey() {
const { credentialId } = await reusePasskey(chain);
const { credentialId } = await reusePasskey();
const account = await getAccount(client, credentialId);
this.onAccountsChanged([account.address]);
this.onConnect?.({ chainId: numberToHex(chainId) });
Expand All @@ -103,7 +103,7 @@ export function passkeyConnector({ chainId }: PasskeyConnectorOptions): CreatePa
// attempt to reuse credential if this is called directly
// TODO: move this into wallet so it's only triggered via rainbowkit?
if (!cache.getState().activeCredential && !params?.isReconnecting) {
await reusePasskey(chain);
await reusePasskey();
}

const accounts = await this.getAccounts();
Expand Down
95 changes: 47 additions & 48 deletions packages/entrykit/src/passkey/reusePasskey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,53 @@ import { bytesToHex, hashMessage } from "viem";
import { cache } from "./cache";
import { getMessageHash } from "./getMessageHash";
import { findPublicKey } from "./findPublicKey";
import { PasskeyCredential, createBridge } from "@latticexyz/id/internal";
import { MUDChain } from "@latticexyz/common/chains";

export async function reusePasskey(chain: MUDChain): Promise<PasskeyCredential> {
const bridge = await createBridge({ url: chain.mudIdUrl, message: "Signing in…" });
try {
const challenge = hashMessage(bytesToHex(crypto.getRandomValues(new Uint8Array(256))));
const { credentialId, signature, metadata } = await bridge.request("sign", { challenge });

const publicKey = await (async () => {
const cachedPublicKey = cache.getState().publicKeys[credentialId];
if (cachedPublicKey) return cachedPublicKey;

// TODO: look up account/public key by credential ID once we store it onchain

const messageHash = await getMessageHash(metadata);
const challenge2 = hashMessage(signature);
const signature2 = await bridge.request("sign", { credentialId, challenge: challenge2 });
if (signature2.credentialId !== credentialId) {
throw new Error("wrong credential");
}

const publicKey = findPublicKey([
{ messageHash, signatureHex: signature },
{ messageHash: await getMessageHash(signature2.metadata), signatureHex: signature2.signature },
]);
if (!publicKey) {
throw new Error("recovery failed");
}

cache.setState((state) => ({
publicKeys: {
...state.publicKeys,
[credentialId]: publicKey,
},
}));

return publicKey;
})();

console.log("recovered passkey", credentialId, publicKey);

cache.setState(() => ({
activeCredential: credentialId,
import { PasskeyCredential } from "@latticexyz/id/internal";
import { sign } from "webauthn-p256";

export async function reusePasskey(): Promise<PasskeyCredential> {
const challenge = hashMessage(bytesToHex(crypto.getRandomValues(new Uint8Array(256))));
const {
raw: { id: credentialId },
signature,
webauthn: metadata,
} = await sign({ hash: challenge });

const publicKey = await (async () => {
const cachedPublicKey = cache.getState().publicKeys[credentialId];
if (cachedPublicKey) return cachedPublicKey;

// TODO: look up account/public key by credential ID once we store it onchain

const messageHash = await getMessageHash(metadata);
const challenge2 = hashMessage(signature);
const signature2 = await sign({ credentialId, hash: challenge2 });
if (signature2.raw.id !== credentialId) {
throw new Error("wrong credential");
}

const publicKey = findPublicKey([
{ messageHash, signatureHex: signature },
{ messageHash: await getMessageHash(signature2.webauthn), signatureHex: signature2.signature },
]);
if (!publicKey) {
throw new Error("recovery failed");
}

cache.setState((state) => ({
publicKeys: {
...state.publicKeys,
[credentialId]: publicKey,
},
}));

return { credentialId, publicKey };
} finally {
bridge.close();
}
return publicKey;
})();

console.log("recovered passkey", credentialId, publicKey);

cache.setState(() => ({
activeCredential: credentialId,
}));

return { credentialId, publicKey };
}
52 changes: 0 additions & 52 deletions packages/entrykit/src/passkey/toWebAuthnAccount.ts

This file was deleted.

6 changes: 4 additions & 2 deletions packages/id/src/rpc/onPostMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ async function onPortMessage(event: MessageEvent<RequestData>) {
reply(port, {
id: event.data.id,
method: event.data.method,
// TODO: send the whole error object back, should be fine
error: {
message: String(error),
message: error instanceof Error ? `${error.message}\n\n${error.stack}` : String(error),
},
});
}
Expand All @@ -60,8 +61,9 @@ async function onPortMessage(event: MessageEvent<RequestData>) {
reply(port, {
id: event.data.id,
method: event.data.method,
// TODO: send the whole error object back, should be fine
error: {
message: String(error),
message: error instanceof Error ? `${error.message}\n\n${error.stack}` : String(error),
},
});
}
Expand Down

0 comments on commit 3c83157

Please sign in to comment.