fix: save key and load key
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import browser from 'webextension-polyfill'
|
import browser from 'webextension-polyfill'
|
||||||
import { useState, useCallback, useEffect } from 'react'
|
import { useState, useCallback, useEffect } from 'react'
|
||||||
import { render } from 'react-dom'
|
import { render } from 'react-dom'
|
||||||
import { generateSecretKey, nip19, utils } from 'nostr-tools'
|
import { generateSecretKey, nip19 } from 'nostr-tools'
|
||||||
import QRCode from 'react-qr-code'
|
import QRCode from 'react-qr-code'
|
||||||
import * as Tabs from '@radix-ui/react-tabs'
|
import * as Tabs from '@radix-ui/react-tabs'
|
||||||
import { LogoIcon } from './icons'
|
import { LogoIcon } from './icons'
|
||||||
@@ -56,8 +56,11 @@ function Options() {
|
|||||||
.get(['private_key', 'relays', 'protocol_handler', 'notifications'])
|
.get(['private_key', 'relays', 'protocol_handler', 'notifications'])
|
||||||
.then((results) => {
|
.then((results) => {
|
||||||
if (results.private_key) {
|
if (results.private_key) {
|
||||||
setPrivKey(nip19.nsecEncode(results.private_key))
|
const pkey = results.private_key
|
||||||
|
const nsec = nip19.nsecEncode(hexToBytes(pkey))
|
||||||
|
setPrivKey(nsec)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.relays) {
|
if (results.relays) {
|
||||||
const relaysList = []
|
const relaysList = []
|
||||||
for (const url in results.relays) {
|
for (const url in results.relays) {
|
||||||
@@ -68,11 +71,13 @@ function Options() {
|
|||||||
}
|
}
|
||||||
setRelays(relaysList)
|
setRelays(relaysList)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.protocol_handler) {
|
if (results.protocol_handler) {
|
||||||
setProtocolHandler(results.protocol_handler)
|
setProtocolHandler(results.protocol_handler)
|
||||||
setHandleNostrLinks(true)
|
setHandleNostrLinks(true)
|
||||||
setShowProtocolHandlerHelp(false)
|
setShowProtocolHandlerHelp(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.notifications) {
|
if (results.notifications) {
|
||||||
setNotifications(true)
|
setNotifications(true)
|
||||||
}
|
}
|
||||||
@@ -519,8 +524,7 @@ examples:
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function generate() {
|
async function generate() {
|
||||||
const sk = generateSecretKey()
|
setPrivKey(nip19.nsecEncode(generateSecretKey()))
|
||||||
setPrivKey(nip19.nsecEncode(utils.bytesToHex(sk)))
|
|
||||||
addUnsavedChanges('private_key')
|
addUnsavedChanges('private_key')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,23 +533,26 @@ examples:
|
|||||||
showMessage('PRIVATE KEY IS INVALID! did not save private key.')
|
showMessage('PRIVATE KEY IS INVALID! did not save private key.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let hexOrEmptyKey = privKey
|
let hexOrEmptyKey = privKey
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { type, data } = nip19.decode(privKey)
|
const { type, data } = nip19.decode(privKey)
|
||||||
if (type === 'nsec') hexOrEmptyKey = bytesToHex(data)
|
if (type === 'nsec') hexOrEmptyKey = bytesToHex(data)
|
||||||
} catch (_) {}
|
} catch (_) {
|
||||||
|
showMessage('Invalid private key format.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
await browser.storage.local.set({
|
await browser.storage.local.set({
|
||||||
private_key: hexOrEmptyKey
|
private_key: hexOrEmptyKey
|
||||||
})
|
})
|
||||||
if (hexOrEmptyKey !== '') {
|
|
||||||
setPrivKey(nip19.nsecEncode(hexToBytes(hexOrEmptyKey)))
|
showMessage('Private Key has been saved.')
|
||||||
}
|
|
||||||
showMessage('saved private key!')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isKeyValid() {
|
function isKeyValid() {
|
||||||
if (privKey === '') return true
|
if (privKey === '') return true
|
||||||
if (privKey.match(/^[a-f0-9]{64}$/)) return true
|
|
||||||
try {
|
try {
|
||||||
if (nip19.decode(privKey).type === 'nsec') return true
|
if (nip19.decode(privKey).type === 'nsec') return true
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|||||||
@@ -1,144 +1,144 @@
|
|||||||
import browser from "webextension-polyfill";
|
import browser from 'webextension-polyfill'
|
||||||
|
|
||||||
export const NO_PERMISSIONS_REQUIRED = {
|
export const NO_PERMISSIONS_REQUIRED = {
|
||||||
replaceURL: true,
|
replaceURL: true,
|
||||||
peekPublicKey: true,
|
peekPublicKey: true
|
||||||
};
|
}
|
||||||
|
|
||||||
export const PERMISSION_NAMES = Object.fromEntries([
|
export const PERMISSION_NAMES = Object.fromEntries([
|
||||||
["getPublicKey", "read your public key"],
|
['getPublicKey', 'read your public key'],
|
||||||
["signEvent", "sign events using your private key"],
|
['signEvent', 'sign events using your private key'],
|
||||||
["nip04.encrypt", "encrypt messages to peers"],
|
['nip04.encrypt', 'encrypt messages to peers'],
|
||||||
["nip04.decrypt", "decrypt messages from peers"],
|
['nip04.decrypt', 'decrypt messages from peers'],
|
||||||
["nip44.encrypt", "encrypt messages to peers"],
|
['nip44.encrypt', 'encrypt messages to peers'],
|
||||||
["nip44.decrypt", "decrypt messages from peers"],
|
['nip44.decrypt', 'decrypt messages from peers']
|
||||||
]);
|
])
|
||||||
|
|
||||||
function matchConditions(conditions, event) {
|
function matchConditions(conditions, event) {
|
||||||
if (conditions?.kinds) {
|
if (conditions?.kinds) {
|
||||||
if (event.kind in conditions.kinds) return true;
|
if (event.kind in conditions.kinds) return true
|
||||||
else return false;
|
else return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPermissionStatus(host, type, event) {
|
export async function getPermissionStatus(host, type, event) {
|
||||||
const { policies } = await browser.storage.local.get("policies");
|
const { policies } = await browser.storage.local.get('policies')
|
||||||
|
|
||||||
const answers = [true, false];
|
const answers = [true, false]
|
||||||
for (let i = 0; i < answers.length; i++) {
|
for (let i = 0; i < answers.length; i++) {
|
||||||
const accept = answers[i];
|
const accept = answers[i]
|
||||||
const { conditions } = policies?.[host]?.[accept]?.[type] || {};
|
const { conditions } = policies?.[host]?.[accept]?.[type] || {}
|
||||||
|
|
||||||
if (conditions) {
|
if (conditions) {
|
||||||
if (type === "signEvent") {
|
if (type === 'signEvent') {
|
||||||
if (matchConditions(conditions, event)) {
|
if (matchConditions(conditions, event)) {
|
||||||
return accept; // may be true or false
|
return accept // may be true or false
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return accept; // may be true or false
|
return accept // may be true or false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updatePermission(host, type, accept, conditions) {
|
export async function updatePermission(host, type, accept, conditions) {
|
||||||
const { policies = {} } = await browser.storage.local.get("policies");
|
const { policies = {} } = await browser.storage.local.get('policies')
|
||||||
|
|
||||||
// if the new conditions is "match everything", override the previous
|
// if the new conditions is "match everything", override the previous
|
||||||
if (Object.keys(conditions).length === 0) {
|
if (Object.keys(conditions).length === 0) {
|
||||||
conditions = {};
|
conditions = {}
|
||||||
} else {
|
} else {
|
||||||
// if we already had a policy for this, merge the conditions
|
// if we already had a policy for this, merge the conditions
|
||||||
const existingConditions = policies[host]?.[accept]?.[type]?.conditions;
|
const existingConditions = policies[host]?.[accept]?.[type]?.conditions
|
||||||
if (existingConditions) {
|
if (existingConditions) {
|
||||||
if (existingConditions.kinds && conditions.kinds) {
|
if (existingConditions.kinds && conditions.kinds) {
|
||||||
Object.keys(existingConditions.kinds).forEach((kind) => {
|
Object.keys(existingConditions.kinds).forEach((kind) => {
|
||||||
conditions.kinds[kind] = true;
|
conditions.kinds[kind] = true
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have a reverse policy (accept / reject) that is exactly equal to this, remove it
|
// if we have a reverse policy (accept / reject) that is exactly equal to this, remove it
|
||||||
const other = !accept;
|
const other = !accept
|
||||||
const reverse = policies?.[host]?.[other]?.[type];
|
const reverse = policies?.[host]?.[other]?.[type]
|
||||||
if (
|
if (
|
||||||
reverse &&
|
reverse &&
|
||||||
JSON.stringify(reverse.conditions) === JSON.stringify(conditions)
|
JSON.stringify(reverse.conditions) === JSON.stringify(conditions)
|
||||||
) {
|
) {
|
||||||
delete policies[host][other][type];
|
delete policies[host][other][type]
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert our new policy
|
// insert our new policy
|
||||||
policies[host] = policies[host] || {};
|
policies[host] = policies[host] || {}
|
||||||
policies[host][accept] = policies[host][accept] || {};
|
policies[host][accept] = policies[host][accept] || {}
|
||||||
policies[host][accept][type] = {
|
policies[host][accept][type] = {
|
||||||
conditions, // filter that must match the event (in case of signEvent)
|
conditions, // filter that must match the event (in case of signEvent)
|
||||||
created_at: Math.round(Date.now() / 1000),
|
created_at: Math.round(Date.now() / 1000)
|
||||||
};
|
}
|
||||||
|
|
||||||
browser.storage.local.set({ policies });
|
browser.storage.local.set({ policies })
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function removePermissions(host, accept, type) {
|
export async function removePermissions(host, accept, type) {
|
||||||
const { policies = {} } = await browser.storage.local.get("policies");
|
const { policies = {} } = await browser.storage.local.get('policies')
|
||||||
delete policies[host]?.[accept]?.[type];
|
delete policies[host]?.[accept]?.[type]
|
||||||
browser.storage.local.set({ policies });
|
browser.storage.local.set({ policies })
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function showNotification(host, answer, type, params) {
|
export async function showNotification(host, answer, type, params) {
|
||||||
const { notifications } = await browser.storage.local.get("notifications");
|
const { notifications } = await browser.storage.local.get('notifications')
|
||||||
if (notifications) {
|
if (notifications) {
|
||||||
const action = answer ? "allowed" : "denied";
|
const action = answer ? 'allowed' : 'denied'
|
||||||
browser.notifications.create(undefined, {
|
browser.notifications.create(undefined, {
|
||||||
type: "basic",
|
type: 'basic',
|
||||||
title: `${type} ${action} for ${host}`,
|
title: `${type} ${action} for ${host}`,
|
||||||
message: JSON.stringify(
|
message: JSON.stringify(
|
||||||
params?.event
|
params?.event
|
||||||
? {
|
? {
|
||||||
kind: params.event.kind,
|
kind: params.event.kind,
|
||||||
content: params.event.content,
|
content: params.event.content,
|
||||||
tags: params.event.tags,
|
tags: params.event.tags
|
||||||
}
|
}
|
||||||
: params,
|
: params,
|
||||||
null,
|
null,
|
||||||
2,
|
2
|
||||||
),
|
),
|
||||||
iconUrl: "icons/48x48.png",
|
iconUrl: 'icons/48x48.png'
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getPosition(width, height) {
|
export async function getPosition(width, height) {
|
||||||
let left = 0;
|
let left = 0
|
||||||
let top = 0;
|
let top = 0
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const lastFocused = await browser.windows.getLastFocused();
|
const lastFocused = await browser.windows.getLastFocused()
|
||||||
|
|
||||||
if (
|
if (
|
||||||
lastFocused &&
|
lastFocused &&
|
||||||
lastFocused.top !== undefined &&
|
lastFocused.top !== undefined &&
|
||||||
lastFocused.left !== undefined &&
|
lastFocused.left !== undefined &&
|
||||||
lastFocused.width !== undefined &&
|
lastFocused.width !== undefined &&
|
||||||
lastFocused.height !== undefined
|
lastFocused.height !== undefined
|
||||||
) {
|
) {
|
||||||
top = Math.round(lastFocused.top + (lastFocused.height - height) / 2);
|
top = Math.round(lastFocused.top + (lastFocused.height - height) / 2)
|
||||||
left = Math.round(lastFocused.left + (lastFocused.width - width) / 2);
|
left = Math.round(lastFocused.left + (lastFocused.width - width) / 2)
|
||||||
} else {
|
} else {
|
||||||
console.error("Last focused window properties are undefined.");
|
console.error('Last focused window properties are undefined.')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error getting window position:", error);
|
console.error('Error getting window position:', error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
top,
|
top,
|
||||||
left,
|
left
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,132 +1,130 @@
|
|||||||
const EXTENSION = "nostrconnect";
|
const EXTENSION = 'nostrconnect'
|
||||||
|
|
||||||
window.nostr = {
|
window.nostr = {
|
||||||
_requests: {},
|
_requests: {},
|
||||||
_pubkey: null,
|
_pubkey: null,
|
||||||
|
|
||||||
async getPublicKey() {
|
async getPublicKey() {
|
||||||
if (this._pubkey) return this._pubkey;
|
if (this._pubkey) return this._pubkey
|
||||||
this._pubkey = await this._call("getPublicKey", {});
|
this._pubkey = await this._call('getPublicKey', {})
|
||||||
return this._pubkey;
|
return this._pubkey
|
||||||
},
|
},
|
||||||
|
|
||||||
async peekPublicKey() {
|
async peekPublicKey() {
|
||||||
return this._call("peekPublicKey", {});
|
return this._call('peekPublicKey', {})
|
||||||
},
|
},
|
||||||
|
|
||||||
async signEvent(event) {
|
async signEvent(event) {
|
||||||
return this._call("signEvent", { event });
|
return this._call('signEvent', { event })
|
||||||
},
|
},
|
||||||
|
|
||||||
async getRelays() {
|
async getRelays() {
|
||||||
return {};
|
return {}
|
||||||
},
|
},
|
||||||
|
|
||||||
nip04: {
|
nip04: {
|
||||||
async encrypt(peer, plaintext) {
|
async encrypt(peer, plaintext) {
|
||||||
return window.nostr._call("nip04.encrypt", { peer, plaintext });
|
return window.nostr._call('nip04.encrypt', { peer, plaintext })
|
||||||
},
|
},
|
||||||
|
|
||||||
async decrypt(peer, ciphertext) {
|
async decrypt(peer, ciphertext) {
|
||||||
return window.nostr._call("nip04.decrypt", { peer, ciphertext });
|
return window.nostr._call('nip04.decrypt', { peer, ciphertext })
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
nip44: {
|
nip44: {
|
||||||
async encrypt(peer, plaintext) {
|
async encrypt(peer, plaintext) {
|
||||||
return window.nostr._call("nip44.encrypt", { peer, plaintext });
|
return window.nostr._call('nip44.encrypt', { peer, plaintext })
|
||||||
},
|
},
|
||||||
|
|
||||||
async decrypt(peer, ciphertext) {
|
async decrypt(peer, ciphertext) {
|
||||||
return window.nostr._call("nip44.decrypt", { peer, ciphertext });
|
return window.nostr._call('nip44.decrypt', { peer, ciphertext })
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_call(type, params) {
|
_call(type, params) {
|
||||||
const id = Math.random().toString().slice(-4);
|
const id = Math.random().toString().slice(-4)
|
||||||
console.log(
|
console.log(
|
||||||
"%c[nostrconnect:%c" +
|
'%c[nostrconnect:%c' +
|
||||||
id +
|
id +
|
||||||
"%c]%c calling %c" +
|
'%c]%c calling %c' +
|
||||||
type +
|
type +
|
||||||
"%c with %c" +
|
'%c with %c' +
|
||||||
JSON.stringify(params || {}),
|
JSON.stringify(params || {}),
|
||||||
"background-color:#f1b912;font-weight:bold;color:white",
|
'background-color:#f1b912;font-weight:bold;color:white',
|
||||||
"background-color:#f1b912;font-weight:bold;color:#a92727",
|
'background-color:#f1b912;font-weight:bold;color:#a92727',
|
||||||
"background-color:#f1b912;color:white;font-weight:bold",
|
'background-color:#f1b912;color:white;font-weight:bold',
|
||||||
"color:auto",
|
'color:auto',
|
||||||
"font-weight:bold;color:#08589d;font-family:monospace",
|
'font-weight:bold;color:#08589d;font-family:monospace',
|
||||||
"color:auto",
|
'color:auto',
|
||||||
"font-weight:bold;color:#90b12d;font-family:monospace",
|
'font-weight:bold;color:#90b12d;font-family:monospace'
|
||||||
);
|
)
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this._requests[id] = { resolve, reject };
|
this._requests[id] = { resolve, reject }
|
||||||
window.postMessage(
|
window.postMessage(
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
ext: EXTENSION,
|
ext: EXTENSION,
|
||||||
type,
|
type,
|
||||||
params,
|
params
|
||||||
},
|
},
|
||||||
"*",
|
'*'
|
||||||
);
|
)
|
||||||
});
|
})
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
window.addEventListener("message", (message) => {
|
window.addEventListener('message', (message) => {
|
||||||
if (
|
if (
|
||||||
!message.data ||
|
!message.data ||
|
||||||
message.data.response === null ||
|
message.data.response === null ||
|
||||||
message.data.response === undefined ||
|
message.data.response === undefined ||
|
||||||
message.data.ext !== EXTENSION ||
|
message.data.ext !== EXTENSION ||
|
||||||
!window.nostr._requests[message.data.id]
|
!window.nostr._requests[message.data.id]
|
||||||
)
|
)
|
||||||
return;
|
return
|
||||||
|
|
||||||
if (message.data.response.error) {
|
if (message.data.response.error) {
|
||||||
const error = new Error(
|
const error = new Error(
|
||||||
`${EXTENSION}: ${message.data.response.error.message}`,
|
`${EXTENSION}: ${message.data.response.error.message}`
|
||||||
);
|
)
|
||||||
error.stack = message.data.response.error.stack;
|
error.stack = message.data.response.error.stack
|
||||||
window.nostr._requests[message.data.id].reject(error);
|
window.nostr._requests[message.data.id].reject(error)
|
||||||
} else {
|
} else {
|
||||||
window.nostr._requests[message.data.id].resolve(message.data.response);
|
window.nostr._requests[message.data.id].resolve(message.data.response)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
"%c[nostrconnect:%c" +
|
'%c[nostrconnect:%c' +
|
||||||
message.data.id +
|
message.data.id +
|
||||||
"%c]%c result: %c" +
|
'%c]%c result: %c' +
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
message?.data?.response ||
|
message?.data?.response || message?.data?.response?.error?.message || {}
|
||||||
message?.data?.response?.error?.message ||
|
),
|
||||||
{},
|
'background-color:#f1b912;font-weight:bold;color:white',
|
||||||
),
|
'background-color:#f1b912;font-weight:bold;color:#a92727',
|
||||||
"background-color:#f1b912;font-weight:bold;color:white",
|
'background-color:#f1b912;color:white;font-weight:bold',
|
||||||
"background-color:#f1b912;font-weight:bold;color:#a92727",
|
'color:auto',
|
||||||
"background-color:#f1b912;color:white;font-weight:bold",
|
'font-weight:bold;color:#08589d'
|
||||||
"color:auto",
|
)
|
||||||
"font-weight:bold;color:#08589d",
|
|
||||||
);
|
|
||||||
|
|
||||||
delete window.nostr._requests[message.data.id];
|
delete window.nostr._requests[message.data.id]
|
||||||
});
|
})
|
||||||
|
|
||||||
// hack to replace nostr:nprofile.../etc links with something else
|
// hack to replace nostr:nprofile.../etc links with something else
|
||||||
let replacing = null;
|
let replacing = null
|
||||||
document.addEventListener("mousedown", replaceNostrSchemeLink);
|
document.addEventListener('mousedown', replaceNostrSchemeLink)
|
||||||
async function replaceNostrSchemeLink(e) {
|
async function replaceNostrSchemeLink(e) {
|
||||||
if (e.target.tagName !== "A" || !e.target.href.startsWith("nostr:")) return;
|
if (e.target.tagName !== 'A' || !e.target.href.startsWith('nostr:')) return
|
||||||
if (replacing === false) return;
|
if (replacing === false) return
|
||||||
|
|
||||||
const response = await window.nostr._call("replaceURL", {
|
const response = await window.nostr._call('replaceURL', {
|
||||||
url: e.target.href,
|
url: e.target.href
|
||||||
});
|
})
|
||||||
if (response === false) {
|
if (response === false) {
|
||||||
replacing = false;
|
replacing = false
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
e.target.href = response;
|
e.target.href = response
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31774,7 +31774,9 @@ For more info, visit https://reactjs.org/link/mock-scheduler`);
|
|||||||
(0, import_react3.useEffect)(() => {
|
(0, import_react3.useEffect)(() => {
|
||||||
import_webextension_polyfill2.default.storage.local.get(["private_key", "relays", "protocol_handler", "notifications"]).then((results) => {
|
import_webextension_polyfill2.default.storage.local.get(["private_key", "relays", "protocol_handler", "notifications"]).then((results) => {
|
||||||
if (results.private_key) {
|
if (results.private_key) {
|
||||||
setPrivKey(nip19_exports.nsecEncode(results.private_key));
|
const pkey = results.private_key;
|
||||||
|
const nsec = nip19_exports.nsecEncode(hexToBytes(pkey));
|
||||||
|
setPrivKey(nsec);
|
||||||
}
|
}
|
||||||
if (results.relays) {
|
if (results.relays) {
|
||||||
const relaysList = [];
|
const relaysList = [];
|
||||||
@@ -32327,8 +32329,7 @@ examples:
|
|||||||
addUnsavedChanges("private_key");
|
addUnsavedChanges("private_key");
|
||||||
}
|
}
|
||||||
async function generate() {
|
async function generate() {
|
||||||
const sk = generateSecretKey();
|
setPrivKey(nip19_exports.nsecEncode(generateSecretKey()));
|
||||||
setPrivKey(nip19_exports.nsecEncode(utils_exports.bytesToHex(sk)));
|
|
||||||
addUnsavedChanges("private_key");
|
addUnsavedChanges("private_key");
|
||||||
}
|
}
|
||||||
async function saveKey() {
|
async function saveKey() {
|
||||||
@@ -32342,20 +32343,17 @@ examples:
|
|||||||
if (type === "nsec")
|
if (type === "nsec")
|
||||||
hexOrEmptyKey = bytesToHex(data);
|
hexOrEmptyKey = bytesToHex(data);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
|
showMessage("Invalid private key format.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
await import_webextension_polyfill2.default.storage.local.set({
|
await import_webextension_polyfill2.default.storage.local.set({
|
||||||
private_key: hexOrEmptyKey
|
private_key: hexOrEmptyKey
|
||||||
});
|
});
|
||||||
if (hexOrEmptyKey !== "") {
|
showMessage("Private Key has been saved.");
|
||||||
setPrivKey(nip19_exports.nsecEncode(hexToBytes(hexOrEmptyKey)));
|
|
||||||
}
|
|
||||||
showMessage("saved private key!");
|
|
||||||
}
|
}
|
||||||
function isKeyValid() {
|
function isKeyValid() {
|
||||||
if (privKey === "")
|
if (privKey === "")
|
||||||
return true;
|
return true;
|
||||||
if (privKey.match(/^[a-f0-9]{64}$/))
|
|
||||||
return true;
|
|
||||||
try {
|
try {
|
||||||
if (nip19_exports.decode(privKey).type === "nsec")
|
if (nip19_exports.decode(privKey).type === "nsec")
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -31412,6 +31412,10 @@ For more info, visit https://reactjs.org/link/mock-scheduler`);
|
|||||||
var Trigger = TabsTrigger;
|
var Trigger = TabsTrigger;
|
||||||
var Content = TabsContent;
|
var Content = TabsContent;
|
||||||
|
|
||||||
|
// node_modules/.pnpm/nostr-tools@2.23.3/node_modules/nostr-tools/lib/esm/utils.js
|
||||||
|
var utf8Decoder2 = new TextDecoder("utf-8");
|
||||||
|
var utf8Encoder2 = new TextEncoder();
|
||||||
|
|
||||||
// extension/popup.jsx
|
// extension/popup.jsx
|
||||||
var import_jsx_runtime = __toESM(require_jsx_runtime());
|
var import_jsx_runtime = __toESM(require_jsx_runtime());
|
||||||
function Popup() {
|
function Popup() {
|
||||||
@@ -31428,9 +31432,9 @@ For more info, visit https://reactjs.org/link/mock-scheduler`);
|
|||||||
(0, import_react3.useEffect)(() => {
|
(0, import_react3.useEffect)(() => {
|
||||||
import_webextension_polyfill.default.storage.local.get(["private_key", "relays"]).then((results) => {
|
import_webextension_polyfill.default.storage.local.get(["private_key", "relays"]).then((results) => {
|
||||||
if (results.private_key) {
|
if (results.private_key) {
|
||||||
const hexKey = getPublicKey(results.private_key);
|
const hexKey = getPublicKey(hexToBytes(results.private_key));
|
||||||
const npubKey = nip19_exports.npubEncode(hexKey);
|
const npub = nip19_exports.npubEncode(hexKey);
|
||||||
setKeys({ npub: npubKey, hex: hexKey });
|
setKeys({ npub, hex: hexKey });
|
||||||
if (results.relays) {
|
if (results.relays) {
|
||||||
const relaysList = [];
|
const relaysList = [];
|
||||||
for (const url in results.relays) {
|
for (const url in results.relays) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import QRCode from 'react-qr-code'
|
|||||||
import { SettingsIcon } from './icons'
|
import { SettingsIcon } from './icons'
|
||||||
import { minidenticon } from 'minidenticons'
|
import { minidenticon } from 'minidenticons'
|
||||||
import * as Tabs from '@radix-ui/react-tabs'
|
import * as Tabs from '@radix-ui/react-tabs'
|
||||||
|
import { hexToBytes } from 'nostr-tools/utils'
|
||||||
|
|
||||||
function Popup() {
|
function Popup() {
|
||||||
const [keys, setKeys] = useState(null)
|
const [keys, setKeys] = useState(null)
|
||||||
@@ -27,19 +28,21 @@ function Popup() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
browser.storage.local.get(['private_key', 'relays']).then((results) => {
|
browser.storage.local.get(['private_key', 'relays']).then((results) => {
|
||||||
if (results.private_key) {
|
if (results.private_key) {
|
||||||
const hexKey = getPublicKey(results.private_key)
|
const hexKey = getPublicKey(hexToBytes(results.private_key))
|
||||||
const npubKey = nip19.npubEncode(hexKey)
|
const npub = nip19.npubEncode(hexKey)
|
||||||
|
|
||||||
setKeys({ npub: npubKey, hex: hexKey })
|
setKeys({ npub: npub, hex: hexKey })
|
||||||
|
|
||||||
if (results.relays) {
|
if (results.relays) {
|
||||||
const relaysList = []
|
const relaysList = []
|
||||||
|
|
||||||
for (const url in results.relays) {
|
for (const url in results.relays) {
|
||||||
if (results.relays[url].write) {
|
if (results.relays[url].write) {
|
||||||
relaysList.push(url)
|
relaysList.push(url)
|
||||||
if (relaysList.length >= 3) break
|
if (relaysList.length >= 3) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (relaysList.length) {
|
if (relaysList.length) {
|
||||||
const nprofileKey = nip19.nprofileEncode({
|
const nprofileKey = nip19.nprofileEncode({
|
||||||
pubkey: hexKey,
|
pubkey: hexKey,
|
||||||
|
|||||||
Reference in New Issue
Block a user