Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env/dev-preference.example
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,4 @@

; FIREFLY_X_CLIENT_ID=
; FIREFLY_X_CLIENT_SECRET=
; PRIVY_APP_ID=
1 change: 1 addition & 0 deletions .pnpmfile.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ approvedList.set('string-width-cjs', 'npm:string-width@^4.2.0')
approvedList.set('strip-ansi-cjs', 'npm:strip-ansi@^6.0.1')
approvedList.set('wrap-ansi-cjs', ['npm:wrap-ansi@^6.0.1', 'npm:wrap-ansi@^7.0.0'])

approvedList.set('cbw-sdk', ['npm:@coinbase/[email protected]'])
/**
* @param {string} parentPackage The current resolving parentPackage
* @param {string} dependedPackage The package it depends on
Expand Down
5 changes: 4 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"packages/xcode",
"pnpm-lock.yaml",
"pnpm-workspace.yaml",
"qya-aa.json"
"qya-aa.json",
".env/dev-preference.example"
],
"TODO: fix those words": ["bridgable", "clonable", "sniffings"],
"ignoreWords": [
Expand Down Expand Up @@ -246,6 +247,7 @@
"words": [
"arbitrum",
"boba",
"caip",
"cashtags",
"celo",
"endregion",
Expand All @@ -259,6 +261,7 @@
"tiktok",
"tweetnacl",
"txid",
"wagmi",
"waitlist",
"youtube"
]
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"spellcheck": "cspell lint --no-must-find-files",
"clean": "gulp clean",
"lingui:compile": "gulp lingui-compile",
"lingui:extract": "gulp lingui-extract"
"lingui:extract": "gulp lingui-extract",
"lingui": "pnpm run lingui:extract && pnpm run lingui:compile"
},
"dependencies": {
"@dimensiondev/holoflows-kit": "0.9.0-20240322092738-f9180f3",
Expand All @@ -45,6 +46,7 @@
"@mui/lab": "5.0.0-alpha.170",
"@mui/material": "5.15.20",
"@mui/system": "5.15.20",
"@privy-io/react-auth": "^3.0.1",
"@tanstack/react-query": "^5.49.2",
"@types/masknet__global-types": "workspace:^",
"@types/react": "npm:types-react@beta",
Expand All @@ -55,7 +57,8 @@
"react": "0.0.0-experimental-58af67a8f8-20240628",
"react-dom": "0.0.0-experimental-58af67a8f8-20240628",
"ses": "1.12.0",
"ts-results-es": "^4.2.0"
"ts-results-es": "^4.2.0",
"wagmi": "^2.17.1"
},
"devDependencies": {
"@changesets/cli": "^2.28.1",
Expand Down
1 change: 1 addition & 0 deletions packages/mask/.webpack/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ export async function createConfiguration(
LOAD_KEY: process.env.LOAD_KEY || '',
FIREFLY_X_CLIENT_ID: process.env.FIREFLY_X_CLIENT_ID || '',
FIREFLY_X_CLIENT_SECRET: process.env.FIREFLY_X_CLIENT_SECRET || '',
PRIVY_APP_ID: process.env.PRIVY_APP_ID || '',
}),
new (rspack?.DefinePlugin || webpack.default.DefinePlugin)({
'process.browser': 'true',
Expand Down
2 changes: 1 addition & 1 deletion packages/mask/.webpack/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export function normalizeBuildFlags(flags: BuildFlags): NormalizedFlags {
devtoolsEditorURI,
// CI / profiling
profiling,
// Secrets
// Secrets
FIREFLY_X_CLIENT_ID,
FIREFLY_X_CLIENT_SECRET,
}
Expand Down
34 changes: 34 additions & 0 deletions packages/mask/background/services/helper/firefly.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { PersistentStorages } from '@masknet/shared-base'

export async function loginFireflyViaTwitter() {
const data = await browser.storage.local.get('firefly_x_oauth')
if (!data?.firefly_x_oauth) throw new Error('X OAuth token not found')
const oauth: Record<string, string> = data.firefly_x_oauth

const res = await fetch('https://firefly.social/api/twitter/auth', {
method: 'POST',
headers: {
'X-Access-Token': oauth.oauth_token,
'X-Access-Token-Secret': oauth.oauth_token_secret,
'X-Client-Id': oauth.oauth_token.split('-')[0],
'X-Consumer-Key': process.env.FIREFLY_X_CLIENT_ID,
'X-Consumer-Secret': '[HIDE_FROM_CLIENT]',
},
})
const json = await res.json()
if (!json.success) throw new Error(json.message)

const res2 = await fetch('https://api.firefly.land/v3/auth/exchange/twitter', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: json.data,
}),
})
const json2 = await res2.json()
await browser.storage.local.set({ firefly_account: json2.data })
await PersistentStorages.Settings.storage.firefly_account.setValue(json2.data)
return json2.data
}
1 change: 1 addition & 0 deletions packages/mask/background/services/helper/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export { getTelemetryID, setTelemetryID } from './telemetry-id.js'
export { fetchSandboxedPluginManifest } from './sandboxed.js'
export { getActiveTab } from './tabs.js'
export { requestXOAuthToken, resolveXOAuth, resetXOAuth } from './oauth-x.js'
export { loginFireflyViaTwitter } from './firefly.js'
2 changes: 1 addition & 1 deletion packages/mask/background/services/helper/oauth-x.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ export async function requestXOAuthToken() {
const user_id = step2.get('user_id')
const screen_name = step2.get('screen_name')

browser.storage.local.set({
await browser.storage.local.set({
firefly_x_oauth: {
oauth_token,
oauth_token_secret,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useEffect } from 'react'
import { useCustomSnackbar } from '@masknet/theme'
import { Button, Box, Typography } from '@mui/material'
import { Trans } from '@lingui/react/macro'
import { createInjectHooksRenderer, useActivatedPluginsSiteAdaptor } from '@masknet/plugin-infra/content-script'
import { MaskMessages } from '@masknet/shared-base'
import { useMatchXS } from '@masknet/shared-base-ui'
import { useCustomSnackbar } from '@masknet/theme'
import { Box, Button, Typography } from '@mui/material'
import { useEffect } from 'react'
import { useAutoPasteFailedDialog } from './AutoPasteFailedDialog.js'
import { Trans } from '@lingui/react/macro'

const GlobalInjection = createInjectHooksRenderer(
useActivatedPluginsSiteAdaptor.visibility.useAnyMode,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { useCallback, useLayoutEffect, useState } from 'react'
import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit'
import { makeStyles } from '@masknet/theme'
import { Trans } from '@lingui/react/macro'
import { MaskMessages } from '@masknet/shared-base'
import { useLocationChange } from '@masknet/shared-base-ui'
import { makeStyles } from '@masknet/theme'
import { useCallback, useLayoutEffect, useState } from 'react'
import { attachReactTreeWithContainer } from '../../../../utils/shadow-root.js'
import { startWatch } from '../../../../utils/startWatch.js'
import { searchInstagramAvatarEditPageSettingDialog, searchInstagramAvatarListSelector } from '../../utils/selector.js'
import { attachReactTreeWithContainer } from '../../../../utils/shadow-root.js'
import { NFTAvatarSettingDialog } from './NFTAvatarSettingDialog.js'
import { Trans } from '@lingui/react/macro'

export async function injectProfileNFTAvatarInInstagram(signal: AbortSignal) {
const watcher = new MutationObserverWatcher(searchInstagramAvatarListSelector())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit'
import { PrivySetup } from '@masknet/shared'
import { ValueRef } from '@masknet/shared-base'
import { useValueRef } from '@masknet/shared-base-ui'
import { RootWeb3ContextProvider } from '@masknet/web3-hooks-base'
import { MutationObserverWatcher } from '@dimensiondev/holoflows-kit'
import { startWatch } from '../../../utils/startWatch.js'
import { attachReactTreeWithContainer } from '../../../utils/shadow-root/renderInShadowRoot.js'
import { startWatch } from '../../../utils/startWatch.js'
import { querySelector, sideBarProfileSelector } from '../utils/selector.js'
import { ProfileLinkAtTwitter, ToolboxHintAtTwitter } from './ToolboxHint_UI.js'

Expand All @@ -28,6 +29,7 @@ export function injectToolboxHintAtTwitter(signal: AbortSignal, category: 'walle
})
attachReactTreeWithContainer(watcher.firstDOMProxy.afterShadow, { signal }).render(
<RootWeb3ContextProvider>
<PrivySetup />
<ToolboxHintAtTwitter category={category} />
</RootWeb3ContextProvider>,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { cloneElement, Suspense } from 'react'
import { QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { RootWeb3ContextProvider } from '@masknet/web3-hooks-base'
import { DialogStackingProvider, MaskThemeProvider } from '@masknet/theme'
import { i18n } from '@lingui/core'
import { useSiteThemeMode } from '@masknet/plugin-infra/content-script'
import { LinguiProviderHMR, SharedContextProvider } from '@masknet/shared'
import { jsxCompose } from '@masknet/shared-base'
import { queryClient } from '@masknet/shared-base-ui'
import { createPortal } from 'react-dom'
import { i18n } from '@lingui/core'
import { DialogStackingProvider, MaskThemeProvider } from '@masknet/theme'
import { RootWeb3ContextProvider } from '@masknet/web3-hooks-base'
import { QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'
import { cloneElement, Suspense } from 'react'
import { createPortal } from 'react-dom'
import { queryPersistOptions } from '../../../shared-ui/utils/persistOptions.js'
import { LinguiProviderHMR, SharedContextProvider } from '@masknet/shared'
import { useSiteThemeMode } from '@masknet/plugin-infra/content-script'
import { useMaskSiteAdaptorMixedTheme } from '../../components/useMaskSiteAdaptorMixedTheme.js'

export function ContentScriptGlobalProvider(children: React.ReactNode) {
Expand Down
3 changes: 2 additions & 1 deletion packages/mask/dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import { LinguiProviderHMR, PersonaContext, SharedContextProvider, Modals } from '@masknet/shared'
import { ErrorBoundary } from '@masknet/shared-base-ui'
import { RootWeb3ContextProvider } from '@masknet/web3-hooks-base'
import { DashboardRoutes, jsxCompose } from '@masknet/shared-base'
import { DashboardRoutes, jsxCompose, PrivySetupProvider } from '@masknet/shared-base'

import { Pages } from './pages/routes.js'
import { UserContext, useAppearance } from '../shared-ui/index.js'
Expand Down Expand Up @@ -53,6 +53,7 @@ export default function Dashboard() {
// #endregion

return jsxCompose(
<PrivySetupProvider />,
<RootWeb3ContextProvider enforceEVM />,
<LinguiProviderHMR i18n={i18n} />,
<StyledEngineProvider injectFirst />,
Expand Down
8 changes: 6 additions & 2 deletions packages/mask/popups/Popup.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PageUIProvider, PersonaContext } from '@masknet/shared'
import { jsxCompose, MaskMessages, PopupRoutes } from '@masknet/shared-base'
import { PageUIProvider, PersonaContext, PrivySetup } from '@masknet/shared'
import { assert, jsxCompose, MaskMessages, PopupRoutes, PrivySetupProvider } from '@masknet/shared-base'
import { PopupSnackbarProvider } from '@masknet/theme'
import { EVMWeb3ContextProvider } from '@masknet/web3-hooks-base'
import { ProviderType } from '@masknet/web3-shared-evm'
Expand Down Expand Up @@ -108,7 +108,10 @@ export default function Popups() {
throttle: 10000,
})

assert(process.env.PRIVY_APP_ID, 'Missing PRIVY_APP_ID')

return jsxCompose(
<PrivySetupProvider />,
<PersistQueryClientProvider client={queryClient} persistOptions={queryPersistOptions} />,
// eslint-disable-next-line react-compiler/react-compiler
<PageUIProvider useTheme={usePopupTheme} />,
Expand All @@ -123,6 +126,7 @@ export default function Popups() {
{process.env.NODE_ENV === 'development' ?
<ReactQueryDevtools buttonPosition="bottom-right" />
: null}
<PrivySetup />
<RouterProvider router={router} fallbackElement={pending} future={{ v7_startTransition: true }} />
</>,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { makeStyles } from '@masknet/theme'
import type { InteractionItemProps } from './interaction.js'
import { Alert, IconButton, Link, Typography } from '@mui/material'
import { useChainId, useNetwork, useWeb3State } from '@masknet/web3-hooks-base'
import { useChainId, useNetwork, usePrivyWallet, useWallet, useWeb3State } from '@masknet/web3-hooks-base'
import { NetworkPluginID } from '@masknet/shared-base'
import { useTitle } from 'react-use'
import { NetworkIcon } from '@masknet/shared'
Expand All @@ -28,6 +28,8 @@ const useStyle = makeStyles()({
})
export function SwitchChainRequest(props: InteractionItemProps) {
const { t } = useLingui()
const wallet = useWallet()
const privyWallet = usePrivyWallet(wallet?.address)
const { setConfirmAction } = props
const { classes } = useStyle()
const origin = props.currentRequest.origin
Expand All @@ -45,6 +47,11 @@ export function SwitchChainRequest(props: InteractionItemProps) {
if (!origin) return null
setConfirmAction(async () => {
if (!nextNetwork) return
if (privyWallet) {
await Network!.switchNetwork(nextNetwork.ID)
await privyWallet.switchChain(nextNetwork.chainId)
return
}
await Network!.switchNetwork(nextNetwork.ID)
await EVMWeb3.switchChain(nextNetwork.chainId, {
providerType: ProviderType.MaskWallet,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
import { compact, mapValues, omit } from 'lodash-es'
import { BigNumber } from 'bignumber.js'
import defer * as web3_utils from 'web3-utils'
import { type TransactionDetail } from '../type.js'
import { UnlockERC20Token } from '../../../components/UnlockERC20Token/index.js'
import { UnlockERC721Token } from '../../../components/UnlockERC721Token/index.js'
import { TransactionPreview } from '../../../components/TransactionPreview/index.js'
import { useCallback, useEffect, useState } from 'react'
import { Trans } from '@lingui/react/macro'
import { Icons } from '@masknet/icons'
import { NetworkPluginID } from '@masknet/shared-base'
import { makeStyles } from '@masknet/theme'
import { useChainContext, usePrivyWallet, useWallet, useWeb3State } from '@masknet/web3-hooks-base'
import { GasOptionType, MessageStateType, TransactionDescriptorType } from '@masknet/web3-shared-base'
import {
abiCoder,
ChainId,
createJsonRpcPayload,
createJsonRpcResponse,
ErrorEditor,
formatEthereumAddress,
PayloadEditor,
abiCoder,
type GasConfig,
ChainId,
ErrorEditor,
} from '@masknet/web3-shared-evm'
import { produce } from 'immer'
import { GasOptionType, TransactionDescriptorType } from '@masknet/web3-shared-base'
import { useChainContext, useWeb3State } from '@masknet/web3-hooks-base'
import { Box, Button, Typography } from '@mui/material'
import { useQueryClient, useSuspenseQuery } from '@tanstack/react-query'
import { BigNumber } from 'bignumber.js'
import { produce } from 'immer'
import { compact, mapValues, omit } from 'lodash-es'
import { useCallback, useEffect, useState } from 'react'
import { useLatest } from 'react-use'
import { NetworkPluginID } from '@masknet/shared-base'
import { Box, Button, Typography } from '@mui/material'
import { Icons } from '@masknet/icons'
import { makeStyles } from '@masknet/theme'
import defer * as web3_utils from 'web3-utils'
import { TransactionPreview } from '../../../components/TransactionPreview/index.js'
import { UnlockERC20Token } from '../../../components/UnlockERC20Token/index.js'
import { UnlockERC721Token } from '../../../components/UnlockERC721Token/index.js'
import { type TransactionDetail } from '../type.js'
import type { InteractionItemProps } from './interaction.js'
import { Trans } from '@lingui/react/macro'

const useStyles = makeStyles()((theme) => ({
text: {
Expand Down Expand Up @@ -79,7 +80,10 @@ const approveParametersType = [
},
]

let mockingPrivyPid = Date.now() // Use unix timestamp as pid to avoid duplicate mocking
export function TransactionRequest(props: InteractionItemProps) {
const wallet = useWallet()
const privyWallet = usePrivyWallet(wallet?.address)
const { currentRequest: request, setConfirmAction, paymentToken, setPaymentToken } = props
const { classes, cx } = useStyles()
const [gasConfig, _setGasConfig] = useState<GasConfig | undefined>()
Expand Down Expand Up @@ -123,6 +127,17 @@ export function TransactionRequest(props: InteractionItemProps) {
}

setConfirmAction(async () => {
if (privyWallet) {
const provider = await privyWallet.getEthereumProvider()
const result: string = await provider.request(request.request.arguments)
mockingPrivyPid += 1
await Message?.updateMessage(request.ID, {
request: request.request,
response: createJsonRpcResponse(mockingPrivyPid, result),
state: MessageStateType.APPROVED,
})
return
}
let params = structuredClone(request.request.arguments.params)
if (approvedAmount) {
if (!transaction.formattedTransaction?._tx.data) return
Expand Down Expand Up @@ -174,7 +189,7 @@ export function TransactionRequest(props: InteractionItemProps) {
}),
)

const response = await Message!.approveAndSendRequest(request.ID, {
const response = await Message?.approveAndSendRequest(request.ID, {
arguments: {
...request.request.arguments,
params,
Expand Down
Loading