diff --git a/landing/cobweb.png b/landing/cobweb.png new file mode 100644 index 0000000..51d28ab Binary files /dev/null and b/landing/cobweb.png differ diff --git a/landing/index.css b/landing/index.css index f2e10a9..1425eac 100644 --- a/landing/index.css +++ b/landing/index.css @@ -198,3 +198,18 @@ code { #differences-content-javascript { display: none; } + +.fp-container { + width: max(40%, 300px); + height: 100vh; +} + +.fp-container img { + width: 64px; + height: 64px; + margin-top: -5rem; +} + +.fp-container .card { + max-height: max-content; +} diff --git a/landing/removed.html b/landing/removed.html new file mode 100644 index 0000000..6fed0e2 --- /dev/null +++ b/landing/removed.html @@ -0,0 +1,36 @@ + + + + + Cobweb - A new way for teens to connect + + + + + + + +
+ + Cobweb logo + +
+

Sorry to see you go.

+

We've detected that you've uninstalled or disabled Cobweb.

+

+ Please make sure that you visit + app.superfluid.finance + and log in with the Metamask wallet you use with Cobweb to close out + any streams that are still open. Otherwise, your token balance will + continue to drain. +

+ +
+
+ + diff --git a/src/pages/Background/index.ts b/src/pages/Background/index.ts index 32af095..5c72432 100644 --- a/src/pages/Background/index.ts +++ b/src/pages/Background/index.ts @@ -16,7 +16,7 @@ import { MONTAG_FOUND, USER_SET_WALLET, DELETE_STREAM, - BLOCK_SITE, + BLOCK_TAG, UPDATE_SETTING, EDIT_CURRENT_STREAM, FETCH_BALANCE, @@ -29,13 +29,13 @@ import { APPROVE_FULL, } from "../shared/events"; import TOKEN_MAP, { PROD_TOKEN_MAP } from "../shared/tokens"; -import { Wallet } from "../shared/types"; +import { PayRates, Wallet } from "../shared/types"; import createStream, { updateStream } from "./lib/createStream"; import deleteStreamByTabId from "./lib/deleteStreamByTabId"; import setNewWallet from "./lib/setNewWallet"; import { getRate } from "./lib/getRate"; import setDefaultSettings from "./lib/initializeCobweb"; -import blockSite from "./lib/blockSite"; +import blockTag from "./lib/blockTag"; import updateRateSetting from "./lib/updateRateSetting"; import fetchAndUpdateBalance from "./lib/fetchAndUpdateBalance"; import setNewAddress from "./lib/updateAddress"; @@ -52,6 +52,7 @@ import { isDev } from "./lib/isDev"; chrome.runtime.onInstalled.addListener((details) => { if (details.reason === chrome.runtime.OnInstalledReason.INSTALL) { setDefaultSettings(); + chrome.runtime.setUninstallURL("https://kewbi.sh/cobweb"); } }); @@ -79,7 +80,7 @@ storage.local.set({ toasts: [] }); let { address: addressTry } = (await storage.local.get("address")) as { address: string | null; }; -if (!addressTry) { +if (!addressTry || addressTry === "NO_ADDRESS") { storage.local.set({ address: metamaskProvider.selectedAddress ?? "NO_ADDRESS", }); @@ -156,7 +157,7 @@ const getWalletAndSigner = async (): Promise<{ } } catch (e) { errorToast(e as Error); - throw e; + // throw e; } return { wallet: walletRes, signer: sfSigner }; }; @@ -180,19 +181,21 @@ const montagFound = async ({ } const tabId = sender.tab.id ?? 0; const rate = await getRate(address); - if (rate && rate.rateAmount !== constants.Zero) { - createStream({ - from: walletRes.address, - to: address, - tabId, - url: sender.tab.url ?? "", - rateAmount: rate.rateAmount, - sf, - sfSigner, - sfToken, - infuraProvider: infuraProvider as InfuraProvider, - }); + if (rate.payWhen === PayRates.BLOCKED) { + return; } + createStream({ + from: walletRes.address, + toTag: request.options.address, + to: address, + tabId, + url: sender.tab.url ?? "", + rateAmount: rate.rateAmount, + sf, + sfSigner, + sfToken, + infuraProvider: infuraProvider as InfuraProvider, + }); }; const deleteStream = async ({ request }: { request: any }) => { @@ -214,9 +217,9 @@ const setUserWallet = async ({ request }: { request: any }) => { setNewWallet(request.options.wallet); }; -const setBlockSite = async ({ request }: { request: any }) => { - blockSite({ - site: request.options.site, +const setBlockTag = async ({ request }: { request: any }) => { + blockTag({ + address: request.options.address, }); }; @@ -247,7 +250,10 @@ const editCurrentStream = async ({ request }: { request: any }) => { const fetchBalance = async () => { const { signer: sfSigner } = await getWalletAndSigner(); - if (!sfToken || !mmProvider || !sf || !sfSigner) { + const { cwInitialized } = (await storage.local.get("cwInitialized")) as { + cwInitialized: boolean | null; + }; + if (!sfToken || !mmProvider || !sf || (cwInitialized && !sfSigner)) { return; } fetchAndUpdateBalance({ sfToken, mmProvider, sfSigner, sf }); @@ -343,8 +349,8 @@ const handleMessaging = async ( sendResponse(); return; } - case BLOCK_SITE: { - setBlockSite({ request }); + case BLOCK_TAG: { + setBlockTag({ request }); sendResponse(); return; } @@ -431,34 +437,38 @@ chrome.alarms.create("cobwebAllowanceCheck" + alarmSuffix, { delayInMinutes: 5, }); chrome.alarms.onAlarm.addListener(async (alarm) => { - var parsedName = alarm.name.match(/^([\S\s]*?)(\d+)$/); - let name = ""; - let suffix = 0; - if (parsedName) { - name = parsedName[0]; - suffix = +parsedName[1]; - } - if (suffix !== alarmSuffix) { - return; - } - const { wallet, signer: sfSigner } = await getWalletAndSigner(); - if (!sf || !sfSigner || !sfToken) { - return; - } - if (name === "cobwebStreamCleanup") { - cleanUpStreams({ sfSigner, sfToken, sf }); - } else if (name === "cobwebAllowanceCheck") { - const { address } = await storage.local.get("address"); - if (!wallet || !address) { + try { + var parsedName = alarm.name.match(/^([\S\s]*?)(\d+)$/); + let name = ""; + let suffix = 0; + if (parsedName) { + name = parsedName[0]; + suffix = +parsedName[1]; + } + if (suffix !== alarmSuffix) { return; } - fetchBalance(); - fetchCobwebAllowance({ - sfToken, - sfSigner, - sf, - walletAddress: wallet.address, - mmAddress: address, - }); - } + const { wallet, signer: sfSigner } = await getWalletAndSigner(); + if (!sf || !sfSigner || !sfToken) { + return; + } + if (name === "cobwebStreamCleanup") { + cleanUpStreams({ sfSigner, sfToken, sf }); + } else if (name === "cobwebAllowanceCheck") { + const { address } = await storage.local.get("address"); + if (!wallet || !address) { + return; + } + fetchBalance(); + fetchCobwebAllowance({ + sfToken, + sfSigner, + sf, + walletAddress: wallet.address, + mmAddress: address, + }); + } + } catch {} }); + +chrome.runtime.onConnect.addListener(() => {}); diff --git a/src/pages/Background/lib/blockSite.ts b/src/pages/Background/lib/blockSite.ts deleted file mode 100644 index 05fe35f..0000000 --- a/src/pages/Background/lib/blockSite.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { storage } from "@extend-chrome/storage"; -import { RateSettings, PayRates } from "../../shared/types"; -import { constants } from "ethers"; - -const blockSite = ({ site }: { site: string }) => { - storage.local.set(({ settings }: { settings: RateSettings }) => { - settings[site] = { payWhen: PayRates.BLOCKED, rateAmount: constants.Zero }; - return settings; - }); -}; - -export default blockSite; diff --git a/src/pages/Background/lib/blockTag.ts b/src/pages/Background/lib/blockTag.ts new file mode 100644 index 0000000..4020f05 --- /dev/null +++ b/src/pages/Background/lib/blockTag.ts @@ -0,0 +1,19 @@ +import { storage } from "@extend-chrome/storage"; +import { RateSettings, PayRates } from "../../shared/types"; +import { constants } from "ethers"; + +const blockTag = async ({ address }: { address: string }) => { + storage.local.set(({ settings }: { settings: RateSettings }) => { + if (!settings) { + settings = {}; + } + let newSettings = structuredClone(settings); + newSettings[address] = { + payWhen: PayRates.BLOCKED, + rateAmount: constants.Zero, + }; + return { settings: newSettings }; + }); +}; + +export default blockTag; diff --git a/src/pages/Background/lib/createStream.ts b/src/pages/Background/lib/createStream.ts index 4a2e4db..2f134f8 100644 --- a/src/pages/Background/lib/createStream.ts +++ b/src/pages/Background/lib/createStream.ts @@ -17,6 +17,7 @@ import TOKEN_MAP from "../../shared/tokens"; const createStream = async ({ from, to, + toTag, tabId, url, rateAmount, @@ -27,6 +28,7 @@ const createStream = async ({ }: { from: string; to: string; + toTag: string; tabId: number; url: string; rateAmount: BigNumber; @@ -115,6 +117,7 @@ const createStream = async ({ ...streams, { recipient: to, + recipientTag: toTag, tabId, rateAmount, requestId: uuid, diff --git a/src/pages/Background/lib/fetchAndUpdateBalance.ts b/src/pages/Background/lib/fetchAndUpdateBalance.ts index e73dbc9..464d3e3 100644 --- a/src/pages/Background/lib/fetchAndUpdateBalance.ts +++ b/src/pages/Background/lib/fetchAndUpdateBalance.ts @@ -14,7 +14,7 @@ const fetchAndUpdateBalance = async ({ mmProvider, }: { sf: Framework; - sfSigner: Signer; + sfSigner: Signer | null; sfToken: SuperToken; mmProvider: Web3Provider; }) => { @@ -47,7 +47,7 @@ const fetchAndUpdateBalance = async ({ const balance = await mmProvider.getBalance(address); storage.local.set({ mmBalance: BigNumber.from(balance) }); - if (!cwInitialized) { + if (!cwInitialized || !sfSigner) { return; } diff --git a/src/pages/Background/lib/getRate.ts b/src/pages/Background/lib/getRate.ts index 240806f..32fe958 100644 --- a/src/pages/Background/lib/getRate.ts +++ b/src/pages/Background/lib/getRate.ts @@ -2,7 +2,7 @@ import { Rate, PayRates } from "../../shared/types"; import { storage } from "@extend-chrome/storage"; import { BigNumber } from "ethers"; -export const getRate = async (address: string): Promise => { +export const getRate = async (address: string): Promise => { const { settings } = await storage.local.get("settings"); const { defaultRate } = await storage.local.get("defaultRate"); const fallbackRate = { @@ -10,13 +10,17 @@ export const getRate = async (address: string): Promise => { payWhen: PayRates.ANY, }; - if (!settings || !settings.length) { + if (!settings || !Object.keys(settings).length) { return defaultRate ?? fallbackRate; } const tryAddress = Object.keys(settings).filter((k) => - k.startsWith(`COBWEB:${address}`) + k.toLowerCase().startsWith(`cobweb:${address.toLowerCase()}`) ); - return settings.get(tryAddress) ?? defaultRate ?? fallbackRate; + return ( + (tryAddress.length > 0 ? settings[tryAddress[0]] : null) ?? + defaultRate ?? + fallbackRate + ); }; diff --git a/src/pages/Background/lib/wrapTokens.ts b/src/pages/Background/lib/wrapTokens.ts index 0c36e57..fc98ac8 100644 --- a/src/pages/Background/lib/wrapTokens.ts +++ b/src/pages/Background/lib/wrapTokens.ts @@ -35,7 +35,6 @@ export const upgradeTokens = async ({ const upgradeTokenOperation = (sfToken as WrapperSuperToken).upgrade({ amount: BigNumber.from(upgrading).toString(), }); - console.log(upgradeTokenOperation); await upgradeTokenOperation.exec(sfSigner); toast("Upgraded!"); } catch (e) { diff --git a/src/pages/Content/index.ts b/src/pages/Content/index.ts index ac63d69..4832fab 100644 --- a/src/pages/Content/index.ts +++ b/src/pages/Content/index.ts @@ -24,3 +24,22 @@ if (monetizationTag) { }); } } + +try { + const port = chrome.runtime.connect({ name: "content-script" }); + const onPortDisconnect = () => { + try { + console.log(chrome.runtime.lastError); + setTimeout(() => { + if (!chrome.runtime?.id) { + document.body.insertAdjacentHTML( + "afterend", + "" + ); + document.getElementById("cobweb-removed-link")?.click(); + } + }, 1000); + } catch {} + }; + port.onDisconnect.addListener(onPortDisconnect); +} catch {} diff --git a/src/pages/Popup/Popup.tsx b/src/pages/Popup/Popup.tsx index a9b967b..9b16b3f 100644 --- a/src/pages/Popup/Popup.tsx +++ b/src/pages/Popup/Popup.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from "react"; import { Link, Navigate, useSearchParams } from "react-router-dom"; import { DELETE_STREAM, - BLOCK_SITE, + BLOCK_TAG, UPDATE_SETTING, UPDATE_STREAM, CHECK_METAMASK, @@ -122,6 +122,17 @@ const Popup = () => { }; }, [currentStream]); + useEffect(() => { + const collapse = document.getElementById("collapse"); + let newCollapse: bootstrap.Collapse | null = null; + if (collapse && currentStream) { + newCollapse = new bootstrap.Collapse(collapse); + } + return () => { + newCollapse?.dispose(); + }; + }, [currentStream]); + const editStream = async ({ oldKey, newKey, @@ -175,13 +186,13 @@ const Popup = () => { const blockStream = async (stream: Stream) => { try { await cancelStream(stream); - const hostname = new URL(url).hostname; chrome.runtime.sendMessage({ - message: BLOCK_SITE, + message: BLOCK_TAG, options: { - site: hostname, + address: stream.recipientTag, }, }); + setCurrentStream(null); } catch { toast("Couldn't block site"); } @@ -269,6 +280,45 @@ const Popup = () => { Block this page + +
+
+ {rate.rateAmount === constants.Zero ? ( + + ) : null} + + + + + + + + + +
+
) : ( <> @@ -350,9 +400,8 @@ const Popup = () => {