Files
nostr-connect/extension/nostr-provider.js
2024-12-22 07:35:25 +07:00

109 lines
2.8 KiB
JavaScript

const EXTENSION = "nostrconnect";
window.nostr = {
_requests: {},
_pubkey: null,
async getPublicKey() {
if (this._pubkey) return this._pubkey;
this._pubkey = await this._call("getPublicKey", {});
return this._pubkey;
},
async signEvent(event) {
return this._call("signEvent", { event });
},
async getRelays() {
return this._call("getRelays", {});
},
nip04: {
async encrypt(peer, plaintext) {
return window.nostr._call("nip04.encrypt", { peer, plaintext });
},
async decrypt(peer, ciphertext) {
return window.nostr._call("nip04.decrypt", { peer, ciphertext });
},
},
_call(type, params) {
const id = Math.random().toString().slice(-4);
console.log(
`%c[nostrconnect:%c${id}%c]%c calling %c${type}%c with %c${JSON.stringify(params || {})}`,
"background-color:#f1b912;font-weight:bold;color:white",
"background-color:#f1b912;font-weight:bold;color:#a92727",
"background-color:#f1b912;color:white;font-weight:bold",
"color:auto",
"font-weight:bold;color:#08589d;font-family:monospace",
"color:auto",
"font-weight:bold;color:#90b12d;font-family:monospace",
);
return new Promise((resolve, reject) => {
this._requests[id] = { resolve, reject };
window.postMessage(
{
id,
ext: EXTENSION,
type,
params,
},
"*",
);
});
},
};
window.addEventListener("message", (message) => {
if (
!message.data ||
message.data.response === null ||
message.data.response === undefined ||
message.data.ext !== EXTENSION ||
!window.nostr._requests[message.data.id]
)
return;
if (message.data.response.error) {
const error = new Error(
`${EXTENSION}: ${message.data.response.error.message}`,
);
error.stack = message.data.response.error.stack;
window.nostr._requests[message.data.id].reject(error);
} else {
window.nostr._requests[message.data.id].resolve(message.data.response);
}
console.log(
`%c[nostrconnect:%c${message.data.id}%c]%c result: %c${JSON.stringify(
message?.data?.response || message?.data?.response?.error?.message || {},
)}`,
"background-color:#f1b912;font-weight:bold;color:white",
"background-color:#f1b912;font-weight:bold;color:#a92727",
"background-color:#f1b912;color:white;font-weight:bold",
"color:auto",
"font-weight:bold;color:#08589d",
);
delete window.nostr._requests[message.data.id];
});
// hack to replace nostr:nprofile.../etc links with something else
let replacing = null;
document.addEventListener("mousedown", replaceNostrSchemeLink);
async function replaceNostrSchemeLink(e) {
if (e.target.tagName !== "A" || !e.target.href.startsWith("nostr:")) return;
if (replacing === false) return;
const response = await window.nostr._call("replaceURL", {
url: e.target.href,
});
if (response === false) {
replacing = false;
return;
}
e.target.href = response;
}