mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-28 00:12:25 +00:00
Merge pull request #1314 from PR0M3TH3AN/codex/add-capabilities-field-to-signers
Add signer `capabilities` and prefer NIP-44 for DM encryption with NIP-04 fallback
This commit is contained in:
4 files changed
+118
-7
No files matched your search
@@ -27,9 +27,17 @@ export async function createNip07Adapter(extension) {
|
||||
signEvent: async () => {
|
||||
throw new Error("NIP-07 extension unavailable.");
|
||||
},
|
||||
requestPermissions: async () => ({ ok: false, error: new Error("extension-unavailable") }),
|
||||
requestPermissions: async () => ({
|
||||
ok: false,
|
||||
error: new Error("extension-unavailable"),
|
||||
}),
|
||||
destroy: async () => {},
|
||||
canSign: () => false,
|
||||
capabilities: {
|
||||
sign: false,
|
||||
nip44: false,
|
||||
nip04: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -92,6 +100,11 @@ export async function createNip07Adapter(extension) {
|
||||
requestPermissions,
|
||||
destroy: async () => {},
|
||||
canSign: () => typeof resolvedExtension.signEvent === "function",
|
||||
capabilities: {
|
||||
sign: typeof resolvedExtension.signEvent === "function",
|
||||
nip44: Boolean(nip44Encrypt || nip44Decrypt),
|
||||
nip04: Boolean(nip04Encrypt || nip04Decrypt),
|
||||
},
|
||||
};
|
||||
|
||||
if (nip04Encrypt) {
|
||||
|
||||
@@ -21,9 +21,17 @@ export async function createNip46Adapter(client) {
|
||||
signEvent: async () => {
|
||||
throw new Error("NIP-46 client unavailable.");
|
||||
},
|
||||
requestPermissions: async () => ({ ok: false, error: new Error("client-unavailable") }),
|
||||
requestPermissions: async () => ({
|
||||
ok: false,
|
||||
error: new Error("client-unavailable"),
|
||||
}),
|
||||
destroy: async () => {},
|
||||
canSign: () => false,
|
||||
capabilities: {
|
||||
sign: false,
|
||||
nip44: false,
|
||||
nip04: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -47,6 +55,13 @@ export async function createNip46Adapter(client) {
|
||||
},
|
||||
canSign: () =>
|
||||
!resolvedClient.destroyed && typeof resolvedClient.signEvent === "function",
|
||||
capabilities: {
|
||||
sign:
|
||||
!resolvedClient.destroyed &&
|
||||
typeof resolvedClient.signEvent === "function",
|
||||
nip44: false,
|
||||
nip04: false,
|
||||
},
|
||||
};
|
||||
|
||||
if (typeof resolvedClient.nip04Encrypt === "function") {
|
||||
@@ -62,5 +77,12 @@ export async function createNip46Adapter(client) {
|
||||
signer.nip44Decrypt = resolvedClient.nip44Decrypt.bind(resolvedClient);
|
||||
}
|
||||
|
||||
signer.capabilities.nip04 = Boolean(
|
||||
signer.nip04Encrypt || signer.nip04Decrypt
|
||||
);
|
||||
signer.capabilities.nip44 = Boolean(
|
||||
signer.nip44Encrypt || signer.nip44Decrypt
|
||||
);
|
||||
|
||||
return signer;
|
||||
}
|
||||
@@ -59,6 +59,11 @@ export async function createNsecAdapter({ privateKey, pubkey } = {}) {
|
||||
requestPermissions: async () => ({ ok: true }),
|
||||
destroy: async () => {},
|
||||
canSign: () => Boolean(normalizedPrivateKey),
|
||||
capabilities: {
|
||||
sign: Boolean(normalizedPrivateKey),
|
||||
nip44: false,
|
||||
nip04: false,
|
||||
},
|
||||
};
|
||||
|
||||
if (typeof cipherClosures.nip04Encrypt === "function") {
|
||||
@@ -74,5 +79,12 @@ export async function createNsecAdapter({ privateKey, pubkey } = {}) {
|
||||
signer.nip44Decrypt = cipherClosures.nip44Decrypt;
|
||||
}
|
||||
|
||||
signer.capabilities.nip04 = Boolean(
|
||||
signer.nip04Encrypt || signer.nip04Decrypt
|
||||
);
|
||||
signer.capabilities.nip44 = Boolean(
|
||||
signer.nip44Encrypt || signer.nip44Decrypt
|
||||
);
|
||||
|
||||
return signer;
|
||||
}
|
||||
+69
-5
@@ -255,6 +255,40 @@ function attachNipMethodAliases(signer) {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveSignerCapabilities(signer) {
|
||||
const fallback = {
|
||||
sign: false,
|
||||
nip44: false,
|
||||
nip04: false,
|
||||
};
|
||||
|
||||
if (!signer || typeof signer !== "object") {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
const capabilities =
|
||||
signer.capabilities && typeof signer.capabilities === "object"
|
||||
? signer.capabilities
|
||||
: {};
|
||||
|
||||
return {
|
||||
sign:
|
||||
typeof capabilities.sign === "boolean"
|
||||
? capabilities.sign
|
||||
: typeof signer.signEvent === "function",
|
||||
nip44:
|
||||
typeof capabilities.nip44 === "boolean"
|
||||
? capabilities.nip44
|
||||
: typeof signer.nip44Encrypt === "function" ||
|
||||
typeof signer.nip44Decrypt === "function",
|
||||
nip04:
|
||||
typeof capabilities.nip04 === "boolean"
|
||||
? capabilities.nip04
|
||||
: typeof signer.nip04Encrypt === "function" ||
|
||||
typeof signer.nip04Decrypt === "function",
|
||||
};
|
||||
}
|
||||
|
||||
function hydrateExtensionSignerCapabilities(signer) {
|
||||
if (!signer || typeof signer !== "object" || signer.type !== "extension") {
|
||||
return;
|
||||
@@ -288,6 +322,7 @@ function setActiveSigner(signer) {
|
||||
|
||||
hydrateExtensionSignerCapabilities(signer);
|
||||
attachNipMethodAliases(signer);
|
||||
signer.capabilities = resolveSignerCapabilities(signer);
|
||||
|
||||
const pubkey =
|
||||
typeof signer.pubkey === "string" && signer.pubkey.trim()
|
||||
@@ -3966,7 +4001,11 @@ export class NostrClient {
|
||||
}
|
||||
|
||||
if (activeSigner) {
|
||||
if (typeof activeSigner.nip44Decrypt === "function") {
|
||||
const capabilities = resolveSignerCapabilities(activeSigner);
|
||||
if (
|
||||
capabilities.nip44 &&
|
||||
typeof activeSigner.nip44Decrypt === "function"
|
||||
) {
|
||||
addCandidate(
|
||||
"nip44",
|
||||
activeSigner.nip44Decrypt.bind(activeSigner),
|
||||
@@ -3977,7 +4016,10 @@ export class NostrClient {
|
||||
},
|
||||
);
|
||||
}
|
||||
if (typeof activeSigner.nip04Decrypt === "function") {
|
||||
if (
|
||||
capabilities.nip04 &&
|
||||
typeof activeSigner.nip04Decrypt === "function"
|
||||
) {
|
||||
addCandidate(
|
||||
"nip04",
|
||||
activeSigner.nip04Decrypt.bind(activeSigner),
|
||||
@@ -4337,13 +4379,21 @@ export class NostrClient {
|
||||
}
|
||||
|
||||
const encryptionCandidates = [];
|
||||
if (typeof signer.nip44Encrypt === "function") {
|
||||
const signerCapabilities = resolveSignerCapabilities(signer);
|
||||
const allowNip04Fallback = signerCapabilities.nip04 === true;
|
||||
if (
|
||||
signerCapabilities.nip44 &&
|
||||
typeof signer.nip44Encrypt === "function"
|
||||
) {
|
||||
encryptionCandidates.push({
|
||||
scheme: "nip44",
|
||||
encrypt: signer.nip44Encrypt,
|
||||
});
|
||||
}
|
||||
if (typeof signer.nip04Encrypt === "function") {
|
||||
if (
|
||||
signerCapabilities.nip04 &&
|
||||
typeof signer.nip04Encrypt === "function"
|
||||
) {
|
||||
encryptionCandidates.push({
|
||||
scheme: "nip04",
|
||||
encrypt: signer.nip04Encrypt,
|
||||
@@ -4375,7 +4425,21 @@ export class NostrClient {
|
||||
typeof sessionActor.privateKey === "string" &&
|
||||
sessionActor.privateKey;
|
||||
|
||||
if (sessionMatchesActor) {
|
||||
const canFallbackWithSession = sessionMatchesActor && allowNip04Fallback;
|
||||
|
||||
if (!encryptionCandidates.length && !canFallbackWithSession) {
|
||||
const error = new Error(
|
||||
"Your signer does not support NIP-44 or NIP-04 encryption.",
|
||||
);
|
||||
userLogger.warn("[nostr] Encryption unsupported for DM send.", error);
|
||||
return {
|
||||
ok: false,
|
||||
error: "encryption-unsupported",
|
||||
details: error,
|
||||
};
|
||||
}
|
||||
|
||||
if (canFallbackWithSession) {
|
||||
try {
|
||||
const tools = (await ensureNostrTools()) || getCachedNostrTools();
|
||||
if (tools?.nip04 && typeof tools.nip04.encrypt === "function") {
|
||||
|
||||
Reference in new issue
Block a user