diff --git a/packages/icons/brands/TwitterX.dark.svg b/packages/icons/brands/TwitterX.dark.svg deleted file mode 100644 index da775cd209ef..000000000000 --- a/packages/icons/brands/TwitterX.dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/packages/icons/brands/TwitterX.light.svg b/packages/icons/brands/TwitterX.light.svg deleted file mode 100644 index 880fe0f4a28c..000000000000 --- a/packages/icons/brands/TwitterX.light.svg +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/packages/icons/brands/TwitterX.svg b/packages/icons/brands/TwitterX.svg new file mode 100644 index 000000000000..39c0f7392f17 --- /dev/null +++ b/packages/icons/brands/TwitterX.svg @@ -0,0 +1,3 @@ + diff --git a/packages/icons/icon-generated-as-jsx.js b/packages/icons/icon-generated-as-jsx.js index 5ae81dd3bad5..1cd23e7ba8c3 100644 --- a/packages/icons/icon-generated-as-jsx.js +++ b/packages/icons/icon-generated-as-jsx.js @@ -605,12 +605,17 @@ export const TwitterRoundGray = /*#__PURE__*/ __createIcon('TwitterRoundGray', [ ]) export const TwitterX = /*#__PURE__*/ __createIcon('TwitterX', [ { - c: ['dark'], - u: () => new URL('./brands/TwitterX.dark.svg', import.meta.url).href, - }, - { - c: ['light'], - u: () => new URL('./brands/TwitterX.light.svg', import.meta.url).href, + j: () => + /*#__PURE__*/ _jsx('svg', { + xmlns: 'http://www.w3.org/2000/svg', + fill: 'none', + viewBox: '0 0 24 24', + children: /*#__PURE__*/ _jsx('path', { + fill: 'currentColor', + d: 'M13.882 10.46 21.313 2h-1.76l-6.456 7.344L7.944 2H2l7.793 11.107L2 21.977h1.76l6.814-7.757 5.443 7.757h5.944L13.88 10.46Zm-2.413 2.744-.79-1.107L4.395 3.3H7.1l5.071 7.103.788 1.106 6.592 9.232h-2.705l-5.378-7.537Z', + }), + }), + s: true, }, ]) export const TwitterXRound = /*#__PURE__*/ __createIcon('TwitterXRound', [ diff --git a/packages/icons/icon-generated-as-url.js b/packages/icons/icon-generated-as-url.js index 1abc6a3f97bc..866443afe0e2 100644 --- a/packages/icons/icon-generated-as-url.js +++ b/packages/icons/icon-generated-as-url.js @@ -108,8 +108,7 @@ export function twitter_colored_url() { return new URL("./brands/TwitterColored. export function twitter_other_colored_url() { return new URL("./brands/TwitterOtherColored.svg", import.meta.url).href } export function twitter_round_url() { return new URL("./brands/TwitterRound.svg", import.meta.url).href } export function twitter_round_gray_url() { return new URL("./brands/TwitterRoundGray.svg", import.meta.url).href } -export function twitter_x_dark_url() { return new URL("./brands/TwitterX.dark.svg", import.meta.url).href } -export function twitter_x_light_url() { return new URL("./brands/TwitterX.light.svg", import.meta.url).href } +export function twitter_x_url() { return new URL("./brands/TwitterX.svg", import.meta.url).href } export function twitter_x_round_dark_url() { return new URL("./brands/TwitterXRound.dark.svg", import.meta.url).href } export function twitter_x_round_light_url() { return new URL("./brands/TwitterXRound.light.svg", import.meta.url).href } export function uniswap_url() { return new URL("./brands/Uniswap.svg", import.meta.url).href } diff --git a/packages/mask/background/services/helper/oauth-x.ts b/packages/mask/background/services/helper/oauth-x.ts index 59ee9f847b53..d970606ed00d 100644 --- a/packages/mask/background/services/helper/oauth-x.ts +++ b/packages/mask/background/services/helper/oauth-x.ts @@ -1,5 +1,6 @@ import { timeout } from '@masknet/kit' import { requestExtensionPermissionFromContentScript } from './request-permission.js' +import { XOAuthRequestOrigins } from '../../../shared/definitions/extension.js' /** Modified from https://github.com/ddo/oauth-1.0a/blob/master/oauth-1.0a.js */ class OAuth { @@ -184,15 +185,7 @@ const client = new OAuth(process.env.FIREFLY_X_CLIENT_ID, process.env.FIREFLY_X_ let pendingOAuth: PromiseWithResolvers<{ oauth_verifier: string; oauth_token: string }> | undefined export async function requestXOAuthToken() { await requestExtensionPermissionFromContentScript({ - origins: [ - // In order to send API request without CORS limit - 'https://api.twitter.com/*', - // In order to run content script on it - 'https://firefly.social/api/mask/delegate-x-token', - 'https://firefly.social/api/auth/callback/twitter', - 'https://canary.firefly.social/api/mask/delegate-x-token', - 'https://canary.firefly.social/api/auth/callback/twitter', - ], + origins: XOAuthRequestOrigins, }) await Promise.all([ fetch('https://firefly.social/api/mask/delegate-x-token'), diff --git a/packages/mask/dashboard/pages/CreateMaskWallet/FireflyWallet/index.tsx b/packages/mask/dashboard/pages/CreateMaskWallet/FireflyWallet/index.tsx new file mode 100644 index 000000000000..8417ee78b084 --- /dev/null +++ b/packages/mask/dashboard/pages/CreateMaskWallet/FireflyWallet/index.tsx @@ -0,0 +1,221 @@ +import Services from '#services' +import { Trans } from '@lingui/react/macro' +import { Icons } from '@masknet/icons' +import { PopupRoutes } from '@masknet/shared-base' +import { makeStyles } from '@masknet/theme' +import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from '@mui/material' +import { memo, useState } from 'react' +import { useAsyncFn, useAsyncRetry } from 'react-use' +import { PrimaryButton } from '../../../components/PrimaryButton/index.js' +import { SetupFrameController } from '../../../components/SetupFrame/index.js' +import { XOAuthRequestOrigins } from '../../../../shared/definitions/extension.js' + +const useStyles = makeStyles()((theme) => ({ + container: { + width: '100%', + display: 'flex', + justifyContent: 'center', + flexDirection: 'column', + flex: 1, + }, + title: { + fontSize: 30, + margin: '12px 0', + lineHeight: '120%', + color: theme.palette.maskColor.main, + }, + tips: { + fontSize: 14, + lineHeight: '18px', + color: theme.palette.maskColor.second, + }, + bold: { + fontWeight: 700, + }, + notes: { + display: 'flex', + padding: theme.spacing(3, 2), + alignItems: 'center', + alignContent: 'stretch', + borderRadius: 12, + marginTop: theme.spacing(3), + background: + theme.palette.mode === 'dark' ? + 'linear-gradient(180deg, rgba(255, 255, 255, 0.10) 0%, rgba(255, 255, 255, 0.00) 100%)' + : 'linear-gradient(180deg, rgba(255, 255, 255, 0.00) 0%, #FFF 100%), linear-gradient(90deg, rgba(98, 126, 234, 0.20) 0%, rgba(59, 153, 252, 0.20) 100%)', + }, + fireflyLogo: { + width: 120, + height: 120, + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + }, + list: { + listStyle: 'none', + color: theme.palette.maskColor.main, + fontSize: '13px', + lineHeight: '18px', + fontWeight: 400, + paddingLeft: 16, + margin: 0, + '& li': { + marginBottom: 12, + listStyle: 'disc', + }, + }, + dialog: { + width: 600, + boxSizing: 'border-box', + padding: 24, + borderRadius: 12, + display: 'flex', + flexDirection: 'column', + gap: 24, + }, + dialogTitle: { + color: theme.palette.maskColor.main, + fontSize: 18, + fontWeight: 700, + lineHeight: '22px', + padding: 0, + }, + dialogContent: { + display: 'flex', + flexDirection: 'column', + gap: 12, + padding: 0, + }, + permissions: { + backgroundColor: theme.palette.maskColor.bg, + padding: 12, + borderRadius: 8, + height: 212, + boxSizing: 'border-box', + minHeight: 0, + flexGrow: 1, + overflow: 'auto', + }, + dialogActions: { + display: 'flex', + justifyContent: 'center', + gap: 12, + padding: 0, + }, + actionButton: { + minWidth: 110, + '&&': { + marginLeft: 0, + }, + }, +})) + +export const Component = memo(function CreateWalletForm() { + const { classes, cx } = useStyles() + const [open, setOpen] = useState(false) + + const { retry, value: hasPermission } = useAsyncRetry(() => { + const hasPermission = browser.permissions.contains({ + origins: XOAuthRequestOrigins, + }) + setOpen(!hasPermission) + return hasPermission + }, []) + + const [{ loading }, request] = useAsyncFn(async () => { + if (!hasPermission) { + setOpen(true) + return + } + try { + const data = await Services.Helper.loginFireflyViaTwitter() + if (!data) return + await Services.Helper.openPopupWindow(PopupRoutes.CreateWallet, { + creatingFireflyWallet: true, + }) + } catch (err) { + console.error('Failed to login firefly', err) + } + }, [hasPermission]) + + return ( +