Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions apps/noter/package/feature/auth/api/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import { router, procedure } from "@/shared/lib/trpc/init";
import { TRPCError } from "@trpc/server";
import { verifyPersonalMessageSignature } from "@mysten/sui/verify";
import { uuidv7 } from "uuidv7";
import {
initiateLoginInput,
Expand Down Expand Up @@ -247,9 +248,18 @@ export const authRouter = router({
const { walletType, address, signature, message } = input;

try {
// TODO: Verify signature on server-side
// For now, we trust the client signature
// In production, use @mysten/sui.js to verify the signature
// Verify the wallet signature before creating a session
const signerAddress = await verifyPersonalMessageSignature(
new TextEncoder().encode(message),
signature,
).catch(() => {
throw new TRPCError({ code: "UNAUTHORIZED", message: "Invalid signature" });
});

if (signerAddress.toSuiAddress() !== address) {
throw new TRPCError({ code: "UNAUTHORIZED", message: "Signature does not match address" });
}

// Create or update user via service
const user = await authService.upsertWalletUser(ctx.db, {
address,
Expand Down
9 changes: 5 additions & 4 deletions apps/noter/package/feature/auth/lib/wallet-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export async function signMessage(

// Sign message using sui:signPersonalMessage feature
const signFeature = wallet.features['sui:signPersonalMessage'] as {
signPersonalMessage: (params: { message: Uint8Array; account: any }) => Promise<{ signature: Uint8Array }>
signPersonalMessage: (params: { message: Uint8Array; account: any }) => Promise<{ signature: string | Uint8Array }>
} | undefined;

if (!signFeature) {
Expand All @@ -144,9 +144,10 @@ export async function signMessage(
account: walletAccount,
});


// Convert Uint8Array signature to base64
const signatureBase64 = Buffer.from(result.signature).toString("base64");
// Wallet standard returns signature as a base64 string; older versions return Uint8Array
const signatureBase64 = typeof result.signature === 'string'
? result.signature
: Buffer.from(result.signature).toString("base64");

return {
signature: signatureBase64,
Expand Down