mirror of
https://github.com/Qortal/chrome-extension.git
synced 2025-03-28 08:15:55 +00:00
started infrustructure
This commit is contained in:
parent
0087985f2d
commit
b8d5481633
@ -1,290 +1,584 @@
|
|||||||
|
async function connection(hostname) {
|
||||||
async function connection(hostname) {
|
|
||||||
const isConnected = await chrome.storage.local.get([hostname]);
|
const isConnected = await chrome.storage.local.get([hostname]);
|
||||||
let connected = false
|
let connected = false;
|
||||||
if(isConnected && Object.keys(isConnected).length > 0 && isConnected[hostname]){
|
if (
|
||||||
connected = true
|
isConnected &&
|
||||||
|
Object.keys(isConnected).length > 0 &&
|
||||||
|
isConnected[hostname]
|
||||||
|
) {
|
||||||
|
connected = true;
|
||||||
}
|
}
|
||||||
return connected
|
return connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In your content script
|
// In your content script
|
||||||
document.addEventListener('qortalExtensionRequests', async (event) => {
|
document.addEventListener("qortalExtensionRequests", async (event) => {
|
||||||
const { type, payload, requestId, timeout } = event.detail; // Capture the requestId
|
const { type, payload, requestId, timeout } = event.detail; // Capture the requestId
|
||||||
if (type === 'REQUEST_USER_INFO') {
|
if (type === "REQUEST_USER_INFO") {
|
||||||
const hostname = window.location.hostname
|
const hostname = window.location.hostname;
|
||||||
const res = await connection(hostname)
|
const res = await connection(hostname);
|
||||||
|
|
||||||
if(!res){
|
if (!res) {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
document.dispatchEvent(
|
||||||
detail: { type: "USER_INFO", data: {
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
error: "Not authorized"
|
detail: {
|
||||||
}, requestId }
|
type: "USER_INFO",
|
||||||
}));
|
data: {
|
||||||
return
|
error: "Not authorized",
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
chrome?.runtime?.sendMessage({ action: "userInfo" }, (response) => {
|
chrome?.runtime?.sendMessage({ action: "userInfo" }, (response) => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
document.dispatchEvent(
|
||||||
detail: { type: "USER_INFO", data: {
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
error: response.error
|
detail: {
|
||||||
}, requestId }
|
type: "USER_INFO",
|
||||||
}));
|
data: {
|
||||||
|
error: response.error,
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// Include the requestId in the detail when dispatching the response
|
// Include the requestId in the detail when dispatching the response
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
document.dispatchEvent(
|
||||||
detail: { type: "USER_INFO", data: response, requestId }
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
}));
|
detail: { type: "USER_INFO", data: response, requestId },
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (type === 'REQUEST_IS_INSTALLED') {
|
} else if (type === "REQUEST_IS_INSTALLED") {
|
||||||
chrome?.runtime?.sendMessage({ action: "version" }, (response) => {
|
chrome?.runtime?.sendMessage({ action: "version" }, (response) => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
console.error("Error:", response.error);
|
console.error("Error:", response.error);
|
||||||
} else {
|
} else {
|
||||||
// Include the requestId in the detail when dispatching the response
|
// Include the requestId in the detail when dispatching the response
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
document.dispatchEvent(
|
||||||
detail: { type: "IS_INSTALLED", data: response, requestId }
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
}));
|
detail: { type: "IS_INSTALLED", data: response, requestId },
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (type === 'REQUEST_CONNECTION') {
|
} else if (type === "REQUEST_CONNECTION") {
|
||||||
const hostname = window.location.hostname
|
const hostname = window.location.hostname;
|
||||||
chrome?.runtime?.sendMessage({ action: "connection", payload: {
|
chrome?.runtime?.sendMessage(
|
||||||
hostname
|
{
|
||||||
}, timeout }, (response) => {
|
action: "connection",
|
||||||
if (response.error) {
|
payload: {
|
||||||
console.error("Error:", response.error);
|
hostname,
|
||||||
} else {
|
},
|
||||||
// Include the requestId in the detail when dispatching the response
|
timeout,
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
},
|
||||||
detail: { type: "CONNECTION", data: response, requestId }
|
(response) => {
|
||||||
}));
|
if (response.error) {
|
||||||
|
console.error("Error:", response.error);
|
||||||
|
} else {
|
||||||
|
// Include the requestId in the detail when dispatching the response
|
||||||
|
document.dispatchEvent(
|
||||||
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
|
detail: { type: "CONNECTION", data: response, requestId },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
} else if (type === 'REQUEST_OAUTH') {
|
} else if (type === "REQUEST_OAUTH") {
|
||||||
const hostname = window.location.hostname
|
const hostname = window.location.hostname;
|
||||||
const res = await connection(hostname)
|
const res = await connection(hostname);
|
||||||
if(!res){
|
if (!res) {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
document.dispatchEvent(
|
||||||
detail: { type: "OAUTH", data: {
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
error: "Not authorized"
|
detail: {
|
||||||
}, requestId }
|
type: "OAUTH",
|
||||||
}));
|
data: {
|
||||||
return
|
error: "Not authorized",
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome?.runtime?.sendMessage({ action: "oauth", payload: {
|
chrome?.runtime?.sendMessage(
|
||||||
nodeBaseUrl: payload.nodeBaseUrl,
|
{
|
||||||
senderAddress: payload.senderAddress,
|
action: "oauth",
|
||||||
senderPublicKey: payload.senderPublicKey, timestamp: payload.timestamp
|
payload: {
|
||||||
}}, (response) => {
|
nodeBaseUrl: payload.nodeBaseUrl,
|
||||||
if (response.error) {
|
senderAddress: payload.senderAddress,
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
senderPublicKey: payload.senderPublicKey,
|
||||||
detail: { type: "OAUTH", data: {
|
timestamp: payload.timestamp,
|
||||||
error: response.error
|
},
|
||||||
}, requestId }
|
},
|
||||||
}));
|
(response) => {
|
||||||
} else {
|
if (response.error) {
|
||||||
// Include the requestId in the detail when dispatching the response
|
document.dispatchEvent(
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
detail: { type: "OAUTH", data: response, requestId }
|
detail: {
|
||||||
}));
|
type: "OAUTH",
|
||||||
|
data: {
|
||||||
|
error: response.error,
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Include the requestId in the detail when dispatching the response
|
||||||
|
document.dispatchEvent(
|
||||||
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
|
detail: { type: "OAUTH", data: response, requestId },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
} else if (type === 'REQUEST_BUY_ORDER') {
|
} else if (type === "REQUEST_BUY_ORDER") {
|
||||||
const hostname = window.location.hostname
|
const hostname = window.location.hostname;
|
||||||
const res = await connection(hostname)
|
const res = await connection(hostname);
|
||||||
if(!res){
|
if (!res) {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
document.dispatchEvent(
|
||||||
detail: { type: "BUY_ORDER", data: {
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
error: "Not authorized"
|
detail: {
|
||||||
}, requestId }
|
type: "BUY_ORDER",
|
||||||
}));
|
data: {
|
||||||
return
|
error: "Not authorized",
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome?.runtime?.sendMessage({ action: "buyOrder", payload: {
|
chrome?.runtime?.sendMessage(
|
||||||
qortalAtAddresses: payload.qortalAtAddresses,
|
{
|
||||||
hostname,
|
action: "buyOrder",
|
||||||
useLocal: payload?.useLocal
|
payload: {
|
||||||
|
qortalAtAddresses: payload.qortalAtAddresses,
|
||||||
}, timeout}, (response) => {
|
hostname,
|
||||||
if (response.error) {
|
useLocal: payload?.useLocal,
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
},
|
||||||
detail: { type: "BUY_ORDER", data: {
|
timeout,
|
||||||
error: response.error
|
},
|
||||||
}, requestId }
|
(response) => {
|
||||||
}));
|
if (response.error) {
|
||||||
} else {
|
document.dispatchEvent(
|
||||||
// Include the requestId in the detail when dispatching the response
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
detail: {
|
||||||
detail: { type: "BUY_ORDER", data: response, requestId }
|
type: "BUY_ORDER",
|
||||||
}));
|
data: {
|
||||||
|
error: response.error,
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Include the requestId in the detail when dispatching the response
|
||||||
|
document.dispatchEvent(
|
||||||
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
|
detail: { type: "BUY_ORDER", data: response, requestId },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
} else if(type === 'REQUEST_LTC_BALANCE'){
|
} else if (type === "REQUEST_LTC_BALANCE") {
|
||||||
|
const hostname = window.location.hostname;
|
||||||
|
const res = await connection(hostname);
|
||||||
const hostname = window.location.hostname
|
if (!res) {
|
||||||
const res = await connection(hostname)
|
document.dispatchEvent(
|
||||||
if(!res){
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
detail: {
|
||||||
detail: { type: "USER_INFO", data: {
|
type: "USER_INFO",
|
||||||
error: "Not authorized"
|
data: {
|
||||||
}, requestId }
|
error: "Not authorized",
|
||||||
}));
|
},
|
||||||
return
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
chrome?.runtime?.sendMessage({ action: "ltcBalance", payload: {
|
chrome?.runtime?.sendMessage(
|
||||||
hostname
|
{
|
||||||
}, timeout }, (response) => {
|
action: "ltcBalance",
|
||||||
|
payload: {
|
||||||
if (response.error) {
|
hostname,
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
},
|
||||||
detail: { type: "LTC_BALANCE", data: {
|
timeout,
|
||||||
error: response.error
|
},
|
||||||
}, requestId }
|
(response) => {
|
||||||
}));
|
if (response.error) {
|
||||||
} else {
|
document.dispatchEvent(
|
||||||
// Include the requestId in the detail when dispatching the response
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
detail: {
|
||||||
detail: { type: "LTC_BALANCE", data: response, requestId }
|
type: "LTC_BALANCE",
|
||||||
}));
|
data: {
|
||||||
|
error: response.error,
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Include the requestId in the detail when dispatching the response
|
||||||
|
document.dispatchEvent(
|
||||||
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
|
detail: { type: "LTC_BALANCE", data: response, requestId },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
} else if(type === 'CHECK_IF_LOCAL'){
|
} else if (type === "CHECK_IF_LOCAL") {
|
||||||
|
const hostname = window.location.hostname;
|
||||||
|
const res = await connection(hostname);
|
||||||
const hostname = window.location.hostname
|
if (!res) {
|
||||||
const res = await connection(hostname)
|
document.dispatchEvent(
|
||||||
if(!res){
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
detail: {
|
||||||
detail: { type: "USER_INFO", data: {
|
type: "USER_INFO",
|
||||||
error: "Not authorized"
|
data: {
|
||||||
}, requestId }
|
error: "Not authorized",
|
||||||
}));
|
},
|
||||||
return
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
chrome?.runtime?.sendMessage({ action: "checkLocal", payload: {
|
chrome?.runtime?.sendMessage(
|
||||||
hostname
|
{
|
||||||
}, timeout }, (response) => {
|
action: "checkLocal",
|
||||||
|
payload: {
|
||||||
if (response.error) {
|
hostname,
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
},
|
||||||
detail: { type: "CHECK_IF_LOCAL", data: {
|
timeout,
|
||||||
error: response.error
|
},
|
||||||
}, requestId }
|
(response) => {
|
||||||
}));
|
if (response.error) {
|
||||||
} else {
|
document.dispatchEvent(
|
||||||
// Include the requestId in the detail when dispatching the response
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
detail: {
|
||||||
detail: { type: "CHECK_IF_LOCAL", data: response, requestId }
|
type: "CHECK_IF_LOCAL",
|
||||||
}));
|
data: {
|
||||||
|
error: response.error,
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Include the requestId in the detail when dispatching the response
|
||||||
|
document.dispatchEvent(
|
||||||
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
|
detail: { type: "CHECK_IF_LOCAL", data: response, requestId },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
} else if (type === 'REQUEST_AUTHENTICATION') {
|
} else if (type === "REQUEST_AUTHENTICATION") {
|
||||||
const hostname = window.location.hostname
|
const hostname = window.location.hostname;
|
||||||
const res = await connection(hostname)
|
const res = await connection(hostname);
|
||||||
if(!res){
|
if (!res) {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
document.dispatchEvent(
|
||||||
detail: { type: "USER_INFO", data: {
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
error: "Not authorized"
|
detail: {
|
||||||
}, requestId }
|
type: "USER_INFO",
|
||||||
}));
|
data: {
|
||||||
return
|
error: "Not authorized",
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
chrome?.runtime?.sendMessage({ action: "authentication", payload: {
|
chrome?.runtime?.sendMessage(
|
||||||
hostname
|
{
|
||||||
}, timeout }, (response) => {
|
action: "authentication",
|
||||||
if (response.error) {
|
payload: {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
hostname,
|
||||||
detail: { type: "AUTHENTICATION", data: {
|
},
|
||||||
error: response.error
|
timeout,
|
||||||
}, requestId }
|
},
|
||||||
}));
|
(response) => {
|
||||||
} else {
|
if (response.error) {
|
||||||
// Include the requestId in the detail when dispatching the response
|
document.dispatchEvent(
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
detail: { type: "AUTHENTICATION", data: response, requestId }
|
detail: {
|
||||||
}));
|
type: "AUTHENTICATION",
|
||||||
|
data: {
|
||||||
|
error: response.error,
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Include the requestId in the detail when dispatching the response
|
||||||
|
document.dispatchEvent(
|
||||||
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
|
detail: { type: "AUTHENTICATION", data: response, requestId },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
} else if (type === 'REQUEST_SEND_QORT') {
|
} else if (type === "REQUEST_SEND_QORT") {
|
||||||
const hostname = window.location.hostname
|
const hostname = window.location.hostname;
|
||||||
const res = await connection(hostname)
|
const res = await connection(hostname);
|
||||||
if(!res){
|
if (!res) {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
document.dispatchEvent(
|
||||||
detail: { type: "USER_INFO", data: {
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
error: "Not authorized"
|
detail: {
|
||||||
}, requestId }
|
type: "USER_INFO",
|
||||||
}));
|
data: {
|
||||||
return
|
error: "Not authorized",
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
chrome?.runtime?.sendMessage({ action: "sendQort", payload: {
|
chrome?.runtime?.sendMessage(
|
||||||
hostname,
|
{
|
||||||
amount: payload.amount,
|
action: "sendQort",
|
||||||
description: payload.description,
|
payload: {
|
||||||
address: payload.address
|
hostname,
|
||||||
}, timeout }, (response) => {
|
amount: payload.amount,
|
||||||
if (response.error) {
|
description: payload.description,
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
address: payload.address,
|
||||||
detail: { type: "SEND_QORT", data: {
|
},
|
||||||
error: response.error
|
timeout,
|
||||||
}, requestId }
|
},
|
||||||
}));
|
(response) => {
|
||||||
} else {
|
if (response.error) {
|
||||||
// Include the requestId in the detail when dispatching the response
|
document.dispatchEvent(
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
detail: { type: "SEND_QORT", data: response, requestId }
|
detail: {
|
||||||
}));
|
type: "SEND_QORT",
|
||||||
|
data: {
|
||||||
|
error: response.error,
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Include the requestId in the detail when dispatching the response
|
||||||
|
document.dispatchEvent(
|
||||||
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
|
detail: { type: "SEND_QORT", data: response, requestId },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
} else if (type === 'REQUEST_CLOSE_POPUP') {
|
} else if (type === "REQUEST_CLOSE_POPUP") {
|
||||||
const hostname = window.location.hostname
|
const hostname = window.location.hostname;
|
||||||
const res = await connection(hostname)
|
const res = await connection(hostname);
|
||||||
if(!res){
|
if (!res) {
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
document.dispatchEvent(
|
||||||
detail: { type: "USER_INFO", data: {
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
error: "Not authorized"
|
detail: {
|
||||||
}, requestId }
|
type: "USER_INFO",
|
||||||
}));
|
data: {
|
||||||
return
|
error: "Not authorized",
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
chrome?.runtime?.sendMessage({ action: "closePopup" }, (response) => {
|
chrome?.runtime?.sendMessage({ action: "closePopup" }, (response) => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
|
document.dispatchEvent(
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
detail: { type: "CLOSE_POPUP", data: {
|
detail: {
|
||||||
error: response.error
|
type: "CLOSE_POPUP",
|
||||||
}, requestId }
|
data: {
|
||||||
}));
|
error: response.error,
|
||||||
|
},
|
||||||
|
requestId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// Include the requestId in the detail when dispatching the response
|
// Include the requestId in the detail when dispatching the response
|
||||||
document.dispatchEvent(new CustomEvent('qortalExtensionResponses', {
|
document.dispatchEvent(
|
||||||
detail: { type: "CLOSE_POPUP", data: true, requestId }
|
new CustomEvent("qortalExtensionResponses", {
|
||||||
}));
|
detail: { type: "CLOSE_POPUP", data: true, requestId },
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Handle other request types as needed...
|
// Handle other request types as needed...
|
||||||
});
|
});
|
||||||
|
|
||||||
|
chrome.runtime?.onMessage.addListener(function (message, sender, sendResponse) {
|
||||||
chrome.runtime?.onMessage.addListener(function(message, sender, sendResponse) {
|
|
||||||
if (message.type === "LOGOUT") {
|
if (message.type === "LOGOUT") {
|
||||||
// Notify the web page
|
// Notify the web page
|
||||||
window.postMessage({
|
window.postMessage(
|
||||||
type: "LOGOUT",
|
{
|
||||||
from: 'qortal'
|
type: "LOGOUT",
|
||||||
}, "*");
|
from: "qortal",
|
||||||
|
},
|
||||||
|
"*"
|
||||||
|
);
|
||||||
} else if (message.type === "RESPONSE_FOR_TRADES") {
|
} else if (message.type === "RESPONSE_FOR_TRADES") {
|
||||||
// Notify the web page
|
// Notify the web page
|
||||||
window.postMessage({
|
window.postMessage(
|
||||||
|
{
|
||||||
type: "RESPONSE_FOR_TRADES",
|
type: "RESPONSE_FOR_TRADES",
|
||||||
from: 'qortal',
|
from: "qortal",
|
||||||
payload: message.message
|
payload: message.message,
|
||||||
}, "*");
|
},
|
||||||
}
|
"*"
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const lastActionTimestamps = {};
|
||||||
|
|
||||||
|
// Function to debounce actions based on message.action
|
||||||
|
function debounceAction(action, wait = 500) {
|
||||||
|
const currentTime = Date.now();
|
||||||
|
|
||||||
|
// Check if this action has been recently triggered
|
||||||
|
if (lastActionTimestamps[action] && currentTime - lastActionTimestamps[action] < wait) {
|
||||||
|
// Ignore this action if it occurred within the debounce time window
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the last timestamp for this action
|
||||||
|
lastActionTimestamps[action] = currentTime;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!window.hasAddedQortalListener) {
|
||||||
|
console.log("Listener added");
|
||||||
|
window.hasAddedQortalListener = true;
|
||||||
|
//qortalRequests
|
||||||
|
const listener = (event) => {
|
||||||
|
|
||||||
|
event.preventDefault(); // Prevent default behavior
|
||||||
|
event.stopImmediatePropagation(); // Stop other listeners from firing
|
||||||
|
// Verify that the message is from the web page and contains expected data
|
||||||
|
if (event.source !== window || !event.data || !event.data.action) return;
|
||||||
|
// // Check if this action should be processed (debounced)
|
||||||
|
// if (!debounceAction(event.data.action)) {
|
||||||
|
// console.log(`Debounced action: ${event.data.action}`);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
if(event?.data?.requestedHandler !== 'UI') return
|
||||||
|
if (event.data.action === "GET_USER_ACCOUNT") {
|
||||||
|
chrome?.runtime?.sendMessage(
|
||||||
|
{ action: "GET_USER_ACCOUNT", type: "qortalRequest" },
|
||||||
|
(response) => {
|
||||||
|
if (response.error) {
|
||||||
|
event.ports[0].postMessage({
|
||||||
|
result: null,
|
||||||
|
error: response.error,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
event.ports[0].postMessage({
|
||||||
|
result: response,
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else if (event.data.action === "SEND_COIN") {
|
||||||
|
chrome?.runtime?.sendMessage(
|
||||||
|
{ action: "SEND_COIN", type: "qortalRequest", payload: event.data },
|
||||||
|
(response) => {
|
||||||
|
if (response.error) {
|
||||||
|
event.ports[0].postMessage({
|
||||||
|
result: null,
|
||||||
|
error: response.error,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
event.ports[0].postMessage({
|
||||||
|
result: response,
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else if (event.data.action === "ENCRYPT_DATA") {
|
||||||
|
chrome?.runtime?.sendMessage(
|
||||||
|
{ action: "ENCRYPT_DATA", type: "qortalRequest", payload: event.data },
|
||||||
|
(response) => {
|
||||||
|
if (response.error) {
|
||||||
|
event.ports[0].postMessage({
|
||||||
|
result: null,
|
||||||
|
error: response.error,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
event.ports[0].postMessage({
|
||||||
|
result: response,
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else if (event.data.action === "DECRYPT_DATA") {
|
||||||
|
chrome?.runtime?.sendMessage(
|
||||||
|
{ action: "DECRYPT_DATA", type: "qortalRequest", payload: event.data },
|
||||||
|
(response) => {
|
||||||
|
if (response.error) {
|
||||||
|
event.ports[0].postMessage({
|
||||||
|
result: null,
|
||||||
|
error: response.error,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
event.ports[0].postMessage({
|
||||||
|
result: response,
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else if (event.data.action === "GET_LIST_ITEMS") {
|
||||||
|
console.log("message", event);
|
||||||
|
|
||||||
|
chrome?.runtime?.sendMessage(
|
||||||
|
{
|
||||||
|
action: "GET_LIST_ITEMS",
|
||||||
|
type: "qortalRequest",
|
||||||
|
payload: event.data,
|
||||||
|
},
|
||||||
|
(response) => {
|
||||||
|
console.log("response", response);
|
||||||
|
if (response.error) {
|
||||||
|
event.ports[0].postMessage({
|
||||||
|
result: null,
|
||||||
|
error: response.error,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
event.ports[0].postMessage({
|
||||||
|
result: response,
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener("message", listener);
|
||||||
|
}
|
||||||
|
151
src/App.tsx
151
src/App.tsx
@ -304,6 +304,8 @@ function App() {
|
|||||||
const holdRefExtState = useRef<extStates>("not-authenticated");
|
const holdRefExtState = useRef<extStates>("not-authenticated");
|
||||||
const isFocusedRef = useRef<boolean>(true);
|
const isFocusedRef = useRef<boolean>(true);
|
||||||
const { isShow, onCancel, onOk, show, message } = useModal();
|
const { isShow, onCancel, onOk, show, message } = useModal();
|
||||||
|
const { onCancel: onCancelQortalRequest, onOk: onOkQortalRequest, show: showQortalRequest, isShow: isShowQortalRequest, message: messageQortalRequest } = useModal();
|
||||||
|
|
||||||
const [openRegisterName, setOpenRegisterName] = useState(false);
|
const [openRegisterName, setOpenRegisterName] = useState(false);
|
||||||
const registerNamePopoverRef = useRef(null);
|
const registerNamePopoverRef = useRef(null);
|
||||||
const [isLoadingRegisterName, setIsLoadingRegisterName] = useState(false);
|
const [isLoadingRegisterName, setIsLoadingRegisterName] = useState(false);
|
||||||
@ -561,55 +563,49 @@ function App() {
|
|||||||
setRequestAuthentication(null);
|
setRequestAuthentication(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const qortalRequestPermisson = async (message, sender, sendResponse)=> {
|
||||||
|
if (
|
||||||
|
message.action === "QORTAL_REQUEST_PERMISSION" &&
|
||||||
|
!isMainWindow
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
await showQortalRequest(message?.payload)
|
||||||
|
sendResponse(true)
|
||||||
|
} catch (error) {
|
||||||
|
sendResponse(false)
|
||||||
|
} finally {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Listen for messages from the background script
|
// Listen for messages from the background script
|
||||||
chrome.runtime?.onMessage.addListener((message, sender, sendResponse) => {
|
const messageListener = (message, sender, sendResponse) => {
|
||||||
// Check if the message is to update the state
|
// Handle various actions
|
||||||
if (
|
if (message.action === "UPDATE_STATE_CONFIRM_SEND_QORT" && !isMainWindow) {
|
||||||
message.action === "UPDATE_STATE_CONFIRM_SEND_QORT" &&
|
|
||||||
!isMainWindow
|
|
||||||
) {
|
|
||||||
// Update the component state with the received 'sendqort' state
|
|
||||||
setSendqortState(message.payload);
|
setSendqortState(message.payload);
|
||||||
setExtstate("web-app-request-payment");
|
setExtstate("web-app-request-payment");
|
||||||
} else if (message.action === "closePopup" && !isMainWindow) {
|
} else if (message.action === "closePopup" && !isMainWindow) {
|
||||||
// Update the component state with the received 'sendqort' state
|
|
||||||
window.close();
|
window.close();
|
||||||
} else if (
|
} else if (message.action === "UPDATE_STATE_REQUEST_CONNECTION" && !isMainWindow) {
|
||||||
message.action === "UPDATE_STATE_REQUEST_CONNECTION" &&
|
|
||||||
!isMainWindow
|
|
||||||
) {
|
|
||||||
|
|
||||||
// Update the component state with the received 'sendqort' state
|
|
||||||
setRequestConnection(message.payload);
|
setRequestConnection(message.payload);
|
||||||
setExtstate("web-app-request-connection");
|
setExtstate("web-app-request-connection");
|
||||||
} else if (
|
} else if (message.action === "UPDATE_STATE_REQUEST_BUY_ORDER" && !isMainWindow) {
|
||||||
message.action === "UPDATE_STATE_REQUEST_BUY_ORDER" &&
|
|
||||||
!isMainWindow
|
|
||||||
) {
|
|
||||||
// Update the component state with the received 'sendqort' state
|
|
||||||
setRequestBuyOrder(message.payload);
|
setRequestBuyOrder(message.payload);
|
||||||
setExtstate("web-app-request-buy-order");
|
setExtstate("web-app-request-buy-order");
|
||||||
} else if (
|
} else if (message.action === "UPDATE_STATE_REQUEST_AUTHENTICATION" && !isMainWindow) {
|
||||||
message.action === "UPDATE_STATE_REQUEST_AUTHENTICATION" &&
|
|
||||||
!isMainWindow
|
|
||||||
) {
|
|
||||||
// Update the component state with the received 'sendqort' state
|
|
||||||
setRequestAuthentication(message.payload);
|
setRequestAuthentication(message.payload);
|
||||||
setExtstate("web-app-request-authentication");
|
setExtstate("web-app-request-authentication");
|
||||||
} else if (message.action === "SET_COUNTDOWN" && !isMainWindow) {
|
} else if (message.action === "SET_COUNTDOWN" && !isMainWindow) {
|
||||||
setCountdown(message.payload);
|
setCountdown(message.payload);
|
||||||
} else if (message.action === "INITIATE_MAIN") {
|
} else if (message.action === "INITIATE_MAIN") {
|
||||||
// Update the component state with the received 'sendqort' state
|
|
||||||
setIsMain(true);
|
setIsMain(true);
|
||||||
isMainRef.current = true;
|
isMainRef.current = true;
|
||||||
} else if (message.action === "CHECK_FOCUS" && isMainWindow) {
|
} else if (message.action === "CHECK_FOCUS" && isMainWindow) {
|
||||||
|
sendResponse(isFocusedRef.current); // Synchronous response
|
||||||
sendResponse(isFocusedRef.current);
|
return true; // Return true if you plan to send a response asynchronously
|
||||||
} else if (
|
} else if (message.action === "NOTIFICATION_OPEN_DIRECT" && isMainWindow) {
|
||||||
message.action === "NOTIFICATION_OPEN_DIRECT" &&
|
|
||||||
isMainWindow
|
|
||||||
) {
|
|
||||||
executeEvent("openDirectMessage", {
|
executeEvent("openDirectMessage", {
|
||||||
from: message.payload.from,
|
from: message.payload.from,
|
||||||
});
|
});
|
||||||
@ -617,22 +613,34 @@ function App() {
|
|||||||
executeEvent("openGroupMessage", {
|
executeEvent("openGroupMessage", {
|
||||||
from: message.payload.from,
|
from: message.payload.from,
|
||||||
});
|
});
|
||||||
} else if (
|
} else if (message.action === "NOTIFICATION_OPEN_ANNOUNCEMENT_GROUP" && isMainWindow) {
|
||||||
message.action === "NOTIFICATION_OPEN_ANNOUNCEMENT_GROUP" &&
|
|
||||||
isMainWindow
|
|
||||||
) {
|
|
||||||
executeEvent("openGroupAnnouncement", {
|
executeEvent("openGroupAnnouncement", {
|
||||||
from: message.payload.from,
|
from: message.payload.from,
|
||||||
});
|
});
|
||||||
} else if (
|
} else if (message.action === "NOTIFICATION_OPEN_THREAD_NEW_POST" && isMainWindow) {
|
||||||
message.action === "NOTIFICATION_OPEN_THREAD_NEW_POST" &&
|
|
||||||
isMainWindow
|
|
||||||
) {
|
|
||||||
executeEvent("openThreadNewPost", {
|
executeEvent("openThreadNewPost", {
|
||||||
data: message.payload.data,
|
data: message.payload.data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
// Call the permission request handler for "QORTAL_REQUEST_PERMISSION"
|
||||||
|
qortalRequestPermisson(message, sender, sendResponse);
|
||||||
|
if (message.action === "QORTAL_REQUEST_PERMISSION" && !isMainWindow) {
|
||||||
|
console.log('isMainWindow', isMainWindow, window?.location?.href )
|
||||||
|
return true; // Return true to indicate an async response is coming
|
||||||
|
}
|
||||||
|
if(message.action === "QORTAL_REQUEST_PERMISSION" && isMainWindow){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add message listener
|
||||||
|
chrome.runtime?.onMessage.addListener(messageListener);
|
||||||
|
|
||||||
|
// Clean up the listener on component unmount
|
||||||
|
return () => {
|
||||||
|
chrome.runtime?.onMessage.removeListener(messageListener);
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
@ -1800,6 +1808,68 @@ function App() {
|
|||||||
</CustomButton>
|
</CustomButton>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{isShowQortalRequest && !isMainWindow && (
|
||||||
|
<>
|
||||||
|
<Spacer height="100px" />
|
||||||
|
|
||||||
|
<TextP
|
||||||
|
sx={{
|
||||||
|
textAlign: "center",
|
||||||
|
lineHeight: "15px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{messageQortalRequest?.text1}
|
||||||
|
</TextP>
|
||||||
|
<Spacer height="10px" />
|
||||||
|
<TextP
|
||||||
|
sx={{
|
||||||
|
textAlign: "center",
|
||||||
|
lineHeight: "15px",
|
||||||
|
fontSize: "10px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{messageQortalRequest?.text2}
|
||||||
|
</TextP>
|
||||||
|
<Spacer height="15px" />
|
||||||
|
<TextP
|
||||||
|
sx={{
|
||||||
|
textAlign: "center",
|
||||||
|
lineHeight: 1.2,
|
||||||
|
fontSize: "16px",
|
||||||
|
fontWeight: 700,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{messageQortalRequest?.text3}
|
||||||
|
</TextP>
|
||||||
|
<Spacer height="29px" />
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "14px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CustomButton
|
||||||
|
sx={{
|
||||||
|
minWidth: "102px",
|
||||||
|
}}
|
||||||
|
onClick={() => onOkQortalRequest("accepted")}
|
||||||
|
>
|
||||||
|
accept
|
||||||
|
</CustomButton>
|
||||||
|
<CustomButton
|
||||||
|
sx={{
|
||||||
|
minWidth: "102px",
|
||||||
|
}}
|
||||||
|
onClick={() => onCancelQortalRequest()}
|
||||||
|
>
|
||||||
|
decline
|
||||||
|
</CustomButton>
|
||||||
|
</Box>
|
||||||
|
<ErrorText>{sendPaymentError}</ErrorText>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
{extState === "web-app-request-buy-order" && !isMainWindow && (
|
{extState === "web-app-request-buy-order" && !isMainWindow && (
|
||||||
<>
|
<>
|
||||||
<Spacer height="100px" />
|
<Spacer height="100px" />
|
||||||
@ -1890,6 +1960,7 @@ function App() {
|
|||||||
<ErrorText>{sendPaymentError}</ErrorText>
|
<ErrorText>{sendPaymentError}</ErrorText>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{extState === "web-app-request-payment" && !isMainWindow && (
|
{extState === "web-app-request-payment" && !isMainWindow && (
|
||||||
<>
|
<>
|
||||||
<Spacer height="100px" />
|
<Spacer height="100px" />
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
// import { encryptAndPublishSymmetricKeyGroupChat } from "./backgroundFunctions/encryption";
|
// import { encryptAndPublishSymmetricKeyGroupChat } from "./backgroundFunctions/encryption";
|
||||||
|
|
||||||
|
import './qortalRequests'
|
||||||
import { constant, isArray } from "lodash";
|
import { constant, isArray } from "lodash";
|
||||||
import {
|
import {
|
||||||
decryptGroupEncryption,
|
decryptGroupEncryption,
|
||||||
@ -144,7 +146,7 @@ export const createEndpointSocket = async (endpoint) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createEndpoint = async (endpoint, customApi) => {
|
export const createEndpoint = async (endpoint, customApi?: string) => {
|
||||||
if (customApi) {
|
if (customApi) {
|
||||||
return `${customApi}${endpoint}`;
|
return `${customApi}${endpoint}`;
|
||||||
}
|
}
|
||||||
@ -949,7 +951,7 @@ async function getAddressInfo(address) {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getKeyPair() {
|
export async function getKeyPair() {
|
||||||
const res = await chrome.storage.local.get(["keyPair"]);
|
const res = await chrome.storage.local.get(["keyPair"]);
|
||||||
if (res?.keyPair) {
|
if (res?.keyPair) {
|
||||||
return res.keyPair;
|
return res.keyPair;
|
||||||
@ -958,7 +960,7 @@ async function getKeyPair() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getSaveWallet() {
|
export async function getSaveWallet() {
|
||||||
const res = await chrome.storage.local.get(["walletInfo"]);
|
const res = await chrome.storage.local.get(["walletInfo"]);
|
||||||
if (res?.walletInfo) {
|
if (res?.walletInfo) {
|
||||||
return res.walletInfo;
|
return res.walletInfo;
|
||||||
@ -2498,7 +2500,7 @@ async function listenForChatMessageForBuyOrder({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeDuplicateWindow(popupUrl) {
|
export function removeDuplicateWindow(popupUrl) {
|
||||||
chrome.windows.getAll(
|
chrome.windows.getAll(
|
||||||
{ populate: true, windowTypes: ["popup"] },
|
{ populate: true, windowTypes: ["popup"] },
|
||||||
(windows) => {
|
(windows) => {
|
||||||
@ -2800,6 +2802,7 @@ async function getChatHeadsDirect() {
|
|||||||
}
|
}
|
||||||
chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
||||||
if (request) {
|
if (request) {
|
||||||
|
|
||||||
switch (request.action) {
|
switch (request.action) {
|
||||||
case "version":
|
case "version":
|
||||||
// Example: respond with the version
|
// Example: respond with the version
|
||||||
|
@ -331,4 +331,43 @@ export function decryptGroupData(data64EncryptedData: string, privateKey: string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new Error("Unable to decrypt data")
|
throw new Error("Unable to decrypt data")
|
||||||
|
}
|
||||||
|
|
||||||
|
export function uint8ArrayStartsWith(uint8Array, string) {
|
||||||
|
const stringEncoder = new TextEncoder()
|
||||||
|
const stringUint8Array = stringEncoder.encode(string)
|
||||||
|
if (uint8Array.length < stringUint8Array.length) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for (let i = 0; i < stringUint8Array.length; i++) {
|
||||||
|
if (uint8Array[i] !== stringUint8Array[i]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
export function decryptDeprecatedSingle(uint8Array, publicKey, privateKey) {
|
||||||
|
const combinedData = uint8Array
|
||||||
|
const str = "qortalEncryptedData"
|
||||||
|
const strEncoder = new TextEncoder()
|
||||||
|
const strUint8Array = strEncoder.encode(str)
|
||||||
|
const strData = combinedData.slice(0, strUint8Array.length)
|
||||||
|
const nonce = combinedData.slice(strUint8Array.length, strUint8Array.length + 24)
|
||||||
|
const _encryptedData = combinedData.slice(strUint8Array.length + 24)
|
||||||
|
|
||||||
|
const _publicKey = window.parent.Base58.decode(publicKey)
|
||||||
|
if (!privateKey || !_publicKey) {
|
||||||
|
throw new Error("Unable to retrieve keys")
|
||||||
|
}
|
||||||
|
const convertedPrivateKey = ed2curve.convertSecretKey(privateKey)
|
||||||
|
const convertedPublicKey = ed2curve.convertPublicKey(_publicKey)
|
||||||
|
const sharedSecret = new Uint8Array(32)
|
||||||
|
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey)
|
||||||
|
const _chatEncryptionSeed = new window.parent.Sha256().process(sharedSecret).finish().result
|
||||||
|
const _decryptedData = nacl.secretbox.open(_encryptedData, nonce, _chatEncryptionSeed)
|
||||||
|
if (!_decryptedData) {
|
||||||
|
throw new Error("Unable to decrypt")
|
||||||
|
}
|
||||||
|
return uint8ArrayToBase64(_decryptedData)
|
||||||
}
|
}
|
85
src/qortalRequests.ts
Normal file
85
src/qortalRequests.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import { decryptData, encryptData, getListItems, getUserAccount, sendCoin } from "./qortalRequests/get";
|
||||||
|
|
||||||
|
chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
||||||
|
if (request) {
|
||||||
|
switch (request.action) {
|
||||||
|
case "GET_USER_ACCOUNT": {
|
||||||
|
getUserAccount()
|
||||||
|
.then((res) => {
|
||||||
|
sendResponse(res);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
sendResponse({ error: "Unable to get user account" });
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "ENCRYPT_DATA": {
|
||||||
|
const data = request.payload;
|
||||||
|
|
||||||
|
encryptData(data)
|
||||||
|
.then((res) => {
|
||||||
|
sendResponse(res);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
sendResponse({ error: error.message });
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "DECRYPT_DATA": {
|
||||||
|
const data = request.payload;
|
||||||
|
|
||||||
|
decryptData(data)
|
||||||
|
.then((res) => {
|
||||||
|
sendResponse(res);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
sendResponse({ error: error.message });
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "GET_LIST_ITEMS": {
|
||||||
|
const data = request.payload;
|
||||||
|
|
||||||
|
getListItems(data)
|
||||||
|
.then((res) => {
|
||||||
|
sendResponse(res);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
sendResponse({ error: error.message });
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "SEND_COIN": {
|
||||||
|
const data = request.payload;
|
||||||
|
const requiredFields = ["coin", "destinationAddress", "amount"];
|
||||||
|
const missingFields: string[] = [];
|
||||||
|
requiredFields.forEach((field) => {
|
||||||
|
if (!data[field]) {
|
||||||
|
missingFields.push(field);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (missingFields.length > 0) {
|
||||||
|
const missingFieldsString = missingFields.join(", ");
|
||||||
|
const errorMsg = `Missing fields: ${missingFieldsString}`;
|
||||||
|
sendResponse({ error: errorMsg });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Example: respond with the version
|
||||||
|
sendCoin()
|
||||||
|
.then((res) => {
|
||||||
|
sendResponse(res);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
sendResponse({ error: "Unable to get user account" });
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
281
src/qortalRequests/get.ts
Normal file
281
src/qortalRequests/get.ts
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
import { createEndpoint, getKeyPair, getSaveWallet, removeDuplicateWindow } from "../background";
|
||||||
|
import Base58 from "../deps/Base58";
|
||||||
|
import {
|
||||||
|
base64ToUint8Array,
|
||||||
|
decryptDeprecatedSingle,
|
||||||
|
decryptGroupData,
|
||||||
|
encryptDataGroup,
|
||||||
|
uint8ArrayStartsWith,
|
||||||
|
uint8ArrayToBase64,
|
||||||
|
} from "../qdn/encryption/group-encryption";
|
||||||
|
import { fileToBase64 } from "../utils/fileReading";
|
||||||
|
|
||||||
|
async function getUserPermission(payload: any) {
|
||||||
|
|
||||||
|
|
||||||
|
function waitForWindowReady(windowId) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const checkInterval = setInterval(() => {
|
||||||
|
chrome.windows.get(windowId, (win) => {
|
||||||
|
if (chrome.runtime.lastError) {
|
||||||
|
clearInterval(checkInterval); // Stop polling if there's an error
|
||||||
|
resolve(false);
|
||||||
|
} else if (win.state === 'normal' || win.state === 'maximized') {
|
||||||
|
clearInterval(checkInterval); // Window is ready
|
||||||
|
resolve(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 100); // Check every 100ms
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await new Promise((res)=> {
|
||||||
|
const popupUrl = chrome.runtime.getURL(
|
||||||
|
"index.html?secondary=true"
|
||||||
|
);
|
||||||
|
console.log('popupUrl', popupUrl)
|
||||||
|
chrome.windows.getAll(
|
||||||
|
{ populate: true, windowTypes: ["popup"] },
|
||||||
|
(windows) => {
|
||||||
|
console.log('windows', windows)
|
||||||
|
// Attempt to find an existing popup window that has a tab with the correct URL
|
||||||
|
const existingPopup = windows.find(
|
||||||
|
(w) =>
|
||||||
|
w.tabs &&
|
||||||
|
w.tabs.some(
|
||||||
|
(tab) => tab.url && tab.url.startsWith(popupUrl)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (existingPopup) {
|
||||||
|
// If the popup exists but is minimized or not focused, focus it
|
||||||
|
chrome.windows.update(existingPopup.id, {
|
||||||
|
focused: true,
|
||||||
|
state: "normal",
|
||||||
|
});
|
||||||
|
res(null)
|
||||||
|
} else {
|
||||||
|
// No existing popup found, create a new one
|
||||||
|
chrome.system.display.getInfo((displays) => {
|
||||||
|
// Assuming the primary display is the first one (adjust logic as needed)
|
||||||
|
const primaryDisplay = displays[0];
|
||||||
|
const screenWidth = primaryDisplay.bounds.width;
|
||||||
|
const windowHeight = 500; // Your window height
|
||||||
|
const windowWidth = 400; // Your window width
|
||||||
|
|
||||||
|
// Calculate left position for the window to appear on the right of the screen
|
||||||
|
const leftPosition = screenWidth - windowWidth;
|
||||||
|
|
||||||
|
// Calculate top position for the window, adjust as desired
|
||||||
|
const topPosition =
|
||||||
|
(primaryDisplay.bounds.height - windowHeight) / 2;
|
||||||
|
|
||||||
|
chrome.windows.create(
|
||||||
|
{
|
||||||
|
url: popupUrl,
|
||||||
|
type: "popup",
|
||||||
|
width: windowWidth,
|
||||||
|
height: windowHeight,
|
||||||
|
left: leftPosition,
|
||||||
|
top: 0,
|
||||||
|
},
|
||||||
|
async (newWindow) => {
|
||||||
|
await waitForWindowReady(newWindow.id);
|
||||||
|
removeDuplicateWindow(popupUrl);
|
||||||
|
res(null)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})
|
||||||
|
|
||||||
|
await new Promise((res)=> {
|
||||||
|
setTimeout(() => {
|
||||||
|
chrome.runtime.sendMessage({
|
||||||
|
action: "SET_COUNTDOWN",
|
||||||
|
payload: 15,
|
||||||
|
});
|
||||||
|
res(true)
|
||||||
|
}, 450);
|
||||||
|
})
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
// Set a timeout for 1 second
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
resolve(false); // No response within 10 second, assume not focused
|
||||||
|
}, 15000);
|
||||||
|
|
||||||
|
// Send message to the content script to check focus
|
||||||
|
console.log('send msg')
|
||||||
|
chrome.runtime.sendMessage({ action: "QORTAL_REQUEST_PERMISSION", payload }, (response) => {
|
||||||
|
console.log('permission response', response)
|
||||||
|
if(response === undefined) return
|
||||||
|
clearTimeout(timeout); // Clear the timeout if we get a response
|
||||||
|
|
||||||
|
if (chrome.runtime.lastError) {
|
||||||
|
resolve(false); // Error occurred, assume not focused
|
||||||
|
} else {
|
||||||
|
resolve(response); // Resolve based on the response
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getUserAccount = async () => {
|
||||||
|
try {
|
||||||
|
const wallet = await getSaveWallet();
|
||||||
|
const address = wallet.address0;
|
||||||
|
const publicKey = wallet.publicKey;
|
||||||
|
return {
|
||||||
|
address,
|
||||||
|
publicKey,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error("Unable to fetch user account");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const encryptData = async (data) => {
|
||||||
|
let data64 = data.data64;
|
||||||
|
let publicKeys = data.publicKeys || [];
|
||||||
|
if (data.file) {
|
||||||
|
data64 = await fileToBase64(data.file);
|
||||||
|
}
|
||||||
|
if (!data64) {
|
||||||
|
throw new Error("Please include data to encrypt");
|
||||||
|
}
|
||||||
|
|
||||||
|
const resKeyPair = await getKeyPair();
|
||||||
|
const parsedData = JSON.parse(resKeyPair);
|
||||||
|
const privateKey = parsedData.privateKey;
|
||||||
|
const userPublicKey = parsedData.publicKey;
|
||||||
|
|
||||||
|
const encryptDataResponse = encryptDataGroup({
|
||||||
|
data64,
|
||||||
|
publicKeys: publicKeys,
|
||||||
|
privateKey,
|
||||||
|
userPublicKey,
|
||||||
|
});
|
||||||
|
if (encryptDataResponse) {
|
||||||
|
return encryptDataResponse;
|
||||||
|
} else {
|
||||||
|
throw new Error("Unable to encrypt");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export const decryptData = async (data) => {
|
||||||
|
const { encryptedData, publicKey } = data;
|
||||||
|
|
||||||
|
|
||||||
|
if (!encryptedData) {
|
||||||
|
throw new Error(`Missing fields: encryptedData`);
|
||||||
|
}
|
||||||
|
const resKeyPair = await getKeyPair();
|
||||||
|
const parsedData = JSON.parse(resKeyPair);
|
||||||
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
||||||
|
const uint8Array = base64ToUint8Array(encryptedData);
|
||||||
|
const startsWithQortalEncryptedData = uint8ArrayStartsWith(
|
||||||
|
uint8Array,
|
||||||
|
"qortalEncryptedData"
|
||||||
|
);
|
||||||
|
if (startsWithQortalEncryptedData) {
|
||||||
|
if (!publicKey) {
|
||||||
|
throw new Error(`Missing fields: publicKey`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const decryptedDataToBase64 = decryptDeprecatedSingle(
|
||||||
|
uint8Array,
|
||||||
|
publicKey,
|
||||||
|
uint8PrivateKey
|
||||||
|
);
|
||||||
|
return decryptedDataToBase64;
|
||||||
|
}
|
||||||
|
const startsWithQortalGroupEncryptedData = uint8ArrayStartsWith(
|
||||||
|
uint8Array,
|
||||||
|
"qortalGroupEncryptedData"
|
||||||
|
);
|
||||||
|
if (startsWithQortalGroupEncryptedData) {
|
||||||
|
const decryptedData = decryptGroupData(
|
||||||
|
encryptedData,
|
||||||
|
parsedData.privateKey
|
||||||
|
);
|
||||||
|
const decryptedDataToBase64 = uint8ArrayToBase64(decryptedData);
|
||||||
|
return decryptedDataToBase64;
|
||||||
|
}
|
||||||
|
throw new Error("Unable to decrypt");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const getListItems = async (data) => {
|
||||||
|
const requiredFields = ['list_name']
|
||||||
|
const missingFields: string[] = []
|
||||||
|
requiredFields.forEach((field) => {
|
||||||
|
if (!data[field]) {
|
||||||
|
missingFields.push(field)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (missingFields.length > 0) {
|
||||||
|
const missingFieldsString = missingFields.join(', ')
|
||||||
|
const errorMsg = `Missing fields: ${missingFieldsString}`
|
||||||
|
throw new Error(errorMsg)
|
||||||
|
}
|
||||||
|
let skip = false
|
||||||
|
// if (window.parent.reduxStore.getState().app.qAPPAutoLists) {
|
||||||
|
// skip = true
|
||||||
|
// }
|
||||||
|
let resPermission
|
||||||
|
if (!skip) {
|
||||||
|
// res1 = await showModalAndWait(
|
||||||
|
// actions.GET_LIST_ITEMS,
|
||||||
|
// {
|
||||||
|
// list_name: data.list_name
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
|
||||||
|
resPermission = await getUserPermission({
|
||||||
|
text1: 'Do you give this application permission to',
|
||||||
|
text2: 'Access the list',
|
||||||
|
text3: data.list_name
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
console.log('resPermission', resPermission)
|
||||||
|
if (resPermission || skip) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
const url = await createEndpoint(`/lists/${data.list_name}`);
|
||||||
|
console.log('url', url)
|
||||||
|
const response = await fetch(url);
|
||||||
|
console.log('response', response)
|
||||||
|
if (!response.ok) throw new Error("Failed to fetch");
|
||||||
|
|
||||||
|
const list = await response.json();
|
||||||
|
return list
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error("Error in retrieving list")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const data = {}
|
||||||
|
throw new Error("User declined to share list")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendCoin = async () => {
|
||||||
|
try {
|
||||||
|
const wallet = await getSaveWallet();
|
||||||
|
const address = wallet.address0;
|
||||||
|
const publicKey = wallet.publicKey;
|
||||||
|
return {
|
||||||
|
address,
|
||||||
|
publicKey,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user