diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dafd21170..d1649eb07 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,6 +10,9 @@ on: merge_group: types: [checks_requested] +env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + jobs: lint: runs-on: ubuntu-latest diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..e1d14e38b --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +//registry.npmjs.org/:_authToken=${NPM_TOKEN} +auto-install-peers=true + diff --git a/.yarnrc.yml b/.yarnrc.yml index 5413a22d8..f2e97e603 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -2,6 +2,11 @@ nmHoistingLimits: workspaces nodeLinker: node-modules +npmScopes: + magiclabs: + npmRegistryServer: "https://registry.npmjs.org" + npmAuthToken: "${NPM_TOKEN}" + plugins: - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs spec: "@yarnpkg/plugin-workspace-tools" diff --git a/packages/@magic-ext/algorand/package.json b/packages/@magic-ext/algorand/package.json index 4a291c1d6..4de039ca3 100644 --- a/packages/@magic-ext/algorand/package.json +++ b/packages/@magic-ext/algorand/package.json @@ -28,6 +28,6 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^31.2.0" + "@magic-sdk/provider": "^33.1.0" } } diff --git a/packages/@magic-ext/aptos/package.json b/packages/@magic-ext/aptos/package.json index 5d29225d3..360c9d9d9 100644 --- a/packages/@magic-ext/aptos/package.json +++ b/packages/@magic-ext/aptos/package.json @@ -28,7 +28,7 @@ }, "devDependencies": { "@aptos-labs/wallet-adapter-core": "^7.10.1", - "@magic-sdk/provider": "^31.2.0", + "@magic-sdk/provider": "^33.1.0", "aptos": "^1.22.1" }, "peerDependencies": { diff --git a/packages/@magic-ext/avalanche/package.json b/packages/@magic-ext/avalanche/package.json index 6f4ffa046..68f3a5a4c 100644 --- a/packages/@magic-ext/avalanche/package.json +++ b/packages/@magic-ext/avalanche/package.json @@ -28,6 +28,6 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^31.2.0" + "@magic-sdk/provider": "^33.1.0" } } diff --git a/packages/@magic-ext/bitcoin/package.json b/packages/@magic-ext/bitcoin/package.json index a106391d8..8022af371 100644 --- a/packages/@magic-ext/bitcoin/package.json +++ b/packages/@magic-ext/bitcoin/package.json @@ -28,6 +28,6 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^31.2.0" + "@magic-sdk/provider": "^33.1.0" } } diff --git a/packages/@magic-ext/conflux/package.json b/packages/@magic-ext/conflux/package.json index 575ec402e..5e4ee388b 100644 --- a/packages/@magic-ext/conflux/package.json +++ b/packages/@magic-ext/conflux/package.json @@ -28,6 +28,6 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^31.2.0" + "@magic-sdk/provider": "^33.1.0" } } diff --git a/packages/@magic-ext/cosmos/package.json b/packages/@magic-ext/cosmos/package.json index d8ce965fe..4033ea0cf 100644 --- a/packages/@magic-ext/cosmos/package.json +++ b/packages/@magic-ext/cosmos/package.json @@ -28,6 +28,6 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^31.2.0" + "@magic-sdk/provider": "^33.1.0" } } diff --git a/packages/@magic-ext/ed25519/package.json b/packages/@magic-ext/ed25519/package.json index ad4aafb49..34ea14b6c 100644 --- a/packages/@magic-ext/ed25519/package.json +++ b/packages/@magic-ext/ed25519/package.json @@ -28,6 +28,6 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^31.2.0" + "@magic-sdk/provider": "^33.1.0" } } diff --git a/packages/@magic-ext/evm/package.json b/packages/@magic-ext/evm/package.json index b00713a42..f5fab2bdb 100644 --- a/packages/@magic-ext/evm/package.json +++ b/packages/@magic-ext/evm/package.json @@ -29,7 +29,7 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^29.5.0", - "@magic-sdk/types": "^24.22.0" + "@magic-sdk/provider": "^33.1.0", + "@magic-sdk/types": "^27.1.0" } } diff --git a/packages/@magic-ext/farcaster/package.json b/packages/@magic-ext/farcaster/package.json index 68e99fd5c..148002459 100644 --- a/packages/@magic-ext/farcaster/package.json +++ b/packages/@magic-ext/farcaster/package.json @@ -29,7 +29,7 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^31.2.0", - "@magic-sdk/types": "^25.2.0" + "@magic-sdk/provider": "^33.1.0", + "@magic-sdk/types": "^27.1.0" } } diff --git a/packages/@magic-ext/flow/package.json b/packages/@magic-ext/flow/package.json index 73d930e1f..a1fcb9b40 100644 --- a/packages/@magic-ext/flow/package.json +++ b/packages/@magic-ext/flow/package.json @@ -28,7 +28,7 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^31.2.0", + "@magic-sdk/provider": "^33.1.0", "@onflow/fcl": "^1.4.1", "@onflow/types": "^1.1.0" }, diff --git a/packages/@magic-ext/gdkms/package.json b/packages/@magic-ext/gdkms/package.json index 87e8da0cb..e6ff28765 100644 --- a/packages/@magic-ext/gdkms/package.json +++ b/packages/@magic-ext/gdkms/package.json @@ -29,7 +29,7 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^31.2.0", - "@magic-sdk/types": "^25.2.0" + "@magic-sdk/provider": "^33.1.0", + "@magic-sdk/types": "^27.1.0" } } diff --git a/packages/@magic-ext/harmony/package.json b/packages/@magic-ext/harmony/package.json index 2d3ed9e0e..9196251a3 100644 --- a/packages/@magic-ext/harmony/package.json +++ b/packages/@magic-ext/harmony/package.json @@ -28,6 +28,6 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^31.2.0" + "@magic-sdk/provider": "^33.1.0" } } diff --git a/packages/@magic-ext/hedera/package.json b/packages/@magic-ext/hedera/package.json index 57df7cf8d..b0370fe3e 100644 --- a/packages/@magic-ext/hedera/package.json +++ b/packages/@magic-ext/hedera/package.json @@ -28,7 +28,7 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^29.5.0" + "@magic-sdk/provider": "^33.1.0" }, "peerDependencies": { "@hashgraph/sdk": "^2.31.0" diff --git a/packages/@magic-ext/icon/package.json b/packages/@magic-ext/icon/package.json index f38e379eb..874159d3b 100644 --- a/packages/@magic-ext/icon/package.json +++ b/packages/@magic-ext/icon/package.json @@ -28,6 +28,6 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^31.2.0" + "@magic-sdk/provider": "^33.1.0" } } diff --git a/packages/@magic-ext/kadena/package.json b/packages/@magic-ext/kadena/package.json index 42518ff96..72d8983fb 100644 --- a/packages/@magic-ext/kadena/package.json +++ b/packages/@magic-ext/kadena/package.json @@ -28,6 +28,6 @@ ] }, "devDependencies": { - "@magic-sdk/provider": "^31.2.0" + "@magic-sdk/provider": "^33.1.0" } } diff --git a/packages/@magic-ext/web3modal-ethers5/.lintstagedrc.yml b/packages/@magic-ext/magic-widget/.lintstagedrc.yml similarity index 100% rename from packages/@magic-ext/web3modal-ethers5/.lintstagedrc.yml rename to packages/@magic-ext/magic-widget/.lintstagedrc.yml diff --git a/packages/@magic-ext/web3modal-ethers5/.prettierrc.js b/packages/@magic-ext/magic-widget/.prettierrc.js similarity index 100% rename from packages/@magic-ext/web3modal-ethers5/.prettierrc.js rename to packages/@magic-ext/magic-widget/.prettierrc.js diff --git a/packages/@magic-ext/web3modal-ethers5/LICENSE b/packages/@magic-ext/magic-widget/LICENSE similarity index 100% rename from packages/@magic-ext/web3modal-ethers5/LICENSE rename to packages/@magic-ext/magic-widget/LICENSE diff --git a/packages/@magic-ext/web3modal-ethers5/babel.config.json b/packages/@magic-ext/magic-widget/babel.config.json similarity index 100% rename from packages/@magic-ext/web3modal-ethers5/babel.config.json rename to packages/@magic-ext/magic-widget/babel.config.json diff --git a/packages/@magic-ext/web3modal-ethers5/eslint.config.mjs b/packages/@magic-ext/magic-widget/eslint.config.mjs similarity index 61% rename from packages/@magic-ext/web3modal-ethers5/eslint.config.mjs rename to packages/@magic-ext/magic-widget/eslint.config.mjs index c68f8e69b..adae3ceb4 100644 --- a/packages/@magic-ext/web3modal-ethers5/eslint.config.mjs +++ b/packages/@magic-ext/magic-widget/eslint.config.mjs @@ -8,12 +8,21 @@ const __dirname = path.dirname(__filename); export default [ ...rootEslintConfig, { - ignores: ['node_modules', 'coverage', 'dist', 'eslint.config.mjs', 'jest.config.ts'], + ignores: [ + 'node_modules', + 'coverage', + 'dist', + 'eslint.config.mjs', + 'jest.config.ts', + 'panda.config.ts', + 'postcss.config.cjs', + 'styled-system', + ], }, { languageOptions: { parserOptions: { - project: ['./tsconfig.json', './test/tsconfig.json'], + project: ['./tsconfig.json'], tsconfigRootDir: __dirname, }, }, diff --git a/packages/@magic-ext/web3modal-ethers5/jest.config.ts b/packages/@magic-ext/magic-widget/jest.config.ts similarity index 77% rename from packages/@magic-ext/web3modal-ethers5/jest.config.ts rename to packages/@magic-ext/magic-widget/jest.config.ts index a25ade0ed..433182c4b 100644 --- a/packages/@magic-ext/web3modal-ethers5/jest.config.ts +++ b/packages/@magic-ext/magic-widget/jest.config.ts @@ -7,7 +7,7 @@ const config: Config.InitialOptions = { '^.+\\.(js|jsx)$': 'babel-jest', '\\.(ts|tsx)$': 'ts-jest', }, - coveragePathIgnorePatterns: ['index.ts', 'index.cdn.ts', 'index.native.ts'], + coveragePathIgnorePatterns: ['index.cdn.ts', 'index.native.ts'], }; export default config; diff --git a/packages/@magic-ext/magic-widget/package.json b/packages/@magic-ext/magic-widget/package.json new file mode 100644 index 000000000..492369b99 --- /dev/null +++ b/packages/@magic-ext/magic-widget/package.json @@ -0,0 +1,82 @@ +{ + "name": "@magic-ext/magic-widget", + "useCustomBuild": true, + "version": "0.1.0", + "description": "Magic SDK Widget Extension with React components.", + "author": "Magic (https://magic.link/)", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/magiclabs/magic-js" + }, + "scripts": { + "prepare": "panda codegen", + "build:css": "panda cssgen --outfile dist/styles.css", + "build": "rollup -c rollup.config.mjs && tsc" + }, + "files": [ + "dist" + ], + "target": "browser", + "type": "module", + "module": "./dist/es/index.mjs", + "types": "./dist/types/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/index.d.ts", + "import": "./dist/es/index.mjs" + } + }, + "externals": { + "include": [ + "@magic-sdk/provider", + "@reown/appkit", + "@reown/appkit-adapter-wagmi", + "@tanstack/react-query", + "@wagmi/core", + "@walletconnect/ethereum-provider", + "react", + "react-dom", + "viem", + "wagmi" + ] + }, + "esbuildAliases": { + "@styled/css": "./styled-system/css", + "@styled/jsx": "./styled-system/jsx", + "@styled/tokens": "./styled-system/tokens", + "@styled/patterns": "./styled-system/patterns" + }, + "dependencies": { + "@magiclabs/ui-components": "^1.49.2", + "@reown/appkit": "^1.8.0", + "@reown/appkit-adapter-wagmi": "^1.8.0", + "@wagmi/core": "^2.0.0", + "@walletconnect/ethereum-provider": "^2.23.0", + "wagmi": "^2.0.0" + }, + "peerDependencies": { + "@tanstack/react-query": "^5.0.0", + "react": ">=18.0.0", + "react-dom": ">=18.0.0", + "viem": "^2.0.0" + }, + "devDependencies": { + "@magic-sdk/provider": "^33.1.0", + "@magic-sdk/types": "^27.1.0", + "@pandacss/dev": "^0.35.0", + "@rollup/plugin-commonjs": "^26.0.1", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-replace": "^5.0.5", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^11.1.6", + "@tanstack/react-query": "^5.0.0", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0", + "rollup": "^4.18.0", + "tslib": "^2.6.3", + "viem": "^2.37.9" + } +} diff --git a/packages/@magic-ext/magic-widget/panda.config.ts b/packages/@magic-ext/magic-widget/panda.config.ts new file mode 100644 index 000000000..3c36167dd --- /dev/null +++ b/packages/@magic-ext/magic-widget/panda.config.ts @@ -0,0 +1,50 @@ +import { magicPreset } from '@magiclabs/ui-components/presets'; +import { defineConfig } from '@pandacss/dev'; + +export default defineConfig({ + // Whether to use css reset + preflight: true, + // Minify the generated css + minify: true, + // Hash all classnames + hash: true, + // Clean the output directory before generating the css + clean: true, + // Note: @layer directives are stripped in rollup.config.mjs for Tailwind compatibility + + importMap: '@styled', + + // Where to look for your css declarations + include: ['./node_modules/@magiclabs/ui-components/dist/panda.buildinfo.json', './src/**/*.{js,jsx,ts,tsx}'], + + // Files to exclude + exclude: [], + + // Styling conditions / modes + conditions: { + light: '[data-color-mode=light] &', + dark: '[data-color-mode=dark] &', + }, + + presets: ['@pandacss/dev/presets', magicPreset], + + // Useful for theme customization + theme: { + extend: {}, + }, + + // The output directory for your css system + outdir: 'styled-system', + + // Output extension impacting build + outExtension: 'js', + + // The JSX framework to use + jsxFramework: 'react', + + globalCss: { + html: { + '--primary': 'black', + }, + }, +}); diff --git a/packages/@magic-ext/magic-widget/pnpm-lock.yaml b/packages/@magic-ext/magic-widget/pnpm-lock.yaml new file mode 100644 index 000000000..9abbee0dc --- /dev/null +++ b/packages/@magic-ext/magic-widget/pnpm-lock.yaml @@ -0,0 +1,123 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@magic-sdk/provider': + specifier: ^31.0.0 + version: 31.2.0(localforage@1.10.0) + '@types/react': + specifier: ^18.0.0 + version: 18.3.27 + react: + specifier: ^18.0.0 + version: 18.3.1 + react-dom: + specifier: ^18.0.0 + version: 18.3.1(react@18.3.1) + +packages: + + '@magic-sdk/provider@31.2.0': + resolution: {integrity: sha512-BiLnTn97HFnUWDT04m38t2z0IyoaVx1b9wb96T7YeYylDrIyOab/ma7L2P2gnLwAOmQq8N8Ky+gid1cVExbKWA==} + peerDependencies: + localforage: ^1.7.4 + + '@magic-sdk/types@25.2.0': + resolution: {integrity: sha512-/S78nj/jBND68Cp6L1JIDugpzIdAGRMsL+XsUHyVmyMhVcZvkZycEOOrmDH0SP0mjd29UvNLnPsJY1RT6A4NeA==} + + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + + '@types/react@18.3.27': + resolution: {integrity: sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + lie@3.1.1: + resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==} + + localforage@1.10.0: + resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + +snapshots: + + '@magic-sdk/provider@31.2.0(localforage@1.10.0)': + dependencies: + '@magic-sdk/types': 25.2.0 + eventemitter3: 4.0.7 + localforage: 1.10.0 + + '@magic-sdk/types@25.2.0': {} + + '@types/prop-types@15.7.15': {} + + '@types/react@18.3.27': + dependencies: + '@types/prop-types': 15.7.15 + csstype: 3.2.3 + + csstype@3.2.3: {} + + eventemitter3@4.0.7: {} + + immediate@3.0.6: {} + + js-tokens@4.0.0: {} + + lie@3.1.1: + dependencies: + immediate: 3.0.6 + + localforage@1.10.0: + dependencies: + lie: 3.1.1 + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 diff --git a/packages/@magic-ext/magic-widget/postcss.config.cjs b/packages/@magic-ext/magic-widget/postcss.config.cjs new file mode 100644 index 000000000..678b267b6 --- /dev/null +++ b/packages/@magic-ext/magic-widget/postcss.config.cjs @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + '@pandacss/dev/postcss': {}, + }, +}; + diff --git a/packages/@magic-ext/magic-widget/rollup.config.mjs b/packages/@magic-ext/magic-widget/rollup.config.mjs new file mode 100644 index 000000000..3bb8ad074 --- /dev/null +++ b/packages/@magic-ext/magic-widget/rollup.config.mjs @@ -0,0 +1,170 @@ +/* eslint-env node */ +/* global process */ +import resolve from '@rollup/plugin-node-resolve'; +import commonjs from '@rollup/plugin-commonjs'; +import typescript from '@rollup/plugin-typescript'; +import replace from '@rollup/plugin-replace'; +import terser from '@rollup/plugin-terser'; +import { readFileSync, existsSync, mkdirSync } from 'fs'; +import { resolve as pathResolve, join } from 'path'; +import { execSync } from 'child_process'; + +// Ensure dist directory exists +if (!existsSync('./dist')) { + mkdirSync('./dist', { recursive: true }); +} + +// Generate CSS first +try { + execSync('./node_modules/.bin/panda cssgen --outfile dist/styles.css', { stdio: 'inherit' }); +} catch { + // CSS generation failed, using existing CSS +} + +// Read the CSS to inject +let cssContent = ''; +try { + cssContent = readFileSync('./dist/styles.css', 'utf-8'); + + // CRITICAL: Remove @layer wrappers - they lower specificity and lose to Tailwind's preflight + function stripLayers(css) { + // Remove @layer declarations like "@layer reset, base, tokens;" + css = css.replace(/@layer\s+[\w\s,]+;/g, ''); + + // Find and unwrap @layer blocks + let result = ''; + let i = 0; + while (i < css.length) { + // Check for @layer + if (css.slice(i, i + 6) === '@layer') { + // Skip past @layer and optional name until { + let j = i + 6; + while (j < css.length && css[j] !== '{') j++; + if (j < css.length) { + j++; // skip the { + // Now find the matching } + let braceCount = 1; + let start = j; + while (j < css.length && braceCount > 0) { + if (css[j] === '{') braceCount++; + else if (css[j] === '}') braceCount--; + j++; + } + // Extract content without the outer braces + result += css.slice(start, j - 1); + i = j; + } else { + result += css[i]; + i++; + } + } else { + result += css[i]; + i++; + } + } + return result; + } + + // Strip layers multiple times to handle nesting + cssContent = stripLayers(cssContent); + cssContent = stripLayers(cssContent); + cssContent = stripLayers(cssContent); + + // Escape for JS string + cssContent = cssContent.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$'); +} catch { + // Could not read CSS file +} + +const pkg = JSON.parse(readFileSync('./package.json', 'utf-8')); + +// External dependencies - not bundled by us, resolved by consumer's bundler +const external = (id) => { + // Externalize specific packages and their subpaths + if ( + id === 'react' || + id === 'react-dom' || + id === 'react-dom/client' || + id === 'react/jsx-runtime' || + id === '@magic-sdk/provider' || + id === 'wagmi' || + id.startsWith('wagmi/') || + id === 'viem' || + id === '@wagmi/core' || + id === '@tanstack/react-query' || + id === '@reown/appkit' || + id === '@reown/appkit/networks' || + id === '@reown/appkit-adapter-wagmi' || + id === '@walletconnect/ethereum-provider' || + id.startsWith('@walletconnect/') + ) { + return true; + } + return false; +}; + +// Alias for @styled/* paths +const aliasPlugin = { + name: 'styled-alias', + resolveId(source) { + if (source.startsWith('@styled/')) { + // Convert @styled/css -> styled-system/css + // Convert @styled/css/cx -> styled-system/css/cx + const relativePath = source.replace('@styled/', 'styled-system/'); + const absolutePath = pathResolve(process.cwd(), relativePath); + + // Try with .js extension + if (existsSync(absolutePath + '.js')) { + return absolutePath + '.js'; + } + + // Try as directory with index.js + if (existsSync(join(absolutePath, 'index.js'))) { + return join(absolutePath, 'index.js'); + } + + // Return as-is and let resolve plugin handle it + return absolutePath; + } + return null; + }, +}; + +const plugins = [ + aliasPlugin, + replace({ + preventAssignment: true, + values: { + MAGIC_WIDGET_CSS: JSON.stringify(cssContent), + }, + }), + resolve({ + extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs'], + }), + commonjs({ + transformMixedEsModules: true, + }), + typescript({ + tsconfig: './tsconfig.json', + }), + terser(), +]; + +export default { + input: 'src/index.ts', + output: { + file: pkg.module, + format: 'esm', + sourcemap: false, + inlineDynamicImports: true, + }, + external, + plugins, + onwarn(warning, warn) { + // Suppress circular dependency warnings from third-party libs + if (warning.code === 'CIRCULAR_DEPENDENCY') return; + // Suppress "this" rewrite warnings + if (warning.code === 'THIS_IS_UNDEFINED') return; + warn(warning); + }, +}; diff --git a/packages/@magic-ext/magic-widget/src/MagicWidget.tsx b/packages/@magic-ext/magic-widget/src/MagicWidget.tsx new file mode 100644 index 000000000..0c7a0b3cd --- /dev/null +++ b/packages/@magic-ext/magic-widget/src/MagicWidget.tsx @@ -0,0 +1,256 @@ +import { Footer, Modal, useCustomVars } from '@magiclabs/ui-components'; +import { VStack } from '../styled-system/jsx'; +import React, { useEffect, useReducer, useState } from 'react'; +import { WagmiProvider } from 'wagmi'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { LoginView } from './views/LoginView'; +import { WalletPendingView } from './views/WalletPendingView'; +import { widgetReducer, initialState, WidgetAction, WidgetState } from './reducer'; +import { MagicWidgetProps, OAuthProvider, ThirdPartyWallet } from './types'; +import { OAuthPendingView } from './views/OAuthPendingView'; +import AdditionalProvidersView from './views/AdditionalProvidersView'; +import { getExtensionInstance } from './extension'; +import { EmailLoginProvider } from './context/EmailLoginContext'; +import { WidgetConfigProvider } from './context/WidgetConfigContext'; +import { EmailOTPView } from './views/EmailOTPView'; +import { DeviceVerificationView } from './views/DeviceVerificationView'; +import { LoginSuccessView } from './views/LoginSuccessView'; +import { MFAView } from './views/MfaView'; +import { RecoveryCodeView } from './views/RecoveryCode'; +import { LostRecoveryCode } from './views/LostRecoveryCode'; +import { WalletConnectView } from './views/WalletConnectView'; +import { ClientTheme } from './types/client-config'; +import { css } from '@styled/css'; +import { useMediaQuery } from './hooks/useMediaQuery'; + +const queryClient = new QueryClient(); + +// Inject CSS into document head (only once) +let cssInjected = false; +function injectCSS() { + if (cssInjected || typeof document === 'undefined') return; + + const styleElement = document.createElement('style'); + styleElement.id = 'magic-widget-styles'; + styleElement.textContent = MAGIC_WIDGET_CSS; + document.head.appendChild(styleElement); + cssInjected = true; +} + +function WidgetContent({ + state, + dispatch, + showFooterLogo, + isModal, +}: { + state: WidgetState; + dispatch: React.Dispatch; + showFooterLogo: boolean; + isModal: boolean; +}) { + const isMobile = useMediaQuery('(max-width: 768px)'); + + const renderView = () => { + switch (state.view) { + case 'login': + return ; + case 'wallet_pending': + if (!state.selectedProvider) { + return ; + } + return ( + + ); + case 'walletconnect_pending': + return ; + case 'oauth_pending': + if (!state.selectedProvider) { + return ; + } + return ( + + ); + case 'additional_providers': + return ; + case 'email_otp_pending': + return ; + case 'device_verification': + return ; + case 'mfa_pending': + return ; + case 'recovery_code': + return ; + case 'lost_recovery_code': + return ; + case 'login_success': + return ; + default: + return ; + } + }; + + return ( + + + + {renderView()} +