diff --git a/.vscode/settings.json b/.vscode/settings.json index 863270840..d699fc73b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,5 +13,5 @@ "changeProcessCWD": true } ], - "cSpell.words": ["JRPC","Solana"] + "cSpell.words": ["clsx", "JRPC", "Ronin", "Solana"] } diff --git a/demo/react-app/package-lock.json b/demo/react-app/package-lock.json index 6888e4d39..b40eb439b 100644 --- a/demo/react-app/package-lock.json +++ b/demo/react-app/package-lock.json @@ -60,15 +60,15 @@ }, "../../packages/base": { "name": "@web3auth/base", - "version": "8.12.4", + "version": "9.3.0", "license": "ISC", "dependencies": { - "@toruslabs/base-controllers": "^6.0.2", + "@toruslabs/base-controllers": "^6.2.2", "@toruslabs/constants": "^14.0.0", "@toruslabs/http-helpers": "^7.0.0", - "@web3auth/auth": "^9.1.3", + "@web3auth/auth": "^9.4.1", "jwt-decode": "^4.0.0", - "loglevel": "^1.9.1", + "loglevel": "^1.9.2", "ts-custom-error": "^3.3.1" }, "engines": { @@ -81,24 +81,24 @@ }, "../../packages/modal": { "name": "@web3auth/modal", - "version": "8.12.7", + "version": "9.3.1", "license": "ISC", "dependencies": { - "@web3auth/base": "^8.12.4", - "@web3auth/base-provider": "^8.12.4", - "@web3auth/no-modal": "^8.12.4", - "@web3auth/openlogin-adapter": "^8.12.4", - "@web3auth/ui": "^8.12.7", - "lodash.clonedeep": "^4.5.0", - "lodash.merge": "^4.6.2" + "@web3auth/auth-adapter": "^9.3.0", + "@web3auth/base": "^9.3.0", + "@web3auth/base-provider": "^9.3.0", + "@web3auth/no-modal": "^9.3.1", + "@web3auth/ui": "^9.3.1", + "deepmerge": "^4.3.1" }, "devDependencies": { "@svgr/webpack": "^8.1.0", "@toruslabs/isomorphic-style-loader": "^5.3.3", - "@toruslabs/openlogin-utils": "^8.2.1", - "@web3auth/wallet-connect-v2-adapter": "^8.12.4", + "@web3auth/account-abstraction-provider": "^9.3.1", + "@web3auth/auth": "^9.4.1", + "@web3auth/wallet-connect-v2-adapter": "^9.3.0", "css-loader": "^7.1.2", - "postcss-prefix-selector": "^1.16.1", + "postcss-prefix-selector": "^2.1.0", "style-loader": "^4.0.0", "url-loader": "^4.1.1" }, @@ -108,7 +108,7 @@ }, "peerDependencies": { "@babel/runtime": "^7.x", - "@web3auth/wallet-connect-v2-adapter": "^8.x" + "@web3auth/wallet-connect-v2-adapter": "^9.x" }, "peerDependenciesMeta": { "@web3auth/wallet-connect-v2-adapter": { @@ -118,17 +118,17 @@ }, "../../packages/plugins/wallet-services-plugin": { "name": "@web3auth/wallet-services-plugin", - "version": "8.12.5", + "version": "9.3.1", "license": "ISC", "dependencies": { - "@toruslabs/openlogin-jrpc": "^8.3.0", - "@web3auth/base": "^8.12.4", - "@web3auth/no-modal": "^8.12.4", - "@web3auth/ws-embed": "^2.0.23", - "loglevel": "^1.9.1" + "@web3auth/auth": "^9.4.1", + "@web3auth/base": "^9.3.0", + "@web3auth/no-modal": "^9.3.1", + "@web3auth/ws-embed": "^3.1.0", + "loglevel": "^1.9.2" }, "devDependencies": { - "@toruslabs/ethereum-controllers": "^6.0.2" + "@toruslabs/ethereum-controllers": "^6.2.2" }, "engines": { "node": ">=18.x", @@ -140,21 +140,18 @@ }, "../../packages/providers/account-abstraction-provider": { "name": "@web3auth/account-abstraction-provider", - "version": "8.5.0-alpha.3", + "version": "9.3.1", "license": "ISC", "dependencies": { - "@ethereumjs/common": "^4.3.0", - "@ethereumjs/tx": "^5.3.0", - "@ethereumjs/util": "^9.0.3", - "@metamask/eth-sig-util": "^7.0.2", - "@metamask/rpc-errors": "^6.2.1", - "@toruslabs/base-controllers": "^5.6.0", - "@toruslabs/openlogin-jrpc": "^8.1.1", - "@web3auth/base": "^8.5.0-alpha.3", - "@web3auth/base-provider": "^8.5.0-alpha.3", - "@web3auth/ethereum-provider": "^8.5.0-alpha.3", - "permissionless": "^0.1.29", - "viem": "^2.10.11" + "@ethereumjs/util": "^9.1.0", + "@toruslabs/base-controllers": "^6.2.2", + "@web3auth/auth": "^9.4.1", + "@web3auth/base": "^9.3.0", + "@web3auth/base-provider": "^9.3.0", + "@web3auth/ethereum-provider": "^9.3.0", + "ethers": "^6.13.4", + "permissionless": "^0.2.13", + "viem": "^2.21.36" }, "engines": { "node": ">=18.x", @@ -166,28 +163,26 @@ }, "../../packages/providers/ethereum-provider": { "name": "@web3auth/ethereum-provider", - "version": "8.12.4", + "version": "9.3.0", "license": "ISC", "dependencies": { - "@ethereumjs/common": "^4.3.0", - "@ethereumjs/tx": "^5.3.0", - "@ethereumjs/util": "^9.0.3", - "@metamask/eth-sig-util": "7.0.2", - "@toruslabs/base-controllers": "^5.10.0", - "@toruslabs/http-helpers": "^6.1.1", - "@toruslabs/openlogin-jrpc": "^8.3.0", - "@web3auth/base": "^8.12.4", - "@web3auth/base-provider": "^8.12.4", + "@ethereumjs/util": "^9.1.0", + "@toruslabs/base-controllers": "^6.2.2", + "@toruslabs/eccrypto": "^5.0.4", + "@toruslabs/http-helpers": "^7.0.0", + "@web3auth/auth": "^9.4.1", + "@web3auth/base": "^9.3.0", + "@web3auth/base-provider": "^9.3.0", "assert": "^2.1.0", "bignumber.js": "^9.1.2", "bn.js": "^5.2.1", - "ethers": "^6.13.2", + "ethers": "^6.13.4", "jsonschema": "^1.4.1" }, "devDependencies": { - "@types/bn.js": "^5.1.5", + "@types/bn.js": "^5.1.6", "@types/json-rpc-random-id": "^1.0.3", - "@walletconnect/types": "^2.15.1" + "@walletconnect/types": "^2.17.1" }, "engines": { "node": ">=18.x", @@ -199,22 +194,21 @@ }, "../../packages/providers/solana-provider": { "name": "@web3auth/solana-provider", - "version": "8.12.4", + "version": "9.3.0", "license": "ISC", "dependencies": { - "@toruslabs/base-controllers": "^6.0.2", - "@toruslabs/openlogin-ed25519": "^8.1.0", + "@toruslabs/base-controllers": "^6.2.2", "@toruslabs/tweetnacl-js": "^1.0.4", - "@web3auth/base": "^8.12.4", - "@web3auth/base-provider": "^8.12.4", + "@web3auth/auth": "^9.4.1", + "@web3auth/base": "^9.3.0", + "@web3auth/base-provider": "^9.3.0", "bn.js": "^5.2.1", "bs58": "^5.0.0", "json-rpc-random-id": "^1.0.1" }, "devDependencies": { - "@solana/web3.js": "^1.95.3", - "@solflare-wallet/sdk": "^1.4.2", - "@types/bn.js": "^5.1.5", + "@solana/web3.js": "^1.95.4", + "@types/bn.js": "^5.1.6", "@types/bs58": "^4.0.4", "@types/json-rpc-random-id": "^1.0.3" }, diff --git a/demo/vue-app-new/package-lock.json b/demo/vue-app-new/package-lock.json index b068576a0..e7f341b24 100644 --- a/demo/vue-app-new/package-lock.json +++ b/demo/vue-app-new/package-lock.json @@ -56,12 +56,12 @@ }, "../../packages/adapters/auth-adapter": { "name": "@web3auth/auth-adapter", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { "@web3auth/auth": "^9.4.1", - "@web3auth/base": "^9.2.3", - "@web3auth/base-provider": "^9.2.3", + "@web3auth/base": "^9.3.0", + "@web3auth/base-provider": "^9.3.0", "deepmerge": "^4.3.1" }, "engines": { @@ -74,11 +74,11 @@ }, "../../packages/adapters/base-evm-adapter": { "name": "@web3auth/base-evm-adapter", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { "@toruslabs/base-controllers": "^6.2.2", - "@web3auth/base": "^9.2.3" + "@web3auth/base": "^9.3.0" }, "engines": { "node": ">=18.x", @@ -90,11 +90,11 @@ }, "../../packages/adapters/base-solana-adapter": { "name": "@web3auth/base-solana-adapter", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { "@toruslabs/base-controllers": "^6.2.2", - "@web3auth/base": "^9.2.3", + "@web3auth/base": "^9.3.0", "bs58": "^5.0.0" }, "devDependencies": { @@ -110,11 +110,11 @@ }, "../../packages/adapters/coinbase-adapter": { "name": "@web3auth/coinbase-adapter", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { - "@web3auth/base": "^9.2.3", - "@web3auth/base-evm-adapter": "^9.2.3" + "@web3auth/base": "^9.3.0", + "@web3auth/base-evm-adapter": "^9.3.0" }, "devDependencies": { "@coinbase/wallet-sdk": "^4.1.0" @@ -130,12 +130,12 @@ }, "../../packages/adapters/default-evm-adapter": { "name": "@web3auth/default-evm-adapter", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { - "@web3auth/base": "^9.2.3", - "@web3auth/base-evm-adapter": "^9.2.3", - "@web3auth/wallet-connect-v2-adapter": "^9.2.3", + "@web3auth/base": "^9.3.0", + "@web3auth/base-evm-adapter": "^9.3.0", + "@web3auth/wallet-connect-v2-adapter": "^9.3.0", "mipd": "^0.0.7" }, "engines": { @@ -148,19 +148,19 @@ }, "../../packages/adapters/default-solana-adapter": { "name": "@web3auth/default-solana-adapter", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { "@solana/wallet-standard-features": "^1.2.0", - "@solana/web3.js": "^1.95.3", + "@solana/web3.js": "^1.95.4", "@wallet-standard/app": "^1.0.1", "@wallet-standard/base": "^1.0.1", "@wallet-standard/features": "^1.0.3", "@web3auth/auth": "^9.4.1", - "@web3auth/base": "^9.2.3", - "@web3auth/base-solana-adapter": "^9.2.3", - "@web3auth/solana-provider": "^9.2.3", - "@web3auth/wallet-connect-v2-adapter": "^9.2.3", + "@web3auth/base": "^9.3.0", + "@web3auth/base-solana-adapter": "^9.3.0", + "@web3auth/solana-provider": "^9.3.0", + "@web3auth/wallet-connect-v2-adapter": "^9.3.0", "bn.js": "^5.2.1" }, "engines": { @@ -173,12 +173,12 @@ }, "../../packages/adapters/torus-evm-adapter": { "name": "@web3auth/torus-evm-adapter", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { "@toruslabs/torus-embed": "^5.0.0", - "@web3auth/base": "^9.2.3", - "@web3auth/base-evm-adapter": "^9.2.3" + "@web3auth/base": "^9.3.0", + "@web3auth/base-evm-adapter": "^9.3.0" }, "engines": { "node": ">=18.x", @@ -190,14 +190,14 @@ }, "../../packages/adapters/torus-solana-adapter": { "name": "@web3auth/torus-solana-adapter", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { "@toruslabs/solana-embed": "^2.1.0", - "@web3auth/base": "^9.2.3", - "@web3auth/base-provider": "^9.2.3", - "@web3auth/base-solana-adapter": "^9.2.3", - "@web3auth/solana-provider": "^9.2.3" + "@web3auth/base": "^9.3.0", + "@web3auth/base-provider": "^9.3.0", + "@web3auth/base-solana-adapter": "^9.3.0", + "@web3auth/solana-provider": "^9.3.0" }, "engines": { "node": ">=18.x", @@ -210,19 +210,19 @@ }, "../../packages/adapters/wallet-connect-v2-adapter": { "name": "@web3auth/wallet-connect-v2-adapter", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { - "@solana/web3.js": "^1.95.3", + "@solana/web3.js": "^1.95.4", "@toruslabs/base-controllers": "^6.2.2", - "@walletconnect/sign-client": "^2.17.0", - "@walletconnect/types": "^2.17.0", - "@walletconnect/utils": "^2.17.0", + "@walletconnect/sign-client": "^2.17.1", + "@walletconnect/types": "^2.17.1", + "@walletconnect/utils": "^2.17.1", "@web3auth/auth": "^9.4.1", - "@web3auth/base": "^9.2.3", - "@web3auth/base-provider": "^9.2.3", - "@web3auth/ethereum-provider": "^9.2.3", - "@web3auth/solana-provider": "^9.2.3", + "@web3auth/base": "^9.3.0", + "@web3auth/base-provider": "^9.3.0", + "@web3auth/ethereum-provider": "^9.3.0", + "@web3auth/solana-provider": "^9.3.0", "bs58": "^5.0.0", "deepmerge": "^4.3.1" }, @@ -239,7 +239,7 @@ }, "../../packages/base": { "name": "@web3auth/base", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { "@toruslabs/base-controllers": "^6.2.2", @@ -260,15 +260,15 @@ }, "../../packages/composables/modal-vue-composables": { "name": "@web3auth/modal-vue-composables", - "version": "9.2.3", + "version": "9.3.1", "license": "ISC", "dependencies": { - "@web3auth/base": "^9.2.3", - "@web3auth/modal": "^9.2.3" + "@web3auth/base": "^9.3.0", + "@web3auth/modal": "^9.3.1" }, "devDependencies": { "@web3auth/auth": "^9.4.1", - "@web3auth/auth-adapter": "^9.2.3" + "@web3auth/auth-adapter": "^9.3.0" }, "engines": { "node": ">=18.x", @@ -281,24 +281,24 @@ }, "../../packages/modal": { "name": "@web3auth/modal", - "version": "9.2.3", + "version": "9.3.1", "license": "ISC", "dependencies": { - "@web3auth/auth-adapter": "^9.2.3", - "@web3auth/base": "^9.2.3", - "@web3auth/base-provider": "^9.2.3", - "@web3auth/no-modal": "^9.2.3", - "@web3auth/ui": "^9.2.3", + "@web3auth/auth-adapter": "^9.3.0", + "@web3auth/base": "^9.3.0", + "@web3auth/base-provider": "^9.3.0", + "@web3auth/no-modal": "^9.3.1", + "@web3auth/ui": "^9.3.1", "deepmerge": "^4.3.1" }, "devDependencies": { "@svgr/webpack": "^8.1.0", "@toruslabs/isomorphic-style-loader": "^5.3.3", - "@web3auth/account-abstraction-provider": "^9.2.3", + "@web3auth/account-abstraction-provider": "^9.3.1", "@web3auth/auth": "^9.4.1", - "@web3auth/wallet-connect-v2-adapter": "^9.2.3", + "@web3auth/wallet-connect-v2-adapter": "^9.3.0", "css-loader": "^7.1.2", - "postcss-prefix-selector": "^1.16.1", + "postcss-prefix-selector": "^2.1.0", "style-loader": "^4.0.0", "url-loader": "^4.1.1" }, @@ -318,18 +318,18 @@ }, "../../packages/no-modal": { "name": "@web3auth/no-modal", - "version": "9.2.3", + "version": "9.3.1", "license": "ISC", "dependencies": { "@web3auth/auth": "^9.4.1", - "@web3auth/base": "^9.2.3", - "@web3auth/base-provider": "^9.2.3", + "@web3auth/base": "^9.3.0", + "@web3auth/base-provider": "^9.3.0", "deepmerge": "^4.3.1" }, "devDependencies": { - "@web3auth/account-abstraction-provider": "^9.2.3", - "@web3auth/auth-adapter": "^9.2.3", - "@web3auth/wallet-connect-v2-adapter": "^9.2.3" + "@web3auth/account-abstraction-provider": "^9.3.1", + "@web3auth/auth-adapter": "^9.3.0", + "@web3auth/wallet-connect-v2-adapter": "^9.3.0" }, "engines": { "node": ">=18.x", @@ -351,13 +351,13 @@ }, "../../packages/plugins/solana-wallet-connector-plugin": { "name": "@web3auth/solana-wallet-connector-plugin", - "version": "9.2.3", + "version": "9.3.1", "license": "ISC", "dependencies": { "@toruslabs/solana-embed": "^2.1.0", "@web3auth/auth": "^9.4.1", - "@web3auth/base": "^9.2.3", - "@web3auth/no-modal": "^9.2.3", + "@web3auth/base": "^9.3.0", + "@web3auth/no-modal": "^9.3.1", "loglevel": "^1.9.2" }, "engines": { @@ -370,13 +370,13 @@ }, "../../packages/plugins/wallet-services-plugin": { "name": "@web3auth/wallet-services-plugin", - "version": "9.2.3", + "version": "9.3.1", "license": "ISC", "dependencies": { "@web3auth/auth": "^9.4.1", - "@web3auth/base": "^9.2.3", - "@web3auth/no-modal": "^9.2.3", - "@web3auth/ws-embed": "^3.0.0", + "@web3auth/base": "^9.3.0", + "@web3auth/no-modal": "^9.3.1", + "@web3auth/ws-embed": "^3.1.0", "loglevel": "^1.9.2" }, "devDependencies": { @@ -392,18 +392,18 @@ }, "../../packages/providers/account-abstraction-provider": { "name": "@web3auth/account-abstraction-provider", - "version": "9.2.3", + "version": "9.3.1", "license": "ISC", "dependencies": { "@ethereumjs/util": "^9.1.0", "@toruslabs/base-controllers": "^6.2.2", "@web3auth/auth": "^9.4.1", - "@web3auth/base": "^9.2.3", - "@web3auth/base-provider": "^9.2.3", - "@web3auth/ethereum-provider": "^9.2.3", - "ethers": "^6.13.3", - "permissionless": "^0.2.7", - "viem": "^2.21.19" + "@web3auth/base": "^9.3.0", + "@web3auth/base-provider": "^9.3.0", + "@web3auth/ethereum-provider": "^9.3.0", + "ethers": "^6.13.4", + "permissionless": "^0.2.13", + "viem": "^2.21.36" }, "engines": { "node": ">=18.x", @@ -477,12 +477,12 @@ }, "../../packages/providers/base-provider": { "name": "@web3auth/base-provider", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { "@toruslabs/base-controllers": "^6.2.2", "@web3auth/auth": "^9.4.1", - "@web3auth/base": "^9.2.3", + "@web3auth/base": "^9.3.0", "json-rpc-random-id": "^1.0.1" }, "devDependencies": { @@ -498,7 +498,7 @@ }, "../../packages/providers/ethereum-provider": { "name": "@web3auth/ethereum-provider", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { "@ethereumjs/util": "^9.1.0", @@ -506,18 +506,18 @@ "@toruslabs/eccrypto": "^5.0.4", "@toruslabs/http-helpers": "^7.0.0", "@web3auth/auth": "^9.4.1", - "@web3auth/base": "^9.2.3", - "@web3auth/base-provider": "^9.2.3", + "@web3auth/base": "^9.3.0", + "@web3auth/base-provider": "^9.3.0", "assert": "^2.1.0", "bignumber.js": "^9.1.2", "bn.js": "^5.2.1", - "ethers": "^6.13.3", + "ethers": "^6.13.4", "jsonschema": "^1.4.1" }, "devDependencies": { "@types/bn.js": "^5.1.6", "@types/json-rpc-random-id": "^1.0.3", - "@walletconnect/types": "^2.17.0" + "@walletconnect/types": "^2.17.1" }, "engines": { "node": ">=18.x", @@ -529,20 +529,20 @@ }, "../../packages/providers/solana-provider": { "name": "@web3auth/solana-provider", - "version": "9.2.3", + "version": "9.3.0", "license": "ISC", "dependencies": { "@toruslabs/base-controllers": "^6.2.2", "@toruslabs/tweetnacl-js": "^1.0.4", "@web3auth/auth": "^9.4.1", - "@web3auth/base": "^9.2.3", - "@web3auth/base-provider": "^9.2.3", + "@web3auth/base": "^9.3.0", + "@web3auth/base-provider": "^9.3.0", "bn.js": "^5.2.1", "bs58": "^5.0.0", "json-rpc-random-id": "^1.0.1" }, "devDependencies": { - "@solana/web3.js": "^1.95.3", + "@solana/web3.js": "^1.95.4", "@types/bn.js": "^5.1.6", "@types/bs58": "^4.0.4", "@types/json-rpc-random-id": "^1.0.3" diff --git a/package-lock.json b/package-lock.json index 403ffb739..563b36b9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,11 +13,15 @@ "packages/composables/*", "packages/hooks/*", "packages/modal", + "packages/modal-ui", "packages/no-modal", "packages/plugins/*", "packages/providers/*", "packages/ui" ], + "dependencies": { + "tailwind-merge": "^2.5.4" + }, "devDependencies": { "@babel/register": "^7.25.9", "@toruslabs/config": "^2.2.0", @@ -1869,6 +1873,374 @@ "tslib": "^2.4.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "dev": true, @@ -3197,6 +3569,12 @@ "node": ">= 8" } }, + "node_modules/@nothing-but/utils": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@nothing-but/utils/-/utils-0.12.1.tgz", + "integrity": "sha512-1qZU1Q5El0IjE7JT/ucvJNzdr2hL3W8Rm27xNf1p6gb3Nw8pGnZmxp6/GEW9h+I1k1cICxXNq25hBwknTQ7yhg==", + "dev": true + }, "node_modules/@npmcli/agent": { "version": "2.2.2", "dev": true, @@ -4832,69 +5210,307 @@ "version": "4.0.1", "license": "MIT", "dependencies": { - "buffer": "~6.0.3" + "buffer": "~6.0.3" + }, + "engines": { + "node": ">=5.10" + } + }, + "node_modules/@solana/wallet-standard-features": { + "version": "1.2.0", + "license": "Apache-2.0", + "dependencies": { + "@wallet-standard/base": "^1.0.1", + "@wallet-standard/features": "^1.0.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@solana/web3.js": { + "version": "1.95.4", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.95.4.tgz", + "integrity": "sha512-sdewnNEA42ZSMxqkzdwEWi6fDgzwtJHaQa5ndUGEJYtoOnM6X5cvPmjoTUp7/k7bRrVAxfBgDnvQQHD6yhlLYw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.0", + "@noble/curves": "^1.4.2", + "@noble/hashes": "^1.4.0", + "@solana/buffer-layout": "^4.0.1", + "agentkeepalive": "^4.5.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.2.1", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.3", + "fast-stable-stringify": "^1.0.0", + "jayson": "^4.1.1", + "node-fetch": "^2.7.0", + "rpc-websockets": "^9.0.2", + "superstruct": "^2.0.2" + } + }, + "node_modules/@solana/web3.js/node_modules/bs58": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/@solana/web3.js/node_modules/node-fetch": { + "version": "2.7.0", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@solid-devtools/debugger": { + "version": "0.23.4", + "resolved": "https://registry.npmjs.org/@solid-devtools/debugger/-/debugger-0.23.4.tgz", + "integrity": "sha512-EfTB1Eo313wztQYGJ4Ec/wE70Ay2d603VCXfT3RlyqO5QfLrQGRHX5NXC07hJpQTJJJ3tbNgzO7+ZKo76MM5uA==", + "dev": true, + "dependencies": { + "@nothing-but/utils": "~0.12.0", + "@solid-devtools/shared": "^0.13.2", + "@solid-primitives/bounds": "^0.0.118", + "@solid-primitives/cursor": "^0.0.112", + "@solid-primitives/event-bus": "^1.0.8", + "@solid-primitives/event-listener": "^2.3.0", + "@solid-primitives/keyboard": "^1.2.5", + "@solid-primitives/platform": "^0.1.0", + "@solid-primitives/rootless": "^1.4.2", + "@solid-primitives/scheduled": "^1.4.1", + "@solid-primitives/static-store": "^0.0.5", + "@solid-primitives/utils": "^6.2.1" + }, + "peerDependencies": { + "solid-js": "^1.8.0" + } + }, + "node_modules/@solid-devtools/shared": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@solid-devtools/shared/-/shared-0.13.2.tgz", + "integrity": "sha512-Y4uaC4EfTVwBR537MZwfaY/eiWAh+hW4mbtnwNuUw/LFmitHSkQhNQTUlLQv/S0chtwrYWQBxvXos1dC7e8R9g==", + "dev": true, + "dependencies": { + "@solid-primitives/event-bus": "^1.0.8", + "@solid-primitives/event-listener": "^2.3.0", + "@solid-primitives/media": "^2.2.5", + "@solid-primitives/refs": "^1.0.5", + "@solid-primitives/rootless": "^1.4.2", + "@solid-primitives/scheduled": "^1.4.1", + "@solid-primitives/static-store": "^0.0.5", + "@solid-primitives/styles": "^0.0.111", + "@solid-primitives/utils": "^6.2.1" + }, + "peerDependencies": { + "solid-js": "^1.8.0" + } + }, + "node_modules/@solid-primitives/bounds": { + "version": "0.0.118", + "resolved": "https://registry.npmjs.org/@solid-primitives/bounds/-/bounds-0.0.118.tgz", + "integrity": "sha512-Qj42w8LlnhJ3r/t+t0c0vrdwIvvQMPgjEFGmLiwREaA85ojLbgL9lSBq2tKvljeLCvRVkgj10KEUf+vc99VCIg==", + "dev": true, + "dependencies": { + "@solid-primitives/event-listener": "^2.3.0", + "@solid-primitives/resize-observer": "^2.0.22", + "@solid-primitives/static-store": "^0.0.5", + "@solid-primitives/utils": "^6.2.1" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/cursor": { + "version": "0.0.112", + "resolved": "https://registry.npmjs.org/@solid-primitives/cursor/-/cursor-0.0.112.tgz", + "integrity": "sha512-TAtU7qD7ipSLSXHnq8FhhosAPVX+dnOCb/ITcGcLlj8e/C9YKcxDhgBHJ3R/d1xDRb5/vO/szJtEz6fnQD311Q==", + "dev": true, + "dependencies": { + "@solid-primitives/utils": "^6.2.1" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/event-bus": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@solid-primitives/event-bus/-/event-bus-1.0.11.tgz", + "integrity": "sha512-bSwVA4aI2aNHomSbEroUnisMSyDDXJbrw4U8kFEvrcYdlLrJX5i6QeCFx+vj/zdQQw62KAllrEIyWP8KMpPVnQ==", + "dev": true, + "dependencies": { + "@solid-primitives/utils": "^6.2.3" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/event-listener": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@solid-primitives/event-listener/-/event-listener-2.3.3.tgz", + "integrity": "sha512-DAJbl+F0wrFW2xmcV8dKMBhk9QLVLuBSW+TR4JmIfTaObxd13PuL7nqaXnaYKDWOYa6otB00qcCUIGbuIhSUgQ==", + "dev": true, + "dependencies": { + "@solid-primitives/utils": "^6.2.3" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/keyboard": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@solid-primitives/keyboard/-/keyboard-1.2.8.tgz", + "integrity": "sha512-pJtcbkjozS6L1xvTht9rPpyPpX55nAkfBzbFWdf3y0Suwh6qClTibvvObzKOf7uzQ+8aZRDH4LsoGmbTKXtJjQ==", + "dev": true, + "dependencies": { + "@solid-primitives/event-listener": "^2.3.3", + "@solid-primitives/rootless": "^1.4.5", + "@solid-primitives/utils": "^6.2.3" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/media": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/@solid-primitives/media/-/media-2.2.9.tgz", + "integrity": "sha512-QUmU62D4/d9YWx/4Dvr/UZasIkIpqNXz7wosA5GLmesRW9XlPa3G5M6uOmTw73SByHNTCw0D6x8bSdtvvLgzvQ==", + "dev": true, + "dependencies": { + "@solid-primitives/event-listener": "^2.3.3", + "@solid-primitives/rootless": "^1.4.5", + "@solid-primitives/static-store": "^0.0.8", + "@solid-primitives/utils": "^6.2.3" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/media/node_modules/@solid-primitives/static-store": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@solid-primitives/static-store/-/static-store-0.0.8.tgz", + "integrity": "sha512-ZecE4BqY0oBk0YG00nzaAWO5Mjcny8Fc06CdbXadH9T9lzq/9GefqcSe/5AtdXqjvY/DtJ5C6CkcjPZO0o/eqg==", + "dev": true, + "dependencies": { + "@solid-primitives/utils": "^6.2.3" + }, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/platform": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@solid-primitives/platform/-/platform-0.1.2.tgz", + "integrity": "sha512-sSxcZfuUrtxcwV0vdjmGnZQcflACzMfLriVeIIWXKp8hzaS3Or3tO6EFQkTd3L8T5dTq+kTtLvPscXIpL0Wzdg==", + "dev": true, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/refs": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@solid-primitives/refs/-/refs-1.0.8.tgz", + "integrity": "sha512-+jIsWG8/nYvhaCoG2Vg6CJOLgTmPKFbaCrNQKWfChalgUf9WrVxWw0CdJb3yX15n5lUcQ0jBo6qYtuVVmBLpBw==", + "dev": true, + "dependencies": { + "@solid-primitives/utils": "^6.2.3" }, - "engines": { - "node": ">=5.10" + "peerDependencies": { + "solid-js": "^1.6.12" } }, - "node_modules/@solana/wallet-standard-features": { - "version": "1.2.0", - "license": "Apache-2.0", + "node_modules/@solid-primitives/resize-observer": { + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/@solid-primitives/resize-observer/-/resize-observer-2.0.26.tgz", + "integrity": "sha512-KbPhwal6ML9OHeUTZszBbt6PYSMj89d4wVCLxlvDYL4U0+p+xlCEaqz6v9dkCwm/0Lb+Wed7W5T1dQZCP3JUUw==", + "dev": true, "dependencies": { - "@wallet-standard/base": "^1.0.1", - "@wallet-standard/features": "^1.0.3" + "@solid-primitives/event-listener": "^2.3.3", + "@solid-primitives/rootless": "^1.4.5", + "@solid-primitives/static-store": "^0.0.8", + "@solid-primitives/utils": "^6.2.3" }, - "engines": { - "node": ">=16" + "peerDependencies": { + "solid-js": "^1.6.12" } }, - "node_modules/@solana/web3.js": { - "version": "1.95.4", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.95.4.tgz", - "integrity": "sha512-sdewnNEA42ZSMxqkzdwEWi6fDgzwtJHaQa5ndUGEJYtoOnM6X5cvPmjoTUp7/k7bRrVAxfBgDnvQQHD6yhlLYw==", - "license": "MIT", + "node_modules/@solid-primitives/resize-observer/node_modules/@solid-primitives/static-store": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@solid-primitives/static-store/-/static-store-0.0.8.tgz", + "integrity": "sha512-ZecE4BqY0oBk0YG00nzaAWO5Mjcny8Fc06CdbXadH9T9lzq/9GefqcSe/5AtdXqjvY/DtJ5C6CkcjPZO0o/eqg==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.25.0", - "@noble/curves": "^1.4.2", - "@noble/hashes": "^1.4.0", - "@solana/buffer-layout": "^4.0.1", - "agentkeepalive": "^4.5.0", - "bigint-buffer": "^1.1.5", - "bn.js": "^5.2.1", - "borsh": "^0.7.0", - "bs58": "^4.0.1", - "buffer": "6.0.3", - "fast-stable-stringify": "^1.0.0", - "jayson": "^4.1.1", - "node-fetch": "^2.7.0", - "rpc-websockets": "^9.0.2", - "superstruct": "^2.0.2" + "@solid-primitives/utils": "^6.2.3" + }, + "peerDependencies": { + "solid-js": "^1.6.12" } }, - "node_modules/@solana/web3.js/node_modules/bs58": { - "version": "4.0.1", - "license": "MIT", + "node_modules/@solid-primitives/rootless": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@solid-primitives/rootless/-/rootless-1.4.5.tgz", + "integrity": "sha512-GFJE9GC3ojx0aUKqAUZmQPyU8fOVMtnVNrkdk2yS4kd17WqVSpXpoTmo9CnOwA+PG7FTzdIkogvfLQSLs4lrww==", + "dev": true, "dependencies": { - "base-x": "^3.0.2" + "@solid-primitives/utils": "^6.2.3" + }, + "peerDependencies": { + "solid-js": "^1.6.12" } }, - "node_modules/@solana/web3.js/node_modules/node-fetch": { - "version": "2.7.0", - "license": "MIT", + "node_modules/@solid-primitives/scheduled": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@solid-primitives/scheduled/-/scheduled-1.4.4.tgz", + "integrity": "sha512-BTGdFP7t+s7RSak+s1u0eTix4lHP23MrbGkgQTFlt1E+4fmnD/bEx3ZfNW7Grylz3GXgKyXrgDKA7jQ/wuWKgA==", + "dev": true, + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/static-store": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@solid-primitives/static-store/-/static-store-0.0.5.tgz", + "integrity": "sha512-ssQ+s/wrlFAEE4Zw8GV499yBfvWx7SMm+ZVc11wvao4T5xg9VfXCL9Oa+x4h+vPMvSV/Knv5LrsLiUa+wlJUXQ==", + "dev": true, "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" + "@solid-primitives/utils": "^6.2.1" }, "peerDependencies": { - "encoding": "^0.1.0" + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/styles": { + "version": "0.0.111", + "resolved": "https://registry.npmjs.org/@solid-primitives/styles/-/styles-0.0.111.tgz", + "integrity": "sha512-1mBxOGAPXmfD5oYCvqjKBDN7SuNjz2qz7RdH7KtsuNLQh6lpuSKadtHnLvru0Y8Vz1InqTJisBIy/6P5kyDmPw==", + "dev": true, + "dependencies": { + "@solid-primitives/rootless": "^1.4.2", + "@solid-primitives/utils": "^6.2.1" }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "peerDependencies": { + "solid-js": "^1.6.12" + } + }, + "node_modules/@solid-primitives/utils": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/@solid-primitives/utils/-/utils-6.2.3.tgz", + "integrity": "sha512-CqAwKb2T5Vi72+rhebSsqNZ9o67buYRdEJrIFzRXz3U59QqezuuxPsyzTSVCacwS5Pf109VRsgCJQoxKRoECZQ==", + "dev": true, + "peerDependencies": { + "solid-js": "^1.6.12" } }, "node_modules/@stablelib/aead": { @@ -6051,6 +6667,47 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, "node_modules/@types/bn.js": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.6.tgz", @@ -7031,6 +7688,10 @@ "resolved": "packages/hooks/modal-react-hooks", "link": true }, + "node_modules/@web3auth/modal-ui": { + "resolved": "packages/modal-ui", + "link": true + }, "node_modules/@web3auth/modal-vue-composables": { "resolved": "packages/composables/modal-vue-composables", "link": true @@ -8240,6 +8901,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/babel-plugin-jsx-dom-expressions": { + "version": "0.39.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.39.3.tgz", + "integrity": "sha512-6RzmSu21zYPlV2gNwzjGG9FgODtt9hIWnx7L//OIioIEuRcnpDZoY8Tr+I81Cy1SrH4qoDyKpwHHo6uAMAeyPA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "7.18.6", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.20.7", + "html-entities": "2.3.3", + "parse5": "^7.1.2", + "validate-html-nesting": "^1.2.1" + }, + "peerDependencies": { + "@babel/core": "^7.20.12" + } + }, + "node_modules/babel-plugin-jsx-dom-expressions/node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.11", "dev": true, @@ -8276,6 +8966,18 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/babel-preset-solid": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/babel-preset-solid/-/babel-preset-solid-1.9.3.tgz", + "integrity": "sha512-jvlx5wDp8s+bEF9sGFw/84SInXOA51ttkUEroQziKMbxplXThVKt83qB6bDTa1HuLNatdU9FHpFOiQWs1tLQIg==", + "dev": true, + "dependencies": { + "babel-plugin-jsx-dom-expressions": "^0.39.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "dev": true, @@ -11456,6 +12158,44 @@ "es6-promise": "^4.0.3" } }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, "node_modules/escalade": { "version": "3.2.0", "dev": true, @@ -14084,6 +14824,12 @@ "dev": true, "license": "ISC" }, + "node_modules/html-entities": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", + "dev": true + }, "node_modules/html-escaper": { "version": "2.0.2", "dev": true, @@ -15265,6 +16011,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "dev": true, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/is-windows": { "version": "1.0.2", "dev": true, @@ -17746,6 +18504,21 @@ "node": ">=10" } }, + "node_modules/merge-anything": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-5.1.7.tgz", + "integrity": "sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==", + "dev": true, + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "license": "MIT" @@ -19756,6 +20529,18 @@ "parse-path": "^7.0.0" } }, + "node_modules/parse5": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "dev": true, + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "dev": true, @@ -23429,6 +24214,25 @@ "randombytes": "^2.1.0" } }, + "node_modules/seroval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.1.1.tgz", + "integrity": "sha512-rqEO6FZk8mv7Hyv4UCj3FD3b6Waqft605TLfsCe/BiaylRpyyMC0b+uA5TJKawX3KzMrdi3wsLbCaLplrQmBvQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/seroval-plugins": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.1.1.tgz", + "integrity": "sha512-qNSy1+nUj7hsCOon7AO4wdAIo9P0jrzAMp18XhiOzA6/uO5TKtP7ScozVJ8T293oRIvi5wyCHSM4TrJo/c/GJA==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "seroval": "^1.0" + } + }, "node_modules/serve-index": { "version": "1.9.1", "dev": true, @@ -23916,6 +24720,56 @@ "node": ">= 14" } }, + "node_modules/solid-devtools": { + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/solid-devtools/-/solid-devtools-0.29.3.tgz", + "integrity": "sha512-9j3VxVbEoC54ML22gAMytR8ZS1nk9xKatsWziKSkI4c/Bcyh4sxQBGESHuXSLs9xaxpyGVTmFl3hknoxEpKzlA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.3", + "@babel/plugin-syntax-typescript": "^7.23.3", + "@babel/types": "^7.23.3", + "@solid-devtools/debugger": "^0.23.3", + "@solid-devtools/shared": "^0.13.1" + }, + "peerDependencies": { + "solid-js": "^1.8.0", + "solid-start": "^0.3.0", + "vite": "^2.2.3 || ^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "solid-start": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/solid-js": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.3.tgz", + "integrity": "sha512-5ba3taPoZGt9GY3YlsCB24kCg0Lv/rie/HTD4kG6h4daZZz7+yK02xn8Vx8dLYBc9i6Ps5JwAbEiqjmKaLB3Ag==", + "dependencies": { + "csstype": "^3.1.0", + "seroval": "^1.1.0", + "seroval-plugins": "^1.1.0" + } + }, + "node_modules/solid-refresh": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/solid-refresh/-/solid-refresh-0.6.3.tgz", + "integrity": "sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==", + "dev": true, + "dependencies": { + "@babel/generator": "^7.23.6", + "@babel/helper-module-imports": "^7.22.15", + "@babel/types": "^7.23.6" + }, + "peerDependencies": { + "solid-js": "^1.3" + } + }, "node_modules/sonic-boom": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.8.0.tgz", @@ -24599,6 +25453,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/tailwind-merge": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.4.tgz", + "integrity": "sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { "version": "3.4.14", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", @@ -26013,6 +26876,12 @@ "dev": true, "license": "MIT" }, + "node_modules/validate-html-nesting": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/validate-html-nesting/-/validate-html-nesting-1.2.2.tgz", + "integrity": "sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==", + "dev": true + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "dev": true, @@ -26121,6 +26990,103 @@ } } }, + "node_modules/vite": { + "version": "5.4.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", + "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-plugin-solid": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/vite-plugin-solid/-/vite-plugin-solid-2.10.2.tgz", + "integrity": "sha512-AOEtwMe2baBSXMXdo+BUwECC8IFHcKS6WQV/1NEd+Q7vHPap5fmIhLcAzr+DUJ04/KHx/1UBU0l1/GWP+rMAPQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.3", + "@types/babel__core": "^7.20.4", + "babel-preset-solid": "^1.8.4", + "merge-anything": "^5.1.7", + "solid-refresh": "^0.6.3", + "vitefu": "^0.2.5" + }, + "peerDependencies": { + "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", + "solid-js": "^1.7.2", + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "@testing-library/jest-dom": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", + "dev": true, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, "node_modules/void-elements": { "version": "3.1.0", "license": "MIT", @@ -27511,6 +28477,38 @@ } } }, + "packages/modal-ui": { + "name": "@web3auth/modal-ui", + "version": "0.0.0", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1", + "solid-js": "^1.8.11" + }, + "devDependencies": { + "@babel/preset-react": "^7.25.9", + "@mertasan/tailwindcss-variables": "^2.7.0", + "autoprefixer": "^10.4.17", + "postcss": "^8.4.33", + "solid-devtools": "^0.29.2", + "tailwindcss": "^3.4.1", + "typescript": "^5.3.3", + "vite": "^5.0.11", + "vite-plugin-solid": "^2.8.2" + }, + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + } + }, + "packages/modal-ui/node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, "packages/no-modal": { "name": "@web3auth/no-modal", "version": "9.3.1", diff --git a/package.json b/package.json index 781d0c779..67ac92afb 100644 --- a/package.json +++ b/package.json @@ -79,9 +79,13 @@ "packages/composables/*", "packages/hooks/*", "packages/modal", + "packages/modal-ui", "packages/no-modal", "packages/plugins/*", "packages/providers/*", "packages/ui" - ] + ], + "dependencies": { + "tailwind-merge": "^2.5.4" + } } diff --git a/packages/modal-ui/.eslintrc.json b/packages/modal-ui/.eslintrc.json new file mode 100644 index 000000000..e924287c7 --- /dev/null +++ b/packages/modal-ui/.eslintrc.json @@ -0,0 +1,32 @@ +{ + "env": { + "browser": true, + "es2020": true, + "node": true + }, + "extends": [ + "@toruslabs/eslint-config-react" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 11, + "project": "./tsconfig.json", + "sourceType": "module" + }, + "root": true, + "rules": { + "@typescript-eslint/no-throw-literal": 0, + "import/extensions": [ + { + "js": "never", + "jsx": "never", + "ts": "never", + "tsx": "never" + }, + "error", + "ignorePackages" + ], + "no-console": 2, + "react/no-is-mounted": 0 + } +} diff --git a/packages/modal-ui/.gitignore b/packages/modal-ui/.gitignore new file mode 100644 index 000000000..76add878f --- /dev/null +++ b/packages/modal-ui/.gitignore @@ -0,0 +1,2 @@ +node_modules +dist \ No newline at end of file diff --git a/packages/modal-ui/README.md b/packages/modal-ui/README.md new file mode 100644 index 000000000..6a1764536 --- /dev/null +++ b/packages/modal-ui/README.md @@ -0,0 +1,34 @@ +## Usage + +Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`. + +This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely be removed once you clone a template. + +```bash +$ npm install # or pnpm install or yarn install +``` + +### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs) + +## Available Scripts + +In the project directory, you can run: + +### `npm run dev` or `npm start` + +Runs the app in the development mode.
+Open [http://localhost:3000](http://localhost:3000) to view it in the browser. + +The page will reload if you make edits.
+ +### `npm run build` + +Builds the app for production to the `dist` folder.
+It correctly bundles Solid in production mode and optimizes the build for the best performance. + +The build is minified and the filenames include the hashes.
+Your app is ready to be deployed! + +## Deployment + +You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.) diff --git a/packages/modal-ui/index.html b/packages/modal-ui/index.html new file mode 100644 index 000000000..3386e2b40 --- /dev/null +++ b/packages/modal-ui/index.html @@ -0,0 +1,15 @@ + + + + + + + Web3auth Modal UI + + + +
+ + + + diff --git a/packages/modal-ui/package.json b/packages/modal-ui/package.json new file mode 100644 index 000000000..fc8c2b194 --- /dev/null +++ b/packages/modal-ui/package.json @@ -0,0 +1,49 @@ +{ + "bugs": { + "url": "https://github.com/Web3Auth/Web3Auth/issues" + }, + "dependencies": { + "clsx": "^2.1.1", + "solid-js": "^1.8.11" + }, + "description": "Ui modal for web3Auth", + "devDependencies": { + "@babel/preset-react": "^7.25.9", + "@mertasan/tailwindcss-variables": "^2.7.0", + "autoprefixer": "^10.4.17", + "postcss": "^8.4.33", + "solid-devtools": "^0.29.2", + "tailwindcss": "^3.4.1", + "typescript": "^5.3.3", + "vite": "^5.0.11", + "vite-plugin-solid": "^2.8.2" + }, + "engines": { + "node": ">=18.x", + "npm": ">=9.x" + }, + "keywords": [ + "blockchain", + "ethereum", + "multichainWallet", + "solana", + "web3Auth", + "web3Auth/ui" + ], + "license": "MIT", + "name": "@web3auth/modal-ui", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Web3Auth/Web3Auth.git" + }, + "scripts": { + "build": "vite build", + "dev": "vite", + "serve": "vite preview", + "start": "vite" + }, + "version": "0.0.0" +} diff --git a/packages/modal-ui/postcss.config.js b/packages/modal-ui/postcss.config.js new file mode 100644 index 000000000..f5174a67c --- /dev/null +++ b/packages/modal-ui/postcss.config.js @@ -0,0 +1,19 @@ +const prefix = ".w3a-parent-container"; + +module.exports = { + purge: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"], + plugins: { + tailwindcss: {}, + "postcss-prefix-selector": { + prefix, + transform(_, selector, prefixedSelector) { + // if selector is already the prefix just return it + // e.g. in the case of css vars that we put under prefix + if (selector === prefix) { + return selector; + } + return prefixedSelector; + }, + }, + }, +}; diff --git a/packages/modal-ui/src/App.tsx b/packages/modal-ui/src/App.tsx new file mode 100644 index 000000000..e22270550 --- /dev/null +++ b/packages/modal-ui/src/App.tsx @@ -0,0 +1,18 @@ +import { createSignal, type Component } from "solid-js"; +import { Modal } from "./components/Modal"; +import { Body } from "./components/Body"; + +const App: Component = () => { + const [open, setOpen] = createSignal(false); + return ( +
+

Try out your new modal

+ + setOpen(false)} placement="center" padding={false} showCloseIcon> + + +
+ ); +}; + +export default App; diff --git a/packages/modal-ui/src/components/Body/Body.tsx b/packages/modal-ui/src/components/Body/Body.tsx new file mode 100644 index 000000000..5253e9784 --- /dev/null +++ b/packages/modal-ui/src/components/Body/Body.tsx @@ -0,0 +1,38 @@ +import { createEffect, createSignal, on } from "solid-js"; +import Footer from "../Footer/Footer"; +import ConnectWallet from "./ConnectWallet"; +import Login from "./Login"; +import { SocialLoginEventType, ExternalWalletEventType, StateEmitterEvents, ModalState, MODAL_STATUS } from "../../interfaces"; +import { LOGIN_PROVIDER, type SafeEventEmitter } from "@web3auth/auth"; +import { ADAPTER_NAMES, ChainNamespaceType, cloneDeep, log, WalletRegistry } from "@web3auth/base"; +import deepmerge from "deepmerge"; +// import { on } from "events"; +export interface BodyProps { + stateListener: SafeEventEmitter; + appLogo?: string; + appName?: string; + chainNamespace: ChainNamespaceType; + walletRegistry?: WalletRegistry; + handleSocialLoginClick: (params: SocialLoginEventType) => void; + handleExternalWalletClick: (params: ExternalWalletEventType) => void; + handleShowExternalWallets: (externalWalletsInitialized: boolean) => void; +} + +const PAGES = { + LOGIN: 'login', + CONNECT_WALLET: 'connect_wallet' +} + +const Body = (props: BodyProps) => { + const [currentPage, setCurrentPage] = createSignal(PAGES.LOGIN); + + return ( +
+ {currentPage() === PAGES.LOGIN && setCurrentPage(PAGES.CONNECT_WALLET)} />} + {currentPage() === PAGES.CONNECT_WALLET && setCurrentPage(PAGES.LOGIN)} />} +
+
+ ); +}; + +export default Body \ No newline at end of file diff --git a/packages/modal-ui/src/components/Body/ConnectWallet.tsx b/packages/modal-ui/src/components/Body/ConnectWallet.tsx new file mode 100644 index 000000000..6cfe04dde --- /dev/null +++ b/packages/modal-ui/src/components/Body/ConnectWallet.tsx @@ -0,0 +1,78 @@ +import { createSignal, For } from "solid-js" +import { WalletButton } from "../WalletButton" + +export interface ConnectWalletProps { + onBackClick?: () => void +}; + +const WALLET_LIST = ['Metamask', 'Ronin Wallet', 'Phantom', 'Rainbow', 'Trust Wallet', 'Coinbase Wallet', 'Uniswap', 'Metamask', 'Ronin Wallet', 'Phantom', 'Rainbow', 'Trust Wallet', 'Coinbase Wallet', 'Uniswap', 'Metamask', 'Ronin Wallet', 'Phantom', 'Rainbow', 'Trust Wallet', 'Coinbase Wallet', 'Uniswap'] + + +const PAGES = { + CONNECT_WALLET: 'Connect Wallet', + SELECTED_WALLET: "Selected Wallet" +} + +const ConnectWallet = ({ onBackClick }: ConnectWalletProps) => { + + const [currentPage, setCurrentPage] = createSignal(PAGES.CONNECT_WALLET); + const [selectedWallet, setSelectedWallet] = createSignal(false); + + const handleBack = () => { + if (!selectedWallet() && currentPage() === PAGES.CONNECT_WALLET && onBackClick) { + onBackClick() + } + + if (selectedWallet) { + setCurrentPage(PAGES.CONNECT_WALLET) + setSelectedWallet(false) + } + } + + return ( +
+
+
+

{currentPage()}

+
+
+ + {!selectedWallet() ?
+ +
    + + {(wallet) => + { setSelectedWallet(true); setCurrentPage(PAGES.SELECTED_WALLET) }} /> + } + +
+
: +
+
+

Scan with a WalletConnect-supported wallet or click the QR code to copy to your clipboard.

+
+

Don't have Trust Wallet?

+ +
+
+ } + + {/*
+
+
+

Install Chrome

+
+
+
+

Install Chrome

+
+
+
+

Install Chrome

+
+
*/} +
+ ) +} + +export default ConnectWallet \ No newline at end of file diff --git a/packages/modal-ui/src/components/Body/Login.tsx b/packages/modal-ui/src/components/Body/Login.tsx new file mode 100644 index 000000000..67fe94b18 --- /dev/null +++ b/packages/modal-ui/src/components/Body/Login.tsx @@ -0,0 +1,38 @@ +import SocialLoginList from "../SocialLoginList"; + +export interface LoginProps { + onExternalWalletClick?: () => void; +}; + +const Login = ({ onExternalWalletClick }: LoginProps) => { + + const handleConnectWallet = (e: MouseEvent) => { + e.preventDefault(); + if (onExternalWalletClick) onExternalWalletClick() + } + return ( +
+
+

Sign in

+

Your Web3Auth wallet with one click

+
+ + + + +
+
+ + +
+ +
+ + +
+
+
+ ) +} + +export default Login; \ No newline at end of file diff --git a/packages/modal-ui/src/components/Body/index.ts b/packages/modal-ui/src/components/Body/index.ts new file mode 100644 index 000000000..15b1fb2bb --- /dev/null +++ b/packages/modal-ui/src/components/Body/index.ts @@ -0,0 +1 @@ +export { default as Body } from "./Body"; diff --git a/packages/modal-ui/src/components/Footer/Footer.tsx b/packages/modal-ui/src/components/Footer/Footer.tsx new file mode 100644 index 000000000..664e593f1 --- /dev/null +++ b/packages/modal-ui/src/components/Footer/Footer.tsx @@ -0,0 +1,21 @@ +const Footer = () => { + return ( +
+
{"modal.footer.message-new"}
+ Web3Auth Logo Light + Web3Auth Logo Dark +
+ ) +} + +export default Footer \ No newline at end of file diff --git a/packages/modal-ui/src/components/Footer/index.ts b/packages/modal-ui/src/components/Footer/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/modal-ui/src/components/LoginModal/LoginModal.tsx b/packages/modal-ui/src/components/LoginModal/LoginModal.tsx new file mode 100644 index 000000000..c556801bd --- /dev/null +++ b/packages/modal-ui/src/components/LoginModal/LoginModal.tsx @@ -0,0 +1,87 @@ +import { ChainNamespaceType, cloneDeep, log, WalletRegistry } from "@web3auth/base"; +import { StateEmitterEvents, SocialLoginEventType, ExternalWalletEventType, ModalState, MODAL_STATUS } from "../../interfaces"; +import { Body } from "../Body"; +import { Modal } from "../Modal"; +import { type SafeEventEmitter } from "@web3auth/auth"; +import { createSignal, createEffect, on, createMemo } from "solid-js"; +import deepmerge from "deepmerge"; + +export interface LoginModalProps { + stateListener: SafeEventEmitter; + appLogo?: string; + appName?: string; + chainNamespace: ChainNamespaceType; + walletRegistry?: WalletRegistry; + handleSocialLoginClick: (params: SocialLoginEventType) => void; + handleExternalWalletClick: (params: ExternalWalletEventType) => void; + handleShowExternalWallets: (externalWalletsInitialized: boolean) => void; + closeModal: () => void; +} + +const LoginModal = (props: LoginModalProps) => { + + const [modalState, setModalState] = createSignal({ + externalWalletsVisibility: false, + status: MODAL_STATUS.INITIALIZED, + hasExternalWallets: false, + externalWalletsInitialized: false, + modalVisibility: false, + modalVisibilityDelayed: false, + postLoadingMessage: "", + walletConnectUri: "", + socialLoginsConfig: { + loginMethods: {}, + loginMethodsOrder: [], + adapter: "", + uiConfig: {}, + }, + externalWalletsConfig: {}, + detailedLoaderAdapter: "", + detailedLoaderAdapterName: "", + showExternalWalletsOnly: false, + }); + + createEffect(on(() => props.stateListener, + () => { + props.stateListener.emit("MOUNTED"); + props.stateListener.on("STATE_UPDATED", (newModalState: Partial) => { + log.debug("state updated", newModalState); + setModalState((prevState) => { + const mergedState = cloneDeep(deepmerge(prevState, newModalState)); + return mergedState; + }); + }); + } + )) + + const preHandleExternalWalletClick = createMemo( + (params: ExternalWalletEventType) => { + const { adapter } = params; + setModalState((prevState) => { + return { ...prevState, detailedLoaderAdapter: adapter, detailedLoaderAdapterName: ADAPTER_NAMES[adapter] }; + }); + props.handleExternalWalletClick(params); + }, + props.handleExternalWalletClick + ); + + const preHandleSocialWalletClick = (params: SocialLoginEventType) => { + const { loginParams } = params; + setModalState((prevState) => { + return { ...prevState, detailedLoaderAdapter: loginParams.loginProvider, detailedLoaderAdapterName: loginParams.name }; + }); + props.handleSocialLoginClick(params); + }; + + const isEmailPrimary = modalState().socialLoginsConfig?.uiConfig?.primaryButton === "emailLogin"; + const isExternalPrimary = modalState().socialLoginsConfig?.uiConfig?.primaryButton === "externalLogin"; + + + return ( + + + + ) +}; + +export default LoginModal; \ No newline at end of file diff --git a/packages/modal-ui/src/components/LoginModal/index.ts b/packages/modal-ui/src/components/LoginModal/index.ts new file mode 100644 index 000000000..ab0f10695 --- /dev/null +++ b/packages/modal-ui/src/components/LoginModal/index.ts @@ -0,0 +1 @@ +export { default as LoginModal } from "./LoginModal"; diff --git a/packages/modal-ui/src/components/Modal/Modal.tsx b/packages/modal-ui/src/components/Modal/Modal.tsx new file mode 100644 index 000000000..1b953d7e5 --- /dev/null +++ b/packages/modal-ui/src/components/Modal/Modal.tsx @@ -0,0 +1,78 @@ +import { Component, JSX, createSignal, createEffect, mergeProps } from "solid-js"; +import { cn } from "../../utils/common"; + +export interface ModalProps { + children: JSX.Element[] | JSX.Element; + open: boolean; + onClose?: () => void; + placement?: 'center' | 'top-center' | 'bottom-center' | 'left' | 'right'; + padding?: boolean; + shadow?: boolean; + border?: boolean; + showCloseIcon?: boolean; +} + +const Modal: Component = (props: ModalProps) => { + + const mergedProps = mergeProps({ open: false, padding: true, placement: 'center', shadow: true, border: true, showCloseIcon: false }, props as ModalProps); + + const [isOpen, setIsOpen] = createSignal(false); + + createEffect(() => { + if (mergedProps.open) { + document.body.style.overflow = "hidden"; + // Give a very small delay for the animation to start from the correct position + setTimeout(() => { + setIsOpen(true); + }, 50); + } else { + setIsOpen(false); + // Remove overflow styling to enable scroll again. + document.body.style.overflow = ""; + } + }, false); + + + const onCloseHandler = () => { + if (mergedProps.onClose) mergedProps.onClose() + }; + + const positions: Record = { + 'center': 'w3a--top-0 w3a--left-0 w3a--items-center w3a--justify-center', + 'top-center': 'w3a--top-8 w3a--left-0 w3a--items-start w3a--justify-center', + 'bottom-center': 'w3a--bottom-8 w3a--left-0 w3a--items-end w3a--justify-center', + 'left': 'sm:w3a--left-8 w3a--flex w3a--items-center w3a--justify-center sm:w3a--justify-start', + 'right': 'sm:w3a--right-8 w3a--flex w3a--items-center w3a--justify-center sm:w3a--justify-end', + }; + + const placementClass = positions[mergedProps.placement as string] + + return ( +
+
+ {mergedProps.showCloseIcon &&
+ + + +
} + {mergedProps.children} +
+
+ + ); +}; + +export default Modal; diff --git a/packages/modal-ui/src/components/Modal/index.ts b/packages/modal-ui/src/components/Modal/index.ts new file mode 100644 index 000000000..38a0f4495 --- /dev/null +++ b/packages/modal-ui/src/components/Modal/index.ts @@ -0,0 +1 @@ +export { default as Modal } from "./Modal"; diff --git a/packages/modal-ui/src/components/SocialLoginButton/SocialLoginButton.tsx b/packages/modal-ui/src/components/SocialLoginButton/SocialLoginButton.tsx new file mode 100644 index 000000000..de27c1423 --- /dev/null +++ b/packages/modal-ui/src/components/SocialLoginButton/SocialLoginButton.tsx @@ -0,0 +1,15 @@ +export interface SocialLoginButtonProps { + showIcon?: boolean; + showText?: boolean; +} + +const SocialLoginButton = ({ showIcon = true, showText = true }: SocialLoginButtonProps) => { + return ( + + ); +}; + +export default SocialLoginButton; \ No newline at end of file diff --git a/packages/modal-ui/src/components/SocialLoginButton/index.ts b/packages/modal-ui/src/components/SocialLoginButton/index.ts new file mode 100644 index 000000000..ff8830f78 --- /dev/null +++ b/packages/modal-ui/src/components/SocialLoginButton/index.ts @@ -0,0 +1 @@ +export { default as SocialLoginButton } from "./SocialLoginButton"; diff --git a/packages/modal-ui/src/components/SocialLoginList/SocialLoginList.tsx b/packages/modal-ui/src/components/SocialLoginList/SocialLoginList.tsx new file mode 100644 index 000000000..9e4684b2d --- /dev/null +++ b/packages/modal-ui/src/components/SocialLoginList/SocialLoginList.tsx @@ -0,0 +1,45 @@ +import { createSignal, For } from "solid-js" +import { SocialLoginButton } from "../SocialLoginButton" +import { cn } from "../../utils/common"; + + +const SocialLoginList = () => { + + const loginMethods = () => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; + + const firstRow = loginMethods().slice(0, 3); + const otherRow = loginMethods().slice(3); + + const [expand, setExpand] = createSignal(false) + + const handleExpand = () => { + setExpand((prev) => !prev) + } + + return ( + +
+ +
+ + {(_) => + + } + +
+ {/* 224px */} +
+ + {(_) => + + } + +
+

We do not store any data related to your social logins.

+ +
+ ) +} + +export default SocialLoginList \ No newline at end of file diff --git a/packages/modal-ui/src/components/SocialLoginList/index.ts b/packages/modal-ui/src/components/SocialLoginList/index.ts new file mode 100644 index 000000000..25f8a9c2c --- /dev/null +++ b/packages/modal-ui/src/components/SocialLoginList/index.ts @@ -0,0 +1 @@ +export { default } from "./SocialLoginList"; diff --git a/packages/modal-ui/src/components/WalletButton/WalletButton.tsx b/packages/modal-ui/src/components/WalletButton/WalletButton.tsx new file mode 100644 index 000000000..c8f7f0054 --- /dev/null +++ b/packages/modal-ui/src/components/WalletButton/WalletButton.tsx @@ -0,0 +1,19 @@ +export interface WalletButtonProps { + label: string; + onClick?: () => void +}; + +const WalletButton = ({ label, ...props }: WalletButtonProps) => { + return ( + + ) +} + +export default WalletButton \ No newline at end of file diff --git a/packages/modal-ui/src/components/WalletButton/index.ts b/packages/modal-ui/src/components/WalletButton/index.ts new file mode 100644 index 000000000..8d8ae3fd9 --- /dev/null +++ b/packages/modal-ui/src/components/WalletButton/index.ts @@ -0,0 +1 @@ +export { default as WalletButton } from "./WalletButton"; diff --git a/packages/modal-ui/src/config.ts b/packages/modal-ui/src/config.ts new file mode 100644 index 000000000..6f6ca8f03 --- /dev/null +++ b/packages/modal-ui/src/config.ts @@ -0,0 +1,23 @@ +import { LOGIN_PROVIDER, LOGIN_PROVIDER_TYPE } from "@web3auth/auth"; + +export function capitalizeFirstLetter(string: string): string { + return string.charAt(0).toUpperCase() + string.slice(1); +} + +const restrictedLoginMethods: Set = new Set([ + LOGIN_PROVIDER.AUTHENTICATOR, + LOGIN_PROVIDER.PASSKEYS, + LOGIN_PROVIDER.JWT, + LOGIN_PROVIDER.WEBAUTHN, +]); +export const AUTH_PROVIDERS = Object.values(LOGIN_PROVIDER).filter((x) => !restrictedLoginMethods.has(x)); + +export const AUTH_PROVIDERS_NAMES = AUTH_PROVIDERS.reduce( + (acc, x) => { + if (x === "email_passwordless") acc[x] = "Email"; + else if (x === "sms_passwordless") acc[x] = "Mobile"; + else acc[x] = capitalizeFirstLetter(x); + return acc; + }, + {} as Record +); diff --git a/packages/modal-ui/src/global.d.ts b/packages/modal-ui/src/global.d.ts new file mode 100644 index 000000000..c2a312aa2 --- /dev/null +++ b/packages/modal-ui/src/global.d.ts @@ -0,0 +1,2 @@ +declare module "*.module.css"; +declare module "*.svg"; diff --git a/packages/modal-ui/src/i18n/dutch.json b/packages/modal-ui/src/i18n/dutch.json new file mode 100644 index 000000000..3507a0938 --- /dev/null +++ b/packages/modal-ui/src/i18n/dutch.json @@ -0,0 +1,76 @@ +{ + "modal": { + "adapter-loader.message": "Verifieer uw {{adapter}}-account om door te gaan", + "adapter-loader.message1": "Verifieer uw {{adapter}}", + "adapter-loader.message2": "account om door te gaan", + "errors-invalid-email": "Ongeldig e-mailadres", + "errors-invalid-number": "Ongeldig telefoonnummer", + "errors-invalid-number-email": "Ongeldig e-mailadres of telefoonnummer", + "errors-required": "Vereist", + "external.back": "Terug", + "external.connect": "Ga verder met een portemonnee", + "external.search-text": "Ziet u uw portemonnee niet?", + "external.search-subtext": "Probeer in plaats daarvan te zoeken", + "external.connect-wallet": "Verbinden met portemonnee", + "external.continue": "Ga verder met externe portemonnee", + "external.dont-have": "Heb niet", + "external.get": "Krijgen", + "external.get-wallet": "Portemonnee krijgen", + "external.install-browser-extension": "{{browser}}-extensie installeren", + "external.install-mobile-app": "Installeer {{os}}-app", + "external.installed": "Geïnstalleerd", + "external.no-wallets-found": "Geen portefeuilles gevonden", + "external.search-wallet": "Zoeken door {{count}} portemonnees...", + "external.title": "Externe portemonnee", + "external.walletconnect-connect": "Verbinden", + "external.walletconnect-copy": "Scan met een WalletConnect-ondersteunde portemonnee of klik op de QR-code om naar uw klembord te kopiëren.", + "external.walletconnect-subtitle": "Scan de QR-code met een WalletConnect-compatibele portemonnee", + "footer.message": "Zelfbeheerde login door", + "footer.message-new": "Zelfkusten via", + "footer.policy": "Privacybeleid", + "footer.terms": "Gebruiksvoorwaarden", + "footer.terms-service": "Gebruiksvoorwaarden", + "footer.version": "Versie", + "header-subtitle": "Selecteer een van de volgende opties om door te gaan", + "header-subtitle-name": "Uw {{appName}}-portemonnee met één klik", + "header-subtitle-new": "Uw blockchain-portemonnee met één klik", + "header-title": "Aanmelden", + "header-tooltip-desc": "De portemonnee dient als een account om uw digitale activa op de blockchain op te slaan en te beheren.", + "header-tooltip-title": "Portemonnee", + "network.add-request": "Deze site vraagt om een netwerk toe te voegen", + "network.cancel": "Annuleren", + "network.from": "Van", + "network.proceed": "Doorgaan", + "network.switch-request": "Deze site vraagt om over te schakelen naar een ander netwerk", + "network.to": "Naar", + "passkey.add": "Passkey toevoegen", + "passkey.haveExisting": "Heeft u een bestaande passkey?", + "passkey.learn-more": "Kom meer te weten", + "passkey.or": "of", + "passkey.register-desc": "Met passkeys kunt u uw identiteit verifiëren via uw gezicht, vingerafdruk of beveiligingssleutels.", + "passkey.register-title": "Registreer Passkey", + "passkey.use": "Ik heb een passkey", + "popup.phone-body": "Uw landcode wordt automatisch gedetecteerd, maar als u een telefoonnummer uit een ander land gebruikt, moet u handmatig de juiste landcode invoeren.", + "popup.phone-header": "Telefoonnummer en landcode", + "post-loading.connected": "U bent verbonden met uw account", + "post-loading.something-wrong": "Er is iets fout gegaan!", + "social.continue": "Doorgaan met", + "social.continueCustom": "Doorgaan met {{adapter}}", + "social.email": "E-mail", + "social.email-continue": "Doorgaan met e-mail", + "social.email-new": "naam@voorbeeld.com", + "social.passwordless-cta": "Doorgaan", + "social.passwordless-login": "Log in", + "social.passwordless-title": "E-mail of telefoon", + "social.phone": "Telefoon", + "social.policy": "We slaan geen gegevens op die verband houden met uw sociale logins.", + "social.sms": "Mobiel", + "social.sms-continue": "Doorgaan met mobiel", + "social.sms-invalid-number": "Ongeldig telefoonnummer", + "social.sms-placeholder-text": "Bijv.:", + "social.view-less": "Minder bekijken", + "social.view-less-socials": "Bekijk minder socials", + "social.view-more": "Meer bekijken", + "social.view-more-socials": "Bekijk meer socials" + } +} \ No newline at end of file diff --git a/packages/modal-ui/src/i18n/english.json b/packages/modal-ui/src/i18n/english.json new file mode 100644 index 000000000..3b4109142 --- /dev/null +++ b/packages/modal-ui/src/i18n/english.json @@ -0,0 +1,76 @@ +{ + "modal": { + "adapter-loader.message": "Verify your {{adapter}} account to continue", + "adapter-loader.message1": "Verify your {{adapter}}", + "adapter-loader.message2": "account to continue", + "errors-invalid-email": "Invalid Email", + "errors-invalid-number": "Invalid Phone Number", + "errors-invalid-number-email": "Invalid Email or Phone Number", + "errors-required": "Required", + "external.back": "Back", + "external.connect": "Continue with a wallet", + "external.search-text": "Don't see your wallet?", + "external.search-subtext": "Try search instead", + "external.connect-wallet": "Connect Wallet", + "external.continue": "Continue with external wallet", + "external.dont-have": "Don't have", + "external.get": "Get", + "external.get-wallet": "Get Wallet", + "external.install-browser-extension": "Install {{browser}} extension", + "external.install-mobile-app": "Install {{os}} app", + "external.installed": "Installed", + "external.no-wallets-found": "No wallets found", + "external.search-wallet": "Search through {{count}} wallets...", + "external.title": "External Wallet", + "external.walletconnect-connect": "Connect", + "external.walletconnect-copy": "Scan with a WalletConnect-supported wallet or click the QR code to copy to your clipboard.", + "external.walletconnect-subtitle": "Scan the QR code with a WalletConnect-compatible wallet", + "footer.message": "Self-custodial login by", + "footer.message-new": "Self-custody via", + "footer.policy": "Privacy Policy", + "footer.terms": "Terms of Use", + "footer.terms-service": "Terms of Service", + "footer.version": "Version", + "header-subtitle": "Select one of the following options to continue", + "header-subtitle-name": "Your {{appName}} wallet with one click", + "header-subtitle-new": "Your blockchain wallet with one click", + "header-title": "Sign in", + "header-tooltip-desc": "The wallet serves as an account to store and manage your digital assets on the blockchain.", + "header-tooltip-title": "Wallet", + "network.add-request": "This site is requesting to add a network", + "network.cancel": "Cancel", + "network.from": "From", + "network.proceed": "Proceed", + "network.switch-request": "This site is requesting to switch networks", + "network.to": "To", + "passkey.add": "Add Passkey", + "passkey.haveExisting": "Have an existing passkey?", + "passkey.learn-more": "Learn more", + "passkey.or": "or", + "passkey.register-desc": "With passkeys, you can verify your identity through your face, fingerprint, or security keys.", + "passkey.register-title": "Register Passkey", + "passkey.use": "I have a passkey", + "popup.phone-body": "Your country code will be detected automatically, but if you're using a phone number from a different country, you'll need to enter the correct country code manually.", + "popup.phone-header": "Phone number and country code", + "post-loading.connected": "You are connected with your account", + "post-loading.something-wrong": "Something went wrong!", + "social.continue": "Continue with", + "social.continueCustom": "Continue with {{adapter}}", + "social.email": "Email", + "social.email-continue": "Continue with Email", + "social.email-new": "name@example.com", + "social.passwordless-cta": "Continue", + "social.passwordless-login": "Login", + "social.passwordless-title": "Email or Phone", + "social.phone": "Phone", + "social.policy": "We do not store any data related to your social logins.", + "social.sms": "Mobile", + "social.sms-continue": "Continue with Mobile", + "social.sms-invalid-number": "Invalid phone number", + "social.sms-placeholder-text": "E.g.:", + "social.view-less": "View less", + "social.view-less-socials": "View less socials", + "social.view-more": "View more", + "social.view-more-socials": "View more socials" + } +} \ No newline at end of file diff --git a/packages/modal-ui/src/i18n/french.json b/packages/modal-ui/src/i18n/french.json new file mode 100644 index 000000000..20621f276 --- /dev/null +++ b/packages/modal-ui/src/i18n/french.json @@ -0,0 +1,74 @@ +{ + "modal": { + "adapter-loader.message": "Vérifiez votre compte {{adapter}} pour continuer", + "adapter-loader.message1": "Vérifiez votre {{adapter}}", + "adapter-loader.message2": "compte pour continuer", + "errors-invalid-email": "E-mail invalide", + "errors-invalid-number": "Numéro de téléphone invalide", + "errors-invalid-number-email": "Adresse e-mail ou numéro de téléphone invalide", + "errors-required": "Champ obligatoire", + "external.back": "Retour", + "external.connect": "Continuer avec un portefeuille", + "external.search-text": "Vous ne voyez pas votre portefeuille ?", + "external.search-subtext": "Essayez plutôt de rechercher", + "external.connect-wallet": "Connecter le portefeuille", + "external.continue": "Continuer avec le portefeuille externe", + "external.dont-have": "N'avez pas", + "external.get": "Obtenir", + "external.get-wallet": "Obtenir un portefeuille", + "external.installed": "Installé", + "external.no-wallets-found": "Aucun portefeuille trouvé", + "external.search-wallet": "Rechercher parmi {{count}} portefeuilles...", + "external.title": "Portefeuille externe", + "external.walletconnect-connect": "Se connecter", + "external.walletconnect-copy": "Scannez avec un portefeuille pris en charge par WalletConnect ou cliquez sur le code QR pour le copier dans votre presse-papiers.", + "external.walletconnect-subtitle": "Scannez le code QR avec un portefeuille compatible WalletConnect", + "footer.message": "Connexion en autonomie par", + "footer.message-new": "Auto-cuir via", + "footer.policy": "Politique de confidentialité", + "footer.terms": "Conditions d'utilisation", + "footer.terms-service": "Conditions d'utilisation", + "footer.version": "Version", + "header-subtitle": "Sélectionnez l'une des options suivantes pour continuer", + "header-subtitle-name": "Votre portefeuille {{appName}} en un clic", + "header-subtitle-new": "Votre portefeuille blockchain en un clic", + "header-title": "Se connecter", + "header-tooltip-desc": "Le portefeuille sert de compte pour stocker et gérer vos actifs numériques sur la blockchain.", + "header-tooltip-title": "Portefeuille", + "network.add-request": "Ce site demande d'ajouter un réseau", + "network.cancel": "Annuler", + "network.from": "De", + "network.proceed": "Continuer", + "network.switch-request": "Ce site demande de changer de réseau", + "network.to": "À", + "passkey.add": "Ajouter Passkey", + "passkey.haveExisting": "Vous disposez déjà d'un passkey ?", + "passkey.learn-more": "Apprendre encore plus", + "passkey.or": "ou", + "passkey.register-desc": "Avec passkeys, vous pouvez vérifier votre identité grâce à votre visage, vos empreintes digitales ou vos clés de sécurité.", + "passkey.register-title": "Inscrivez-vous Passkey", + "passkey.use": "J'ai un passkey", + "popup.phone-body": "Votre code pays sera détecté automatiquement, mais si vous utilisez un numéro de téléphone d'un autre pays, vous devrez saisir manuellement le bon code pays.", + "popup.phone-header": "Numéro de téléphone et code pays", + "post-loading.connected": "Vous êtes connecté avec votre compte", + "post-loading.something-wrong": "Quelque chose s'est mal passé!", + "social.continue": "Continuer avec", + "social.continueCustom": "Continuer avec {{adapter}}", + "social.email": "Email", + "social.email-continue": "Continuer avec l'email", + "social.email-new": "nom@exemple.com", + "social.passwordless-cta": "Continuer", + "social.passwordless-login": "Se connecter", + "social.passwordless-title": "Email ou téléphone", + "social.phone": "Téléphone", + "social.policy": "Nous ne stockons aucune donnée liée à vos connexions sociales.", + "social.sms": "Mobile", + "social.sms-continue": "Continuer avec le mobile", + "social.sms-invalid-number": "Numéro de téléphone invalide", + "social.sms-placeholder-text": "Par exemple :", + "social.view-less": "Voir moins", + "social.view-less-socials": "Voir moins socials", + "social.view-more": "Voir plus", + "social.view-more-socials": "Voir plus socials" + } +} \ No newline at end of file diff --git a/packages/modal-ui/src/i18n/german.json b/packages/modal-ui/src/i18n/german.json new file mode 100644 index 000000000..90e171516 --- /dev/null +++ b/packages/modal-ui/src/i18n/german.json @@ -0,0 +1,76 @@ +{ + "modal": { + "adapter-loader.message": "Bestätigen Sie Ihr {{adapter}}-Konto, um fortzufahren", + "adapter-loader.message1": "Bestätigen Sie Ihr {{adapter}}", + "adapter-loader.message2": "Konto fortzusetzen", + "errors-invalid-email": "Ungültige E-Mail", + "errors-invalid-number": "Ungültige Telefonnummer", + "errors-invalid-number-email": "Ungültige E-Mail-Adresse oder Telefonnummer", + "errors-required": "Erforderlich", + "external.back": "Zurück", + "external.connect": "Fahren Sie mit einer Brieftasche fort", + "external.search-text": "Sie sehen Ihr Portemonnaie nicht?", + "external.search-subtext": "Versuchen Sie es stattdessen mit der Suche", + "external.connect-wallet": "Wallet verbinden", + "external.continue": "Fahren Sie mit der externen Wallet fort", + "external.dont-have": "Haben nicht", + "external.get": "Erhalten", + "external.get-wallet": "Wallet erhalten", + "external.install-browser-extension": "Installieren Sie die {{browser}}-Erweiterung", + "external.install-mobile-app": "Installieren Sie die {{os}}-App", + "external.installed": "Installiert", + "external.no-wallets-found": "Keine Wallets gefunden", + "external.search-wallet": "Suche durch {{count}} Geldbörsen...", + "external.title": "Externe Geldbörse", + "external.walletconnect-connect": "Verbinden", + "external.walletconnect-copy": "Scannen Sie mit einem von WalletConnect unterstützten Wallet oder klicken Sie auf den QR-Code, um ihn in Ihre Zwischenablage zu kopieren.", + "external.walletconnect-subtitle": "Scannen Sie den QR-Code mit einer WalletConnect-kompatiblen Geldbörse", + "footer.message": "Selbstverwahrungs-Login durch", + "footer.message-new": "Selbstversorgung über", + "footer.policy": "Datenschutzrichtlinie", + "footer.terms": "Nutzungsbedingungen", + "footer.terms-service": "Nutzungsbedingungen", + "footer.version": "Versión", + "header-subtitle": "Wählen Sie eine der folgenden Optionen aus, um fortzufahren", + "header-subtitle-name": "Ihre {{appName}}-Brieftasche mit einem Klick", + "header-subtitle-new": "Ihre Blockchain-Brieftasche mit einem Klick", + "header-title": "Einloggen", + "header-tooltip-desc": "Die Brieftasche dient als Konto zum Speichern und Verwalten Ihrer digitalen Assets auf der Blockchain.", + "header-tooltip-title": "Brieftasche", + "network.add-request": "Diese Website fordert das Hinzufügen eines Netzwerks an", + "network.cancel": "Abbrechen", + "network.from": "Von", + "network.proceed": "Fortfahren", + "network.switch-request": "Diese Website fordert einen Netzwerkwechsel an", + "network.to": "Zu", + "passkey.add": "Passkey hinzufügen", + "passkey.haveExisting": "Haben Sie bereits einen passkey?", + "passkey.learn-more": "Erfahren Sie mehr", + "passkey.or": "oder", + "passkey.register-desc": "Mit passkeys können Sie Ihre Identität durch Ihr Gesicht, Ihren Fingerabdruck oder Sicherheitsschlüssel überprüfen.", + "passkey.register-title": "Registrieren Sie Passkey", + "passkey.use": "Ich habe einen passkey", + "popup.phone-body": "Ihr Ländercode wird automatisch erkannt, aber wenn Sie eine Telefonnummer aus einem anderen Land verwenden, müssen Sie den richtigen Ländercode manuell eingeben.", + "popup.phone-header": "Telefonnummer und Ländercode", + "post-loading.connected": "Sie sind mit Ihrem Konto verbunden", + "post-loading.something-wrong": "Etwas ist schief gelaufen!", + "social.continue": "Weitermachen mit", + "social.continueCustom": "Fahren Sie mit {{adapter}} fort", + "social.email": "E-Mail", + "social.email-continue": "Weitermachen mit E-Mail", + "social.email-new": "name@example.com", + "social.passwordless-cta": "Weitermachen", + "social.passwordless-login": "Anmeldung", + "social.passwordless-title": "E-Mail oder Telefon", + "social.phone": "Telefon", + "social.policy": "Wir speichern keine Daten im Zusammenhang mit Ihren Social Logins.", + "social.sms": "Mobiltelefon", + "social.sms-continue": "Mit Mobilgerät fortfahren", + "social.sms-invalid-number": "Ungültige Telefonnummer", + "social.sms-placeholder-text": "Z.B.:", + "social.view-less": "Weniger anzeigen", + "social.view-less-socials": "Weniger anzeigen socials", + "social.view-more": "Mehr anzeigen", + "social.view-more-socials": "Weitere socials anzeigen" + } +} \ No newline at end of file diff --git a/packages/modal-ui/src/i18n/index.ts b/packages/modal-ui/src/i18n/index.ts new file mode 100644 index 000000000..68656f846 --- /dev/null +++ b/packages/modal-ui/src/i18n/index.ts @@ -0,0 +1,12 @@ +import nl from "./dutch.json"; +import en from "./english.json"; +import fr from "./french.json"; +import de from "./german.json"; +import ja from "./japanese.json"; +import ko from "./korean.json"; +import zh from "./mandarin.json"; +import pt from "./portuguese.json"; +import es from "./spanish.json"; +import tr from "./turkish.json"; + +export { de, en, es, fr, ja, ko, nl, pt, tr, zh }; diff --git a/packages/modal-ui/src/i18n/japanese.json b/packages/modal-ui/src/i18n/japanese.json new file mode 100644 index 000000000..451b83644 --- /dev/null +++ b/packages/modal-ui/src/i18n/japanese.json @@ -0,0 +1,76 @@ +{ + "modal": { + "adapter-loader.message": "{{adapter}} アカウントを確認して続行する", + "adapter-loader.message1": "{{adapter}} を確認する", + "adapter-loader.message2": "続行するアカウント", + "errors-invalid-email": "無効な電子メール", + "errors-invalid-number": "無効な電話番号", + "errors-invalid-number-email": "無効なメールアドレスまたは電話番号", + "errors-required": "必須", + "external.back": "戻る", + "external.connect": "ウォレットを続ける", + "external.search-text": "財布が見えませんか?", + "external.search-subtext": "代わりに検索してみてください", + "external.connect-wallet": "ウォレットを接続", + "external.continue": "外部ウォレットを続行する", + "external.dont-have": "持っていない", + "external.get": "取得", + "external.get-wallet": "ウォレットを取得", + "external.install-browser-extension": "{{browser}} 拡張機能をインストール", + "external.install-mobile-app": "{{os}}アプリをインストール", + "external.installed": "インストール済み", + "external.no-wallets-found": "ウォレットが見つかりません", + "external.search-wallet": "{{count}} ウォレットを検索...", + "external.title": "外部ウォレット", + "external.walletconnect-connect": "接続する", + "external.walletconnect-copy": "WalletConnect がサポートするウォレットでスキャンするか、QR コードをクリックしてクリップボードにコピーします。", + "external.walletconnect-subtitle": "WalletConnect対応ウォレットでQRコードをスキャンしてください", + "footer.message": "自己保管ログイン by", + "footer.message-new": "経由の自立", + "footer.policy": "プライバシーポリシー", + "footer.terms": "利用規約", + "footer.terms-service": "利用規約", + "footer.version": "バージョン", + "header-subtitle": "続行するために以下のオプションのいずれかを選択してください", + "header-subtitle-name": "ワンクリックで {{appName}} ウォレット", + "header-subtitle-new": "ワンクリックであなたのブロックチェーンウォレット", + "header-title": "ログイン", + "header-tooltip-desc": "ウォレットは、ブロックチェーン上でデジタル資産を保存および管理するためのアカウントとして機能します。", + "header-tooltip-title": "ウォレット", + "network.add-request": "このサイトはネットワークの追加をリクエストしています", + "network.cancel": "キャンセル", + "network.from": "から", + "network.proceed": "進む", + "network.switch-request": "このサイトはネットワークの切り替えを要求しています", + "network.to": "へ", + "passkey.add": "{パス}を追加", + "passkey.haveExisting": "既存の passkey をお持ちですか?", + "passkey.learn-more": "もっと詳しく知る", + "passkey.or": "または", + "passkey.register-desc": "passkeys を使用すると、顔、指紋、またはセキュリティ キーを使用して本人確認を行うことができます。", + "passkey.register-title": "Passkey を登録する", + "passkey.use": "Passkey を持っています", + "popup.phone-body": "国コードは自動的に検出されますが、異なる国の電話番号を使用する場合は、正しい国コードを手動で入力する必要があります。", + "popup.phone-header": "電話番号と国コード", + "post-loading.connected": "アカウントに接続されています", + "post-loading.something-wrong": "何かがうまくいかなかった!", + "social.continue": "続ける", + "social.continueCustom": "{{adapter}}を続けます", + "social.email": "Eメール", + "social.email-continue": "メールで続行", + "social.email-new": "name@example.com", + "social.passwordless-cta": "続ける", + "social.passwordless-login": "ログイン", + "social.passwordless-title": "メールまたは電話", + "social.phone": "電話", + "social.policy": "ソーシャルログインに関連するデータは保存されません。", + "social.sms": "モバイル", + "social.sms-continue": "モバイルで続行", + "social.sms-invalid-number": "無効な電話番号", + "social.sms-placeholder-text": "例:", + "social.view-less": "表示が少なくなります", + "social.view-less-socials": "表示を減らす socials", + "social.view-more": "もっと見る", + "social.view-more-socials": "もっと見る socials" + } +} \ No newline at end of file diff --git a/packages/modal-ui/src/i18n/korean.json b/packages/modal-ui/src/i18n/korean.json new file mode 100644 index 000000000..479a19dbe --- /dev/null +++ b/packages/modal-ui/src/i18n/korean.json @@ -0,0 +1,76 @@ +{ + "modal": { + "adapter-loader.message": "계속하려면 {{adapter}} 계정을 인증하세요", + "adapter-loader.message1": "{{adapter}}를 인증하세요", + "adapter-loader.message2": "계속할 계정", + "errors-invalid-email": "유효하지 않은 이메일", + "errors-invalid-number": "유효하지 않은 전화번호", + "errors-invalid-number-email": "유효하지 않은 이메일 또는 전화번호", + "errors-required": "필수", + "external.back": "뒤로", + "external.connect": "지갑으로 계속하기", + "external.search-text": "지갑이 보이지 않나요?", + "external.search-subtext": "검색해보세요", + "external.connect-wallet": "지갑 연결", + "external.continue": "외부 지갑으로 계속하기", + "external.dont-have": "없음", + "external.get": "받기", + "external.get-wallet": "지갑 받기", + "external.install-browser-extension": "{{browser}} 확장 프로그램 설치", + "external.install-mobile-app": "{{os}} 앱 설치", + "external.installed": "설치 완료", + "external.no-wallets-found": "지갑을 찾을 수 없습니다.", + "external.search-wallet": "{{count}}개의 지갑을 검색 중입니다...", + "external.title": "외부 지갑", + "external.walletconnect-connect": "연결", + "external.walletconnect-copy": "WalletConnect 호환 지갑으로 스캔하거나, QR 코드를 클릭하여 클립보드에 복사하세요.", + "external.walletconnect-subtitle": "WalletConnect 호환 지갑으로 QR 코드를 스캔하세요", + "footer.message": "자가 관리형 로그인", + "footer.message-new": "셀프 커스터디", + "footer.policy": "개인정보 처리방침", + "footer.terms": "이용 약관", + "footer.terms-service": "서비스 약관", + "footer.version": "버전", + "header-subtitle": "계속하려면 다음 중 하나를 선택하세요", + "header-subtitle-name": "한 번의 클릭으로 {{appName}} 지갑 이용하기", + "header-subtitle-new": "한 번의 클릭으로 블록체인 지갑 이용하기", + "header-title": "로그인", + "header-tooltip-desc": "이 지갑은 블록체인 상에서 디지털 자산을 보관하고 관리하는 데 사용되는 계정입니다.", + "header-tooltip-title": "지갑", + "network.add-request": "이 사이트에서 네트워크 추가를 요청하고 있습니다", + "network.cancel": "취소", + "network.from": "보낸 사람", + "network.proceed": "계속", + "network.switch-request": "이 사이트에서 네트워크 전환을 요청하고 있습니다", + "network.to": "받는 사람", + "passkey.add": "Passkey 추가", + "passkey.haveExisting": "기존 passkey가 있나요?", + "passkey.learn-more": "더 알아보기", + "passkey.or": "또는", + "passkey.register-desc": "passkeys 사용 시 얼굴, 지문 또는 보안 키를 통해 본인임을 인증할 수 있습니다.", + "passkey.register-title": "Passkey 등록", + "passkey.use": "기존 Passkey 사용하기", + "popup.phone-body": "국가 코드는 자동으로 감지됩니다. 그러나 다른 국가의 전화번호를 사용하는 경우, 올바른 국가 코드를 수동으로 입력해야 합니다.", + "popup.phone-header": "전화번호 및 국가 코드", + "post-loading.connected": "계정에 연결되었습니다", + "post-loading.something-wrong": "오류가 발생했습니다!", + "social.continue": "계속하기", + "social.continueCustom": "{{adapter}}로 계속하기", + "social.email": "이메일", + "social.email-continue": "이메일로 계속하기", + "social.email-new": "name@example.com", + "social.passwordless-cta": "계속", + "social.passwordless-login": "로그인", + "social.passwordless-title": "이메일 또는 전화번호", + "social.phone": "전화번호", + "social.policy": "저희는 소셜 로그인과 관련된 어떠한 데이터도 저장하지 않습니다.", + "social.sms": "모바일", + "social.sms-continue": "모바일로 계속하기", + "social.sms-invalid-number": "유효하지 않은 전화번호", + "social.sms-placeholder-text": "예시:", + "social.view-less": "간략히 보기", + "social.view-less-socials": "Socials 간략히 보기", + "social.view-more": "더보기", + "social.view-more-socials": "Socials 더보기" + } +} \ No newline at end of file diff --git a/packages/modal-ui/src/i18n/mandarin.json b/packages/modal-ui/src/i18n/mandarin.json new file mode 100644 index 000000000..268977875 --- /dev/null +++ b/packages/modal-ui/src/i18n/mandarin.json @@ -0,0 +1,76 @@ +{ + "modal": { + "adapter-loader.message": "验证您的{{adapter}}帐户以继续", + "adapter-loader.message1": "在您的{{adapter}}上验证", + "adapter-loader.message2": "帐号继续", + "errors-invalid-email": "无效的电子邮件", + "errors-invalid-number": "电话号码无效", + "errors-invalid-number-email": "无效的电子邮件或电话号码", + "errors-required": "必填", + "external.back": "返回", + "external.connect": "继续使用钱包", + "external.search-text": "没看到你的钱包吗?", + "external.search-subtext": "尝试改为搜索", + "external.connect-wallet": "连接钱包", + "external.continue": "继续使用外部钱包", + "external.dont-have": "没有", + "external.get": "获取", + "external.get-wallet": "获取钱包", + "external.install-browser-extension": "安装{{browser}}扩展", + "external.install-mobile-app": "安装{{os}}应用", + "external.installed": "已安装", + "external.no-wallets-found": "没有找到钱包", + "external.search-wallet": "搜索{{count}}个钱包...", + "external.title": "外部钱包", + "external.walletconnect-connect": "连接", + "external.walletconnect-copy": "使用支持 WalletConnect 的钱包进行扫描或单击二维码以复制到剪贴板。", + "external.walletconnect-subtitle": "使用兼容 WalletConnect 的钱包扫描 QR 码", + "footer.message": "自托管登录由", + "footer.message-new": "自我castody通过", + "footer.policy": "隐私政策", + "footer.terms": "使用条款", + "footer.terms-service": "服务条款", + "footer.version": "版本", + "header-subtitle": "选择以下选项以继续", + "header-subtitle-name": "一键点击您的 {{appName}} 钱包", + "header-subtitle-new": "一键点击您的区块链钱包", + "header-title": "登录", + "header-tooltip-desc": "钱包作为一个账户用于在区块链上存储和管理您的数字资产。", + "header-tooltip-title": "钱包", + "network.add-request": "此站点正在请求添加网络", + "network.cancel": "取消", + "network.from": "从", + "network.proceed": "继续", + "network.switch-request": "此站点正在请求切换网络", + "network.to": "至", + "passkey.add": "添加Passkey", + "passkey.haveExisting": "已有 passkey 吗?", + "passkey.learn-more": "了解更多", + "passkey.or": "或者", + "passkey.register-desc": "使用passkeys,您可以通过面部、指纹或安全密钥验证您的身份。", + "passkey.register-title": "注册Passkey", + "passkey.use": "我有一个Passkey", + "popup.phone-body": "您的国家代码将自动检测到,但如果您使用其他国家/地区的电话号码,您需要手动输入正确的国家代码。", + "popup.phone-header": "电话号码和国家代码", + "post-loading.connected": "您与您的帐户有联系", + "post-loading.something-wrong": "出了些问题!", + "social.continue": "继续", + "social.continueCustom": "继续使用{{adapter}}", + "social.email": "电子邮件", + "social.email-continue": "继续使用电子邮件", + "social.email-new": "name@example.com", + "social.passwordless-cta": "继续", + "social.passwordless-login": "登录", + "social.passwordless-title": "邮件或电话", + "social.phone": "电话", + "social.policy": "我们不存储与您的社交登录相关的任何数据。", + "social.sms": "移动", + "social.sms-continue": "继续使用移动设备", + "social.sms-invalid-number": "无效的电话号码", + "social.sms-placeholder-text": "例如:", + "social.view-less": "少查看", + "social.view-less-socials": "查看更少socials", + "social.view-more": "查看更多", + "social.view-more-socials": "查看更多socials" + } +} \ No newline at end of file diff --git a/packages/modal-ui/src/i18n/portuguese.json b/packages/modal-ui/src/i18n/portuguese.json new file mode 100644 index 000000000..d1ba98186 --- /dev/null +++ b/packages/modal-ui/src/i18n/portuguese.json @@ -0,0 +1,76 @@ +{ + "modal": { + "adapter-loader.message": "Verifique a sua conta {{adapter}} para continuar", + "adapter-loader.message1": "Verifique o(a) seu/sua {{adapter}}", + "adapter-loader.message2": "conta para continuar", + "errors-invalid-email": "E-mail inválido", + "errors-invalid-number": "Número de telefone inválido", + "errors-invalid-number-email": "Email ou número de telefone inválido", + "errors-required": "Obrigatório", + "external.back": "Voltar", + "external.connect": "Continuar com uma carteira", + "external.search-text": "Não vê sua carteira?", + "external.search-subtext": "Tente pesquisar", + "external.connect-wallet": "Conectar carteira", + "external.continue": "Continuar com carteira externa", + "external.dont-have": "Não tem", + "external.get": "Obter", + "external.get-wallet": "Obter carteira", + "external.install-browser-extension": "Instalar extensão {{browser}}", + "external.install-mobile-app": "Instalar aplicativo {{os}}", + "external.installed": "Instalado", + "external.no-wallets-found": "Nenhuma carteira encontrada", + "external.search-wallet": "Pesquisar através de {{count}} carteiras...", + "external.title": "Carteira Externa", + "external.walletconnect-connect": "Conectar", + "external.walletconnect-copy": "Digitalize com uma carteira compatível com WalletConnect ou clique no código QR para copiar para sua área de transferência.", + "external.walletconnect-subtitle": "Digitalize o código QR com uma carteira compatível com WalletConnect", + "footer.message": "Login de autocustódia por", + "footer.message-new": "Autoconfiança via", + "footer.policy": "Política de Privacidade", + "footer.terms": "Termos de Uso", + "footer.terms-service": "Termos de Serviço", + "footer.version": "Versão", + "header-subtitle": "Selecione uma das seguintes opções para continuar", + "header-subtitle-name": "Sua carteira {{appName}} com um clique", + "header-subtitle-new": "Sua carteira de blockchain com um clique", + "header-title": "Entrar", + "header-tooltip-desc": "A carteira serve como uma conta para armazenar e gerenciar seus ativos digitais na blockchain.", + "header-tooltip-title": "Carteira", + "network.add-request": "Este site está solicitando adicionar uma rede", + "network.cancel": "Cancelar", + "network.from": "De", + "network.proceed": "Prosseguir", + "network.switch-request": "Este site está solicitando trocar de rede", + "network.to": "Para", + "passkey.add": "Adicionar Passkey", + "passkey.haveExisting": "Você já possui um passkey?", + "passkey.learn-more": "Saber mais", + "passkey.or": "ou", + "passkey.register-desc": "Com passkeys, você pode verificar sua identidade por meio de seu rosto, impressão digital ou chaves de segurança.", + "passkey.register-title": "Registre-se Passkey", + "passkey.use": "Eu tenho uma passkey", + "popup.phone-body": "O código do seu país será detectado automaticamente, mas se estiver usando um número de telefone de um país diferente, você precisará inserir manualmente o código correto do país.", + "popup.phone-header": "Número de telefone e código do país", + "post-loading.connected": "Você está conectado com sua conta", + "post-loading.something-wrong": "Algo deu errado!", + "social.continue": "Continuar com", + "social.continueCustom": "Continue com o {{adapter}}", + "social.email": "Email", + "social.email-continue": "Continuar com email", + "social.email-new": "nome@exemplo.com", + "social.passwordless-cta": "Continuar", + "social.passwordless-login": "Conecte-se", + "social.passwordless-title": "Email ou telefone", + "social.phone": "Telefone", + "social.policy": "Não armazenamos nenhum dado relacionado ao seu login por rede social.", + "social.sms": "Móvel", + "social.sms-continue": "Continuar com o celular", + "social.sms-invalid-number": "Número de telefone inválido", + "social.sms-placeholder-text": "Por exemplo:", + "social.view-less": "Ver menos", + "social.view-less-socials": "Ver menos socials", + "social.view-more": "Ver mais", + "social.view-more-socials": "Ver mais socials" + } +} \ No newline at end of file diff --git a/packages/modal-ui/src/i18n/spanish.json b/packages/modal-ui/src/i18n/spanish.json new file mode 100644 index 000000000..e5202338f --- /dev/null +++ b/packages/modal-ui/src/i18n/spanish.json @@ -0,0 +1,76 @@ +{ + "modal": { + "adapter-loader.message": "Verifica tu cuenta {{adapter}} para continuar", + "adapter-loader.message1": "Verifique su {{adapter}}", + "adapter-loader.message2": "cuenta para continuar", + "errors-invalid-email": "Correo electrónico no válido", + "errors-invalid-number": "Número de teléfono no válido", + "errors-invalid-number-email": "Correo electrónico o número de teléfono no válido", + "errors-required": "Campo obligatorio", + "external.back": "Atrás", + "external.connect": "Conectar con la billetera", + "external.search-text": "¿No ves tu billetera?", + "external.search-subtext": "Intenta buscar en su lugar", + "external.connect-wallet": "Conectar billetera", + "external.continue": "Continuar con billetera externa", + "external.dont-have": "No tiene", + "external.get": "Obtener", + "external.get-wallet": "Obtener billetera", + "external.install-browser-extension": "Instalar extensión {{browser}}", + "external.install-mobile-app": "Instalar aplicación {{os}}", + "external.installed": "Instalado", + "external.no-wallets-found": "No se encontraron billeteras", + "external.search-wallet": "Buscar a través de {{count}} billeteras...", + "external.title": "Billetera Externa", + "external.walletconnect-connect": "Conectar", + "external.walletconnect-copy": "Escanee con una billetera compatible con WalletConnect o haga clic en el código QR para copiarlo en su portapapeles.", + "external.walletconnect-subtitle": "Escanear el código QR con una billetera compatible con WalletConnect", + "footer.message": "Inicio de sesión con autocustodia por", + "footer.message-new": "Autocustodia a través de", + "footer.policy": "Política de privacidad", + "footer.terms": "Términos de Uso", + "footer.terms-service": "Términos de servicio", + "footer.version": "Versión", + "header-subtitle": "Seleccione una de las siguientes opciones para continuar", + "header-subtitle-name": "Su billetera {{appName}} con un solo clic", + "header-subtitle-new": "Su billetera blockchain con un solo clic", + "header-title": "Iniciar sesión", + "header-tooltip-desc": "La billetera sirve como una cuenta para almacenar y administrar sus activos digitales en la blockchain.", + "header-tooltip-title": "Billetera", + "network.add-request": "Este sitio está solicitando agregar una red", + "network.cancel": "Cancelar", + "network.from": "De", + "network.proceed": "Continuar", + "network.switch-request": "Este sitio está solicitando cambiar de red", + "network.to": "A", + "passkey.add": "Añadir Passkey", + "passkey.haveExisting": "¿Tiene un passkey existente?", + "passkey.learn-more": "Aprende más", + "passkey.or": "o", + "passkey.register-desc": "Con passkeys, puedes verificar tu identidad a través de tu rostro, huella digital o claves de seguridad.", + "passkey.register-title": "Registrarse Passkey", + "passkey.use": "Tengo una Passkey", + "popup.phone-body": "Su código de país se detectará automáticamente, pero si está utilizando un número de teléfono de otro país, deberá ingresar manualmente el código de país correcto.", + "popup.phone-header": "Número de teléfono y código de país", + "post-loading.connected": "Estás conectado con tu cuenta", + "post-loading.something-wrong": "¡Algo salió mal!", + "social.continue": "Continuar con", + "social.continueCustom": "Continuar con {{adapter}}", + "social.email": "Correo electrónico", + "social.email-continue": "Continuar con correo electrónico", + "social.email-new": "nombre@ejemplo.com", + "social.passwordless-cta": "Continuar", + "social.passwordless-login": "Acceso", + "social.passwordless-title": "Email o teléfono", + "social.phone": "Teléfono", + "social.policy": "No almacenamos ningún dato relacionado con sus inicios de sesión sociales.", + "social.sms": "Móvil", + "social.sms-continue": "Continuar con móvil", + "social.sms-invalid-number": "Número de teléfono inválido", + "social.sms-placeholder-text": "Por ej.:", + "social.view-less": "Ver menos", + "social.view-less-socials": "Ver menos socials", + "social.view-more": "Ver más", + "social.view-more-socials": "Ver más socials" + } +} \ No newline at end of file diff --git a/packages/modal-ui/src/i18n/turkish.json b/packages/modal-ui/src/i18n/turkish.json new file mode 100644 index 000000000..600f59878 --- /dev/null +++ b/packages/modal-ui/src/i18n/turkish.json @@ -0,0 +1,76 @@ +{ + "modal": { + "adapter-loader.message": "Devam etmek için {{adapter}} hesabınızı doğrula", + "adapter-loader.message1": "{{adapter}} doğrula", + "adapter-loader.message2": "devam edecek hesap", + "errors-invalid-email": "Geçersiz E-posta", + "errors-invalid-number": "Geçersiz Telefon Numarası", + "errors-invalid-number-email": "Geçersiz E-posta veya Telefon Numarası", + "errors-required": "Zorunlu", + "external.back": "Geri", + "external.connect": "Cüzdanla devam et", + "external.search-text": "Cüzdanınızı görmüyor musunuz?", + "external.search-subtext": "Bunun yerine aramayı deneyin", + "external.connect-wallet": "Cüzdanı Bağla", + "external.continue": "Harici cüzdanla devam et", + "external.dont-have": "Yok", + "external.get": "Al", + "external.get-wallet": "Cüzdan Al", + "external.install-browser-extension": "{{browser}} uzantısını yükle", + "external.install-mobile-app": "{{os}} uygulamasını yükle", + "external.installed": "Yüklendi", + "external.no-wallets-found": "Cüzdan bulunamadı", + "external.search-wallet": "{{count}} cüzdan ara...", + "external.title": "Harici Cüzdan", + "external.walletconnect-connect": "Bağla", + "external.walletconnect-copy": "WalletConnect destekli bir cüzdanla tarayın veya panonuza kopyalamak için QR kodunu tıklayın.", + "external.walletconnect-subtitle": "QR kodunu WalletConnect uyumlu bir cüzdanla tarayın", + "footer.message": "Öz-yönetimli giriş yapan:", + "footer.message-new": "Kendi kendine velayet", + "footer.policy": "Gizlilik Politikası", + "footer.terms": "Kullanım Şartları", + "footer.terms-service": "Hizmet Şartları", + "footer.version": "Versiyon", + "header-subtitle": "Devam etmek için seçeneklerden birini işaretle", + "header-subtitle-name": "Tek tıklama ile {{appName}} cüzdanınız", + "header-subtitle-new": "Tek tıklama ile blockchain cüzdanınız", + "header-title": "Giriş yap", + "header-tooltip-desc": "Cüzdan, dijital varlıklarınızı blockchain'de saklama ve yönetme görevi görür.", + "header-tooltip-title": "Cüzdan", + "network.add-request": "Bu site bir ağ eklemek istiyor", + "network.cancel": "İptal", + "network.from": "Nereden", + "network.proceed": "Devam", + "network.switch-request": "Bu site ağ değiştirmeyi talep ediyor", + "network.to": "Nereye", + "passkey.add": "Passkey ekle", + "passkey.haveExisting": "Mevcut bir passkey'ınız mı var?", + "passkey.learn-more": "Daha fazla bilgi edin", + "passkey.or": "veya", + "passkey.register-desc": "passkeys ile kimliğinizi yüzünüz, parmak iziniz veya güvenlik anahtarlarınız aracılığıyla doğrulayabilirsiniz.", + "passkey.register-title": "Passkey'ı kaydedin", + "passkey.use": "Bir passkey'im var", + "popup.phone-body": "Ülke kodunuz otomatik olarak algılanacaktır, ancak farklı bir ülkeden bir telefon numarası kullanıyorsanız, doğru ülke kodunu manuel olarak girmeniz gerekir.", + "popup.phone-header": "Telefon numarası ve ülke kodu", + "post-loading.connected": "Hesabınızla bağlandınız", + "post-loading.something-wrong": "Bir şeyler ters gitti!", + "social.continue": "Devam et: ", + "social.continueCustom": "{{adapter}} ile devam et", + "social.email": "E-posta", + "social.email-continue": "E-posta ile devam et", + "social.email-new": "isim@ornek.com", + "social.passwordless-cta": "Devam et", + "social.passwordless-login": "Giriş yapmak", + "social.passwordless-title": "E-posta veya Telefon", + "social.phone": "Telefon", + "social.policy": "Sosyal medya girişlerinizle ilgili hiçbir veriyi saklamıyoruz.", + "social.sms": "Mobil Telefon", + "social.sms-continue": "Telefon ile devam et", + "social.sms-invalid-number": "Geçersiz telefon numarası", + "social.sms-placeholder-text": "Örneğin:", + "social.view-less": "Daha az görüntüle", + "social.view-less-socials": "Daha az socials görüntüle", + "social.view-more": "Daha fazla görüntüle", + "social.view-more-socials": "Daha fazlasını görüntüle socials" + } +} \ No newline at end of file diff --git a/packages/modal-ui/src/index.css b/packages/modal-ui/src/index.css new file mode 100644 index 000000000..0beb27162 --- /dev/null +++ b/packages/modal-ui/src/index.css @@ -0,0 +1,15 @@ +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap"); +@tailwind base; +@tailwind components; +@tailwind utilities; + +body { + padding: 0px !important; + margin: 0px !important; + box-sizing: border-box; +} + +.w3a-parent-container { + font-family: "Inter"; + position: relative; +} diff --git a/packages/modal-ui/src/index.tsx b/packages/modal-ui/src/index.tsx new file mode 100644 index 000000000..845c773c0 --- /dev/null +++ b/packages/modal-ui/src/index.tsx @@ -0,0 +1,14 @@ +/* @refresh reload */ +import "./index.css"; + +import { render } from "solid-js/web"; + +import App from "./App"; + +const root = document.getElementById("root"); + +if (import.meta.env.DEV && !(root instanceof HTMLElement)) { + throw new Error("Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?"); +} + +render(() => , root!); diff --git a/packages/modal-ui/src/interfaces.ts b/packages/modal-ui/src/interfaces.ts new file mode 100644 index 000000000..a2d701ed6 --- /dev/null +++ b/packages/modal-ui/src/interfaces.ts @@ -0,0 +1,123 @@ +import type { SafeEventEmitter, UX_MODE_TYPE, WhiteLabelData } from "@web3auth/auth"; +import { + BaseAdapterConfig, + ChainNamespaceType, + LoginMethodConfig, + WALLET_ADAPTER_TYPE, + WalletRegistry, + WalletRegistryItem, + Web3AuthNoModalEvents, +} from "@web3auth/base"; + +// capture whitelabel only once +export interface UIConfig extends WhiteLabelData { + /** + * order of how login methods are shown + * + * @defaultValue `["google", "facebook", "twitter", "reddit", "discord", "twitch", "apple", "line", "github", "kakao", "linkedin", "weibo", "wechat", "email_passwordless"]` + */ + loginMethodsOrder?: string[]; + + /** + * Z-index of the modal and iframe + * @defaultValue 99998 + */ + modalZIndex?: string; + + /** + * Whether to show errors on Web3Auth modal. + * + * @defaultValue `true` + */ + displayErrorsOnModal?: boolean; + + /** + * number of columns to display the Social Login buttons + * + * @defaultValue `3` + */ + loginGridCol?: 2 | 3; + + /** + * Decides which button will be the focus of the modal + * For `socialLogin` the social icon will be colored + * For other options like `emailLogin` and `externalLogin` the respective buttons will be coverted into a primary button + * + * @defaultValue `socialLogin` + */ + primaryButton?: "externalLogin" | "socialLogin" | "emailLogin"; + + adapterListener: SafeEventEmitter; + + /** + * UX Mode for the auth adapter + */ + uxMode?: UX_MODE_TYPE; +} + +export interface LoginModalProps extends UIConfig { + chainNamespace: ChainNamespaceType; + walletRegistry: WalletRegistry; +} + +export const LOGIN_MODAL_EVENTS = { + INIT_EXTERNAL_WALLETS: "INIT_EXTERNAL_WALLETS", + LOGIN: "LOGIN", + DISCONNECT: "DISCONNECT", + MODAL_VISIBILITY: "MODAL_VISIBILITY", +} as const; + +export type SocialLoginsConfig = { + loginMethodsOrder: string[]; + loginMethods: LoginMethodConfig; + adapter: WALLET_ADAPTER_TYPE; + uiConfig: Omit; +}; + +export const MODAL_STATUS = { + INITIALIZED: "initialized", + CONNECTED: "connected", + CONNECTING: "connecting", + ERRORED: "errored", +}; +export type ModalStatusType = (typeof MODAL_STATUS)[keyof typeof MODAL_STATUS]; + +export interface ModalState { + status: ModalStatusType; + externalWalletsInitialized: boolean; + hasExternalWallets: boolean; + externalWalletsVisibility: boolean; + modalVisibility: boolean; + modalVisibilityDelayed: boolean; + postLoadingMessage: string; + walletConnectUri: string; + socialLoginsConfig: SocialLoginsConfig; + externalWalletsConfig: Record; + detailedLoaderAdapter: string; + detailedLoaderAdapterName: string; + showExternalWalletsOnly: boolean; +} + +export type SocialLoginEventType = { adapter: string; loginParams: { loginProvider: string; login_hint?: string; name: string } }; +export type ExternalWalletEventType = { adapter: string }; + +export const DEFAULT_LOGO_LIGHT = "https://images.web3auth.io/web3auth-logo-w.svg"; // logo used on light mode +export const DEFAULT_LOGO_DARK = "https://images.web3auth.io/web3auth-logo-w-light.svg"; // logo used on dark mode + +export const WALLET_CONNECT_LOGO = "https://images.web3auth.io/login-wallet-connect.svg"; + +export type StateEmitterEvents = { + STATE_UPDATED: (state: Partial) => void; + MOUNTED: () => void; +}; + +export type ExternalButton = { + name: string; + displayName?: string; + href?: string; + hasInjectedWallet: boolean; + hasWalletConnect: boolean; + hasInstallLinks: boolean; + walletRegistryItem?: WalletRegistryItem; + imgExtension?: string; +}; diff --git a/packages/modal-ui/src/localeImport.ts b/packages/modal-ui/src/localeImport.ts new file mode 100644 index 000000000..2544faf02 --- /dev/null +++ b/packages/modal-ui/src/localeImport.ts @@ -0,0 +1,20 @@ +import i18n from "i18next"; +import { initReactI18next } from "react-i18next"; + +import { en } from "./i18n"; + +const i18nInstance = i18n.createInstance() as typeof i18n; +i18nInstance.use(initReactI18next).init({ + resources: { + en: { translation: en }, + }, + lng: "en", + fallbackLng: "en", + interpolation: { escapeValue: false }, + debug: false, + react: { + useSuspense: true, + }, +}); + +export default i18nInstance; diff --git a/packages/modal-ui/src/loginModal.tsx b/packages/modal-ui/src/loginModal.tsx new file mode 100644 index 000000000..100800ae7 --- /dev/null +++ b/packages/modal-ui/src/loginModal.tsx @@ -0,0 +1,373 @@ +import "./index.css"; + +import { applyWhiteLabelTheme, LANGUAGES, SafeEventEmitter } from "@web3auth/auth"; +import { + ADAPTER_EVENTS, + BaseAdapterConfig, + ChainNamespaceType, + CONNECTED_EVENT_DATA, + IAdapterDataEvent, + log, + LoginMethodConfig, + WALLET_ADAPTER_TYPE, + WALLET_ADAPTERS, + WalletConnectV2Data, + WalletRegistry, + Web3AuthError, + Web3AuthNoModalEvents, +} from "@web3auth/base"; +import { render } from "solid-js/web"; + +import { LoginModal as Modal } from "./components/LoginModal"; +// import { ThemedContext } from "./context/ThemeContext"; +import { + DEFAULT_LOGO_DARK, + DEFAULT_LOGO_LIGHT, + ExternalWalletEventType, + LOGIN_MODAL_EVENTS, + LoginModalProps, + MODAL_STATUS, + ModalState, + SocialLoginEventType, + StateEmitterEvents, + UIConfig, +} from "./interfaces"; +import i18n from "./localeImport"; +import { getUserLanguage } from "./utils/modal"; +import { Body } from "./components/Body"; + +function createWrapper(parentZIndex: string): HTMLElement { + const existingWrapper = document.getElementById("w3a-parent-container"); + if (existingWrapper) existingWrapper.remove(); + + const parent = document.createElement("section"); + parent.classList.add("w3a-parent-container"); + parent.setAttribute("id", "w3a-parent-container"); + parent.style.zIndex = parentZIndex; + parent.style.position = "relative"; + const wrapper = document.createElement("section"); + wrapper.setAttribute("id", "w3a-container"); + parent.appendChild(wrapper); + document.body.appendChild(parent); + return wrapper; +} + +export class LoginModal extends SafeEventEmitter { + private uiConfig: UIConfig; + + private stateEmitter: SafeEventEmitter; + + private chainNamespace: ChainNamespaceType; + + private walletRegistry: WalletRegistry; + + constructor(uiConfig: LoginModalProps) { + super(); + this.uiConfig = uiConfig; + + if (!uiConfig.logoDark) this.uiConfig.logoDark = DEFAULT_LOGO_DARK; + if (!uiConfig.logoLight) this.uiConfig.logoLight = DEFAULT_LOGO_LIGHT; + if (!uiConfig.mode) this.uiConfig.mode = "light"; + if (!uiConfig.modalZIndex) this.uiConfig.modalZIndex = "99998"; + if (typeof uiConfig.displayErrorsOnModal === "undefined") this.uiConfig.displayErrorsOnModal = true; + if (!uiConfig.appName) this.uiConfig.appName = "Web3Auth"; + if (!uiConfig.loginGridCol) this.uiConfig.loginGridCol = 3; + if (!uiConfig.primaryButton) this.uiConfig.primaryButton = "socialLogin"; + if (!uiConfig.defaultLanguage) this.uiConfig.defaultLanguage = getUserLanguage(uiConfig.defaultLanguage); + + this.stateEmitter = new SafeEventEmitter(); + this.chainNamespace = uiConfig.chainNamespace; + this.walletRegistry = uiConfig.walletRegistry; + this.subscribeCoreEvents(this.uiConfig.adapterListener); + } + + get isDark(): boolean { + return this.uiConfig.mode === "dark" || (this.uiConfig.mode === "auto" && window.matchMedia("(prefers-color-scheme: dark)").matches); + } + + initModal = async (): Promise => { + const darkState = { isDark: this.isDark }; + + const useLang = this.uiConfig.defaultLanguage || LANGUAGES.en; + + // Load new language resource + + if (useLang === LANGUAGES.de) { + import("./i18n/german.json") + .then((messages) => { + i18n.addResourceBundle(useLang as string, "translation", messages.default); + return i18n.changeLanguage(useLang); + }) + .catch((error) => { + log.error(error); + }); + } else if (useLang === LANGUAGES.ja) { + import(`./i18n/japanese.json`) + .then((messages) => { + i18n.addResourceBundle(useLang as string, "translation", messages.default); + return i18n.changeLanguage(useLang); + }) + .catch((error) => { + log.error(error); + }); + } else if (useLang === LANGUAGES.ko) { + import(`./i18n/korean.json`) + .then((messages) => { + i18n.addResourceBundle(useLang as string, "translation", messages.default); + return i18n.changeLanguage(useLang); + }) + .catch((error) => { + log.error(error); + }); + } else if (useLang === LANGUAGES.zh) { + import(`./i18n/mandarin.json`) + .then((messages) => { + i18n.addResourceBundle(useLang as string, "translation", messages.default); + return i18n.changeLanguage(useLang); + }) + .catch((error) => { + log.error(error); + }); + } else if (useLang === LANGUAGES.es) { + import(`./i18n/spanish.json`) + .then((messages) => { + i18n.addResourceBundle(useLang as string, "translation", messages.default); + return i18n.changeLanguage(useLang); + }) + .catch((error) => { + log.error(error); + }); + } else if (useLang === LANGUAGES.fr) { + import(`./i18n/french.json`) + .then((messages) => { + i18n.addResourceBundle(useLang as string, "translation", messages.default); + return i18n.changeLanguage(useLang); + }) + .catch((error) => { + log.error(error); + }); + } else if (useLang === LANGUAGES.pt) { + import(`./i18n/portuguese.json`) + .then((messages) => { + i18n.addResourceBundle(useLang as string, "translation", messages.default); + return i18n.changeLanguage(useLang); + }) + .catch((error) => { + log.error(error); + }); + } else if (useLang === LANGUAGES.nl) { + import(`./i18n/dutch.json`) + .then((messages) => { + i18n.addResourceBundle(useLang as string, "translation", messages.default); + return i18n.changeLanguage(useLang); + }) + .catch((error) => { + log.error(error); + }); + } else if (useLang === LANGUAGES.tr) { + import(`./i18n/turkish.json`) + .then((messages) => { + i18n.addResourceBundle(useLang as string, "translation", messages.default); + return i18n.changeLanguage(useLang); + }) + .catch((error) => { + log.error(error); + }); + } else if (useLang === LANGUAGES.en) { + import(`./i18n/english.json`) + .then((messages) => { + i18n.addResourceBundle(useLang as string, "translation", messages.default); + return i18n.changeLanguage(useLang); + }) + .catch((error) => { + log.error(error); + }); + } + + return new Promise((resolve) => { + this.stateEmitter.once("MOUNTED", () => { + log.info("rendered"); + this.setState({ + status: MODAL_STATUS.INITIALIZED, + }); + return resolve(); + }); + + const container = createWrapper(this.uiConfig.modalZIndex); + if (darkState.isDark) { + container.classList.add("w3a--dark"); + } else { + container.classList.remove("w3a--dark"); + } + + const root = document.getElementById("w3a-parent-container"); + + if (import.meta.env.DEV && !(root instanceof HTMLElement)) { + throw new Error("Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?"); + } + + render( + () => + , + root!); + + + if (this.uiConfig?.theme) { + const rootElement = document.getElementById("w3a-parent-container") as HTMLElement; + applyWhiteLabelTheme(rootElement, this.uiConfig.theme); + } + }); + }; + + addSocialLogins = ( + adapter: WALLET_ADAPTER_TYPE, + loginMethods: LoginMethodConfig, + loginMethodsOrder: string[], + uiConfig: Omit + ): void => { + this.setState({ + socialLoginsConfig: { + adapter, + loginMethods, + loginMethodsOrder, + uiConfig, + }, + }); + log.info("addSocialLogins", adapter, loginMethods, loginMethodsOrder, uiConfig); + }; + + addWalletLogins = (externalWalletsConfig: Record, options: { showExternalWalletsOnly: boolean }): void => { + this.setState({ + externalWalletsConfig, + externalWalletsInitialized: true, + showExternalWalletsOnly: !!options?.showExternalWalletsOnly, + externalWalletsVisibility: true, + }); + }; + + open = () => { + this.setState({ + modalVisibility: true, + }); + this.emit(LOGIN_MODAL_EVENTS.MODAL_VISIBILITY, true); + }; + + closeModal = () => { + this.setState({ + modalVisibility: false, + externalWalletsVisibility: false, + }); + this.emit(LOGIN_MODAL_EVENTS.MODAL_VISIBILITY, false); + }; + + initExternalWalletContainer = () => { + this.setState({ + hasExternalWallets: true, + }); + }; + + private handleShowExternalWallets = (status: boolean) => { + this.emit(LOGIN_MODAL_EVENTS.INIT_EXTERNAL_WALLETS, { externalWalletsInitialized: status }); + }; + + private handleExternalWalletClick = (params: ExternalWalletEventType) => { + log.info("external wallet clicked", params); + const { adapter } = params; + this.emit(LOGIN_MODAL_EVENTS.LOGIN, { + adapter, + }); + }; + + private handleSocialLoginClick = (params: SocialLoginEventType) => { + log.info("social login clicked", params); + const { adapter, loginParams } = params; + this.emit(LOGIN_MODAL_EVENTS.LOGIN, { + adapter, + loginParams: { loginProvider: loginParams.loginProvider, login_hint: loginParams.login_hint, name: loginParams.name }, + }); + }; + + private setState = (newState: Partial) => { + this.stateEmitter.emit("STATE_UPDATED", newState); + }; + + private updateWalletConnect = (walletConnectUri: string): void => { + if (!walletConnectUri) return; + this.setState({ + walletConnectUri, + }); + }; + + private handleAdapterData = (adapterData: IAdapterDataEvent) => { + if (adapterData.adapterName === WALLET_ADAPTERS.WALLET_CONNECT_V2) { + const walletConnectData = adapterData.data as WalletConnectV2Data; + this.updateWalletConnect(walletConnectData.uri); + } + }; + + private subscribeCoreEvents = (listener: SafeEventEmitter) => { + listener.on(ADAPTER_EVENTS.CONNECTING, (data) => { + log.info("connecting with adapter", data); + // don't show loader in case of wallet connect, because currently it listens for incoming for incoming + // connections without any user interaction. + if (data?.adapter !== WALLET_ADAPTERS.WALLET_CONNECT_V2) { + // const provider = data?.loginProvider || ""; + + this.setState({ status: MODAL_STATUS.CONNECTING }); + } + }); + listener.on(ADAPTER_EVENTS.CONNECTED, (data: CONNECTED_EVENT_DATA) => { + log.debug("connected with adapter", data); + // only show success if not being reconnected again. + if (!data.reconnected) { + this.setState({ + status: MODAL_STATUS.CONNECTED, + modalVisibility: true, + postLoadingMessage: "modal.post-loading.connected", + }); + } else { + this.setState({ + status: MODAL_STATUS.CONNECTED, + }); + } + }); + // TODO: send adapter name in error + listener.on(ADAPTER_EVENTS.ERRORED, (error: Web3AuthError) => { + log.error("error", error, error.message); + if (error.code === 5000) { + if (this.uiConfig.displayErrorsOnModal) + this.setState({ + modalVisibility: true, + postLoadingMessage: error.message || "modal.post-loading.something-wrong", + status: MODAL_STATUS.ERRORED, + }); + else + this.setState({ + modalVisibility: false, + }); + } else { + this.setState({ + modalVisibility: true, + status: MODAL_STATUS.INITIALIZED, + }); + } + }); + listener.on(ADAPTER_EVENTS.DISCONNECTED, () => { + this.setState({ status: MODAL_STATUS.INITIALIZED, externalWalletsVisibility: false }); + // this.toggleMessage(""); + }); + listener.on(ADAPTER_EVENTS.ADAPTER_DATA_UPDATED, (adapterData: IAdapterDataEvent) => { + this.handleAdapterData(adapterData); + }); + }; +} diff --git a/packages/modal-ui/src/utils/common.ts b/packages/modal-ui/src/utils/common.ts new file mode 100644 index 000000000..e4e9bc514 --- /dev/null +++ b/packages/modal-ui/src/utils/common.ts @@ -0,0 +1,24 @@ +/** Merge classes with tailwind-merge with clsx full feature */ +import clsx, { ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +const cache = new Map(); + +/** Merge classes with tailwind-merge with clsx full feature and memoization */ +export function cn(...inputs: ClassValue[]) { + // Create a cache key using JSON.stringify + const cacheKey = JSON.stringify(inputs); + + // Check if the result is already cached + if (cache.has(cacheKey)) { + return cache.get(cacheKey)!; + } + + // If not cached, compute the result + const result = twMerge(clsx(inputs)); + + // Store the result in the cache + cache.set(cacheKey, result); + + return result; +} diff --git a/packages/modal-ui/src/utils/modal.ts b/packages/modal-ui/src/utils/modal.ts new file mode 100644 index 000000000..0b7eb5f53 --- /dev/null +++ b/packages/modal-ui/src/utils/modal.ts @@ -0,0 +1,101 @@ +import { get, post } from "@toruslabs/http-helpers"; +import { LANGUAGE_MAP, LANGUAGE_TYPE, LANGUAGES } from "@web3auth/auth"; +import { log, LoginMethodConfig, WALLET_ADAPTERS, WalletInitializationError } from "@web3auth/base"; + +import { AUTH_PROVIDERS, AUTH_PROVIDERS_NAMES } from "../config"; + +export const getAdapterSocialLogins = (adapterName: string, loginMethodsConfig: LoginMethodConfig = {}): LoginMethodConfig => { + const finalLoginMethodsConfig: LoginMethodConfig = {}; + if (adapterName === WALLET_ADAPTERS.AUTH) { + AUTH_PROVIDERS.forEach((loginMethod) => { + const currentLoginMethodConfig = loginMethodsConfig[loginMethod] || { + name: AUTH_PROVIDERS_NAMES[loginMethod], + showOnMobile: true, + showOnModal: true, + showOnDesktop: true, + }; + finalLoginMethodsConfig[loginMethod] = { ...currentLoginMethodConfig }; + }); + log.debug("auth login method ui config", finalLoginMethodsConfig); + } else { + throw WalletInitializationError.invalidParams(`${adapterName} is not a valid adapter`); + } + return finalLoginMethodsConfig; +}; + +export async function validateImageUrl(url: string): Promise { + return new Promise((resolve, reject) => { + const img = new Image(); + img.src = url; + if (img.complete) { + resolve(true); + } else { + img.addEventListener("load", () => { + resolve(true); + }); + img.addEventListener("error", () => { + reject(); + }); + } + }); +} + +export async function getNetworkIconId(ticker: string): Promise { + const fallbackId = "network-default"; + if (!ticker) return fallbackId; + try { + const url = `https://images.web3auth.io/network-${ticker.toLowerCase()}.svg`; + const isValid = await validateImageUrl(url); + if (isValid) { + return `network-${ticker.toLowerCase()}`; + } + return fallbackId; + } catch { + return fallbackId; + } +} + +export const passwordlessBackendUrl = "https://api-passwordless.web3auth.io"; + +export const getUserCountry = async (): Promise<{ country: string; dialCode: string } | null> => { + try { + const result = await get<{ data: { country: string; dial_code: string } }>(`${passwordlessBackendUrl}/api/v3/user/location`); + if (result && result.data.country) return { country: result.data.country, dialCode: result.data.dial_code }; + return null; + } catch (error) { + log.error("error getting user country", error); + return null; + } +}; + +export const validatePhoneNumber = async (phoneNumber: string): Promise => { + try { + const result = await post<{ success: boolean; parsed_number: string }>(`${passwordlessBackendUrl}/api/v3/phone_number/validate`, { + phone_number: phoneNumber, + }); + if (result && result.success) return result.parsed_number; + return false; + } catch (error: unknown) { + log.error("error validating phone number", error); + if ((error as Response).status === 400) { + return false; + } + // sending true because we don't want the user to be stuck on a flow + // if there is an error with the api or something went wrong. + return true; + } +}; + +interface NavigatorLanguage { + userLanguage?: string; +} + +export const getUserLanguage = (defaultLanguage: string | undefined): LANGUAGE_TYPE => { + let userLanguage = defaultLanguage; + if (!userLanguage) { + const browserLanguage = + typeof window !== "undefined" ? (window.navigator as NavigatorLanguage).userLanguage || window.navigator.language || "en-US" : "en-US"; + userLanguage = browserLanguage.split("-")[0]; + } + return Object.prototype.hasOwnProperty.call(LANGUAGE_MAP, userLanguage) ? (userLanguage as LANGUAGE_TYPE) : LANGUAGES.en; +}; diff --git a/packages/modal-ui/tailwind.config.ts b/packages/modal-ui/tailwind.config.ts new file mode 100644 index 000000000..8652c8939 --- /dev/null +++ b/packages/modal-ui/tailwind.config.ts @@ -0,0 +1,226 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import tailwindCssVariables from "@mertasan/tailwindcss-variables"; +import type { Config } from "tailwindcss"; +import colors from "tailwindcss/colors"; + +const config: Config = { + content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx,css,md,mdx,html,json,scss}"], + prefix: "w3a--", + darkMode: "class", + theme: { + extend: { + fontSize: { + xxs: "0.625rem", + }, + screens: { + smb: "380px", + xs: "440px", + mb: "570px", + tab: "840px", + }, + containers: { + smb: "380px", + xs: "440px", + mb: "570px", + tab: "840px", + sm: "640px", + md: "768px", + lg: "1024px", + xl: "1280px", + "2xl": "1536px", + }, + }, + fontFamily: { + header: ["Inter"], + body: ["Inter"], + }, + colors: { + transparent: colors.transparent, + app: { + onPrimary: "var(--app-on-primary)", + primary: { + 900: "var(--app-primary-900)", + 800: "var(--app-primary-800)", + 700: "var(--app-primary-700)", + 600: "var(--app-primary-600)", + 500: "var(--app-primary-500)", + 400: "var(--app-primary-400)", + 300: "var(--app-primary-300)", + 200: "var(--app-primary-200)", + 100: "var(--app-primary-100)", + 50: "var(--app-primary-50)", + }, + gray: { + 900: "var(--app-gray-900)", + 800: "var(--app-gray-800)", + 700: "var(--app-gray-700)", + 600: "var(--app-gray-600)", + 500: "var(--app-gray-500)", + 400: "var(--app-gray-400)", + 300: "var(--app-gray-300)", + 200: "var(--app-gray-200)", + 100: "var(--app-gray-100)", + 50: "var(--app-gray-50)", + }, + blue: { + 900: "var(--app-blue-900)", + 800: "var(--app-blue-800)", + 700: "var(--app-blue-700)", + 600: "var(--app-blue-600)", + 500: "var(--app-blue-500)", + 400: "var(--app-blue-400)", + 300: "var(--app-blue-300)", + 200: "var(--app-blue-200)", + 100: "var(--app-blue-100)", + 50: "var(--app-blue-50)", + }, + red: { + 900: "var(--app-red-900)", + 800: "var(--app-red-800)", + 700: "var(--app-red-700)", + 600: "var(--app-red-600)", + 500: "var(--app-red-500)", + 400: "var(--app-red-400)", + 300: "var(--app-red-300)", + 200: "var(--app-red-200)", + 100: "var(--app-red-100)", + 50: "var(--app-red-50)", + }, + green: { + 900: "var(--app-green-900)", + 800: "var(--app-green-800)", + 700: "var(--app-green-700)", + 600: "var(--app-green-600)", + 500: "var(--app-green-500)", + 400: "var(--app-green-400)", + 300: "var(--app-green-300)", + 200: "var(--app-green-200)", + 100: "var(--app-green-100)", + 50: "var(--app-green-50)", + }, + yellow: { + 900: "var(--app-yellow-900)", + 800: "var(--app-yellow-800)", + 700: "var(--app-yellow-700)", + 600: "var(--app-yellow-600)", + 500: "var(--app-yellow-500)", + 400: "var(--app-yellow-400)", + 300: "var(--app-yellow-300)", + 200: "var(--app-yellow-200)", + 100: "var(--app-yellow-100)", + 50: "var(--app-yellow-50)", + }, + light: { + "surface-main": "var(--app-gray-100)", + surface1: "var(--app-white)", + surface2: "var(--app-gray-50)", + surface3: "var(--app-gray-100)", + surface4: "var(--app-gray-200)", + }, + dark: { + "surface-main": "var(--app-gray-900)", + surface1: "var(--app-black)", + surface2: "var(--app-gray-900)", + surface3: "var(--app-gray-800)", + surface4: "var(--app-gray-700)", + }, + success: "var(--app-success)", + warning: "var(--app-warning)", + error: "var(--app-error)", + info: "var(--app-info)", + white: "var(--app-white)", + black: "var(--app-black)", + }, + }, + variables: { + ".w3a-parent-container": { + DEFAULT: { + app: { + "on-primary": "#ffffff", + primary: { + 900: "#233876", + 800: "#1e429f", + 700: "#1a56db", + 600: "#0346ff", + 500: "#3f83f8", + 400: "#76a9fa", + 300: "#a4cafe", + 200: "#c3ddfd", + 100: "#e1effe", + 50: "#ebf5ff", + }, + gray: { + 900: "#111928", + 800: "#1f2a37", + 700: "#374151", + 600: "#4b5563", + 500: "#6b7280", + 400: "#9ca3af", + 300: "#d1d5db", + 200: "#e5e7eb", + 100: "#f3f4f6", + 50: "#f9fafb", + }, + blue: { + 900: "#233876", + 800: "#1e429f", + 700: "#1a56db", + 600: "#0346ff", + 500: "#3f83f8", + 400: "#76a9fa", + 300: "#a4cafe", + 200: "#c3ddfd", + 100: "#e1effe", + 50: "#ebf5ff", + }, + red: { + 900: "#771d1d", + 800: "#9b1c1c", + 700: "#c81e1e", + 600: "#e02424", + 500: "#f05252", + 400: "#f98080", + 300: "#f8b4b4", + 200: "#fbd5d5", + 100: "#fde8e8", + 50: "#fdf2f2", + }, + green: { + 900: "#014737", + 800: "#03543f", + 700: "#046c4e", + 600: "#057a55", + 500: "#0e9f6e", + 400: "#31c48d", + 300: "#84e1bc", + 200: "#bcf0da", + 100: "#def7ec", + 50: "#f3faf7", + }, + yellow: { + 900: "#633112", + 800: "#723b13", + 700: "#8e4b10", + 600: "#9f580a", + 500: "#c27803", + 400: "#e3a008", + 300: "#faca15", + 200: "#fce96a", + 100: "#fdf6b2", + 50: "#fdfdea", + }, + success: "#30cca4", + warning: "#fbc94a", + error: "#fb4a61", + info: "#d4d4d4", + white: "#ffffff", + black: "#000000", + }, + }, + }, + }, + }, + plugins: [tailwindCssVariables], +}; + +export default config; diff --git a/packages/modal-ui/tsconfig.json b/packages/modal-ui/tsconfig.json new file mode 100644 index 000000000..a16fbe90c --- /dev/null +++ b/packages/modal-ui/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "isolatedModules": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + "module": "ESNext", + "moduleResolution": "node", + "noEmit": true, + "target": "ESNext", + "types": [ + "vite/client" + ] + }, + "extends": "../../tsconfig.json", + "include": [ + "assets", + "css", + "src", + "test" + ] +} diff --git a/packages/modal-ui/vite.config.ts b/packages/modal-ui/vite.config.ts new file mode 100644 index 000000000..74fce7ed2 --- /dev/null +++ b/packages/modal-ui/vite.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from 'vite'; +import solidPlugin from 'vite-plugin-solid'; +// import devtools from 'solid-devtools/vite'; + +export default defineConfig({ + plugins: [ + /* + Uncomment the following line to enable solid-devtools. + For more info see https://github.com/thetarnav/solid-devtools/tree/main/packages/extension#readme + */ + // devtools(), + solidPlugin(), + ], + server: { + port: 3000, + }, + build: { + target: 'esnext', + }, +}); diff --git a/packages/modal-ui/webpack.config.js b/packages/modal-ui/webpack.config.js new file mode 100644 index 000000000..7c76b9edd --- /dev/null +++ b/packages/modal-ui/webpack.config.js @@ -0,0 +1,73 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +const path = require("path"); +const generateWebpackConfig = require("../../webpack.config"); + +const pkg = require("./package.json"); + +const currentPath = path.resolve("."); + +const ssrModule = { + rules: [ + { + test: /\.css$/, + use: [ + "@toruslabs/isomorphic-style-loader", + { + loader: "css-loader", + }, + { + loader: "postcss-loader", + options: { + postcssOptions: { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, + }, + }, + }, + ], + }, + { + test: /\.svg$/, + exclude: /node_modules/, + use: ["@svgr/webpack", "url-loader"], + }, + ], +}; + +const config = generateWebpackConfig({ + currentPath, + pkg, + alias: {}, + module: { + rules: [ + { + test: /\.css$/i, + use: [ + { loader: "style-loader", options: {} }, + { loader: "css-loader", options: {} }, + { + loader: "postcss-loader", + options: { + postcssOptions: { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, + }, + }, + }, + ], + }, + { + test: /\.svg$/, + exclude: /node_modules/, + use: ["@svgr/webpack", "url-loader"], + }, + ], + }, + ssrModule, +}); + +module.exports = config;