mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-07-26 14:57:45 +02:00
feat: Add NIP-44 validation and better gift wrap error diagnostics
- Validate signer has NIP-44 support before attempting decryption - NIP-59 gift wraps REQUIRE NIP-44 encryption - Fail early with helpful message if signer lacks nip44 - Suggests using compatible extensions (Alby, nos2x-fox, etc.) - Add specific error messages for common decryption failures - JSON parse errors → "Decrypted content is not valid JSON" - Missing event properties → "Seal is missing required properties" - Author mismatch → "Seal and rumor authors don't match" - Includes event ID in error messages for debugging - Add test for signer without NIP-44 support This helps diagnose the two production errors: 1. "Unexpected token 'T', "This is to"..." → JSON parse failure 2. "can't serialize event" → malformed seal event Users will now see clear error messages explaining the issue (incompatible extension, malformed gift wrap, etc.)
This commit is contained in:
@@ -53,6 +53,32 @@ describe("unwrapAndUnseal", () => {
|
||||
});
|
||||
|
||||
describe("validation", () => {
|
||||
it("should reject signer without NIP-44 support", async () => {
|
||||
const giftWrap: NostrEvent = {
|
||||
id: "test-id",
|
||||
pubkey: "ephemeral-key",
|
||||
created_at: 1234567890,
|
||||
kind: 1059,
|
||||
tags: [],
|
||||
content: "encrypted-content",
|
||||
sig: "signature",
|
||||
};
|
||||
|
||||
// Signer without nip44
|
||||
const signerWithoutNip44: ISigner = {
|
||||
getPublicKey: vi.fn().mockResolvedValue("mock-pubkey"),
|
||||
signEvent: vi.fn(),
|
||||
};
|
||||
|
||||
await expect(
|
||||
unwrapAndUnseal(giftWrap, signerWithoutNip44),
|
||||
).rejects.toThrow(GiftWrapError);
|
||||
|
||||
await expect(
|
||||
unwrapAndUnseal(giftWrap, signerWithoutNip44),
|
||||
).rejects.toThrow("does not support NIP-44");
|
||||
});
|
||||
|
||||
it("should reject non-1059 events", async () => {
|
||||
const invalidGiftWrap: NostrEvent = {
|
||||
id: "test-id",
|
||||
|
||||
@@ -89,6 +89,16 @@ export async function unwrapAndUnseal(
|
||||
throw new GiftWrapError("Gift wrap content is empty", "MISSING_CONTENT");
|
||||
}
|
||||
|
||||
// CRITICAL: Validate signer has NIP-44 support
|
||||
// NIP-59 gift wraps REQUIRE NIP-44 encryption
|
||||
if (!signer.nip44) {
|
||||
throw new GiftWrapError(
|
||||
"Signer does not support NIP-44 encryption (required for NIP-59 gift wraps). " +
|
||||
"Please use a browser extension that supports NIP-44 (e.g., Alby, nos2x-fox, Nostr-Connect).",
|
||||
"NO_SIGNER",
|
||||
);
|
||||
}
|
||||
|
||||
// CRITICAL: Add to event store before unlocking
|
||||
// Applesauce requires the event to be in the store for caching to work
|
||||
// We wrap in try-catch because the event might not be valid for the event store
|
||||
@@ -147,6 +157,34 @@ export async function unwrapAndUnseal(
|
||||
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
|
||||
// Provide helpful error messages for common issues
|
||||
if (message.includes("Unexpected token") || message.includes("JSON")) {
|
||||
throw new GiftWrapError(
|
||||
`Decrypted content is not valid JSON. This gift wrap may be malformed or use incompatible encryption. ` +
|
||||
`Event ID: ${giftWrap.id.slice(0, 16)}... (${message})`,
|
||||
"INVALID_SEAL",
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
message.includes("can't serialize") ||
|
||||
message.includes("wrong or missing properties")
|
||||
) {
|
||||
throw new GiftWrapError(
|
||||
`Decrypted seal is missing required event properties. This gift wrap may be malformed. ` +
|
||||
`Event ID: ${giftWrap.id.slice(0, 16)}... (${message})`,
|
||||
"INVALID_SEAL",
|
||||
);
|
||||
}
|
||||
|
||||
if (message.includes("Seal author does not match rumor author")) {
|
||||
throw new GiftWrapError(
|
||||
`Seal and rumor authors don't match - possible tampering. ` +
|
||||
`Event ID: ${giftWrap.id.slice(0, 16)}...`,
|
||||
"INVALID_SEAL",
|
||||
);
|
||||
}
|
||||
|
||||
// Map decryption errors
|
||||
if (
|
||||
message.includes("decrypt") ||
|
||||
|
||||
Reference in New Issue
Block a user