2024-04-14 14:57:30 +03:00
|
|
|
|
// @ts-nocheck
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// import { encryptAndPublishSymmetricKeyGroupChat } from "./backgroundFunctions/encryption";
|
2024-09-16 12:35:43 +03:00
|
|
|
|
import { constant, isArray } from "lodash";
|
2024-09-09 20:36:39 +03:00
|
|
|
|
import {
|
|
|
|
|
decryptGroupEncryption,
|
|
|
|
|
encryptAndPublishSymmetricKeyGroupChat,
|
|
|
|
|
publishGroupEncryptedResource,
|
|
|
|
|
uint8ArrayToObject,
|
|
|
|
|
} from "./backgroundFunctions/encryption";
|
|
|
|
|
import { PUBLIC_NOTIFICATION_CODE_FIRST_SECRET_KEY } from "./constants/codes";
|
|
|
|
|
import { QORT_DECIMALS } from "./constants/constants";
|
2024-04-14 14:57:30 +03:00
|
|
|
|
import Base58 from "./deps/Base58";
|
2024-09-09 20:36:39 +03:00
|
|
|
|
import {
|
|
|
|
|
base64ToUint8Array,
|
|
|
|
|
decryptSingle,
|
|
|
|
|
encryptSingle,
|
|
|
|
|
objectToBase64,
|
|
|
|
|
} from "./qdn/encryption/group-encryption";
|
|
|
|
|
import { reusableGet } from "./qdn/publish/pubish";
|
2024-07-12 23:44:21 -04:00
|
|
|
|
import { signChat } from "./transactions/signChat";
|
2024-04-14 14:57:30 +03:00
|
|
|
|
import { createTransaction } from "./transactions/transactions";
|
2024-07-04 20:14:32 +03:00
|
|
|
|
import { decryptChatMessage } from "./utils/decryptChatMessage";
|
2024-04-14 14:57:30 +03:00
|
|
|
|
import { decryptStoredWallet } from "./utils/decryptWallet";
|
|
|
|
|
import PhraseWallet from "./utils/generateWallet/phrase-wallet";
|
2024-09-11 15:42:01 +03:00
|
|
|
|
import { RequestQueueWithPromise } from "./utils/queue/queue";
|
2024-04-14 14:57:30 +03:00
|
|
|
|
import { validateAddress } from "./utils/validateAddress";
|
2024-09-09 20:36:39 +03:00
|
|
|
|
import { Sha256 } from "asmcrypto.js";
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let lastGroupNotification;
|
|
|
|
|
export const groupApi = "https://ext-node.qortal.link";
|
|
|
|
|
export const groupApiSocket = "wss://ext-node.qortal.link";
|
|
|
|
|
export const groupApiLocal = "http://127.0.0.1:12391";
|
|
|
|
|
export const groupApiSocketLocal = "ws://127.0.0.1:12391";
|
|
|
|
|
const timeDifferenceForNotificationChatsBackground = 600000;
|
|
|
|
|
const requestQueueAnnouncements = new RequestQueueWithPromise(1);
|
|
|
|
|
let isMobile = false;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-12 05:41:57 +03:00
|
|
|
|
const isMobileDevice = () => {
|
|
|
|
|
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-12 05:41:57 +03:00
|
|
|
|
if (/android/i.test(userAgent)) {
|
|
|
|
|
return true; // Android device
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
|
|
|
|
|
return true; // iOS device
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (isMobileDevice()) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
isMobile = true;
|
2024-09-12 05:41:57 +03:00
|
|
|
|
console.log("Running on a mobile device");
|
|
|
|
|
} else {
|
|
|
|
|
console.log("Running on a desktop");
|
|
|
|
|
}
|
2024-09-11 15:42:01 +03:00
|
|
|
|
const allQueues = {
|
|
|
|
|
requestQueueAnnouncements: requestQueueAnnouncements,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
};
|
2024-09-11 15:42:01 +03:00
|
|
|
|
|
|
|
|
|
const controlAllQueues = (action) => {
|
|
|
|
|
Object.keys(allQueues).forEach((key) => {
|
|
|
|
|
const val = allQueues[key];
|
|
|
|
|
try {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (typeof val[action] === "function") {
|
2024-09-11 15:42:01 +03:00
|
|
|
|
val[action]();
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(error);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const clearAllQueues = () => {
|
|
|
|
|
Object.keys(allQueues).forEach((key) => {
|
|
|
|
|
const val = allQueues[key];
|
|
|
|
|
try {
|
|
|
|
|
val.clear();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(error);
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
};
|
2024-09-11 15:42:01 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const pauseAllQueues = () => controlAllQueues("pause");
|
|
|
|
|
const resumeAllQueues = () => controlAllQueues("resume");
|
|
|
|
|
const checkDifference = (createdTimestamp) => {
|
|
|
|
|
return (
|
|
|
|
|
Date.now() - createdTimestamp < timeDifferenceForNotificationChatsBackground
|
|
|
|
|
);
|
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const getApiKeyFromStorage = async () => {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.storage.local.get("apiKey", (result) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
return reject(chrome.runtime.lastError);
|
|
|
|
|
}
|
|
|
|
|
resolve(result.apiKey || null); // Return null if apiKey isn't found
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
// const getArbitraryEndpoint = ()=> {
|
|
|
|
|
// const apiKey = await getApiKeyFromStorage(); // Retrieve apiKey asynchronously
|
|
|
|
|
// if (apiKey) {
|
|
|
|
|
// return `/arbitrary/resources/search`;
|
|
|
|
|
// } else {
|
|
|
|
|
// return `/arbitrary/resources/searchsimple`;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
const getArbitraryEndpoint = async () => {
|
|
|
|
|
const apiKey = await getApiKeyFromStorage(); // Retrieve apiKey asynchronously
|
|
|
|
|
if (apiKey) {
|
|
|
|
|
return `/arbitrary/resources/searchsimple`;
|
|
|
|
|
} else {
|
|
|
|
|
return `/arbitrary/resources/searchsimple`;
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
export const getBaseApi = async (customApi?: string) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (customApi) {
|
|
|
|
|
return customApi;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const apiKey = await getApiKeyFromStorage(); // Retrieve apiKey asynchronously
|
|
|
|
|
if (apiKey) {
|
|
|
|
|
return groupApiLocal;
|
|
|
|
|
} else {
|
|
|
|
|
return groupApi;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const createEndpointSocket = async (endpoint) => {
|
|
|
|
|
const apiKey = await getApiKeyFromStorage(); // Retrieve apiKey asynchronously
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (apiKey) {
|
|
|
|
|
return `${groupApiSocketLocal}${endpoint}`;
|
|
|
|
|
} else {
|
|
|
|
|
return `${groupApiSocket}${endpoint}`;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const createEndpoint = async (endpoint, customApi) => {
|
|
|
|
|
if (customApi) {
|
|
|
|
|
return `${customApi}${endpoint}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const apiKey = await getApiKeyFromStorage(); // Retrieve apiKey asynchronously
|
|
|
|
|
|
|
|
|
|
if (apiKey) {
|
|
|
|
|
// Check if the endpoint already contains a query string
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const separator = endpoint.includes("?") ? "&" : "?";
|
2024-09-09 20:36:39 +03:00
|
|
|
|
return `${groupApiLocal}${endpoint}${separator}apiKey=${apiKey}`;
|
|
|
|
|
} else {
|
|
|
|
|
return `${groupApi}${endpoint}`;
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
|
|
|
|
export const walletVersion = 2;
|
|
|
|
|
// List of your API endpoints
|
|
|
|
|
const apiEndpoints = [
|
|
|
|
|
"https://api.qortal.org",
|
2024-07-10 05:58:38 +03:00
|
|
|
|
"https://api2.qortal.org",
|
|
|
|
|
"https://appnode.qortal.org",
|
2024-04-14 14:57:30 +03:00
|
|
|
|
"https://apinode.qortalnodes.live",
|
|
|
|
|
"https://apinode1.qortalnodes.live",
|
|
|
|
|
"https://apinode2.qortalnodes.live",
|
|
|
|
|
"https://apinode3.qortalnodes.live",
|
|
|
|
|
"https://apinode4.qortalnodes.live",
|
|
|
|
|
];
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const buyTradeNodeBaseUrl = "https://appnode.qortal.org";
|
|
|
|
|
const proxyAccountAddress = "QXPejUe5Za1KD3zCMViWCX35AreMQ9H7ku";
|
|
|
|
|
const proxyAccountPublicKey = "5hP6stDWybojoDw5t8z9D51nV945oMPX7qBd29rhX1G7";
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const pendingResponses = new Map();
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let groups = null;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let socket;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let timeoutId;
|
|
|
|
|
let groupSocketTimeout;
|
|
|
|
|
let socketTimeout: any;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let interval;
|
|
|
|
|
let intervalThreads;
|
2024-04-14 14:57:30 +03:00
|
|
|
|
// Function to check each API endpoint
|
2024-09-09 20:36:39 +03:00
|
|
|
|
export async function findUsableApi() {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
for (const endpoint of apiEndpoints) {
|
|
|
|
|
try {
|
|
|
|
|
const response = await fetch(`${endpoint}/admin/status`);
|
|
|
|
|
if (!response.ok) throw new Error("Failed to fetch");
|
|
|
|
|
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
if (data.isSynchronizing === false && data.syncPercent === 100) {
|
|
|
|
|
console.log(`Usable API found: ${endpoint}`);
|
|
|
|
|
return endpoint;
|
|
|
|
|
} else {
|
|
|
|
|
console.log(`API not ready: ${endpoint}`);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(`Error checking API ${endpoint}:`, error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw new Error("No usable API found");
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
export function isExtMsg(data) {
|
|
|
|
|
let isMsgFromExtensionGroup = true;
|
2024-09-12 18:12:56 +03:00
|
|
|
|
try {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const decode1 = atob(data);
|
|
|
|
|
const decode2 = atob(decode1);
|
2024-09-12 18:12:56 +03:00
|
|
|
|
const keyStr = decode2.slice(0, 10);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-12 18:12:56 +03:00
|
|
|
|
// Convert the key string back to a number
|
|
|
|
|
const highestKey = parseInt(keyStr, 10);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (isNaN(highestKey)) {
|
|
|
|
|
isMsgFromExtensionGroup = false;
|
2024-09-12 18:12:56 +03:00
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
isMsgFromExtensionGroup = false;
|
2024-09-12 18:12:56 +03:00
|
|
|
|
}
|
2024-09-14 11:42:05 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return isMsgFromExtensionGroup;
|
2024-09-12 18:12:56 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
async function checkWebviewFocus() {
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
// Set a timeout for 1 second
|
|
|
|
|
const timeout = setTimeout(() => {
|
|
|
|
|
resolve(false); // No response within 1 second, assume not focused
|
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
|
|
// Send message to the content script to check focus
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.runtime.sendMessage({ action: "CHECK_FOCUS" }, (response) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function playNotificationSound() {
|
2024-09-16 13:49:56 +03:00
|
|
|
|
// chrome.runtime.sendMessage({ action: "PLAY_NOTIFICATION_SOUND" });
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const handleNotificationDirect = async (directs) => {
|
|
|
|
|
let isFocused;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const dataDirects = directs.filter((direct) => direct?.sender !== address);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!dataDirects || dataDirects?.length === 0) return;
|
|
|
|
|
isFocused = await checkWebviewFocus();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (isFocused) {
|
|
|
|
|
throw new Error("isFocused");
|
|
|
|
|
}
|
|
|
|
|
const newActiveChats = dataDirects;
|
|
|
|
|
const oldActiveChats = await getChatHeadsDirect();
|
|
|
|
|
|
|
|
|
|
if (newActiveChats?.length === 0) return;
|
|
|
|
|
|
|
|
|
|
let newestLatestTimestamp;
|
|
|
|
|
let oldestLatestTimestamp;
|
|
|
|
|
// Find the latest timestamp from newActiveChats
|
|
|
|
|
newActiveChats?.forEach((newChat) => {
|
|
|
|
|
if (
|
|
|
|
|
!newestLatestTimestamp ||
|
|
|
|
|
newChat?.timestamp > newestLatestTimestamp?.timestamp
|
|
|
|
|
) {
|
|
|
|
|
newestLatestTimestamp = newChat;
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
// Find the latest timestamp from oldActiveChats
|
|
|
|
|
oldActiveChats?.forEach((oldChat) => {
|
|
|
|
|
if (
|
|
|
|
|
!oldestLatestTimestamp ||
|
|
|
|
|
oldChat?.timestamp > oldestLatestTimestamp?.timestamp
|
|
|
|
|
) {
|
|
|
|
|
oldestLatestTimestamp = oldChat;
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (
|
|
|
|
|
(checkDifference(newestLatestTimestamp.timestamp) &&
|
|
|
|
|
!oldestLatestTimestamp) ||
|
|
|
|
|
(newestLatestTimestamp &&
|
|
|
|
|
newestLatestTimestamp?.timestamp > oldestLatestTimestamp?.timestamp)
|
|
|
|
|
) {
|
|
|
|
|
const notificationId =
|
|
|
|
|
"chat_notification_" +
|
|
|
|
|
Date.now() +
|
|
|
|
|
"_type=direct" +
|
|
|
|
|
`_from=${newestLatestTimestamp.address}`;
|
|
|
|
|
chrome.notifications.create(notificationId, {
|
|
|
|
|
type: "basic",
|
|
|
|
|
iconUrl: "qort.png", // Add an appropriate icon for chat notifications
|
|
|
|
|
title: `New Direct message! ${
|
|
|
|
|
newestLatestTimestamp?.name && `from ${newestLatestTimestamp.name}`
|
|
|
|
|
}`,
|
|
|
|
|
message: "You have received a new direct message",
|
|
|
|
|
priority: 2, // Use the maximum priority to ensure it's noticeable
|
|
|
|
|
// buttons: [
|
|
|
|
|
// { title: 'Go to group' }
|
|
|
|
|
// ]
|
|
|
|
|
});
|
|
|
|
|
if (!isMobile) {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chrome.notifications.clear(notificationId);
|
|
|
|
|
}, 7000);
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
// chrome.runtime.sendMessage(
|
|
|
|
|
// {
|
|
|
|
|
// action: "notification",
|
|
|
|
|
// payload: {
|
|
|
|
|
// },
|
|
|
|
|
// }
|
|
|
|
|
// )
|
|
|
|
|
// audio.play();
|
|
|
|
|
playNotificationSound();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!isFocused) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{
|
|
|
|
|
action: "notification",
|
2024-09-16 12:35:43 +03:00
|
|
|
|
payload: {},
|
2024-09-09 20:36:39 +03:00
|
|
|
|
},
|
|
|
|
|
(response) => {
|
|
|
|
|
if (!response?.error) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const notificationId = "chat_notification_" + Date.now();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
chrome.notifications.create(notificationId, {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
type: "basic",
|
|
|
|
|
iconUrl: "qort.png", // Add an appropriate icon for chat notifications
|
2024-09-09 20:36:39 +03:00
|
|
|
|
title: `New Direct message!`,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
message: "You have received a new direct message",
|
2024-09-09 20:36:39 +03:00
|
|
|
|
priority: 2, // Use the maximum priority to ensure it's noticeable
|
|
|
|
|
// buttons: [
|
|
|
|
|
// { title: 'Go to group' }
|
|
|
|
|
// ]
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!isMobile) {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chrome.notifications.clear(notificationId);
|
|
|
|
|
}, 7000);
|
|
|
|
|
}
|
|
|
|
|
playNotificationSound();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// audio.play();
|
2024-09-16 12:35:43 +03:00
|
|
|
|
// }
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
} finally {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
setChatHeadsDirect(dataDirects);
|
|
|
|
|
// chrome.runtime.sendMessage(
|
|
|
|
|
// {
|
|
|
|
|
// action: "setChatHeads",
|
|
|
|
|
// payload: {
|
|
|
|
|
// data,
|
|
|
|
|
// },
|
|
|
|
|
// }
|
|
|
|
|
// );
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
};
|
|
|
|
|
async function getThreadActivity() {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const key = `threadactivity-${address}`;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const res = await chrome.storage.local.get([key]);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (res?.[key]) {
|
|
|
|
|
const parsedData = JSON.parse(res[key]);
|
|
|
|
|
return parsedData;
|
|
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function updateThreadActivity({ threadId, qortalName, groupId, thread }) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
|
|
|
|
const ONE_WEEK_IN_MS = 7 * 24 * 60 * 60 * 1000; // One week in milliseconds
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let lastResetTime = 0;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// Retrieve the last reset timestamp from storage
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const key = `threadactivity-${address}`;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
chrome.storage.local.get([key], (data) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let threads;
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (!data[key] || Object.keys(data?.[key]?.length === 0)) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
threads = {
|
|
|
|
|
createdThreads: [],
|
|
|
|
|
mostVisitedThreads: [],
|
|
|
|
|
recentThreads: [],
|
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} else {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
threads = JSON.parse(data[key]);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (threads?.lastResetTime) {
|
|
|
|
|
lastResetTime = threads.lastResetTime;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const currentTime = Date.now();
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// Check if a week has passed since the last reset
|
|
|
|
|
if (!lastResetTime || currentTime - lastResetTime > ONE_WEEK_IN_MS) {
|
|
|
|
|
// Reset the visit counts for all most visited threads
|
2024-09-16 12:35:43 +03:00
|
|
|
|
threads.mostVisitedThreads.forEach((thread) => (thread.visitCount = 0));
|
2024-09-09 20:36:39 +03:00
|
|
|
|
lastResetTime = currentTime; // Update the last reset time
|
2024-09-16 12:35:43 +03:00
|
|
|
|
threads.lastResetTime = lastResetTime;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update the recent threads list
|
2024-09-16 12:35:43 +03:00
|
|
|
|
threads.recentThreads = threads.recentThreads.filter(
|
|
|
|
|
(t) => t.threadId !== threadId
|
|
|
|
|
);
|
|
|
|
|
threads.recentThreads.unshift({
|
|
|
|
|
threadId,
|
|
|
|
|
qortalName,
|
|
|
|
|
groupId,
|
|
|
|
|
thread,
|
|
|
|
|
visitCount: 1,
|
|
|
|
|
lastVisited: Date.now(),
|
|
|
|
|
});
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// Sort the recent threads by lastVisited time (descending)
|
|
|
|
|
threads.recentThreads.sort((a, b) => b.lastVisited - a.lastVisited);
|
|
|
|
|
// Limit the recent threads list to 2 items
|
|
|
|
|
threads.recentThreads = threads.recentThreads.slice(0, 2);
|
|
|
|
|
|
|
|
|
|
// Update the most visited threads list
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const existingThread = threads.mostVisitedThreads.find(
|
|
|
|
|
(t) => t.threadId === threadId
|
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (existingThread) {
|
|
|
|
|
existingThread.visitCount += 1;
|
|
|
|
|
existingThread.lastVisited = Date.now(); // Update the last visited time as well
|
|
|
|
|
} else {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
threads.mostVisitedThreads.push({
|
|
|
|
|
threadId,
|
|
|
|
|
qortalName,
|
|
|
|
|
groupId,
|
|
|
|
|
thread,
|
|
|
|
|
visitCount: 1,
|
|
|
|
|
lastVisited: Date.now(),
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sort the most visited threads by visitCount (descending)
|
|
|
|
|
threads.mostVisitedThreads.sort((a, b) => b.visitCount - a.visitCount);
|
|
|
|
|
// Limit the most visited threads list to 2 items
|
|
|
|
|
threads.mostVisitedThreads = threads.mostVisitedThreads.slice(0, 2);
|
|
|
|
|
|
|
|
|
|
// Store the updated thread information and last reset time
|
|
|
|
|
// chrome.storage.local.set({ threads, lastResetTime });
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const dataString = JSON.stringify(threads);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.storage.local.set({ [`threadactivity-${address}`]: dataString });
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const handleNotification = async (groups) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let mutedGroups = await getUserSettings({key: 'mutedGroups'}) || []
|
|
|
|
|
if(!isArray(mutedGroups)) mutedGroups = []
|
|
|
|
|
|
|
|
|
|
let isFocused;
|
|
|
|
|
const data = groups.filter((group) => group?.sender !== address && !mutedGroups.includes(group.groupId));
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!data || data?.length === 0) return;
|
|
|
|
|
isFocused = await checkWebviewFocus();
|
|
|
|
|
|
|
|
|
|
if (isFocused) {
|
|
|
|
|
throw new Error("isFocused");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const newActiveChats = data;
|
|
|
|
|
const oldActiveChats = await getChatHeads();
|
|
|
|
|
|
|
|
|
|
let results = [];
|
|
|
|
|
let newestLatestTimestamp;
|
|
|
|
|
let oldestLatestTimestamp;
|
|
|
|
|
// Find the latest timestamp from newActiveChats
|
|
|
|
|
newActiveChats?.forEach((newChat) => {
|
|
|
|
|
if (
|
|
|
|
|
!newestLatestTimestamp ||
|
|
|
|
|
newChat?.timestamp > newestLatestTimestamp?.timestamp
|
|
|
|
|
) {
|
|
|
|
|
newestLatestTimestamp = newChat;
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
// Find the latest timestamp from oldActiveChats
|
|
|
|
|
oldActiveChats?.forEach((oldChat) => {
|
|
|
|
|
if (
|
|
|
|
|
!oldestLatestTimestamp ||
|
|
|
|
|
oldChat?.timestamp > oldestLatestTimestamp?.timestamp
|
|
|
|
|
) {
|
|
|
|
|
oldestLatestTimestamp = oldChat;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
(checkDifference(newestLatestTimestamp.timestamp) &&
|
|
|
|
|
!oldestLatestTimestamp) ||
|
|
|
|
|
(newestLatestTimestamp &&
|
|
|
|
|
newestLatestTimestamp?.timestamp > oldestLatestTimestamp?.timestamp)
|
|
|
|
|
) {
|
|
|
|
|
if (
|
|
|
|
|
!lastGroupNotification ||
|
|
|
|
|
Date.now() - lastGroupNotification >= 120000
|
|
|
|
|
) {
|
|
|
|
|
if (
|
|
|
|
|
!newestLatestTimestamp?.data ||
|
|
|
|
|
!isExtMsg(newestLatestTimestamp?.data)
|
|
|
|
|
)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
const notificationId =
|
|
|
|
|
"chat_notification_" +
|
|
|
|
|
Date.now() +
|
|
|
|
|
"_type=group" +
|
|
|
|
|
`_from=${newestLatestTimestamp.groupId}`;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
chrome.notifications.create(notificationId, {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
type: "basic",
|
|
|
|
|
iconUrl: "qort.png", // Add an appropriate icon for chat notifications
|
|
|
|
|
title: "New Group Message!",
|
2024-09-09 20:36:39 +03:00
|
|
|
|
message: `You have received a new message from ${newestLatestTimestamp?.groupName}`,
|
|
|
|
|
priority: 2, // Use the maximum priority to ensure it's noticeable
|
|
|
|
|
// buttons: [
|
|
|
|
|
// { title: 'Go to group' }
|
|
|
|
|
// ]
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!isMobile) {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chrome.notifications.clear(notificationId);
|
|
|
|
|
}, 7000);
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// chrome.runtime.sendMessage(
|
|
|
|
|
// {
|
|
|
|
|
// action: "notification",
|
|
|
|
|
// payload: {
|
|
|
|
|
// },
|
|
|
|
|
// }
|
|
|
|
|
// )
|
|
|
|
|
// audio.play();
|
2024-09-16 12:35:43 +03:00
|
|
|
|
playNotificationSound();
|
|
|
|
|
lastGroupNotification = Date.now();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!isFocused) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
chrome.runtime.sendMessage(
|
|
|
|
|
{
|
|
|
|
|
action: "notification",
|
2024-09-16 12:35:43 +03:00
|
|
|
|
payload: {},
|
2024-09-09 20:36:39 +03:00
|
|
|
|
},
|
|
|
|
|
(response) => {
|
|
|
|
|
if (!response?.error) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const notificationId = "chat_notification_" + Date.now();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
chrome.notifications.create(notificationId, {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
type: "basic",
|
|
|
|
|
iconUrl: "qort.png", // Add an appropriate icon for chat notifications
|
|
|
|
|
title: "New Group Message!",
|
|
|
|
|
message: "You have received a new message from one of your groups",
|
2024-09-09 20:36:39 +03:00
|
|
|
|
priority: 2, // Use the maximum priority to ensure it's noticeable
|
|
|
|
|
// buttons: [
|
|
|
|
|
// { title: 'Go to group' }
|
|
|
|
|
// ]
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!isMobile) {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chrome.notifications.clear(notificationId);
|
|
|
|
|
}, 7000);
|
|
|
|
|
}
|
|
|
|
|
playNotificationSound();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// audio.play();
|
2024-09-16 12:35:43 +03:00
|
|
|
|
lastGroupNotification = Date.now();
|
|
|
|
|
// }
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
} finally {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!data || data?.length === 0) return;
|
|
|
|
|
setChatHeads(data);
|
|
|
|
|
// chrome.runtime.sendMessage(
|
|
|
|
|
// {
|
|
|
|
|
// action: "setChatHeads",
|
|
|
|
|
// payload: {
|
|
|
|
|
// data,
|
|
|
|
|
// },
|
|
|
|
|
// }
|
|
|
|
|
// );
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
const checkThreads = async (bringBack) => {
|
|
|
|
|
try {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let myName = "";
|
|
|
|
|
const userData = await getUserInfo();
|
|
|
|
|
if (userData?.name) {
|
|
|
|
|
myName = userData.name;
|
|
|
|
|
}
|
|
|
|
|
let newAnnouncements = [];
|
|
|
|
|
let dataToBringBack = [];
|
|
|
|
|
const threadActivity = await getThreadActivity();
|
|
|
|
|
if (!threadActivity) return null;
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const selectedThreads = [
|
|
|
|
|
...threadActivity.createdThreads.slice(0, 2),
|
|
|
|
|
...threadActivity.mostVisitedThreads.slice(0, 2),
|
|
|
|
|
...threadActivity.recentThreads.slice(0, 2),
|
2024-09-16 12:35:43 +03:00
|
|
|
|
];
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (selectedThreads?.length === 0) return null;
|
|
|
|
|
const tempData = {};
|
|
|
|
|
for (const thread of selectedThreads) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const identifier = `thmsg-${thread?.threadId}`;
|
|
|
|
|
const name = thread?.qortalName;
|
|
|
|
|
const endpoint = await getArbitraryEndpoint();
|
|
|
|
|
const url = await createEndpoint(
|
|
|
|
|
`${endpoint}?mode=ALL&service=DOCUMENT&identifier=${identifier}&limit=1&includemetadata=false&offset=${0}&reverse=true&prefix=true`
|
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const response = await fetch(url, {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
method: "GET",
|
2024-09-09 20:36:39 +03:00
|
|
|
|
headers: {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
const responseData = await response.json();
|
|
|
|
|
|
|
|
|
|
const latestMessage = responseData.filter(
|
|
|
|
|
(pub) => pub?.name !== myName
|
|
|
|
|
)[0];
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// const latestMessage = responseData[0]
|
|
|
|
|
|
|
|
|
|
if (!latestMessage) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
continue;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
checkDifference(latestMessage.created) &&
|
|
|
|
|
latestMessage.created > thread?.lastVisited &&
|
|
|
|
|
(!thread?.lastNotified || thread?.lastNotified < thread?.created)
|
|
|
|
|
) {
|
|
|
|
|
tempData[thread.threadId] = latestMessage.created;
|
|
|
|
|
newAnnouncements.push(thread);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (latestMessage.created > thread?.lastVisited) {
|
|
|
|
|
dataToBringBack.push(thread);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
conosle.log({ error });
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (bringBack) {
|
|
|
|
|
return dataToBringBack;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const updateThreadWithLastNotified = {
|
|
|
|
|
...threadActivity,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
createdThreads: (threadActivity?.createdThreads || [])?.map((item) => {
|
|
|
|
|
if (tempData[item.threadId]) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
return {
|
|
|
|
|
...item,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
lastNotified: tempData[item.threadId],
|
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} else {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return item;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
}),
|
2024-09-16 12:35:43 +03:00
|
|
|
|
mostVisitedThreads: (threadActivity?.mostVisitedThreads || [])?.map(
|
|
|
|
|
(item) => {
|
|
|
|
|
if (tempData[item.threadId]) {
|
|
|
|
|
return {
|
|
|
|
|
...item,
|
|
|
|
|
lastNotified: tempData[item.threadId],
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
return item;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
),
|
|
|
|
|
recentThreads: (threadActivity?.recentThreads || [])?.map((item) => {
|
|
|
|
|
if (tempData[item.threadId]) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
return {
|
|
|
|
|
...item,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
lastNotified: tempData[item.threadId],
|
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} else {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return item;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
}),
|
2024-09-16 12:35:43 +03:00
|
|
|
|
};
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const address = wallet.address0;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const dataString = JSON.stringify(updateThreadWithLastNotified);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.storage.local.set({ [`threadactivity-${address}`]: dataString });
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (newAnnouncements.length > 0) {
|
|
|
|
|
const notificationId =
|
|
|
|
|
"chat_notification_" +
|
|
|
|
|
Date.now() +
|
|
|
|
|
"_type=thread-post" +
|
|
|
|
|
`_data=${JSON.stringify(newAnnouncements[0])}`;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
chrome.notifications.create(notificationId, {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
type: "basic",
|
|
|
|
|
iconUrl: "qort.png", // Add an appropriate icon for chat notifications
|
2024-09-09 20:36:39 +03:00
|
|
|
|
title: `New thread post!`,
|
|
|
|
|
message: `New post in ${newAnnouncements[0]?.thread?.threadData?.title}`,
|
|
|
|
|
priority: 2, // Use the maximum priority to ensure it's noticeable
|
|
|
|
|
// buttons: [
|
|
|
|
|
// { title: 'Go to group' }
|
|
|
|
|
// ]
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!isMobile) {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chrome.notifications.clear(notificationId);
|
|
|
|
|
}, 7000);
|
|
|
|
|
}
|
|
|
|
|
playNotificationSound();
|
2024-09-12 05:41:57 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const savedtimestampAfter = await getTimestampGroupAnnouncement();
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "SET_GROUP_ANNOUNCEMENTS",
|
|
|
|
|
payload: savedtimestampAfter,
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} catch (error) {
|
|
|
|
|
} finally {
|
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
};
|
|
|
|
|
const checkNewMessages = async () => {
|
|
|
|
|
try {
|
|
|
|
|
let mutedGroups = await getUserSettings({key: 'mutedGroups'}) || []
|
|
|
|
|
if(!isArray(mutedGroups)) mutedGroups = []
|
|
|
|
|
let myName = "";
|
|
|
|
|
const userData = await getUserInfo();
|
|
|
|
|
if (userData?.name) {
|
|
|
|
|
myName = userData.name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let newAnnouncements = [];
|
|
|
|
|
const activeData = (await getStoredData("active-groups-directs")) || {
|
|
|
|
|
groups: [],
|
|
|
|
|
directs: [],
|
|
|
|
|
};
|
|
|
|
|
const groups = activeData?.groups;
|
|
|
|
|
if (!groups || groups?.length === 0) return;
|
|
|
|
|
const savedtimestamp = await getTimestampGroupAnnouncement();
|
|
|
|
|
|
|
|
|
|
await Promise.all(
|
|
|
|
|
groups.map(async (group) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
|
|
|
|
const identifier = `grp-${group.groupId}-anc-`;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const endpoint = await getArbitraryEndpoint();
|
|
|
|
|
const url = await createEndpoint(
|
|
|
|
|
`${endpoint}?mode=ALL&service=DOCUMENT&identifier=${identifier}&limit=1&includemetadata=false&offset=0&reverse=true&prefix=true`
|
|
|
|
|
);
|
|
|
|
|
const response = await requestQueueAnnouncements.enqueue(() => {
|
|
|
|
|
return fetch(url, {
|
|
|
|
|
method: "GET",
|
2024-09-11 15:42:01 +03:00
|
|
|
|
headers: {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
2024-09-11 15:42:01 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
});
|
2024-09-11 15:42:01 +03:00
|
|
|
|
const responseData = await response.json();
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
|
|
|
|
const latestMessage = responseData.filter(
|
|
|
|
|
(pub) => pub?.name !== myName
|
|
|
|
|
)[0];
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (!latestMessage) {
|
2024-09-11 15:42:01 +03:00
|
|
|
|
return; // continue to the next group
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
checkDifference(latestMessage.created) &&
|
|
|
|
|
(!savedtimestamp[group.groupId] ||
|
|
|
|
|
latestMessage.created >
|
|
|
|
|
savedtimestamp?.[group.groupId]?.notification)
|
|
|
|
|
) {
|
2024-09-11 15:42:01 +03:00
|
|
|
|
newAnnouncements.push(group);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
await addTimestampGroupAnnouncement({
|
|
|
|
|
groupId: group.groupId,
|
|
|
|
|
timestamp: Date.now(),
|
|
|
|
|
});
|
2024-09-11 15:42:01 +03:00
|
|
|
|
// save new timestamp
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2024-09-11 15:42:01 +03:00
|
|
|
|
console.error(error); // Handle error if needed
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
if (newAnnouncements.length > 0 && !mutedGroups.includes(newAnnouncements[0]?.groupId)) {
|
|
|
|
|
const notificationId =
|
|
|
|
|
"chat_notification_" +
|
|
|
|
|
Date.now() +
|
|
|
|
|
"_type=group-announcement" +
|
|
|
|
|
`_from=${newAnnouncements[0]?.groupId}`;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.notifications.create(notificationId, {
|
|
|
|
|
type: "basic",
|
|
|
|
|
iconUrl: "qort.png", // Add an appropriate icon for chat notifications
|
|
|
|
|
title: `New group announcement!`,
|
|
|
|
|
message: `You have received a new announcement from ${newAnnouncements[0]?.groupName}`,
|
|
|
|
|
priority: 2, // Use the maximum priority to ensure it's noticeable
|
|
|
|
|
// buttons: [
|
|
|
|
|
// { title: 'Go to group' }
|
|
|
|
|
// ]
|
|
|
|
|
});
|
|
|
|
|
if (!isMobile) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chrome.notifications.clear(notificationId);
|
|
|
|
|
}, 7000);
|
2024-09-12 05:41:57 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
playNotificationSound();
|
|
|
|
|
}
|
|
|
|
|
const savedtimestampAfter = await getTimestampGroupAnnouncement();
|
|
|
|
|
chrome.runtime.sendMessage({
|
2024-09-09 20:36:39 +03:00
|
|
|
|
action: "SET_GROUP_ANNOUNCEMENTS",
|
|
|
|
|
payload: savedtimestampAfter,
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
} catch (error) {
|
|
|
|
|
} finally {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const listenForNewGroupAnnouncements = async () => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
|
|
|
|
setTimeout(() => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
checkNewMessages();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}, 500);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (interval) {
|
|
|
|
|
clearInterval(interval);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
|
|
|
|
let isCalling = false;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
interval = setInterval(async () => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (isCalling) return;
|
|
|
|
|
isCalling = true;
|
|
|
|
|
const res = await checkNewMessages();
|
|
|
|
|
isCalling = false;
|
|
|
|
|
}, 180000);
|
|
|
|
|
} catch (error) {}
|
|
|
|
|
};
|
|
|
|
|
const listenForThreadUpdates = async () => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
|
|
|
|
setTimeout(() => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
checkThreads();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}, 500);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (intervalThreads) {
|
|
|
|
|
clearInterval(intervalThreads);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let isCalling = false;
|
|
|
|
|
intervalThreads = setInterval(async () => {
|
|
|
|
|
if (isCalling) return;
|
|
|
|
|
isCalling = true;
|
|
|
|
|
const res = await checkThreads();
|
|
|
|
|
isCalling = false;
|
|
|
|
|
}, 60000);
|
|
|
|
|
} catch (error) {}
|
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
const forceCloseWebSocket = () => {
|
|
|
|
|
if (socket) {
|
|
|
|
|
clearTimeout(timeoutId);
|
|
|
|
|
clearTimeout(groupSocketTimeout);
|
|
|
|
|
clearTimeout(socketTimeout);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
timeoutId = null;
|
|
|
|
|
groupSocketTimeout = null;
|
|
|
|
|
socket.close(1000, "forced");
|
|
|
|
|
socket = null;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
async function getNameInfo() {
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const validApi = await getBaseApi();
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const response = await fetch(validApi + "/names/address/" + address);
|
|
|
|
|
const nameData = await response.json();
|
|
|
|
|
if (nameData?.length > 0) {
|
|
|
|
|
return nameData[0].name;
|
|
|
|
|
} else {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
async function getAddressInfo(address) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const validApi = await getBaseApi();
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const response = await fetch(validApi + "/addresses/" + address);
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
|
|
|
|
|
if (!response?.ok && data?.error !== 124)
|
|
|
|
|
throw new Error("Cannot fetch address info");
|
|
|
|
|
if (data?.error === 124) {
|
|
|
|
|
return {
|
|
|
|
|
address,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-09 00:44:02 +03:00
|
|
|
|
async function getKeyPair() {
|
|
|
|
|
const res = await chrome.storage.local.get(["keyPair"]);
|
|
|
|
|
if (res?.keyPair) {
|
|
|
|
|
return res.keyPair;
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error("Wallet not authenticated");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
async function getSaveWallet() {
|
|
|
|
|
const res = await chrome.storage.local.get(["walletInfo"]);
|
|
|
|
|
if (res?.walletInfo) {
|
|
|
|
|
return res.walletInfo;
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error("No wallet saved");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function clearAllNotifications() {
|
2024-09-14 11:42:05 +03:00
|
|
|
|
const notifications = await chrome.notifications.getAll();
|
|
|
|
|
for (const notificationId of Object.keys(notifications)) {
|
|
|
|
|
await chrome.notifications.clear(notificationId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
async function getUserInfo() {
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
|
|
|
|
const addressInfo = await getAddressInfo(address);
|
|
|
|
|
const name = await getNameInfo();
|
|
|
|
|
return {
|
|
|
|
|
name,
|
2024-07-11 03:44:45 +03:00
|
|
|
|
publicKey: wallet.publicKey,
|
2024-04-14 14:57:30 +03:00
|
|
|
|
...addressInfo,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function connection(hostname) {
|
|
|
|
|
const isConnected = chrome.storage.local.get([hostname]);
|
|
|
|
|
return isConnected;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-12 23:44:21 -04:00
|
|
|
|
async function getTradeInfo(qortalAtAddress) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const response = await fetch(
|
|
|
|
|
buyTradeNodeBaseUrl + "/crosschain/trade/" + qortalAtAddress
|
|
|
|
|
);
|
2024-07-12 23:44:21 -04:00
|
|
|
|
if (!response?.ok) throw new Error("Cannot crosschain trade information");
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
async function getBalanceInfo() {
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const validApi = await getBaseApi();
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const response = await fetch(validApi + "/addresses/balance/" + address);
|
|
|
|
|
|
|
|
|
|
if (!response?.ok) throw new Error("Cannot fetch balance");
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
return data;
|
|
|
|
|
}
|
2024-07-17 17:00:43 -04:00
|
|
|
|
async function getLTCBalance() {
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
let _url = `${buyTradeNodeBaseUrl}/crosschain/ltc/walletbalance`;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const keyPair = await getKeyPair();
|
|
|
|
|
const parsedKeyPair = JSON.parse(keyPair);
|
|
|
|
|
let _body = parsedKeyPair.ltcPublicKey;
|
2024-07-17 17:00:43 -04:00
|
|
|
|
const response = await fetch(_url, {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
method: "POST",
|
2024-07-17 17:00:43 -04:00
|
|
|
|
headers: {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
"Content-Type": "application/json",
|
2024-07-17 17:00:43 -04:00
|
|
|
|
},
|
2024-09-09 20:36:39 +03:00
|
|
|
|
body: _body,
|
|
|
|
|
});
|
|
|
|
|
if (response?.ok) {
|
|
|
|
|
const data = await response.text();
|
|
|
|
|
const dataLTCBalance = (Number(data) / 1e8).toFixed(8);
|
|
|
|
|
return +dataLTCBalance;
|
|
|
|
|
} else throw new Error("Onable to get LTC balance");
|
2024-07-17 17:00:43 -04:00
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const processTransactionVersion2Chat = async (body: any, customApi) => {
|
2024-07-12 23:44:21 -04:00
|
|
|
|
// const validApi = await findUsableApi();
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const url = await createEndpoint(
|
|
|
|
|
"/transactions/process?apiVersion=2",
|
|
|
|
|
customApi
|
|
|
|
|
);
|
2024-07-12 23:44:21 -04:00
|
|
|
|
return fetch(url, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: {},
|
|
|
|
|
body: Base58.encode(body),
|
|
|
|
|
}).then(async (response) => {
|
|
|
|
|
try {
|
|
|
|
|
const json = await response.clone().json();
|
|
|
|
|
return json;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return await response.text();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const processTransactionVersion2 = async (body: any) => {
|
|
|
|
|
const url = await createEndpoint(`/transactions/process?apiVersion=2`);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const response = await fetch(url, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json", // Ensure the body is correctly parsed
|
|
|
|
|
},
|
|
|
|
|
body, // Convert body to JSON string
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// if (!response.ok) {
|
|
|
|
|
// // If the response is not successful (status code is not 2xx)
|
|
|
|
|
// throw new Error(`HTTP error! Status: ${response.status}`);
|
|
|
|
|
// }
|
2024-07-12 23:44:21 -04:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
try {
|
|
|
|
|
const json = await response.clone().json();
|
|
|
|
|
return json;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} catch (jsonError) {
|
|
|
|
|
try {
|
|
|
|
|
const text = await response.text();
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return text;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} catch (textError) {
|
|
|
|
|
throw new Error(`Failed to parse response as both JSON and text.`);
|
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error processing transaction:", error);
|
|
|
|
|
throw error; // Re-throw the error after logging it
|
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
};
|
|
|
|
|
|
2024-07-04 20:14:32 +03:00
|
|
|
|
const transaction = async (
|
|
|
|
|
{ type, params, apiVersion, keyPair }: any,
|
|
|
|
|
validApi
|
|
|
|
|
) => {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const tx = createTransaction(type, keyPair, params);
|
|
|
|
|
let res;
|
|
|
|
|
|
|
|
|
|
if (apiVersion && apiVersion === 2) {
|
|
|
|
|
const signedBytes = Base58.encode(tx.signedBytes);
|
2024-04-14 18:03:30 +03:00
|
|
|
|
res = await processTransactionVersion2(signedBytes, validApi);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let success = true;
|
|
|
|
|
if (res?.error) {
|
|
|
|
|
success = false;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
|
|
|
|
return {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
success,
|
2024-04-14 14:57:30 +03:00
|
|
|
|
data: res,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
const makeTransactionRequest = async (
|
|
|
|
|
receiver,
|
|
|
|
|
lastRef,
|
|
|
|
|
amount,
|
|
|
|
|
fee,
|
2024-04-14 18:03:30 +03:00
|
|
|
|
keyPair,
|
|
|
|
|
validApi
|
2024-04-14 14:57:30 +03:00
|
|
|
|
) => {
|
2024-07-04 20:14:32 +03:00
|
|
|
|
const myTxnrequest = await transaction(
|
|
|
|
|
{
|
|
|
|
|
nonce: 0,
|
|
|
|
|
type: 2,
|
|
|
|
|
params: {
|
|
|
|
|
recipient: receiver,
|
|
|
|
|
// recipientName: recipientName,
|
|
|
|
|
amount: amount,
|
|
|
|
|
lastReference: lastRef,
|
|
|
|
|
fee: fee,
|
|
|
|
|
},
|
|
|
|
|
apiVersion: 2,
|
|
|
|
|
keyPair,
|
2024-04-14 14:57:30 +03:00
|
|
|
|
},
|
2024-07-04 20:14:32 +03:00
|
|
|
|
validApi
|
|
|
|
|
);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
return myTxnrequest;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getLastRef = async () => {
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const validApi = await getBaseApi();
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const response = await fetch(
|
|
|
|
|
validApi + "/addresses/lastreference/" + address
|
|
|
|
|
);
|
|
|
|
|
if (!response?.ok) throw new Error("Cannot fetch balance");
|
|
|
|
|
const data = await response.text();
|
|
|
|
|
return data;
|
|
|
|
|
};
|
|
|
|
|
const sendQortFee = async () => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const validApi = await getBaseApi();
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const response = await fetch(
|
|
|
|
|
validApi + "/transactions/unitfee?txType=PAYMENT"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
throw new Error("Error when fetching join fee");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
const qortFee = (Number(data) / 1e8).toFixed(8);
|
|
|
|
|
return qortFee;
|
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
async function getNameOrAddress(receiver) {
|
|
|
|
|
try {
|
|
|
|
|
const isAddress = validateAddress(receiver);
|
|
|
|
|
if (isAddress) {
|
|
|
|
|
return receiver;
|
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const validApi = await getBaseApi();
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
|
|
|
|
const response = await fetch(validApi + "/names/" + receiver);
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
if (data?.owner) return data.owner;
|
|
|
|
|
if (data?.error) {
|
|
|
|
|
throw new Error("Name does not exist");
|
|
|
|
|
}
|
|
|
|
|
if (!response?.ok) throw new Error("Cannot fetch name");
|
|
|
|
|
return { error: "cannot validate address or name" };
|
2024-04-16 13:25:36 +03:00
|
|
|
|
} catch (error) {
|
2024-07-04 20:14:32 +03:00
|
|
|
|
throw new Error(error?.message || "cannot validate address or name");
|
2024-04-16 13:25:36 +03:00
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
2024-07-09 00:44:02 +03:00
|
|
|
|
|
2024-09-12 22:23:47 +03:00
|
|
|
|
export async function getPublicKey(receiver) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const validApi = await getBaseApi();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
const response = await fetch(validApi + "/addresses/publickey/" + receiver);
|
|
|
|
|
if (!response?.ok) throw new Error("Cannot fetch recipient's public key");
|
|
|
|
|
|
|
|
|
|
const data = await response.text();
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!data?.error && data !== "false") return data;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (data?.error) {
|
|
|
|
|
throw new Error("Cannot fetch recipient's public key");
|
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
throw new Error("Cannot fetch recipient's public key");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} catch (error) {
|
|
|
|
|
throw new Error(error?.message || "cannot validate address or name");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 02:52:05 +03:00
|
|
|
|
const MAX_STORAGE_SIZE = 3 * 1024 * 1024; // 3MB in bytes
|
|
|
|
|
|
|
|
|
|
async function getDataPublishes(groupId, type) {
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
|
|
|
|
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
chrome.storage.local.get([`${address}-publishData`], (result) => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
console.error("Error retrieving data:", chrome.runtime.lastError);
|
2024-09-16 02:52:05 +03:00
|
|
|
|
resolve(null); // Return null in case of an error
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let storedData = result[`${address}-publishData`] || {}; // Get the stored data or initialize an empty object
|
|
|
|
|
let groupData = storedData[groupId] || {}; // Get data by groupId
|
|
|
|
|
let typeData = groupData[type] || {}; // Get data by type
|
|
|
|
|
|
|
|
|
|
resolve(typeData); // Resolve with the data inside the specific type
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function addDataPublishes(newData, groupId, type) {
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
|
|
|
|
const nameIdentifier = `${newData.name}-${newData.identifier}`;
|
|
|
|
|
|
|
|
|
|
// Prevent adding data larger than 50KB
|
|
|
|
|
if (newData?.size > 50000) return false;
|
|
|
|
|
|
|
|
|
|
return new Promise((res) => {
|
|
|
|
|
chrome.storage.local.get([`${address}-publishData`], (result) => {
|
|
|
|
|
let storedData = result[`${address}-publishData`] || {}; // Get existing data or initialize
|
|
|
|
|
let groupData = storedData[groupId] || {}; // Get or initialize group by groupId
|
|
|
|
|
let typeData = groupData[type] || {}; // Get or initialize the type within the group
|
|
|
|
|
|
|
|
|
|
let totalSize = 0;
|
|
|
|
|
|
|
|
|
|
// Calculate the current size of all stored data
|
2024-09-16 12:35:43 +03:00
|
|
|
|
Object.values(storedData).forEach((group) => {
|
|
|
|
|
Object.values(group).forEach((type) => {
|
|
|
|
|
Object.values(type).forEach((data) => {
|
2024-09-16 02:52:05 +03:00
|
|
|
|
totalSize += data.size; // Accumulate the sizes of actual data
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Check if adding the new data exceeds 3MB
|
|
|
|
|
if (totalSize + newData.size > MAX_STORAGE_SIZE) {
|
|
|
|
|
// Sort and remove older data within the group and type
|
|
|
|
|
let dataEntries = Object.entries(typeData);
|
|
|
|
|
dataEntries.sort((a, b) => a[1].timestampSaved - b[1].timestampSaved);
|
|
|
|
|
|
|
|
|
|
// Remove old data until there's enough space
|
2024-09-16 12:35:43 +03:00
|
|
|
|
while (
|
|
|
|
|
totalSize + newData.size > MAX_STORAGE_SIZE &&
|
|
|
|
|
dataEntries.length > 0
|
|
|
|
|
) {
|
2024-09-16 02:52:05 +03:00
|
|
|
|
const removedEntry = dataEntries.shift();
|
|
|
|
|
totalSize -= removedEntry[1].size;
|
|
|
|
|
delete typeData[removedEntry[0]]; // Remove from the typeData
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add or update the new data within the group and type
|
|
|
|
|
if (totalSize + newData.size <= MAX_STORAGE_SIZE) {
|
|
|
|
|
typeData[`${nameIdentifier}`] = newData; // Add new data under name-identifier
|
|
|
|
|
groupData[type] = typeData; // Update type data within the group
|
|
|
|
|
storedData[groupId] = groupData; // Update group data within the stored data
|
|
|
|
|
|
|
|
|
|
// Save the updated structure back to chrome.storage.local
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.storage.local.set(
|
|
|
|
|
{ [`${address}-publishData`]: storedData },
|
|
|
|
|
() => {
|
|
|
|
|
res(true); // Data successfully added
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-09-16 02:52:05 +03:00
|
|
|
|
} else {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
console.error("Failed to add data, still exceeds storage limit.");
|
2024-09-16 02:52:05 +03:00
|
|
|
|
res(false); // Failure due to storage limit
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
// Fetch user settings based on the key
|
|
|
|
|
async function getUserSettings({ key }) {
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 02:52:05 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
chrome.storage.local.get([`${address}-userSettings`], (result) => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
console.error("Error retrieving data:", chrome.runtime.lastError);
|
|
|
|
|
resolve(null); // Return null in case of an error
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const storedData = result[`${address}-userSettings`] || {}; // Get the stored data or initialize an empty object
|
|
|
|
|
const value = storedData[key] || null; // Get data by key
|
|
|
|
|
|
|
|
|
|
resolve(value); // Resolve with the data for the specific key
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add or update user settings
|
|
|
|
|
async function addUserSettings({ keyValue }) {
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
|
|
|
|
const { key, value } = keyValue;
|
|
|
|
|
|
|
|
|
|
// No need to check size here, unless value is a large object. For simple settings, size checks aren't necessary.
|
|
|
|
|
|
|
|
|
|
return new Promise((res) => {
|
|
|
|
|
chrome.storage.local.get([`${address}-userSettings`], (result) => {
|
|
|
|
|
let storedData = result[`${address}-userSettings`] || {}; // Get existing data or initialize
|
|
|
|
|
|
|
|
|
|
storedData[key] = value; // Update the key-value pair within the stored data
|
|
|
|
|
|
|
|
|
|
// Save the updated structure back to chrome.storage.local
|
|
|
|
|
chrome.storage.local.set(
|
|
|
|
|
{ [`${address}-userSettings`]: storedData },
|
|
|
|
|
() => {
|
|
|
|
|
res(true); // Data successfully added
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function decryptWallet({ password, wallet, walletVersion }) {
|
|
|
|
|
try {
|
|
|
|
|
const response = await decryptStoredWallet(password, wallet);
|
|
|
|
|
const wallet2 = new PhraseWallet(response, walletVersion);
|
|
|
|
|
const keyPair = wallet2._addresses[0].keyPair;
|
|
|
|
|
const ltcPrivateKey =
|
|
|
|
|
wallet2._addresses[0].ltcWallet.derivedMasterPrivateKey;
|
|
|
|
|
const ltcPublicKey = wallet2._addresses[0].ltcWallet.derivedMasterPublicKey;
|
|
|
|
|
const ltcAddress = wallet2._addresses[0].ltcWallet.address;
|
|
|
|
|
const toSave = {
|
|
|
|
|
privateKey: Base58.encode(keyPair.privateKey),
|
|
|
|
|
publicKey: Base58.encode(keyPair.publicKey),
|
|
|
|
|
ltcPrivateKey: ltcPrivateKey,
|
|
|
|
|
ltcPublicKey: ltcPublicKey,
|
|
|
|
|
};
|
|
|
|
|
const dataString = JSON.stringify(toSave);
|
|
|
|
|
await new Promise((resolve, reject) => {
|
|
|
|
|
chrome.storage.local.set({ keyPair: dataString }, () => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
reject(new Error(chrome.runtime.lastError.message));
|
2024-07-09 00:44:02 +03:00
|
|
|
|
} else {
|
|
|
|
|
resolve(true);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
2024-07-11 03:44:45 +03:00
|
|
|
|
const newWallet = {
|
|
|
|
|
...wallet,
|
2024-07-17 20:53:38 -04:00
|
|
|
|
publicKey: Base58.encode(keyPair.publicKey),
|
2024-09-09 20:36:39 +03:00
|
|
|
|
ltcAddress: ltcAddress,
|
|
|
|
|
};
|
2024-07-09 00:44:02 +03:00
|
|
|
|
await new Promise((resolve, reject) => {
|
2024-07-11 03:44:45 +03:00
|
|
|
|
chrome.storage.local.set({ walletInfo: newWallet }, () => {
|
2024-07-09 00:44:02 +03:00
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
reject(new Error(chrome.runtime.lastError.message));
|
|
|
|
|
} else {
|
|
|
|
|
resolve(true);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2024-07-15 22:07:57 -04:00
|
|
|
|
return true;
|
2024-07-09 00:44:02 +03:00
|
|
|
|
} catch (error) {
|
|
|
|
|
throw new Error(error.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function signChatFunc(chatBytesArray, chatNonce, customApi, keyPair) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let response;
|
2024-07-15 22:07:57 -04:00
|
|
|
|
try {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const signedChatBytes = signChat(chatBytesArray, chatNonce, keyPair);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
|
|
|
|
const res = await processTransactionVersion2Chat(
|
|
|
|
|
signedChatBytes,
|
|
|
|
|
customApi
|
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
response = res;
|
2024-07-15 22:07:57 -04:00
|
|
|
|
} catch (e) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
console.error(e);
|
|
|
|
|
console.error(e.message);
|
|
|
|
|
response = false;
|
2024-07-15 22:07:57 -04:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
return response;
|
2024-07-12 23:44:21 -04:00
|
|
|
|
}
|
|
|
|
|
function sbrk(size, heap) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let brk = 512 * 1024; // stack top
|
|
|
|
|
let old = brk;
|
|
|
|
|
brk += size;
|
|
|
|
|
if (brk > heap.length) throw new Error("heap exhausted");
|
|
|
|
|
return old;
|
2024-07-12 23:44:21 -04:00
|
|
|
|
}
|
|
|
|
|
|
2024-07-15 22:07:57 -04:00
|
|
|
|
const computePow = async ({ chatBytes, path, difficulty }) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let response = null;
|
2024-07-15 22:07:57 -04:00
|
|
|
|
await new Promise((resolve, reject) => {
|
|
|
|
|
const _chatBytesArray = Object.keys(chatBytes).map(function (key) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
return chatBytes[key];
|
|
|
|
|
});
|
|
|
|
|
const chatBytesArray = new Uint8Array(_chatBytesArray);
|
|
|
|
|
const chatBytesHash = new Sha256().process(chatBytesArray).finish().result;
|
|
|
|
|
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 });
|
|
|
|
|
const heap = new Uint8Array(memory.buffer);
|
|
|
|
|
|
|
|
|
|
const hashPtr = sbrk(32, heap);
|
|
|
|
|
const hashAry = new Uint8Array(memory.buffer, hashPtr, 32);
|
|
|
|
|
hashAry.set(chatBytesHash);
|
|
|
|
|
const workBufferLength = 8 * 1024 * 1024;
|
|
|
|
|
const workBufferPtr = sbrk(workBufferLength, heap);
|
2024-07-15 22:07:57 -04:00
|
|
|
|
const importObject = {
|
|
|
|
|
env: {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
memory: memory,
|
|
|
|
|
},
|
|
|
|
|
};
|
2024-07-15 22:07:57 -04:00
|
|
|
|
function loadWebAssembly(filename, imports) {
|
|
|
|
|
// Fetch the file and compile it
|
2024-09-09 20:36:39 +03:00
|
|
|
|
return fetch(filename)
|
|
|
|
|
.then((response) => response.arrayBuffer())
|
|
|
|
|
.then((buffer) => WebAssembly.compile(buffer))
|
|
|
|
|
.then((module) => {
|
|
|
|
|
// Create the instance.
|
|
|
|
|
return new WebAssembly.Instance(module, importObject);
|
|
|
|
|
});
|
2024-07-15 22:07:57 -04:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
loadWebAssembly(path).then((wasmModule) => {
|
|
|
|
|
response = {
|
|
|
|
|
nonce: wasmModule.exports.compute2(
|
|
|
|
|
hashPtr,
|
|
|
|
|
workBufferPtr,
|
|
|
|
|
workBufferLength,
|
|
|
|
|
difficulty
|
|
|
|
|
),
|
|
|
|
|
chatBytesArray,
|
|
|
|
|
};
|
|
|
|
|
resolve();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
return response;
|
|
|
|
|
};
|
2024-07-12 23:44:21 -04:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const getStoredData = async (key) => {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
chrome.storage.local.get(key, (result) => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
return reject(chrome.runtime.lastError);
|
|
|
|
|
}
|
|
|
|
|
resolve(result[key]);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function handleActiveGroupDataFromSocket({ groups, directs }) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "SET_GROUPS",
|
|
|
|
|
payload: groups,
|
|
|
|
|
});
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "SET_DIRECTS",
|
|
|
|
|
payload: directs,
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
groups = groups;
|
|
|
|
|
directs = directs;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const activeData = {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
groups: groups || [], // Your groups data here
|
|
|
|
|
directs: directs || [], // Your directs data here
|
2024-09-09 20:36:39 +03:00
|
|
|
|
};
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// Save the active data to localStorage
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.storage.local.set({ "active-groups-directs": activeData });
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
handleNotification(groups);
|
|
|
|
|
handleNotificationDirect(directs);
|
|
|
|
|
} catch (error) {}
|
|
|
|
|
} catch (error) {}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function sendChat({ qortAddress, recipientPublicKey, message }) {
|
2024-07-12 23:44:21 -04:00
|
|
|
|
let _reference = new Uint8Array(64);
|
|
|
|
|
self.crypto.getRandomValues(_reference);
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let sendTimestamp = Date.now();
|
2024-07-12 23:44:21 -04:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let reference = Base58.encode(_reference);
|
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
2024-07-15 22:07:57 -04:00
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
publicKey: uint8PublicKey,
|
2024-07-15 22:07:57 -04:00
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const balance = await getBalanceInfo();
|
|
|
|
|
const hasEnoughBalance = +balance < 4 ? false : true;
|
|
|
|
|
const difficulty = 8;
|
2024-07-15 22:07:57 -04:00
|
|
|
|
const jsonData = {
|
|
|
|
|
atAddress: message.atAddress,
|
|
|
|
|
foreignKey: message.foreignKey,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
receivingAddress: message.receivingAddress,
|
2024-07-15 22:07:57 -04:00
|
|
|
|
};
|
|
|
|
|
const finalJson = {
|
|
|
|
|
callRequest: jsonData,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
extra: "whatever additional data goes here",
|
2024-07-15 22:07:57 -04:00
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const messageStringified = JSON.stringify(finalJson);
|
|
|
|
|
|
|
|
|
|
const tx = await createTransaction(18, keyPair, {
|
|
|
|
|
timestamp: sendTimestamp,
|
|
|
|
|
recipient: qortAddress,
|
|
|
|
|
recipientPublicKey: recipientPublicKey,
|
|
|
|
|
hasChatReference: 0,
|
|
|
|
|
message: messageStringified,
|
|
|
|
|
lastReference: reference,
|
|
|
|
|
proofOfWorkNonce: 0,
|
|
|
|
|
isEncrypted: 1,
|
|
|
|
|
isText: 1,
|
|
|
|
|
});
|
|
|
|
|
if (!hasEnoughBalance) {
|
|
|
|
|
const _encryptedMessage = tx._encryptedMessage;
|
|
|
|
|
const encryptedMessageToBase58 = Base58.encode(_encryptedMessage);
|
2024-07-19 21:57:57 -04:00
|
|
|
|
return {
|
|
|
|
|
encryptedMessageToBase58,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
signature: "id-" + Date.now() + "-" + Math.floor(Math.random() * 1000),
|
|
|
|
|
reference,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
const path = chrome.runtime.getURL("memory-pow.wasm.full");
|
|
|
|
|
|
|
|
|
|
const { nonce, chatBytesArray } = await computePow({
|
|
|
|
|
chatBytes: tx.chatBytes,
|
|
|
|
|
path,
|
|
|
|
|
difficulty,
|
|
|
|
|
});
|
|
|
|
|
let _response = await signChatFunc(
|
|
|
|
|
chatBytesArray,
|
|
|
|
|
nonce,
|
|
|
|
|
"https://appnode.qortal.org",
|
|
|
|
|
keyPair
|
|
|
|
|
);
|
|
|
|
|
if (_response?.error) {
|
|
|
|
|
throw new Error(_response?.message);
|
2024-07-19 21:57:57 -04:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
return _response;
|
|
|
|
|
}
|
2024-07-15 22:07:57 -04:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
async function sendChatGroup({
|
|
|
|
|
groupId,
|
|
|
|
|
typeMessage,
|
|
|
|
|
chatReference,
|
|
|
|
|
messageText,
|
|
|
|
|
}) {
|
|
|
|
|
let _reference = new Uint8Array(64);
|
|
|
|
|
self.crypto.getRandomValues(_reference);
|
|
|
|
|
|
|
|
|
|
let reference = Base58.encode(_reference);
|
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
2024-09-12 22:23:47 +03:00
|
|
|
|
// const balance = await getBalanceInfo();
|
|
|
|
|
// const hasEnoughBalance = +balance < 4 ? false : true;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const difficulty = 8;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const tx = await createTransaction(181, keyPair, {
|
|
|
|
|
timestamp: Date.now(),
|
|
|
|
|
groupID: Number(groupId),
|
|
|
|
|
hasReceipient: 0,
|
|
|
|
|
hasChatReference: typeMessage === "edit" ? 1 : 0,
|
|
|
|
|
// chatReference: chatReference,
|
|
|
|
|
message: messageText,
|
|
|
|
|
lastReference: reference,
|
|
|
|
|
proofOfWorkNonce: 0,
|
|
|
|
|
isEncrypted: 0, // Set default to not encrypted for groups
|
|
|
|
|
isText: 1,
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-12 22:23:47 +03:00
|
|
|
|
// if (!hasEnoughBalance) {
|
|
|
|
|
// throw new Error("Must have at least 4 QORT to send a chat message");
|
|
|
|
|
// }
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const path = chrome.runtime.getURL("memory-pow.wasm.full");
|
|
|
|
|
|
|
|
|
|
const { nonce, chatBytesArray } = await computePow({
|
|
|
|
|
chatBytes: tx.chatBytes,
|
|
|
|
|
path,
|
|
|
|
|
difficulty,
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let _response = await signChatFunc(chatBytesArray, nonce, null, keyPair);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (_response?.error) {
|
|
|
|
|
throw new Error(_response?.message);
|
|
|
|
|
}
|
|
|
|
|
return _response;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function sendChatDirect({
|
2024-09-12 22:23:47 +03:00
|
|
|
|
address,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
directTo,
|
|
|
|
|
typeMessage,
|
|
|
|
|
chatReference,
|
|
|
|
|
messageText,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
publicKeyOfRecipient,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let recipientPublicKey;
|
|
|
|
|
let recipientAddress = address;
|
|
|
|
|
if (publicKeyOfRecipient) {
|
|
|
|
|
recipientPublicKey = publicKeyOfRecipient;
|
2024-09-12 22:23:47 +03:00
|
|
|
|
} else {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
recipientAddress = await getNameOrAddress(directTo);
|
|
|
|
|
recipientPublicKey = await getPublicKey(recipientAddress);
|
2024-09-12 22:23:47 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!recipientAddress) {
|
|
|
|
|
recipientAddress = await getNameOrAddress(directTo);
|
2024-09-12 22:23:47 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!recipientPublicKey) throw new Error("Cannot retrieve publickey");
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let _reference = new Uint8Array(64);
|
|
|
|
|
self.crypto.getRandomValues(_reference);
|
2024-07-15 22:07:57 -04:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let reference = Base58.encode(_reference);
|
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
2024-09-12 22:23:47 +03:00
|
|
|
|
// const balance = await getBalanceInfo();
|
|
|
|
|
// const hasEnoughBalance = +balance < 4 ? false : true;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const difficulty = 8;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const finalJson = {
|
|
|
|
|
message: messageText,
|
|
|
|
|
version: 2,
|
|
|
|
|
};
|
|
|
|
|
const messageStringified = JSON.stringify(finalJson);
|
|
|
|
|
const tx = await createTransaction(18, keyPair, {
|
|
|
|
|
timestamp: Date.now(),
|
|
|
|
|
recipient: recipientAddress,
|
|
|
|
|
recipientPublicKey: recipientPublicKey,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
hasChatReference: 0,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
message: messageStringified,
|
|
|
|
|
lastReference: reference,
|
|
|
|
|
proofOfWorkNonce: 0,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
isEncrypted: 1,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
isText: 1,
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-12 22:23:47 +03:00
|
|
|
|
// if (!hasEnoughBalance) {
|
|
|
|
|
// throw new Error("Must have at least 4 QORT to send a chat message");
|
|
|
|
|
// }
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const path = chrome.runtime.getURL("memory-pow.wasm.full");
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const { nonce, chatBytesArray } = await computePow({
|
|
|
|
|
chatBytes: tx.chatBytes,
|
|
|
|
|
path,
|
|
|
|
|
difficulty,
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
|
|
|
|
let _response = await signChatFunc(chatBytesArray, nonce, null, keyPair);
|
2024-07-15 22:07:57 -04:00
|
|
|
|
if (_response?.error) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
throw new Error(_response?.message);
|
|
|
|
|
}
|
|
|
|
|
return _response;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function decryptSingleFunc({
|
|
|
|
|
messages,
|
|
|
|
|
secretKeyObject,
|
|
|
|
|
skipDecodeBase64,
|
|
|
|
|
}) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let holdMessages = [];
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
for (const message of messages) {
|
|
|
|
|
try {
|
|
|
|
|
const res = await decryptSingle({
|
|
|
|
|
data64: message.data,
|
|
|
|
|
secretKeyObject,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
skipDecodeBase64,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const decryptToUnit8Array = base64ToUint8Array(res);
|
|
|
|
|
const responseData = uint8ArrayToObject(decryptToUnit8Array);
|
|
|
|
|
holdMessages.push({ ...message, text: responseData });
|
2024-09-16 12:35:43 +03:00
|
|
|
|
} catch (error) {}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
return holdMessages;
|
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function decryptSingleForPublishes({
|
|
|
|
|
messages,
|
|
|
|
|
secretKeyObject,
|
|
|
|
|
skipDecodeBase64,
|
|
|
|
|
}) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let holdMessages = [];
|
|
|
|
|
|
|
|
|
|
for (const message of messages) {
|
|
|
|
|
try {
|
|
|
|
|
const res = await decryptSingle({
|
|
|
|
|
data64: message.data,
|
|
|
|
|
secretKeyObject,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
skipDecodeBase64,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const decryptToUnit8Array = base64ToUint8Array(res);
|
|
|
|
|
const responseData = uint8ArrayToObject(decryptToUnit8Array);
|
|
|
|
|
holdMessages.push({ ...message, decryptedData: responseData });
|
2024-09-16 12:35:43 +03:00
|
|
|
|
} catch (error) {}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
return holdMessages;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function decryptDirectFunc({ messages, involvingAddress }) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const senderPublicKey = await getPublicKey(involvingAddress);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let holdMessages = [];
|
|
|
|
|
|
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
|
|
|
|
for (const message of messages) {
|
|
|
|
|
try {
|
|
|
|
|
const decodedMessage = decryptChatMessage(
|
|
|
|
|
message.data,
|
|
|
|
|
keyPair.privateKey,
|
|
|
|
|
senderPublicKey,
|
|
|
|
|
message.reference
|
|
|
|
|
);
|
|
|
|
|
const parsedMessage = JSON.parse(decodedMessage);
|
|
|
|
|
holdMessages.push({ ...message, ...parsedMessage });
|
2024-09-16 12:35:43 +03:00
|
|
|
|
} catch (error) {}
|
2024-07-15 22:07:57 -04:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
return holdMessages;
|
2024-07-12 23:44:21 -04:00
|
|
|
|
}
|
|
|
|
|
|
2024-07-15 22:07:57 -04:00
|
|
|
|
async function createBuyOrderTx({ crosschainAtInfo }) {
|
2024-07-12 23:44:21 -04:00
|
|
|
|
try {
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
2024-07-12 23:44:21 -04:00
|
|
|
|
const message = {
|
|
|
|
|
atAddress: crosschainAtInfo.qortalAtAddress,
|
|
|
|
|
foreignKey: parsedData.ltcPrivateKey,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
receivingAddress: address,
|
|
|
|
|
};
|
|
|
|
|
const res = await sendChat({
|
|
|
|
|
qortAddress: proxyAccountAddress,
|
|
|
|
|
recipientPublicKey: proxyAccountPublicKey,
|
|
|
|
|
message,
|
|
|
|
|
});
|
2024-07-15 22:07:57 -04:00
|
|
|
|
if (res?.signature) {
|
|
|
|
|
listenForChatMessageForBuyOrder({
|
|
|
|
|
nodeBaseUrl: buyTradeNodeBaseUrl,
|
|
|
|
|
senderAddress: proxyAccountAddress,
|
|
|
|
|
senderPublicKey: proxyAccountPublicKey,
|
2024-07-12 23:44:21 -04:00
|
|
|
|
signature: res?.signature,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
|
|
|
|
if (res?.encryptedMessageToBase58) {
|
|
|
|
|
return {
|
|
|
|
|
atAddress: crosschainAtInfo.qortalAtAddress,
|
|
|
|
|
encryptedMessageToBase58: res?.encryptedMessageToBase58,
|
|
|
|
|
node: buyTradeNodeBaseUrl,
|
|
|
|
|
qortAddress: address,
|
|
|
|
|
chatSignature: res?.signature,
|
|
|
|
|
senderPublicKey: parsedData.publicKey,
|
|
|
|
|
sender: address,
|
|
|
|
|
reference: res?.reference,
|
|
|
|
|
};
|
2024-07-19 21:57:57 -04:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
return {
|
|
|
|
|
atAddress: crosschainAtInfo.qortalAtAddress,
|
|
|
|
|
chatSignature: res?.signature,
|
|
|
|
|
node: buyTradeNodeBaseUrl,
|
|
|
|
|
qortAddress: address,
|
|
|
|
|
};
|
2024-07-17 17:00:43 -04:00
|
|
|
|
} else {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
throw new Error("Unable to send buy order message");
|
2024-07-12 23:44:21 -04:00
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw new Error(error.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function sendChatNotification(
|
|
|
|
|
res,
|
|
|
|
|
groupId,
|
|
|
|
|
secretKeyObject,
|
|
|
|
|
numberOfMembers
|
|
|
|
|
) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const data = await objectToBase64({
|
|
|
|
|
type: "notification",
|
|
|
|
|
subType: "new-group-encryption",
|
|
|
|
|
data: {
|
|
|
|
|
timestamp: res.timestamp,
|
|
|
|
|
name: res.name,
|
|
|
|
|
message: `${res.name} has updated the encryption key`,
|
|
|
|
|
numberOfMembers,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
encryptSingle({
|
|
|
|
|
data64: data,
|
|
|
|
|
secretKeyObject: secretKeyObject,
|
|
|
|
|
})
|
|
|
|
|
.then((res2) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
pauseAllQueues();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
sendChatGroup({
|
|
|
|
|
groupId,
|
|
|
|
|
typeMessage: undefined,
|
|
|
|
|
chatReference: undefined,
|
|
|
|
|
messageText: res2,
|
|
|
|
|
})
|
|
|
|
|
.then(() => {})
|
|
|
|
|
.catch((error) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
console.error("1", error.message);
|
2024-09-11 15:42:01 +03:00
|
|
|
|
})
|
2024-09-16 12:35:43 +03:00
|
|
|
|
.finally(() => {
|
|
|
|
|
resumeAllQueues();
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
console.error("2", error.message);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
} catch (error) {}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
export const getFee = async (txType) => {
|
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
const data = await reusableGet(
|
|
|
|
|
`/transactions/unitfee?txType=${txType}×tamp=${timestamp}`
|
|
|
|
|
);
|
|
|
|
|
const arbitraryFee = (Number(data) / 1e8).toFixed(8);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return {
|
|
|
|
|
timestamp,
|
|
|
|
|
fee: arbitraryFee,
|
|
|
|
|
};
|
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function leaveGroup({ groupId }) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const lastReference = await getLastRef();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const feeres = await getFee("LEAVE_GROUP");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
const tx = await createTransaction(32, keyPair, {
|
|
|
|
|
fee: feeres.fee,
|
|
|
|
|
registrantAddress: address,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
rGroupId: groupId,
|
|
|
|
|
lastReference: lastReference,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const signedBytes = Base58.encode(tx.signedBytes);
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const res = await processTransactionVersion2(signedBytes);
|
|
|
|
|
if (!res?.signature)
|
|
|
|
|
throw new Error("Transaction was not able to be processed");
|
|
|
|
|
return res;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function joinGroup({ groupId }) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const lastReference = await getLastRef();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const feeres = await getFee("JOIN_GROUP");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
const tx = await createTransaction(31, keyPair, {
|
|
|
|
|
fee: feeres.fee,
|
|
|
|
|
registrantAddress: address,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
rGroupId: groupId,
|
|
|
|
|
lastReference: lastReference,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const signedBytes = Base58.encode(tx.signedBytes);
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const res = await processTransactionVersion2(signedBytes);
|
|
|
|
|
if (!res?.signature)
|
|
|
|
|
throw new Error(res?.message || "Transaction was not able to be processed");
|
|
|
|
|
return res;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function cancelInvitationToGroup({ groupId, qortalAddress }) {
|
|
|
|
|
const lastReference = await getLastRef();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const feeres = await getFee("CANCEL_GROUP_INVITE");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
const tx = await createTransaction(30, keyPair, {
|
|
|
|
|
fee: feeres.fee,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
recipient: qortalAddress,
|
|
|
|
|
rGroupId: groupId,
|
|
|
|
|
lastReference: lastReference,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const signedBytes = Base58.encode(tx.signedBytes);
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const res = await processTransactionVersion2(signedBytes);
|
|
|
|
|
if (!res?.signature)
|
|
|
|
|
throw new Error("Transaction was not able to be processed");
|
|
|
|
|
return res;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function cancelBan({ groupId, qortalAddress }) {
|
|
|
|
|
const lastReference = await getLastRef();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const feeres = await getFee("CANCEL_GROUP_BAN");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
const tx = await createTransaction(27, keyPair, {
|
|
|
|
|
fee: feeres.fee,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
recipient: qortalAddress,
|
|
|
|
|
rGroupId: groupId,
|
|
|
|
|
lastReference: lastReference,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const signedBytes = Base58.encode(tx.signedBytes);
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const res = await processTransactionVersion2(signedBytes);
|
|
|
|
|
if (!res?.signature)
|
|
|
|
|
throw new Error("Transaction was not able to be processed");
|
|
|
|
|
return res;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function registerName({ name }) {
|
|
|
|
|
const lastReference = await getLastRef();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const feeres = await getFee("REGISTER_NAME");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
const tx = await createTransaction(3, keyPair, {
|
|
|
|
|
fee: feeres.fee,
|
|
|
|
|
name,
|
|
|
|
|
value: "",
|
2024-09-16 12:35:43 +03:00
|
|
|
|
lastReference: lastReference,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const signedBytes = Base58.encode(tx.signedBytes);
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const res = await processTransactionVersion2(signedBytes);
|
|
|
|
|
if (!res?.signature)
|
|
|
|
|
throw new Error("Transaction was not able to be processed");
|
|
|
|
|
return res;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function makeAdmin({ groupId, qortalAddress }) {
|
|
|
|
|
const lastReference = await getLastRef();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const feeres = await getFee("ADD_GROUP_ADMIN");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
const tx = await createTransaction(24, keyPair, {
|
|
|
|
|
fee: feeres.fee,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
recipient: qortalAddress,
|
|
|
|
|
rGroupId: groupId,
|
|
|
|
|
lastReference: lastReference,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const signedBytes = Base58.encode(tx.signedBytes);
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const res = await processTransactionVersion2(signedBytes);
|
|
|
|
|
if (!res?.signature)
|
|
|
|
|
throw new Error("Transaction was not able to be processed");
|
|
|
|
|
return res;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function removeAdmin({ groupId, qortalAddress }) {
|
|
|
|
|
const lastReference = await getLastRef();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const feeres = await getFee("REMOVE_GROUP_ADMIN");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
const tx = await createTransaction(25, keyPair, {
|
|
|
|
|
fee: feeres.fee,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
recipient: qortalAddress,
|
|
|
|
|
rGroupId: groupId,
|
|
|
|
|
lastReference: lastReference,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const signedBytes = Base58.encode(tx.signedBytes);
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const res = await processTransactionVersion2(signedBytes);
|
|
|
|
|
if (!res?.signature)
|
|
|
|
|
throw new Error("Transaction was not able to be processed");
|
|
|
|
|
return res;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function banFromGroup({
|
|
|
|
|
groupId,
|
|
|
|
|
qortalAddress,
|
|
|
|
|
rBanReason = "",
|
|
|
|
|
rBanTime,
|
|
|
|
|
}) {
|
|
|
|
|
const lastReference = await getLastRef();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const feeres = await getFee("GROUP_BAN");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
const tx = await createTransaction(26, keyPair, {
|
|
|
|
|
fee: feeres.fee,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
recipient: qortalAddress,
|
|
|
|
|
rGroupId: groupId,
|
|
|
|
|
rBanReason: rBanReason,
|
|
|
|
|
rBanTime,
|
|
|
|
|
lastReference: lastReference,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const signedBytes = Base58.encode(tx.signedBytes);
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const res = await processTransactionVersion2(signedBytes);
|
|
|
|
|
if (!res?.signature)
|
|
|
|
|
throw new Error("Transaction was not able to be processed");
|
|
|
|
|
return res;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function kickFromGroup({ groupId, qortalAddress, rBanReason = "" }) {
|
|
|
|
|
const lastReference = await getLastRef();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const feeres = await getFee("GROUP_KICK");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
const tx = await createTransaction(28, keyPair, {
|
|
|
|
|
fee: feeres.fee,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
recipient: qortalAddress,
|
|
|
|
|
rGroupId: groupId,
|
|
|
|
|
rBanReason: rBanReason,
|
|
|
|
|
lastReference: lastReference,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const signedBytes = Base58.encode(tx.signedBytes);
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const res = await processTransactionVersion2(signedBytes);
|
|
|
|
|
if (!res?.signature)
|
|
|
|
|
throw new Error("Transaction was not able to be processed");
|
|
|
|
|
return res;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function createGroup({
|
|
|
|
|
groupName,
|
|
|
|
|
groupDescription,
|
|
|
|
|
groupType,
|
|
|
|
|
groupApprovalThreshold,
|
|
|
|
|
minBlock,
|
|
|
|
|
maxBlock,
|
|
|
|
|
}) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!address) throw new Error("Cannot find user");
|
|
|
|
|
const lastReference = await getLastRef();
|
|
|
|
|
const feeres = await getFee("CREATE_GROUP");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const tx = await createTransaction(22, keyPair, {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
fee: feeres.fee,
|
|
|
|
|
registrantAddress: address,
|
|
|
|
|
rGroupName: groupName,
|
|
|
|
|
rGroupDesc: groupDescription,
|
|
|
|
|
rGroupType: groupType,
|
|
|
|
|
rGroupApprovalThreshold: groupApprovalThreshold,
|
|
|
|
|
rGroupMinimumBlockDelay: minBlock,
|
|
|
|
|
rGroupMaximumBlockDelay: maxBlock,
|
|
|
|
|
lastReference: lastReference,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const signedBytes = Base58.encode(tx.signedBytes);
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const res = await processTransactionVersion2(signedBytes);
|
|
|
|
|
if (!res?.signature)
|
|
|
|
|
throw new Error("Transaction was not able to be processed");
|
|
|
|
|
return res;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function inviteToGroup({ groupId, qortalAddress, inviteTime }) {
|
|
|
|
|
const address = await getNameOrAddress(qortalAddress);
|
|
|
|
|
if (!address) throw new Error("Cannot find user");
|
|
|
|
|
const lastReference = await getLastRef();
|
|
|
|
|
const feeres = await getFee("GROUP_INVITE");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
|
|
|
|
publicKey: uint8PublicKey,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const tx = await createTransaction(29, keyPair, {
|
|
|
|
|
fee: feeres.fee,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
recipient: address,
|
|
|
|
|
rGroupId: groupId,
|
|
|
|
|
rInviteTime: inviteTime,
|
|
|
|
|
lastReference: lastReference,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const signedBytes = Base58.encode(tx.signedBytes);
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const res = await processTransactionVersion2(signedBytes);
|
|
|
|
|
if (!res?.signature)
|
|
|
|
|
throw new Error("Transaction was not able to be processed");
|
|
|
|
|
return res;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-07-09 00:44:02 +03:00
|
|
|
|
async function sendCoin({ password, amount, receiver }, skipConfirmPassword) {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
try {
|
|
|
|
|
const confirmReceiver = await getNameOrAddress(receiver);
|
|
|
|
|
if (confirmReceiver.error)
|
|
|
|
|
throw new Error("Invalid receiver address or name");
|
|
|
|
|
const wallet = await getSaveWallet();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let keyPair = "";
|
2024-07-15 22:07:57 -04:00
|
|
|
|
if (skipConfirmPassword) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
2024-07-09 00:44:02 +03:00
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
publicKey: uint8PublicKey,
|
2024-07-09 00:44:02 +03:00
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
const response = await decryptStoredWallet(password, wallet);
|
2024-07-15 22:07:57 -04:00
|
|
|
|
const wallet2 = new PhraseWallet(response, walletVersion);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
keyPair = wallet2._addresses[0].keyPair;
|
2024-07-09 00:44:02 +03:00
|
|
|
|
}
|
2024-07-15 22:07:57 -04:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const lastRef = await getLastRef();
|
|
|
|
|
const fee = await sendQortFee();
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const validApi = await findUsableApi();
|
2024-04-14 18:03:30 +03:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
const res = await makeTransactionRequest(
|
|
|
|
|
confirmReceiver,
|
|
|
|
|
lastRef,
|
|
|
|
|
amount,
|
|
|
|
|
fee,
|
2024-07-09 00:44:02 +03:00
|
|
|
|
keyPair,
|
2024-04-14 18:03:30 +03:00
|
|
|
|
validApi
|
2024-04-14 14:57:30 +03:00
|
|
|
|
);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-07-04 20:14:32 +03:00
|
|
|
|
return { res, validApi };
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw new Error(error.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function fetchMessages(apiCall) {
|
|
|
|
|
let retryDelay = 2000; // Start with a 2-second delay
|
2024-07-12 23:44:21 -04:00
|
|
|
|
const maxDuration = 360000 * 2; // Maximum duration set to 12 minutes
|
2024-07-04 20:14:32 +03:00
|
|
|
|
const startTime = Date.now(); // Record the start time
|
|
|
|
|
|
|
|
|
|
// Promise to handle polling logic
|
|
|
|
|
return new Promise((resolve, reject) => {
|
2024-07-15 22:07:57 -04:00
|
|
|
|
const attemptFetch = async () => {
|
|
|
|
|
if (Date.now() - startTime > maxDuration) {
|
|
|
|
|
return reject(new Error("Maximum polling time exceeded"));
|
|
|
|
|
}
|
2024-07-04 20:14:32 +03:00
|
|
|
|
|
2024-07-15 22:07:57 -04:00
|
|
|
|
try {
|
|
|
|
|
const response = await fetch(apiCall);
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
if (data && data.length > 0) {
|
|
|
|
|
resolve(data[0]); // Resolve the promise when data is found
|
|
|
|
|
} else {
|
|
|
|
|
setTimeout(attemptFetch, retryDelay);
|
|
|
|
|
retryDelay = Math.min(retryDelay * 2, 360000); // Ensure delay does not exceed 6 minutes
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
reject(error); // Reject the promise on error
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
attemptFetch(); // Initial call to start the polling
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-17 17:00:43 -04:00
|
|
|
|
async function fetchMessagesForBuyOrders(apiCall, signature, senderPublicKey) {
|
2024-07-15 22:07:57 -04:00
|
|
|
|
let retryDelay = 2000; // Start with a 2-second delay
|
|
|
|
|
const maxDuration = 360000 * 2; // Maximum duration set to 12 minutes
|
|
|
|
|
const startTime = Date.now(); // Record the start time
|
2024-09-09 20:36:39 +03:00
|
|
|
|
let triedChatMessage = [];
|
2024-07-15 22:07:57 -04:00
|
|
|
|
// Promise to handle polling logic
|
2024-09-09 20:36:39 +03:00
|
|
|
|
await new Promise((res) => {
|
2024-07-17 17:00:43 -04:00
|
|
|
|
setTimeout(() => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
res();
|
2024-07-17 17:00:43 -04:00
|
|
|
|
}, 40000);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-07-15 22:07:57 -04:00
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
const attemptFetch = async () => {
|
|
|
|
|
if (Date.now() - startTime > maxDuration) {
|
|
|
|
|
return reject(new Error("Maximum polling time exceeded"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const response = await fetch(apiCall);
|
|
|
|
|
let data = await response.json();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
data = data.filter(
|
|
|
|
|
(item) => !triedChatMessage.includes(item.signature)
|
|
|
|
|
);
|
2024-07-15 22:07:57 -04:00
|
|
|
|
if (data && data.length > 0) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const encodedMessageObj = data[0];
|
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
2024-07-15 22:07:57 -04:00
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
publicKey: uint8PublicKey,
|
2024-07-15 22:07:57 -04:00
|
|
|
|
};
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const decodedMessage = decryptChatMessage(
|
|
|
|
|
encodedMessageObj.data,
|
|
|
|
|
keyPair.privateKey,
|
|
|
|
|
senderPublicKey,
|
|
|
|
|
encodedMessageObj.reference
|
|
|
|
|
);
|
|
|
|
|
const parsedMessage = JSON.parse(decodedMessage);
|
2024-07-15 22:07:57 -04:00
|
|
|
|
if (parsedMessage?.extra?.chatRequestSignature === signature) {
|
|
|
|
|
resolve(parsedMessage);
|
|
|
|
|
} else {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
triedChatMessage.push(encodedMessageObj.signature);
|
2024-07-15 22:07:57 -04:00
|
|
|
|
setTimeout(attemptFetch, retryDelay);
|
|
|
|
|
retryDelay = Math.min(retryDelay * 2, 360000); // Ensure delay does not exceed 6 minutes
|
2024-07-04 20:14:32 +03:00
|
|
|
|
}
|
2024-07-15 22:07:57 -04:00
|
|
|
|
// Resolve the promise when data is found
|
|
|
|
|
} else {
|
|
|
|
|
setTimeout(attemptFetch, retryDelay);
|
|
|
|
|
retryDelay = Math.min(retryDelay * 2, 360000); // Ensure delay does not exceed 6 minutes
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
reject(error); // Reject the promise on error
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-07-04 20:14:32 +03:00
|
|
|
|
|
2024-07-15 22:07:57 -04:00
|
|
|
|
attemptFetch(); // Initial call to start the polling
|
2024-07-04 20:14:32 +03:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
async function listenForChatMessage({
|
|
|
|
|
nodeBaseUrl,
|
|
|
|
|
senderAddress,
|
|
|
|
|
senderPublicKey,
|
|
|
|
|
timestamp,
|
|
|
|
|
}) {
|
2024-07-04 20:14:32 +03:00
|
|
|
|
try {
|
|
|
|
|
let validApi = "";
|
|
|
|
|
const checkIfNodeBaseUrlIsAcceptable = apiEndpoints.find(
|
|
|
|
|
(item) => item === nodeBaseUrl
|
|
|
|
|
);
|
|
|
|
|
if (checkIfNodeBaseUrlIsAcceptable) {
|
|
|
|
|
validApi = checkIfNodeBaseUrlIsAcceptable;
|
|
|
|
|
} else {
|
|
|
|
|
validApi = await findUsableApi();
|
|
|
|
|
}
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const before = timestamp + 5000;
|
|
|
|
|
const after = timestamp - 5000;
|
|
|
|
|
const apiCall = `${validApi}/chat/messages?involving=${senderAddress}&involving=${address}&reverse=true&limit=1&before=${before}&after=${after}&encoding=BASE64`;
|
|
|
|
|
const encodedMessageObj = await fetchMessages(apiCall);
|
2024-07-15 22:07:57 -04:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const resKeyPair = await getKeyPair();
|
|
|
|
|
const parsedData = JSON.parse(resKeyPair);
|
2024-07-15 22:07:57 -04:00
|
|
|
|
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
const keyPair = {
|
|
|
|
|
privateKey: uint8PrivateKey,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
publicKey: uint8PublicKey,
|
2024-07-15 22:07:57 -04:00
|
|
|
|
};
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const decodedMessage = decryptChatMessage(
|
|
|
|
|
encodedMessageObj.data,
|
|
|
|
|
keyPair.privateKey,
|
|
|
|
|
senderPublicKey,
|
|
|
|
|
encodedMessageObj.reference
|
|
|
|
|
);
|
2024-07-04 20:14:32 +03:00
|
|
|
|
return { secretCode: decodedMessage };
|
2024-04-14 14:57:30 +03:00
|
|
|
|
} catch (error) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
console.error(error);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
throw new Error(error.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
async function listenForChatMessageForBuyOrder({
|
|
|
|
|
nodeBaseUrl,
|
|
|
|
|
senderAddress,
|
|
|
|
|
senderPublicKey,
|
|
|
|
|
signature,
|
|
|
|
|
}) {
|
2024-07-12 23:44:21 -04:00
|
|
|
|
try {
|
|
|
|
|
let validApi = "";
|
|
|
|
|
const checkIfNodeBaseUrlIsAcceptable = apiEndpoints.find(
|
|
|
|
|
(item) => item === nodeBaseUrl
|
|
|
|
|
);
|
|
|
|
|
if (checkIfNodeBaseUrlIsAcceptable) {
|
|
|
|
|
validApi = checkIfNodeBaseUrlIsAcceptable;
|
|
|
|
|
} else {
|
|
|
|
|
validApi = await findUsableApi();
|
|
|
|
|
}
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const before = Date.now() + 1200000;
|
|
|
|
|
const after = Date.now();
|
|
|
|
|
const apiCall = `${validApi}/chat/messages?involving=${senderAddress}&involving=${address}&reverse=true&limit=1&before=${before}&after=${after}&encoding=BASE64`;
|
|
|
|
|
const parsedMessageObj = await fetchMessagesForBuyOrders(
|
|
|
|
|
apiCall,
|
|
|
|
|
signature,
|
|
|
|
|
senderPublicKey
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// const resKeyPair = await getKeyPair()
|
|
|
|
|
// const parsedData = JSON.parse(resKeyPair)
|
|
|
|
|
// const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
|
|
|
// const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
|
|
|
// const keyPair = {
|
|
|
|
|
// privateKey: uint8PrivateKey,
|
|
|
|
|
// publicKey: uint8PublicKey
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
// const decodedMessage = decryptChatMessage(encodedMessageObj.data, keyPair.privateKey, senderPublicKey, encodedMessageObj.reference)
|
|
|
|
|
// const parsedMessage = JSON.parse(decodedMessage)
|
|
|
|
|
chrome.tabs.query({}, function (tabs) {
|
|
|
|
|
tabs.forEach((tab) => {
|
|
|
|
|
chrome.tabs.sendMessage(tab.id, {
|
|
|
|
|
type: "RESPONSE_FOR_TRADES",
|
|
|
|
|
message: parsedMessageObj,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(error);
|
|
|
|
|
throw new Error(error.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
function removeDuplicateWindow(popupUrl) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
chrome.windows.getAll(
|
|
|
|
|
{ populate: true, windowTypes: ["popup"] },
|
|
|
|
|
(windows) => {
|
|
|
|
|
// Filter to find popups matching the specific URL
|
|
|
|
|
const existingPopupsPending = windows.filter(
|
|
|
|
|
(w) =>
|
|
|
|
|
w.tabs &&
|
|
|
|
|
w.tabs.some(
|
|
|
|
|
(tab) => tab.pendingUrl && tab.pendingUrl.startsWith(popupUrl)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
const existingPopups = windows.filter(
|
|
|
|
|
(w) =>
|
|
|
|
|
w.tabs &&
|
2024-09-16 12:35:43 +03:00
|
|
|
|
w.tabs.some((tab) => tab.url && tab.url.startsWith(popupUrl))
|
2024-09-09 20:36:39 +03:00
|
|
|
|
);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
|
|
|
|
if (existingPopupsPending.length > 1) {
|
|
|
|
|
chrome.windows.remove(
|
|
|
|
|
existingPopupsPending?.[0]?.tabs?.[0]?.windowId,
|
|
|
|
|
() => {}
|
|
|
|
|
);
|
|
|
|
|
} else if (
|
|
|
|
|
existingPopupsPending.length > 0 &&
|
|
|
|
|
existingPopups.length > 0
|
|
|
|
|
) {
|
|
|
|
|
chrome.windows.remove(
|
|
|
|
|
existingPopupsPending?.[0]?.tabs?.[0]?.windowId,
|
|
|
|
|
() => {}
|
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function setChatHeads(data) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
|
|
|
|
const dataString = JSON.stringify(data);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return await new Promise((resolve, reject) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
chrome.storage.local.set({ [`chatheads-${address}`]: dataString }, () => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
reject(new Error(chrome.runtime.lastError.message));
|
|
|
|
|
} else {
|
|
|
|
|
resolve(true);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function getTempPublish() {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const key = `tempPublish-${address}`;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const res = await chrome.storage.local.get([key]);
|
|
|
|
|
const SIX_MINUTES = 6 * 60 * 1000; // 6 minutes in milliseconds
|
|
|
|
|
|
|
|
|
|
if (res?.[key]) {
|
|
|
|
|
const parsedData = JSON.parse(res[key]);
|
|
|
|
|
const currentTime = Date.now();
|
|
|
|
|
|
|
|
|
|
// Filter through each top-level key (e.g., "announcement") and then through its nested entries
|
|
|
|
|
const filteredData = Object.fromEntries(
|
|
|
|
|
Object.entries(parsedData).map(([category, entries]) => {
|
|
|
|
|
// Filter out entries inside each category that are older than 6 minutes
|
|
|
|
|
const filteredEntries = Object.fromEntries(
|
|
|
|
|
Object.entries(entries).filter(([entryKey, entryValue]) => {
|
|
|
|
|
return currentTime - entryValue.timestampSaved < SIX_MINUTES;
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
return [category, filteredEntries];
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (JSON.stringify(filteredData) !== JSON.stringify(parsedData)) {
|
|
|
|
|
const dataString = JSON.stringify(filteredData);
|
|
|
|
|
await chrome.storage.local.set({ [key]: dataString });
|
|
|
|
|
}
|
|
|
|
|
return filteredData;
|
|
|
|
|
} else {
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function saveTempPublish({ data, key }) {
|
|
|
|
|
const existingTemp = await getTempPublish();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
|
|
|
|
const newTemp = {
|
|
|
|
|
...existingTemp,
|
|
|
|
|
[key]: {
|
|
|
|
|
...(existingTemp[key] || {}),
|
2024-09-16 12:35:43 +03:00
|
|
|
|
[data.identifier]: {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
data,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
timestampSaved: Date.now(),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const dataString = JSON.stringify(newTemp);
|
|
|
|
|
|
|
|
|
|
return await new Promise((resolve, reject) => {
|
|
|
|
|
chrome.storage.local.set({ [`tempPublish-${address}`]: dataString }, () => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
reject(new Error(chrome.runtime.lastError.message));
|
|
|
|
|
} else {
|
|
|
|
|
resolve(newTemp[key]);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function setChatHeadsDirect(data) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
|
|
|
|
const dataString = JSON.stringify(data);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return await new Promise((resolve, reject) => {
|
|
|
|
|
chrome.storage.local.set(
|
|
|
|
|
{ [`chatheads-direct-${address}`]: dataString },
|
|
|
|
|
() => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
reject(new Error(chrome.runtime.lastError.message));
|
|
|
|
|
} else {
|
|
|
|
|
resolve(true);
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function getTimestampEnterChat() {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const key = `enter-chat-timestamp-${address}`;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const res = await chrome.storage.local.get([key]);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (res?.[key]) {
|
|
|
|
|
const parsedData = JSON.parse(res[key]);
|
|
|
|
|
return parsedData;
|
|
|
|
|
} else {
|
|
|
|
|
return {};
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function getTimestampGroupAnnouncement() {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const key = `group-announcement-${address}`;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const res = await chrome.storage.local.get([key]);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (res?.[key]) {
|
|
|
|
|
const parsedData = JSON.parse(res[key]);
|
|
|
|
|
return parsedData;
|
|
|
|
|
} else {
|
|
|
|
|
return {};
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function addTimestampGroupAnnouncement({
|
|
|
|
|
groupId,
|
|
|
|
|
timestamp,
|
|
|
|
|
seenTimestamp,
|
|
|
|
|
}) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const data = (await getTimestampGroupAnnouncement()) || {};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
data[groupId] = {
|
|
|
|
|
notification: timestamp,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
seentimestamp: seenTimestamp ? true : false,
|
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const dataString = JSON.stringify(data);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return await new Promise((resolve, reject) => {
|
|
|
|
|
chrome.storage.local.set(
|
|
|
|
|
{ [`group-announcement-${address}`]: dataString },
|
|
|
|
|
() => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
reject(new Error(chrome.runtime.lastError.message));
|
|
|
|
|
} else {
|
|
|
|
|
resolve(true);
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
|
|
|
|
}
|
2024-07-15 22:07:57 -04:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function getGroupData() {
|
2024-09-12 18:12:56 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const key = `group-data-${address}`;
|
2024-09-12 18:12:56 +03:00
|
|
|
|
const res = await chrome.storage.local.get([key]);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (res?.[key]) {
|
|
|
|
|
const parsedData = JSON.parse(res[key]);
|
|
|
|
|
return parsedData;
|
|
|
|
|
} else {
|
|
|
|
|
return {};
|
|
|
|
|
}
|
2024-09-12 18:12:56 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function getGroupDataSingle(groupId) {
|
2024-09-12 18:12:56 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const key = `group-data-${address}`;
|
2024-09-12 18:12:56 +03:00
|
|
|
|
const res = await chrome.storage.local.get([key]);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (res?.[key]) {
|
|
|
|
|
const parsedData = JSON.parse(res[key]);
|
|
|
|
|
return parsedData[groupId] || null;
|
|
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2024-09-12 18:12:56 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function setGroupData({
|
|
|
|
|
groupId,
|
2024-09-12 18:12:56 +03:00
|
|
|
|
secretKeyData,
|
|
|
|
|
secretKeyResource,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
admins,
|
|
|
|
|
}) {
|
2024-09-12 18:12:56 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const data = (await getGroupData()) || {};
|
2024-09-12 18:12:56 +03:00
|
|
|
|
data[groupId] = {
|
|
|
|
|
timestampLastSet: Date.now(),
|
|
|
|
|
admins,
|
|
|
|
|
secretKeyData,
|
|
|
|
|
secretKeyResource,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
};
|
2024-09-12 18:12:56 +03:00
|
|
|
|
const dataString = JSON.stringify(data);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return await new Promise((resolve, reject) => {
|
2024-09-12 18:12:56 +03:00
|
|
|
|
chrome.storage.local.set({ [`group-data-${address}`]: dataString }, () => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
reject(new Error(chrome.runtime.lastError.message));
|
|
|
|
|
} else {
|
|
|
|
|
resolve(true);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function addTimestampEnterChat({ groupId, timestamp }) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const data = await getTimestampEnterChat();
|
|
|
|
|
data[groupId] = timestamp;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const dataString = JSON.stringify(data);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return await new Promise((resolve, reject) => {
|
|
|
|
|
chrome.storage.local.set(
|
|
|
|
|
{ [`enter-chat-timestamp-${address}`]: dataString },
|
|
|
|
|
() => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
reject(new Error(chrome.runtime.lastError.message));
|
|
|
|
|
} else {
|
|
|
|
|
resolve(true);
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function notifyAdminRegenerateSecretKey({ groupName, adminAddress }) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const name = await getNameInfo(address);
|
|
|
|
|
const nameOrAddress = name || address;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
await sendChatDirect({
|
|
|
|
|
directTo: adminAddress,
|
|
|
|
|
typeMessage: undefined,
|
|
|
|
|
chatReference: undefined,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
messageText: `<p>Member ${nameOrAddress} has requested that you regenerate the group's secret key. Group: ${groupName}</p>`,
|
|
|
|
|
});
|
|
|
|
|
return true;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function getChatHeads() {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const key = `chatheads-${address}`;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const res = await chrome.storage.local.get([key]);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (res?.[key]) {
|
|
|
|
|
const parsedData = JSON.parse(res[key]);
|
|
|
|
|
return parsedData;
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error("No Chatheads saved");
|
|
|
|
|
}
|
2024-07-12 23:44:21 -04:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
async function getChatHeadsDirect() {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const key = `chatheads-direct-${address}`;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const res = await chrome.storage.local.get([key]);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (res?.[key]) {
|
|
|
|
|
const parsedData = JSON.parse(res[key]);
|
|
|
|
|
return parsedData;
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error("No Chatheads saved");
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-12 05:01:36 +03:00
|
|
|
|
chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
2024-04-14 14:57:30 +03:00
|
|
|
|
if (request) {
|
|
|
|
|
switch (request.action) {
|
|
|
|
|
case "version":
|
|
|
|
|
// Example: respond with the version
|
|
|
|
|
sendResponse({ version: "1.0" });
|
|
|
|
|
break;
|
|
|
|
|
case "storeWalletInfo":
|
|
|
|
|
chrome.storage.local.set({ walletInfo: request.wallet }, () => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
sendResponse({ error: chrome.runtime.lastError.message });
|
|
|
|
|
} else {
|
|
|
|
|
sendResponse({ result: "Data saved successfully" });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "getWalletInfo":
|
2024-09-09 20:36:39 +03:00
|
|
|
|
getKeyPair()
|
|
|
|
|
.then(() => {
|
|
|
|
|
chrome.storage.local.get(["walletInfo"], (result) => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
sendResponse({ error: chrome.runtime.lastError.message });
|
|
|
|
|
} else if (result.walletInfo) {
|
|
|
|
|
sendResponse({ walletInfo: result.walletInfo });
|
|
|
|
|
} else {
|
|
|
|
|
sendResponse({ error: "No wallet info found" });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
2024-07-15 22:07:57 -04:00
|
|
|
|
});
|
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
break;
|
|
|
|
|
case "validApi":
|
|
|
|
|
findUsableApi()
|
|
|
|
|
.then((usableApi) => {
|
|
|
|
|
console.log("Usable API:", usableApi);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
case "name":
|
|
|
|
|
getNameInfo()
|
|
|
|
|
.then((name) => {
|
|
|
|
|
sendResponse(name);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "userInfo":
|
|
|
|
|
getUserInfo()
|
|
|
|
|
.then((name) => {
|
|
|
|
|
sendResponse(name);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: "User not authenticated" });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
break;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
case "decryptWallet":
|
|
|
|
|
{
|
|
|
|
|
const { password, wallet } = request.payload;
|
2024-07-15 22:07:57 -04:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
decryptWallet({
|
|
|
|
|
password,
|
|
|
|
|
wallet,
|
|
|
|
|
walletVersion,
|
2024-07-09 00:44:02 +03:00
|
|
|
|
})
|
2024-09-09 20:36:39 +03:00
|
|
|
|
.then((hasDecrypted) => {
|
|
|
|
|
sendResponse(hasDecrypted);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error?.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-07-15 22:07:57 -04:00
|
|
|
|
|
2024-07-09 00:44:02 +03:00
|
|
|
|
break;
|
2024-04-14 14:57:30 +03:00
|
|
|
|
case "balance":
|
|
|
|
|
getBalanceInfo()
|
|
|
|
|
.then((balance) => {
|
|
|
|
|
sendResponse(balance);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
break;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
case "ltcBalance":
|
|
|
|
|
{
|
|
|
|
|
getLTCBalance()
|
|
|
|
|
.then((balance) => {
|
|
|
|
|
sendResponse(balance);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
break;
|
2024-04-14 14:57:30 +03:00
|
|
|
|
case "sendCoin":
|
|
|
|
|
{
|
|
|
|
|
const { receiver, password, amount } = request.payload;
|
|
|
|
|
sendCoin({ receiver, password, amount })
|
2024-09-16 12:35:43 +03:00
|
|
|
|
.then(({ res }) => {
|
|
|
|
|
if (!res?.success) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
sendResponse({ error: res?.data?.message });
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
sendResponse(true);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
case "inviteToGroup":
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{
|
|
|
|
|
const { groupId, qortalAddress, inviteTime } = request.payload;
|
|
|
|
|
inviteToGroup({ groupId, qortalAddress, inviteTime })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-07-04 20:14:32 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
break;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
case "saveTempPublish":
|
|
|
|
|
{
|
|
|
|
|
const { data, key } = request.payload;
|
|
|
|
|
saveTempPublish({ data, key })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "getTempPublish":
|
|
|
|
|
{
|
|
|
|
|
getTempPublish()
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case "createGroup":
|
|
|
|
|
{
|
|
|
|
|
const {
|
|
|
|
|
groupName,
|
|
|
|
|
groupDescription,
|
|
|
|
|
groupType,
|
|
|
|
|
groupApprovalThreshold,
|
|
|
|
|
minBlock,
|
|
|
|
|
maxBlock,
|
|
|
|
|
} = request.payload;
|
|
|
|
|
createGroup({
|
|
|
|
|
groupName,
|
|
|
|
|
groupDescription,
|
|
|
|
|
groupType,
|
|
|
|
|
groupApprovalThreshold,
|
|
|
|
|
minBlock,
|
|
|
|
|
maxBlock,
|
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case "cancelInvitationToGroup":
|
|
|
|
|
{
|
|
|
|
|
const { groupId, qortalAddress } = request.payload;
|
|
|
|
|
cancelInvitationToGroup({ groupId, qortalAddress })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case "leaveGroup":
|
|
|
|
|
{
|
|
|
|
|
const { groupId } = request.payload;
|
|
|
|
|
leaveGroup({ groupId })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case "joinGroup":
|
|
|
|
|
{
|
|
|
|
|
const { groupId } = request.payload;
|
|
|
|
|
joinGroup({ groupId })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case "kickFromGroup":
|
|
|
|
|
{
|
|
|
|
|
const { groupId, qortalAddress, rBanReason } = request.payload;
|
|
|
|
|
kickFromGroup({ groupId, qortalAddress, rBanReason })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case "banFromGroup":
|
|
|
|
|
{
|
|
|
|
|
const { groupId, qortalAddress, rBanReason, rBanTime } =
|
|
|
|
|
request.payload;
|
|
|
|
|
banFromGroup({ groupId, qortalAddress, rBanReason, rBanTime })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case "addDataPublishes":
|
|
|
|
|
{
|
|
|
|
|
const { data, groupId, type } = request.payload;
|
|
|
|
|
addDataPublishes(data, groupId, type)
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "getDataPublishes":
|
|
|
|
|
{
|
|
|
|
|
const { groupId, type } = request.payload;
|
|
|
|
|
getDataPublishes(groupId, type)
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "addUserSettings":
|
|
|
|
|
{
|
|
|
|
|
const { keyValue } = request.payload;
|
|
|
|
|
addUserSettings({keyValue})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "getUserSettings":
|
|
|
|
|
{
|
|
|
|
|
const { key } = request.payload;
|
|
|
|
|
getUserSettings({key})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "cancelBan":
|
|
|
|
|
{
|
|
|
|
|
const { groupId, qortalAddress } = request.payload;
|
|
|
|
|
cancelBan({ groupId, qortalAddress })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case "registerName":
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const { name } = request.payload;
|
|
|
|
|
registerName({ name })
|
2024-09-09 20:36:39 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
break;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
case "makeAdmin":
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const { groupId, qortalAddress } = request.payload;
|
|
|
|
|
makeAdmin({ groupId, qortalAddress })
|
2024-09-09 20:36:39 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
break;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
case "removeAdmin":
|
2024-09-09 20:36:39 +03:00
|
|
|
|
{
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const { groupId, qortalAddress } = request.payload;
|
|
|
|
|
removeAdmin({ groupId, qortalAddress })
|
2024-09-09 20:36:39 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-07-09 00:44:02 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
break;
|
2024-09-16 02:52:05 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
case "oauth": {
|
|
|
|
|
const { nodeBaseUrl, senderAddress, senderPublicKey, timestamp } =
|
|
|
|
|
request.payload;
|
|
|
|
|
|
|
|
|
|
listenForChatMessage({
|
|
|
|
|
nodeBaseUrl,
|
|
|
|
|
senderAddress,
|
|
|
|
|
senderPublicKey,
|
|
|
|
|
timestamp,
|
|
|
|
|
})
|
2024-07-04 20:14:32 +03:00
|
|
|
|
.then(({ secretCode }) => {
|
|
|
|
|
sendResponse(secretCode);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
case "setChatHeads": {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const { data } = request.payload;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
setChatHeads({
|
|
|
|
|
data,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
})
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "getChatHeads": {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
getChatHeads()
|
2024-09-09 20:36:39 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "notification": {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const notificationId = "chat_notification_" + Date.now(); // Create a unique ID
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const {} = request.payload;
|
|
|
|
|
chrome.notifications.create(notificationId, {
|
|
|
|
|
type: "basic",
|
|
|
|
|
iconUrl: "qort.png", // Add an appropriate icon for chat notifications
|
|
|
|
|
title: "New Group Message!",
|
|
|
|
|
message: "You have received a new message from one of your groups",
|
|
|
|
|
priority: 2, // Use the maximum priority to ensure it's noticeable
|
|
|
|
|
// buttons: [
|
|
|
|
|
// { title: 'Go to group' }
|
|
|
|
|
// ]
|
|
|
|
|
});
|
|
|
|
|
// Set a timeout to clear the notification after 'timeout' milliseconds
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chrome.notifications.clear(notificationId);
|
|
|
|
|
}, 3000);
|
|
|
|
|
sendResponse(true);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "addTimestampEnterChat": {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const { groupId, timestamp } = request.payload;
|
|
|
|
|
addTimestampEnterChat({ groupId, timestamp })
|
2024-09-09 20:36:39 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case "setApiKey": {
|
|
|
|
|
const { payload } = request;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// Save the apiKey in chrome.storage.local for persistence
|
|
|
|
|
chrome.storage.local.set({ apiKey: payload }, () => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
sendResponse(true);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return true;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "getApiKey": {
|
|
|
|
|
getApiKeyFromStorage()
|
2024-09-16 12:35:43 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
return true;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "notifyAdminRegenerateSecretKey": {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const { groupName, adminAddress } = request.payload;
|
|
|
|
|
notifyAdminRegenerateSecretKey({ groupName, adminAddress })
|
2024-09-09 20:36:39 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-09-14 11:42:05 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
case "addGroupNotificationTimestamp": {
|
|
|
|
|
const { groupId, timestamp } = request.payload;
|
|
|
|
|
addTimestampGroupAnnouncement({
|
|
|
|
|
groupId,
|
|
|
|
|
timestamp,
|
|
|
|
|
seenTimestamp: true,
|
|
|
|
|
})
|
2024-09-14 11:42:05 +03:00
|
|
|
|
.then((res) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
sendResponse(res);
|
2024-09-14 11:42:05 +03:00
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
2024-09-14 11:42:05 +03:00
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
case "clearAllNotifications": {
|
|
|
|
|
clearAllNotifications()
|
|
|
|
|
.then((res) => {})
|
|
|
|
|
.catch((error) => {});
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-09-12 18:12:56 +03:00
|
|
|
|
case "setGroupData": {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const { groupId, secretKeyData, secretKeyResource, admins } =
|
|
|
|
|
request.payload;
|
|
|
|
|
setGroupData({
|
|
|
|
|
groupId,
|
2024-09-12 18:12:56 +03:00
|
|
|
|
secretKeyData,
|
|
|
|
|
secretKeyResource,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
admins,
|
|
|
|
|
})
|
2024-09-12 18:12:56 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "getGroupDataSingle": {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const { groupId } = request.payload;
|
2024-09-12 18:12:56 +03:00
|
|
|
|
getGroupDataSingle(groupId)
|
2024-09-16 12:35:43 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
return true;
|
2024-09-12 18:12:56 +03:00
|
|
|
|
break;
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
case "getTimestampEnterChat": {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
getTimestampEnterChat()
|
2024-09-09 20:36:39 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "getGroupNotificationTimestamp": {
|
|
|
|
|
getTimestampGroupAnnouncement()
|
2024-09-16 12:35:43 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
case "authentication":
|
|
|
|
|
{
|
|
|
|
|
getSaveWallet()
|
|
|
|
|
.then(() => {
|
|
|
|
|
sendResponse(true);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const popupUrl = chrome.runtime.getURL(
|
|
|
|
|
"index.html?secondary=true"
|
|
|
|
|
);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
|
|
|
|
chrome.windows.getAll(
|
|
|
|
|
{ populate: true, windowTypes: ["popup"] },
|
|
|
|
|
(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",
|
|
|
|
|
});
|
|
|
|
|
} 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;
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.windows.create(
|
|
|
|
|
{
|
|
|
|
|
url: chrome.runtime.getURL(
|
|
|
|
|
"index.html?secondary=true"
|
|
|
|
|
),
|
|
|
|
|
type: "popup",
|
|
|
|
|
width: windowWidth,
|
|
|
|
|
height: windowHeight,
|
|
|
|
|
left: leftPosition,
|
|
|
|
|
top: 0,
|
|
|
|
|
},
|
|
|
|
|
() => {
|
|
|
|
|
removeDuplicateWindow(popupUrl);
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const interactionId = Date.now().toString(); // Simple example; consider a better unique ID
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "SET_COUNTDOWN",
|
|
|
|
|
payload: request.timeout ? 0.75 * request.timeout : 60,
|
|
|
|
|
});
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "UPDATE_STATE_REQUEST_AUTHENTICATION",
|
|
|
|
|
payload: {
|
|
|
|
|
hostname,
|
|
|
|
|
interactionId,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}, 500);
|
|
|
|
|
|
|
|
|
|
// Store sendResponse callback with the interaction ID
|
|
|
|
|
pendingResponses.set(interactionId, sendResponse);
|
|
|
|
|
let intervalId = null;
|
|
|
|
|
const startTime = Date.now();
|
|
|
|
|
const checkInterval = 3000; // Check every 3 seconds
|
2024-07-04 20:14:32 +03:00
|
|
|
|
const timeout = request.timeout
|
|
|
|
|
? 0.75 * (request.timeout * 1000)
|
|
|
|
|
: 60000; // Stop after 15 seconds
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
|
|
|
|
const checkFunction = () => {
|
|
|
|
|
getSaveWallet()
|
|
|
|
|
.then(() => {
|
|
|
|
|
clearInterval(intervalId); // Stop checking
|
|
|
|
|
sendResponse(true); // Perform the success action
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "closePopup",
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
// Handle error if needed
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (Date.now() - startTime > timeout) {
|
|
|
|
|
sendResponse({
|
|
|
|
|
error: "User has not authenticated, try again.",
|
|
|
|
|
});
|
|
|
|
|
clearInterval(intervalId); // Stop checking due to timeout
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
// Handle timeout situation if needed
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
intervalId = setInterval(checkFunction, checkInterval);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
break;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
case "buyOrder":
|
|
|
|
|
{
|
|
|
|
|
const { qortalAtAddress, hostname } = request.payload;
|
|
|
|
|
getTradeInfo(qortalAtAddress)
|
|
|
|
|
.then((crosschainAtInfo) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const popupUrl = chrome.runtime.getURL(
|
|
|
|
|
"index.html?secondary=true"
|
|
|
|
|
);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
|
|
|
|
chrome.windows.getAll(
|
|
|
|
|
{ populate: true, windowTypes: ["popup"] },
|
|
|
|
|
(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",
|
|
|
|
|
});
|
|
|
|
|
} 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;
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.windows.create(
|
|
|
|
|
{
|
|
|
|
|
url: chrome.runtime.getURL(
|
|
|
|
|
"index.html?secondary=true"
|
|
|
|
|
),
|
|
|
|
|
type: "popup",
|
|
|
|
|
width: windowWidth,
|
|
|
|
|
height: windowHeight,
|
|
|
|
|
left: leftPosition,
|
|
|
|
|
top: 0,
|
|
|
|
|
},
|
|
|
|
|
() => {
|
|
|
|
|
removeDuplicateWindow(popupUrl);
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const interactionId = Date.now().toString(); // Simple example; consider a better unique ID
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "SET_COUNTDOWN",
|
|
|
|
|
payload: request.timeout ? 0.9 * request.timeout : 20,
|
|
|
|
|
});
|
|
|
|
|
chrome.runtime.sendMessage({
|
2024-09-09 20:36:39 +03:00
|
|
|
|
action: "UPDATE_STATE_REQUEST_BUY_ORDER",
|
2024-04-14 14:57:30 +03:00
|
|
|
|
payload: {
|
|
|
|
|
hostname,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
crosschainAtInfo,
|
2024-04-14 14:57:30 +03:00
|
|
|
|
interactionId,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}, 500);
|
|
|
|
|
|
|
|
|
|
// Store sendResponse callback with the interaction ID
|
|
|
|
|
pendingResponses.set(interactionId, sendResponse);
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case "connection":
|
|
|
|
|
{
|
|
|
|
|
const { hostname } = request.payload;
|
|
|
|
|
|
|
|
|
|
connection(hostname)
|
|
|
|
|
.then((isConnected) => {
|
|
|
|
|
if (
|
|
|
|
|
Object.keys(isConnected)?.length > 0 &&
|
|
|
|
|
isConnected[hostname]
|
|
|
|
|
) {
|
|
|
|
|
sendResponse(true);
|
|
|
|
|
} else {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const popupUrl = chrome.runtime.getURL(
|
|
|
|
|
"index.html?secondary=true"
|
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
chrome.windows.getAll(
|
|
|
|
|
{ populate: true, windowTypes: ["popup"] },
|
|
|
|
|
(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)
|
|
|
|
|
)
|
|
|
|
|
);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (existingPopup) {
|
|
|
|
|
// If the popup exists but is minimized or not focused, focus it
|
|
|
|
|
chrome.windows.update(existingPopup.id, {
|
|
|
|
|
focused: true,
|
|
|
|
|
state: "normal",
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
} else {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// 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;
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.windows.create(
|
|
|
|
|
{
|
2024-09-09 20:36:39 +03:00
|
|
|
|
url: popupUrl,
|
|
|
|
|
type: "popup",
|
|
|
|
|
width: windowWidth,
|
|
|
|
|
height: windowHeight,
|
|
|
|
|
left: leftPosition,
|
|
|
|
|
top: 0,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
},
|
|
|
|
|
() => {
|
|
|
|
|
removeDuplicateWindow(popupUrl);
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const interactionId = Date.now().toString(); // Simple example; consider a better unique ID
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "SET_COUNTDOWN",
|
|
|
|
|
payload: request.timeout ? 0.9 * request.timeout : 20,
|
|
|
|
|
});
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "UPDATE_STATE_REQUEST_CONNECTION",
|
|
|
|
|
payload: {
|
|
|
|
|
hostname,
|
|
|
|
|
interactionId,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}, 500);
|
|
|
|
|
|
|
|
|
|
// Store sendResponse callback with the interaction ID
|
|
|
|
|
pendingResponses.set(interactionId, sendResponse);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-07-15 22:07:57 -04:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
break;
|
|
|
|
|
case "sendQort":
|
|
|
|
|
{
|
|
|
|
|
const { amount, hostname, address, description } = request.payload;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const popupUrl = chrome.runtime.getURL("index.html?secondary=true");
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
|
|
|
|
chrome.windows.getAll(
|
|
|
|
|
{ populate: true, windowTypes: ["popup"] },
|
|
|
|
|
(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",
|
|
|
|
|
});
|
|
|
|
|
} 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;
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.windows.create(
|
|
|
|
|
{
|
|
|
|
|
url: chrome.runtime.getURL("index.html?secondary=true"),
|
|
|
|
|
type: "popup",
|
|
|
|
|
width: windowWidth,
|
|
|
|
|
height: windowHeight,
|
|
|
|
|
left: leftPosition,
|
|
|
|
|
top: 0,
|
|
|
|
|
},
|
|
|
|
|
() => {
|
|
|
|
|
removeDuplicateWindow(popupUrl);
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const interactionId = Date.now().toString(); // Simple example; consider a better unique ID
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "SET_COUNTDOWN",
|
2024-04-15 22:38:00 +03:00
|
|
|
|
payload: (request.timeout ? request.timeout : 60) - 6,
|
2024-04-14 14:57:30 +03:00
|
|
|
|
});
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "UPDATE_STATE_CONFIRM_SEND_QORT",
|
|
|
|
|
payload: {
|
|
|
|
|
amount,
|
|
|
|
|
address,
|
|
|
|
|
hostname,
|
|
|
|
|
description,
|
|
|
|
|
interactionId,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}, 500);
|
|
|
|
|
|
|
|
|
|
// Store sendResponse callback with the interaction ID
|
|
|
|
|
pendingResponses.set(interactionId, sendResponse);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case "responseToConnectionRequest":
|
|
|
|
|
{
|
|
|
|
|
const { hostname, isOkay } = request.payload;
|
|
|
|
|
const interactionId3 = request.payload.interactionId;
|
|
|
|
|
if (!isOkay) {
|
|
|
|
|
const originalSendResponse = pendingResponses.get(interactionId3);
|
|
|
|
|
if (originalSendResponse) {
|
|
|
|
|
originalSendResponse(false);
|
|
|
|
|
sendResponse(false);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
const originalSendResponse = pendingResponses.get(interactionId3);
|
|
|
|
|
if (originalSendResponse) {
|
|
|
|
|
// Example of setting domain permission
|
|
|
|
|
chrome.storage.local.set({ [hostname]: true });
|
|
|
|
|
|
|
|
|
|
originalSendResponse(true);
|
|
|
|
|
sendResponse(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-07-09 07:27:22 +03:00
|
|
|
|
|
|
|
|
|
pendingResponses.delete(interactionId3);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case "sendQortConfirmation":
|
|
|
|
|
const { password, amount, receiver, isDecline } = request.payload;
|
|
|
|
|
const interactionId2 = request.payload.interactionId;
|
|
|
|
|
// Retrieve the stored sendResponse callback
|
|
|
|
|
const originalSendResponse = pendingResponses.get(interactionId2);
|
|
|
|
|
|
|
|
|
|
if (originalSendResponse) {
|
|
|
|
|
if (isDecline) {
|
|
|
|
|
originalSendResponse({ error: "User has declined" });
|
|
|
|
|
sendResponse(false);
|
2024-07-09 07:27:22 +03:00
|
|
|
|
pendingResponses.delete(interactionId2);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
return;
|
|
|
|
|
}
|
2024-07-09 00:44:02 +03:00
|
|
|
|
sendCoin({ password, amount, receiver }, true)
|
2024-04-14 14:57:30 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(true);
|
|
|
|
|
// Use the sendResponse callback to respond to the original message
|
|
|
|
|
originalSendResponse(res);
|
2024-07-09 07:27:22 +03:00
|
|
|
|
// Remove the callback from the Map as it's no longer needed
|
|
|
|
|
pendingResponses.delete(interactionId2);
|
2024-04-15 22:30:49 +03:00
|
|
|
|
// chrome.runtime.sendMessage({
|
|
|
|
|
// action: "closePopup",
|
|
|
|
|
// });
|
2024-04-14 14:57:30 +03:00
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
2024-04-15 22:30:49 +03:00
|
|
|
|
sendResponse({ error: error.message });
|
2024-04-14 14:57:30 +03:00
|
|
|
|
originalSendResponse({ error: error.message });
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
break;
|
|
|
|
|
case "buyOrderConfirmation":
|
|
|
|
|
{
|
|
|
|
|
const { crosschainAtInfo, isDecline } = request.payload;
|
|
|
|
|
const interactionId2 = request.payload.interactionId;
|
|
|
|
|
// Retrieve the stored sendResponse callback
|
|
|
|
|
const originalSendResponse = pendingResponses.get(interactionId2);
|
|
|
|
|
|
|
|
|
|
if (originalSendResponse) {
|
|
|
|
|
if (isDecline) {
|
|
|
|
|
originalSendResponse({ error: "User has declined" });
|
|
|
|
|
sendResponse(false);
|
|
|
|
|
pendingResponses.delete(interactionId2);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
createBuyOrderTx({ crosschainAtInfo })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(true);
|
|
|
|
|
originalSendResponse(res);
|
|
|
|
|
pendingResponses.delete(interactionId2);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
// originalSendResponse({ error: error.message });
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-07-12 23:44:21 -04:00
|
|
|
|
break;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
case "encryptAndPublishSymmetricKeyGroupChat": {
|
|
|
|
|
const { groupId, previousData, previousNumber } = request.payload;
|
2024-07-15 22:07:57 -04:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
encryptAndPublishSymmetricKeyGroupChat({
|
|
|
|
|
groupId,
|
|
|
|
|
previousData,
|
|
|
|
|
previousNumber,
|
|
|
|
|
})
|
2024-09-16 12:35:43 +03:00
|
|
|
|
.then(({ data, numberOfMembers }) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
sendResponse(data);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
|
|
|
|
if (!previousData) {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// first secret key of the group
|
|
|
|
|
sendChatGroup({
|
|
|
|
|
groupId,
|
|
|
|
|
typeMessage: undefined,
|
|
|
|
|
chatReference: undefined,
|
|
|
|
|
messageText: PUBLIC_NOTIFICATION_CODE_FIRST_SECRET_KEY,
|
|
|
|
|
})
|
|
|
|
|
.then(() => {})
|
|
|
|
|
.catch((error) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
console.error("1", error.message);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
sendChatNotification(data, groupId, previousData, numberOfMembers);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
});
|
2024-07-15 22:07:57 -04:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "publishGroupEncryptedResource": {
|
|
|
|
|
const { encryptedData, identifier } = request.payload;
|
|
|
|
|
|
|
|
|
|
publishGroupEncryptedResource({
|
2024-09-16 12:35:43 +03:00
|
|
|
|
encryptedData,
|
|
|
|
|
identifier,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
})
|
|
|
|
|
.then((data) => {
|
|
|
|
|
sendResponse(data);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
return true;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "handleActiveGroupDataFromSocket": {
|
|
|
|
|
const { groups, directs } = request.payload;
|
|
|
|
|
handleActiveGroupDataFromSocket({
|
2024-09-16 12:35:43 +03:00
|
|
|
|
groups,
|
|
|
|
|
directs,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
})
|
|
|
|
|
.then((data) => {
|
|
|
|
|
sendResponse(true);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "getThreadActivity": {
|
|
|
|
|
checkThreads(true)
|
|
|
|
|
.then((data) => {
|
|
|
|
|
sendResponse(data);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case "updateThreadActivity": {
|
|
|
|
|
const { threadId, qortalName, groupId, thread } = request.payload;
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
updateThreadActivity({ threadId, qortalName, groupId, thread })
|
2024-09-09 20:36:39 +03:00
|
|
|
|
.then(() => {
|
|
|
|
|
sendResponse(true);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "decryptGroupEncryption": {
|
|
|
|
|
const { data } = request.payload;
|
|
|
|
|
|
|
|
|
|
decryptGroupEncryption({ data })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "encryptSingle": {
|
|
|
|
|
const { data, secretKeyObject } = request.payload;
|
|
|
|
|
|
|
|
|
|
encryptSingle({ data64: data, secretKeyObject: secretKeyObject })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "decryptSingle": {
|
|
|
|
|
const { data, secretKeyObject, skipDecodeBase64 } = request.payload;
|
|
|
|
|
|
|
|
|
|
decryptSingleFunc({ messages: data, secretKeyObject, skipDecodeBase64 })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-09-11 15:42:01 +03:00
|
|
|
|
case "pauseAllQueues": {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
pauseAllQueues();
|
|
|
|
|
sendResponse(true);
|
2024-09-11 15:42:01 +03:00
|
|
|
|
|
|
|
|
|
break;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-11 15:42:01 +03:00
|
|
|
|
}
|
|
|
|
|
case "resumeAllQueues": {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
resumeAllQueues();
|
|
|
|
|
sendResponse(true);
|
2024-09-11 15:42:01 +03:00
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
case "decryptSingleForPublishes": {
|
|
|
|
|
const { data, secretKeyObject, skipDecodeBase64 } = request.payload;
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
decryptSingleForPublishes({
|
|
|
|
|
messages: data,
|
|
|
|
|
secretKeyObject,
|
|
|
|
|
skipDecodeBase64,
|
|
|
|
|
})
|
2024-09-09 20:36:39 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
case "decryptDirect": {
|
|
|
|
|
const { data, involvingAddress } = request.payload;
|
|
|
|
|
|
|
|
|
|
decryptDirectFunc({ messages: data, involvingAddress })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
case "sendChatGroup": {
|
|
|
|
|
const {
|
|
|
|
|
groupId,
|
|
|
|
|
typeMessage = undefined,
|
|
|
|
|
chatReference = undefined,
|
|
|
|
|
messageText,
|
|
|
|
|
} = request.payload;
|
|
|
|
|
|
|
|
|
|
sendChatGroup({ groupId, typeMessage, chatReference, messageText })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
break;
|
2024-07-15 22:07:57 -04:00
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
case "sendChatDirect": {
|
|
|
|
|
const {
|
|
|
|
|
directTo,
|
|
|
|
|
typeMessage = undefined,
|
|
|
|
|
chatReference = undefined,
|
|
|
|
|
messageText,
|
2024-09-12 22:23:47 +03:00
|
|
|
|
publicKeyOfRecipient,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
address,
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} = request.payload;
|
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
sendChatDirect({
|
|
|
|
|
directTo,
|
|
|
|
|
chatReference,
|
|
|
|
|
messageText,
|
|
|
|
|
typeMessage,
|
|
|
|
|
publicKeyOfRecipient,
|
|
|
|
|
address,
|
|
|
|
|
})
|
2024-09-09 20:36:39 +03:00
|
|
|
|
.then((res) => {
|
|
|
|
|
sendResponse(res);
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.error(error.message);
|
|
|
|
|
sendResponse({ error: error.message });
|
|
|
|
|
});
|
2024-07-15 22:07:57 -04:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "setupGroupWebsocket": {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
checkNewMessages();
|
|
|
|
|
checkThreads();
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// if(socket){
|
|
|
|
|
// if(groups){
|
|
|
|
|
// console.log('hasgroups1')
|
|
|
|
|
// chrome.runtime.sendMessage({
|
|
|
|
|
// action: "SET_GROUPS",
|
|
|
|
|
// payload: groups,
|
|
|
|
|
// });
|
|
|
|
|
// }
|
|
|
|
|
// if(directs){
|
|
|
|
|
// console.log('hasgroups1')
|
|
|
|
|
// chrome.runtime.sendMessage({
|
|
|
|
|
// action: "SET_DIRECTS",
|
|
|
|
|
// payload: directs,
|
|
|
|
|
// });
|
|
|
|
|
// }
|
|
|
|
|
// sendResponse(true)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
// setTimeout(() => {
|
|
|
|
|
// // initWebsocketMessageGroup()
|
|
|
|
|
// listenForNewGroupAnnouncements()
|
|
|
|
|
// listenForThreadUpdates()
|
|
|
|
|
// }, 200);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
sendResponse(true);
|
2024-07-12 23:44:21 -04:00
|
|
|
|
|
2024-04-14 14:57:30 +03:00
|
|
|
|
break;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-07-04 20:14:32 +03:00
|
|
|
|
case "logout":
|
|
|
|
|
{
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const logoutFunc = async () => {
|
|
|
|
|
forceCloseWebSocket();
|
|
|
|
|
clearAllQueues();
|
|
|
|
|
if (interval) {
|
|
|
|
|
// for announcement notification
|
|
|
|
|
clearInterval(interval);
|
|
|
|
|
}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
|
|
|
|
const key1 = `tempPublish-${address}`;
|
|
|
|
|
const key2 = `group-data-${address}`;
|
|
|
|
|
const key3 = `${address}-publishData`;
|
|
|
|
|
chrome.storage.local.remove(
|
|
|
|
|
[
|
|
|
|
|
"keyPair",
|
|
|
|
|
"walletInfo",
|
|
|
|
|
"apiKey",
|
|
|
|
|
"active-groups-directs",
|
|
|
|
|
key1,
|
|
|
|
|
key2,
|
|
|
|
|
key3,
|
|
|
|
|
],
|
|
|
|
|
() => {
|
|
|
|
|
if (chrome.runtime.lastError) {
|
|
|
|
|
// Handle error
|
|
|
|
|
console.error(chrome.runtime.lastError.message);
|
|
|
|
|
} else {
|
|
|
|
|
chrome.tabs.query({}, function (tabs) {
|
|
|
|
|
tabs.forEach((tab) => {
|
|
|
|
|
chrome.tabs.sendMessage(tab.id, { type: "LOGOUT" });
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
// Data removed successfully
|
|
|
|
|
sendResponse(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
logoutFunc();
|
|
|
|
|
} catch (error) {}
|
2024-07-04 20:14:32 +03:00
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
|
2024-07-04 20:14:32 +03:00
|
|
|
|
break;
|
2024-04-14 14:57:30 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
});
|
2024-04-15 22:30:49 +03:00
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// Function to save window position and size
|
|
|
|
|
const saveWindowBounds = (windowId) => {
|
|
|
|
|
chrome.windows.get(windowId, (window) => {
|
|
|
|
|
const { top, left, width, height } = window;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.storage.local.set(
|
|
|
|
|
{
|
|
|
|
|
windowBounds: { top, left, width, height },
|
|
|
|
|
},
|
|
|
|
|
() => {
|
|
|
|
|
console.log("Window bounds saved:", { top, left, width, height });
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Function to restore window position and size
|
|
|
|
|
const restoreWindowBounds = (callback) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.storage.local.get("windowBounds", (data) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (data.windowBounds) {
|
|
|
|
|
callback(data.windowBounds);
|
|
|
|
|
} else {
|
|
|
|
|
callback(null); // No saved bounds, use default size/position
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2024-09-12 05:01:36 +03:00
|
|
|
|
chrome.action?.onClicked?.addListener((tab) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const popupUrl = chrome.runtime.getURL("index.html?main=true");
|
2024-04-14 14:57:30 +03:00
|
|
|
|
chrome.windows.getAll(
|
|
|
|
|
{ populate: true, windowTypes: ["popup"] },
|
|
|
|
|
(windows) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
console.log("windows", windows);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
// Attempt to find an existing popup window that has a tab with the correct URL
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const existingPopup = windows.find((w) => {
|
|
|
|
|
return (
|
|
|
|
|
w.tabs &&
|
|
|
|
|
w.tabs.some((tab) => tab.url && tab.url.startsWith(popupUrl))
|
|
|
|
|
);
|
|
|
|
|
});
|
2024-04-14 14:57:30 +03:00
|
|
|
|
if (existingPopup) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
console.log("Focusing existing popup window", existingPopup.id);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
// If the popup exists but is minimized or not focused, focus it
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
|
|
|
|
if (isMobile) {
|
|
|
|
|
const correctTab = existingPopup.tabs.find(
|
|
|
|
|
(tab) => tab.url && tab.url.startsWith(popupUrl)
|
|
|
|
|
);
|
|
|
|
|
if (correctTab) {
|
|
|
|
|
chrome.tabs.update(correctTab.id, { active: true });
|
|
|
|
|
chrome.windows.update(existingPopup.id, {
|
|
|
|
|
focused: true,
|
|
|
|
|
state: "normal",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
chrome.windows.update(existingPopup.id, {
|
|
|
|
|
focused: true,
|
|
|
|
|
state: "normal",
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-04-14 14:57:30 +03:00
|
|
|
|
} else {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
console.log("No existing popup, creating new window...");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// No existing popup found, restore the saved bounds or create a new one
|
|
|
|
|
restoreWindowBounds((savedBounds) => {
|
|
|
|
|
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 screenHeight = primaryDisplay.bounds.height;
|
|
|
|
|
|
|
|
|
|
// Create a new window that uses the saved bounds if available
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.windows.create(
|
|
|
|
|
{
|
|
|
|
|
url: chrome.runtime.getURL("index.html?main=true"),
|
|
|
|
|
type: "popup",
|
|
|
|
|
width: savedBounds ? savedBounds.width : screenWidth,
|
|
|
|
|
height: savedBounds ? savedBounds.height : screenHeight,
|
|
|
|
|
left: savedBounds ? savedBounds.left : 0,
|
|
|
|
|
top: savedBounds ? savedBounds.top : 0,
|
|
|
|
|
},
|
|
|
|
|
(newWindow) => {
|
|
|
|
|
// Listen for changes in the window's size or position and save them
|
|
|
|
|
chrome.windows.onBoundsChanged.addListener((window) => {
|
|
|
|
|
if (window.id === newWindow.id) {
|
|
|
|
|
saveWindowBounds(newWindow.id);
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
// Save the final window bounds when the window is closed
|
|
|
|
|
chrome.windows.onRemoved.addListener((windowId) => {
|
|
|
|
|
if (windowId === newWindow.id) {
|
|
|
|
|
saveWindowBounds(windowId); // Save the position/size before it’s closed
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-04-14 14:57:30 +03:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const interactionId = Date.now().toString(); // Simple example; consider a better unique ID
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
chrome.runtime.sendMessage({
|
2024-09-09 20:36:39 +03:00
|
|
|
|
action: "INITIATE_MAIN",
|
|
|
|
|
payload: {},
|
2024-04-14 14:57:30 +03:00
|
|
|
|
});
|
|
|
|
|
}, 500);
|
|
|
|
|
|
|
|
|
|
// Store sendResponse callback with the interaction ID
|
|
|
|
|
pendingResponses.set(interactionId, sendResponse);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const checkGroupList = async () => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
|
|
|
|
const url = await createEndpoint(`/chat/active/${address}`);
|
|
|
|
|
const response = await fetch(url, {
|
|
|
|
|
method: "GET",
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
const data = await response.json();
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
|
|
|
|
const filteredGroups =
|
|
|
|
|
data.groups?.filter((item) => item?.groupId !== 0) || [];
|
|
|
|
|
const sortedGroups = filteredGroups.sort(
|
|
|
|
|
(a, b) => (b.timestamp || 0) - (a.timestamp || 0)
|
|
|
|
|
);
|
|
|
|
|
const sortedDirects = (data?.direct || [])
|
|
|
|
|
.filter(
|
|
|
|
|
(item) =>
|
|
|
|
|
item?.name !== "extension-proxy" &&
|
|
|
|
|
item?.address !== "QSMMGSgysEuqDCuLw3S4cHrQkBrh3vP3VH"
|
|
|
|
|
)
|
|
|
|
|
.sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0));
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
handleActiveGroupDataFromSocket({
|
|
|
|
|
groups: sortedGroups,
|
2024-09-16 12:35:43 +03:00
|
|
|
|
directs: sortedDirects,
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} catch (error) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
console.error(error);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} finally {
|
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
};
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const checkActiveChatsForNotifications = async () => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
try {
|
|
|
|
|
const popupUrl = chrome.runtime.getURL("index.html?main=true");
|
|
|
|
|
|
|
|
|
|
chrome.windows.getAll(
|
|
|
|
|
{ populate: true, windowTypes: ["popup"] },
|
|
|
|
|
(windows) => {
|
|
|
|
|
// Attempt to find an existing popup window that has a tab with the correct URL
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const existingPopup = windows.find((w) => {
|
|
|
|
|
return (
|
|
|
|
|
w.tabs &&
|
|
|
|
|
w.tabs.some((tab) => tab.url && tab.url.startsWith(popupUrl))
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (existingPopup) {
|
|
|
|
|
} else {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
checkGroupList();
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-09-16 12:35:43 +03:00
|
|
|
|
} catch (error) {}
|
|
|
|
|
};
|
|
|
|
|
chrome.notifications?.onClicked?.addListener((notificationId) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
const popupUrl = chrome.runtime.getURL("index.html?main=true");
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const isDirect = notificationId.includes("_type=direct_");
|
|
|
|
|
const isGroup = notificationId.includes("_type=group_");
|
|
|
|
|
const isGroupAnnouncement = notificationId.includes(
|
|
|
|
|
"_type=group-announcement_"
|
|
|
|
|
);
|
|
|
|
|
const isNewThreadPost = notificationId.includes("_type=thread-post_");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
let isExisting = false;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
chrome.windows.getAll(
|
|
|
|
|
{ populate: true, windowTypes: ["popup"] },
|
|
|
|
|
async (windows) => {
|
|
|
|
|
// Attempt to find an existing popup window that has a tab with the correct URL
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const existingPopup = windows.find((w) => {
|
|
|
|
|
return (
|
|
|
|
|
w.tabs &&
|
|
|
|
|
w.tabs.some((tab) => tab.url && tab.url.startsWith(popupUrl))
|
|
|
|
|
);
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
if (existingPopup) {
|
|
|
|
|
// If the popup exists but is minimized or not focused, focus it
|
|
|
|
|
chrome.windows.update(existingPopup.id, {
|
|
|
|
|
focused: true,
|
|
|
|
|
state: "normal",
|
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
isExisting = true;
|
2024-09-09 20:36:39 +03:00
|
|
|
|
} else {
|
|
|
|
|
// No existing popup found, restore saved bounds or create a new one
|
|
|
|
|
restoreWindowBounds((savedBounds) => {
|
|
|
|
|
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 screenHeight = primaryDisplay.bounds.height;
|
|
|
|
|
|
|
|
|
|
// Create a new window that takes up the full screen or uses saved bounds
|
2024-09-16 12:35:43 +03:00
|
|
|
|
chrome.windows.create(
|
|
|
|
|
{
|
|
|
|
|
url: chrome.runtime.getURL("index.html?main=true"),
|
|
|
|
|
type: "popup",
|
|
|
|
|
width: savedBounds ? savedBounds.width : screenWidth,
|
|
|
|
|
height: savedBounds ? savedBounds.height : screenHeight,
|
|
|
|
|
left: savedBounds ? savedBounds.left : 0,
|
|
|
|
|
top: savedBounds ? savedBounds.top : 0,
|
|
|
|
|
},
|
|
|
|
|
(newWindow) => {
|
|
|
|
|
// Listen for changes in the window's size or position and save them
|
|
|
|
|
chrome.windows.onBoundsChanged.addListener((window) => {
|
|
|
|
|
if (window.id === newWindow.id) {
|
|
|
|
|
saveWindowBounds(newWindow.id);
|
|
|
|
|
}
|
|
|
|
|
});
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
2024-09-16 12:35:43 +03:00
|
|
|
|
// Save the final window bounds when the window is closed
|
|
|
|
|
chrome.windows.onRemoved.addListener((windowId) => {
|
|
|
|
|
if (windowId === newWindow.id) {
|
|
|
|
|
saveWindowBounds(windowId); // Save the position/size before it’s closed
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-09-16 12:35:43 +03:00
|
|
|
|
const activeData = (await getStoredData("active-groups-directs")) || {
|
|
|
|
|
groups: [],
|
|
|
|
|
directs: [],
|
|
|
|
|
};
|
|
|
|
|
setTimeout(
|
|
|
|
|
() => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
chrome.runtime.sendMessage({
|
2024-09-16 12:35:43 +03:00
|
|
|
|
action: "SET_GROUPS",
|
|
|
|
|
payload: activeData?.groups || [],
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
|
|
|
|
chrome.runtime.sendMessage({
|
2024-09-16 12:35:43 +03:00
|
|
|
|
action: "SET_DIRECTS",
|
|
|
|
|
payload: activeData?.directs || [],
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
},
|
|
|
|
|
isExisting ? 100 : 1000
|
|
|
|
|
);
|
|
|
|
|
const interactionId = Date.now().toString(); // Simple example; consider a better unique ID
|
|
|
|
|
|
|
|
|
|
setTimeout(
|
|
|
|
|
() => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
chrome.runtime.sendMessage({
|
2024-09-16 12:35:43 +03:00
|
|
|
|
action: "INITIATE_MAIN",
|
|
|
|
|
payload: {},
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|
2024-09-16 12:35:43 +03:00
|
|
|
|
|
|
|
|
|
// Handle different types of notifications
|
|
|
|
|
if (isDirect) {
|
|
|
|
|
const fromValue = notificationId.split("_from=")[1];
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "NOTIFICATION_OPEN_DIRECT",
|
|
|
|
|
payload: { from: fromValue },
|
|
|
|
|
});
|
|
|
|
|
} else if (isGroup) {
|
|
|
|
|
const fromValue = notificationId.split("_from=")[1];
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "NOTIFICATION_OPEN_GROUP",
|
|
|
|
|
payload: { from: fromValue },
|
|
|
|
|
});
|
|
|
|
|
} else if (isGroupAnnouncement) {
|
|
|
|
|
const fromValue = notificationId.split("_from=")[1];
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "NOTIFICATION_OPEN_ANNOUNCEMENT_GROUP",
|
|
|
|
|
payload: { from: fromValue },
|
|
|
|
|
});
|
|
|
|
|
} else if (isNewThreadPost) {
|
|
|
|
|
const dataValue = notificationId.split("_data=")[1];
|
|
|
|
|
const dataParsed = JSON.parse(dataValue);
|
|
|
|
|
|
|
|
|
|
chrome.runtime.sendMessage({
|
|
|
|
|
action: "NOTIFICATION_OPEN_THREAD_NEW_POST",
|
|
|
|
|
payload: { data: dataParsed },
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
isExisting ? 400 : 3000
|
|
|
|
|
);
|
2024-09-09 20:36:39 +03:00
|
|
|
|
|
|
|
|
|
// Store sendResponse callback with the interaction ID
|
|
|
|
|
pendingResponses.set(interactionId, sendResponse);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Reconnect when service worker wakes up
|
2024-09-12 05:01:36 +03:00
|
|
|
|
chrome.runtime?.onStartup.addListener(() => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
console.log("Service worker started up, reconnecting WebSocket...");
|
|
|
|
|
// initWebsocketMessageGroup();
|
|
|
|
|
// listenForNewGroupAnnouncements()
|
|
|
|
|
// listenForThreadUpdates()
|
|
|
|
|
});
|
|
|
|
|
|
2024-09-12 05:01:36 +03:00
|
|
|
|
chrome.runtime?.onInstalled.addListener((details) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (details.reason === chrome.runtime.OnInstalledReason.INSTALL) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
console.log("Extension Installed");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// Perform tasks that should only happen on extension installation
|
|
|
|
|
// Example: Initialize WebSocket, set default settings, etc.
|
|
|
|
|
} else if (details.reason === chrome.runtime.OnInstalledReason.UPDATE) {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
console.log("Extension Updated");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// Handle the update logic here (e.g., migrate settings)
|
2024-09-16 12:35:43 +03:00
|
|
|
|
} else if (
|
|
|
|
|
details.reason === chrome.runtime.OnInstalledReason.CHROME_UPDATE
|
|
|
|
|
) {
|
|
|
|
|
console.log("Chrome updated");
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// Optional: Handle Chrome-specific updates if necessary
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialize WebSocket and other required listeners
|
|
|
|
|
// initWebsocketMessageGroup();
|
|
|
|
|
// listenForNewGroupAnnouncements();
|
|
|
|
|
// listenForThreadUpdates();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Check if the alarm already exists before creating it
|
2024-09-12 05:01:36 +03:00
|
|
|
|
chrome.alarms?.get("checkForNotifications", (existingAlarm) => {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
if (!existingAlarm) {
|
|
|
|
|
// If the alarm does not exist, create it
|
2024-09-12 22:23:47 +03:00
|
|
|
|
chrome.alarms.create("checkForNotifications", { periodInMinutes: 10 });
|
2024-09-09 20:36:39 +03:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2024-09-12 05:01:36 +03:00
|
|
|
|
chrome.alarms?.onAlarm.addListener(async (alarm) => {
|
2024-09-16 12:35:43 +03:00
|
|
|
|
try {
|
|
|
|
|
if (alarm.name === "checkForNotifications") {
|
2024-09-09 20:36:39 +03:00
|
|
|
|
// initWebsocketMessageGroup(address);
|
|
|
|
|
const wallet = await getSaveWallet();
|
|
|
|
|
const address = wallet.address0;
|
2024-09-16 12:35:43 +03:00
|
|
|
|
if (!address) return;
|
|
|
|
|
checkActiveChatsForNotifications();
|
|
|
|
|
checkNewMessages();
|
|
|
|
|
checkThreads();
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {}
|
2024-09-09 20:36:39 +03:00
|
|
|
|
});
|