mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Fix NWC encryption fallback handling
This commit is contained in:
1 parent
9d57a43c98
commit
aa4e86758a
2 files changed
+99
-19
No files matched your search
+29
-19
@@ -341,16 +341,21 @@ function createNip44Encryption(context) {
|
||||
|
||||
function getWalletSupportedEncryption(infoEvent) {
|
||||
if (!infoEvent || !Array.isArray(infoEvent.tags)) {
|
||||
return ["nip04"];
|
||||
return { schemes: [], explicit: false };
|
||||
}
|
||||
|
||||
const tag = infoEvent.tags.find((entry) => Array.isArray(entry) && entry[0] === "encryption");
|
||||
if (!tag || typeof tag[1] !== "string") {
|
||||
return ["nip04"];
|
||||
return { schemes: [], explicit: false };
|
||||
}
|
||||
|
||||
const values = normalizeSpaceSeparatedValues(tag[1]);
|
||||
return values.length ? values : ["nip04"];
|
||||
if (!values.length) {
|
||||
return { schemes: [], explicit: false };
|
||||
}
|
||||
|
||||
const schemes = Array.from(new Set(values));
|
||||
return { schemes, explicit: true };
|
||||
}
|
||||
|
||||
function getEncryptionCandidates(context) {
|
||||
@@ -487,31 +492,35 @@ async function ensureEncryption(context) {
|
||||
}
|
||||
}
|
||||
|
||||
const walletSchemes = getWalletSupportedEncryption(infoEvent);
|
||||
const { schemes: walletSchemes } = getWalletSupportedEncryption(infoEvent);
|
||||
const candidates = getEncryptionCandidates(context).filter((candidate) => {
|
||||
return !state.unsupported.has(candidate.scheme);
|
||||
});
|
||||
|
||||
for (const candidate of candidates) {
|
||||
if (walletSchemes.includes(candidate.scheme)) {
|
||||
context.encryption = candidate;
|
||||
return candidate;
|
||||
}
|
||||
const compatibleCandidates = walletSchemes.length
|
||||
? candidates.filter((candidate) => walletSchemes.includes(candidate.scheme))
|
||||
: candidates;
|
||||
|
||||
if (compatibleCandidates.length) {
|
||||
const selected = compatibleCandidates[0];
|
||||
context.encryption = selected;
|
||||
return selected;
|
||||
}
|
||||
|
||||
const fallback = candidates.find((candidate) => candidate.scheme === "nip04");
|
||||
if (fallback) {
|
||||
console.warn(
|
||||
"[nwcClient] Falling back to nip04 encryption despite wallet not advertising support."
|
||||
);
|
||||
context.encryption = fallback;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
if (walletSchemes.includes("nip04")) {
|
||||
if (
|
||||
walletSchemes.includes("nip04") &&
|
||||
!candidates.some((candidate) => candidate.scheme === "nip04")
|
||||
) {
|
||||
throw new Error("NostrTools.nip04.encrypt is not available.");
|
||||
}
|
||||
|
||||
if (walletSchemes.length) {
|
||||
const message = `Wallet advertises unsupported encryption schemes: ${walletSchemes.join(", ")}.`;
|
||||
const error = new Error(message);
|
||||
error.code = "UNSUPPORTED_ENCRYPTION";
|
||||
throw error;
|
||||
}
|
||||
|
||||
throw new Error("No compatible wallet encryption scheme available.");
|
||||
}
|
||||
|
||||
@@ -983,4 +992,5 @@ export const __TESTING__ = Object.freeze({
|
||||
ensureActiveState,
|
||||
buildPayInvoiceParams,
|
||||
getActiveState: () => activeState,
|
||||
ensureEncryptionForContext: ensureEncryption,
|
||||
});
|
||||
@@ -48,6 +48,21 @@ await (async () => {
|
||||
getPublicKey() {
|
||||
return "c".repeat(64);
|
||||
},
|
||||
nip44: {
|
||||
v2: {
|
||||
async encrypt(plaintext, key) {
|
||||
return `nip44:${key}:${plaintext}`;
|
||||
},
|
||||
async decrypt(ciphertext, key) {
|
||||
return `nip44:${key}:${ciphertext}`;
|
||||
},
|
||||
utils: {
|
||||
getConversationKey(secretBytes, pubkey) {
|
||||
return `key-${pubkey}-${secretBytes.length}`;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const walletPubkey = "b".repeat(64);
|
||||
@@ -75,6 +90,61 @@ await (async () => {
|
||||
assert.equal(reparsed.secretKey, secretKey);
|
||||
assert.equal(reparsed.queryParams.lud16, lud16);
|
||||
|
||||
context.infoEvent = {
|
||||
kind: 13194,
|
||||
tags: [["encryption", "nip44_v2"]],
|
||||
};
|
||||
|
||||
const encryption = await __TESTING__.ensureEncryptionForContext(context);
|
||||
assert.equal(encryption.scheme, "nip44_v2");
|
||||
const encrypted = await encryption.encrypt("payload");
|
||||
assert.match(encrypted, /^nip44:key-b{64}-/);
|
||||
|
||||
resetWalletClient();
|
||||
})();
|
||||
|
||||
await (async () => {
|
||||
resetWalletClient();
|
||||
|
||||
window.NostrTools = {
|
||||
getPublicKey() {
|
||||
return "c".repeat(64);
|
||||
},
|
||||
nip04: {
|
||||
async encrypt() {
|
||||
return "nip04";
|
||||
},
|
||||
async decrypt() {
|
||||
return "nip04";
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const walletPubkey = "b".repeat(64);
|
||||
const secretKey = "a".repeat(64);
|
||||
const relays = ["wss://relay.one.example"];
|
||||
const uri =
|
||||
`nostr+walletconnect://${walletPubkey}` +
|
||||
`?relay=${encodeURIComponent(relays[0])}` +
|
||||
`&secret=${secretKey}`;
|
||||
|
||||
const context = ensureActiveState({ nwcUri: uri });
|
||||
context.infoEvent = {
|
||||
kind: 13194,
|
||||
tags: [["encryption", "nip44_v2"]],
|
||||
};
|
||||
|
||||
await assert.rejects(
|
||||
() => __TESTING__.ensureEncryptionForContext(context),
|
||||
(error) => {
|
||||
assert.match(
|
||||
error?.message || "",
|
||||
/Wallet advertises unsupported encryption schemes: nip44_v2\./
|
||||
);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
resetWalletClient();
|
||||
})();
|
||||
|
||||
|
||||
Reference in new issue
Block a user