From b97ddcbd2d55b9f905ca3899f361c2e7c747b156 Mon Sep 17 00:00:00 2001 From: abretonc7s Date: Wed, 15 Jan 2025 08:39:59 +0800 Subject: [PATCH 01/28] feat: turborepo setup --- .gitignore | 3 + package.json | 3 + packages/sdk-communication-layer/package.json | 2 + packages/sdk-react/package.json | 2 +- packages/sdk/package.json | 6 +- turbo.json | 34 +++++ yarn.lock | 120 +++++++++++++++++- 7 files changed, 165 insertions(+), 5 deletions(-) create mode 100644 turbo.json diff --git a/.gitignore b/.gitignore index b215516a5..a903d2f51 100644 --- a/.gitignore +++ b/.gitignore @@ -120,3 +120,6 @@ packages/devreact/webpack.config.json # Local Netlify folder .netlify + +# Turborepo +.turbo diff --git a/package.json b/package.json index 21519f22e..5e2875f2f 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "postinstall": "patch-package", "link-packages": "./scripts/link-packages.sh", "prepare": "husky install", + "dev:core": "turbo run dev --parallel --filter=@metamask/sdk-communication-layer --filter=@metamask/sdk --filter=@metamask/sdk-react", "lint": "yarn workspaces foreach --no-private run lint", "lint:changelogs": "yarn workspaces foreach --no-private run lint:changelog", "lint:eslint": "yarn workspaces foreach --no-private run lint:eslint", @@ -86,6 +87,8 @@ "rimraf": "^3.0.2", "serve": "^14.2.1", "ts-jest": "^29.0.3", + "turbo": "^2.3.3", + "turborepo": "^0.0.1", "typescript": "^4.3.5" }, "engines": { diff --git a/packages/sdk-communication-layer/package.json b/packages/sdk-communication-layer/package.json index 48662eda2..524b35ddc 100644 --- a/packages/sdk-communication-layer/package.json +++ b/packages/sdk-communication-layer/package.json @@ -25,6 +25,7 @@ "build:clean": "yarn clean && yarn build", "build": "yarn build:types && rollup -c --bundleConfigAsCjs", "build:dev": "yarn build:types && NODE_ENV=dev rollup -c --bundleConfigAsCjs", + "dev": "concurrently \"tsc --watch\" \"rollup -c --bundleConfigAsCjs -w\"", "build:post-tsc": "echo 'N/A'", "build:pre-tsc": "echo 'N/A'", "size": "size-limit", @@ -69,6 +70,7 @@ "@types/uuid": "^9.0.0", "@typescript-eslint/eslint-plugin": "^4.26.0", "@typescript-eslint/parser": "^4.26.0", + "concurrently": "^9.1.2", "cross-fetch": "^4.0.0", "eciesjs": "^0.4.11", "eslint": "^7.30.0", diff --git a/packages/sdk-react/package.json b/packages/sdk-react/package.json index cc3963a90..60f3b8861 100644 --- a/packages/sdk-react/package.json +++ b/packages/sdk-react/package.json @@ -34,7 +34,7 @@ "build:post-tsc": "echo 'N/A'", "build:pre-tsc": "echo 'N/A'", "clean": "rimraf dist", - "dev": "rollup -c -w", + "dev": "rollup -c -w --bundleConfigAsCjs", "lint": "yarn lint:eslint && yarn lint:misc --check", "lint:changelog": "../../scripts/validate-changelog.sh @metamask/sdk-react", "lint:eslint": "eslint . --cache --ext js,ts", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 53031e736..bc70ef57c 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -25,7 +25,6 @@ "build:types": "tsc --project tsconfig.build.json --emitDeclarationOnly --outDir dist/types", "build": "yarn build:types && rollup -c --bundleConfigAsCjs", "build:clean": "yarn clean && yarn build", - "build:dev": "yarn build:types && NODE_ENV=dev rollup -c --bundleConfigAsCjs", "build:post-tsc": "echo 'N/A'", "build:pre-tsc": "echo 'N/A'", "typecheck": "tsc --noEmit", @@ -44,7 +43,9 @@ "test:e2e": "jest --testPathPattern \"/e2e/\"", "test:ci": "jest --coverage --passWithNoTests --setupFilesAfterEnv ./jest-preload.js --testPathIgnorePatterns \"/e2e/\"", "test:dev": "jest -c ./jest.config.ts --detectOpenHandles --testPathIgnorePatterns \"/e2e/\"", - "watch": "rollup -c -w" + "watch": "rollup -c -w", + "dev": "concurrently \"tsc --watch\" \"rollup -c -w --bundleConfigAsCjs\"", + "build:dev": "yarn build:types && NODE_ENV=dev rollup -c --bundleConfigAsCjs" }, "dependencies": { "@babel/runtime": "^7.26.0", @@ -91,6 +92,7 @@ "@typescript-eslint/parser": "^4.26.0", "browserify-zlib": "^0.2.0", "buffer": "^6.0.3", + "concurrently": "^9.1.2", "crypto-browserify": "^3.12.0", "eslint": "^7.30.0", "eslint-config-prettier": "^8.3.0", diff --git a/turbo.json b/turbo.json new file mode 100644 index 000000000..326a78f2b --- /dev/null +++ b/turbo.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://turbo.build/schema.json", + "globalDependencies": [ + "**/.env.*local" + ], + "globalEnv": [ + "NODE_ENV", + "SITEED_NPM_TOKEN" + ], + "tasks": { + "build": { + "dependsOn": [ + "^build" + ], + "outputs": [ + "dist/**", + ".next/**" + ] + }, + "check-types": { + "dependsOn": [ + "^check-types" + ] + }, + "lint": { + "outputs": [] + }, + "dev": { + "cache": false, + "persistent": true, + "outputs": ["dist/**"] + } + } +} diff --git a/yarn.lock b/yarn.lock index 381eb1ea6..44a5bb269 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10939,6 +10939,7 @@ __metadata: "@typescript-eslint/eslint-plugin": ^4.26.0 "@typescript-eslint/parser": ^4.26.0 bufferutil: ^4.0.8 + concurrently: ^9.1.2 cross-fetch: ^4.0.0 date-fns: ^2.29.3 debug: ^4.3.4 @@ -11580,6 +11581,7 @@ __metadata: bowser: ^2.9.0 browserify-zlib: ^0.2.0 buffer: ^6.0.3 + concurrently: ^9.1.2 cross-fetch: ^4.0.0 crypto-browserify: ^3.12.0 debug: ^4.3.4 @@ -25325,6 +25327,24 @@ __metadata: languageName: node linkType: hard +"concurrently@npm:^9.1.2": + version: 9.1.2 + resolution: "concurrently@npm:9.1.2" + dependencies: + chalk: ^4.1.2 + lodash: ^4.17.21 + rxjs: ^7.8.1 + shell-quote: ^1.8.1 + supports-color: ^8.1.1 + tree-kill: ^1.2.2 + yargs: ^17.7.2 + bin: + conc: dist/bin/concurrently.js + concurrently: dist/bin/concurrently.js + checksum: 9e25e8ee6272ada26739aff1fb43e96ac458fafca82f45b8360bdd9115d60bbc679d282dfc52001b861b6e9f32b3063aed975691d8dec9e62807a9679763a1d8 + languageName: node + linkType: hard + "confusing-browser-globals@npm:^1.0.11": version: 1.0.11 resolution: "confusing-browser-globals@npm:1.0.11" @@ -38093,6 +38113,8 @@ __metadata: serve: ^14.2.1 ts-jest: ^29.0.3 ts-node: ^10.9.1 + turbo: ^2.3.3 + turborepo: ^0.0.1 typescript: ^4.3.5 languageName: unknown linkType: soft @@ -45998,7 +46020,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.5.5, rxjs@npm:^7.8.0": +"rxjs@npm:^7.5.5, rxjs@npm:^7.8.0, rxjs@npm:^7.8.1": version: 7.8.1 resolution: "rxjs@npm:7.8.1" dependencies: @@ -46687,6 +46709,13 @@ __metadata: languageName: node linkType: hard +"shell-quote@npm:^1.8.1": + version: 1.8.2 + resolution: "shell-quote@npm:1.8.2" + checksum: 1e97b62ced1c4c5135015978ebf273bed1f425a68cf84163e83fbb0f34b3ff9471e656720dab2b7cbb4ae0f58998e686d17d166c28dfb3662acd009e8bd7faed + languageName: node + linkType: hard + "side-channel@npm:^1.0.4": version: 1.0.4 resolution: "side-channel@npm:1.0.4" @@ -48168,7 +48197,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.0.0": +"supports-color@npm:^8.0.0, supports-color@npm:^8.1.1": version: 8.1.1 resolution: "supports-color@npm:8.1.1" dependencies: @@ -49022,6 +49051,15 @@ __metadata: languageName: node linkType: hard +"tree-kill@npm:^1.2.2": + version: 1.2.2 + resolution: "tree-kill@npm:1.2.2" + bin: + tree-kill: cli.js + checksum: 49117f5f410d19c84b0464d29afb9642c863bc5ba40fcb9a245d474c6d5cc64d1b177a6e6713129eb346b40aebb9d4631d967517f9fbe8251c35b21b13cd96c7 + languageName: node + linkType: hard + "trim-newlines@npm:^3.0.0": version: 3.0.1 resolution: "trim-newlines@npm:3.0.1" @@ -49247,6 +49285,34 @@ __metadata: languageName: node linkType: hard +"turbo-darwin-64@npm:2.3.3": + version: 2.3.3 + resolution: "turbo-darwin-64@npm:2.3.3" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"turbo-darwin-arm64@npm:2.3.3": + version: 2.3.3 + resolution: "turbo-darwin-arm64@npm:2.3.3" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"turbo-linux-64@npm:2.3.3": + version: 2.3.3 + resolution: "turbo-linux-64@npm:2.3.3" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"turbo-linux-arm64@npm:2.3.3": + version: 2.3.3 + resolution: "turbo-linux-arm64@npm:2.3.3" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "turbo-stream@npm:^2.0.0": version: 2.2.0 resolution: "turbo-stream@npm:2.2.0" @@ -49254,6 +49320,56 @@ __metadata: languageName: node linkType: hard +"turbo-windows-64@npm:2.3.3": + version: 2.3.3 + resolution: "turbo-windows-64@npm:2.3.3" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"turbo-windows-arm64@npm:2.3.3": + version: 2.3.3 + resolution: "turbo-windows-arm64@npm:2.3.3" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"turbo@npm:^2.3.3": + version: 2.3.3 + resolution: "turbo@npm:2.3.3" + dependencies: + turbo-darwin-64: 2.3.3 + turbo-darwin-arm64: 2.3.3 + turbo-linux-64: 2.3.3 + turbo-linux-arm64: 2.3.3 + turbo-windows-64: 2.3.3 + turbo-windows-arm64: 2.3.3 + dependenciesMeta: + turbo-darwin-64: + optional: true + turbo-darwin-arm64: + optional: true + turbo-linux-64: + optional: true + turbo-linux-arm64: + optional: true + turbo-windows-64: + optional: true + turbo-windows-arm64: + optional: true + bin: + turbo: bin/turbo + checksum: b495ad024c2586fd090d3aabcc1263a89d72ee96d93b2259b553d9c931e22056a388e030a51bd70a11ec8bec373d1cb0a6ef0931806e8a283cb8360c000d0538 + languageName: node + linkType: hard + +"turborepo@npm:^0.0.1": + version: 0.0.1 + resolution: "turborepo@npm:0.0.1" + checksum: 4975a23063185a87729f5de4fdb42c2118b52d88263128fa1416fe651798725a8d9f3e8a10a099d1188bd5ae04a39a93fe39810ced7e9187230ae9aa3ba645cf + languageName: node + linkType: hard + "tweetnacl-util@npm:^0.15.1": version: 0.15.1 resolution: "tweetnacl-util@npm:0.15.1" From 2d70abd699133555b905e9a32986efebcceb1598 Mon Sep 17 00:00:00 2001 From: abretonc7s Date: Wed, 15 Jan 2025 10:41:52 +0800 Subject: [PATCH 02/28] feat: new nextjs playground --- package.json | 3 +- packages/playground-next/.gitignore | 41 + packages/playground-next/README.md | 36 + packages/playground-next/eslint.config.mjs | 16 + packages/playground-next/next.config.ts | 7 + packages/playground-next/package.json | 27 + packages/playground-next/public/file.svg | 1 + packages/playground-next/public/globe.svg | 1 + packages/playground-next/public/next.svg | 1 + packages/playground-next/public/vercel.svg | 1 + packages/playground-next/public/window.svg | 1 + packages/playground-next/src/app/favicon.ico | Bin 0 -> 25931 bytes packages/playground-next/src/app/globals.css | 42 + packages/playground-next/src/app/layout.tsx | 41 + .../playground-next/src/app/page.module.css | 35 + packages/playground-next/src/app/page.tsx | 57 + packages/playground-next/tsconfig.json | 27 + yarn.lock | 1983 ++++++++++++++++- 18 files changed, 2304 insertions(+), 16 deletions(-) create mode 100644 packages/playground-next/.gitignore create mode 100644 packages/playground-next/README.md create mode 100644 packages/playground-next/eslint.config.mjs create mode 100644 packages/playground-next/next.config.ts create mode 100644 packages/playground-next/package.json create mode 100644 packages/playground-next/public/file.svg create mode 100644 packages/playground-next/public/globe.svg create mode 100644 packages/playground-next/public/next.svg create mode 100644 packages/playground-next/public/vercel.svg create mode 100644 packages/playground-next/public/window.svg create mode 100644 packages/playground-next/src/app/favicon.ico create mode 100644 packages/playground-next/src/app/globals.css create mode 100644 packages/playground-next/src/app/layout.tsx create mode 100644 packages/playground-next/src/app/page.module.css create mode 100644 packages/playground-next/src/app/page.tsx create mode 100644 packages/playground-next/tsconfig.json diff --git a/package.json b/package.json index 5e2875f2f..bf049cf85 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "packages/devexpo", "packages/devreactnative", "packages/devnext", - "packages/deve2e" + "packages/deve2e", + "packages/playground-next" ], "scripts": { "build": "yarn install && cd packages/sdk-socket-server-next && yarn install && cd ../.. && yarn workspaces foreach --verbose run build:pre-tsc && yarn workspaces foreach --verbose --topological --parallel --no-private run build && yarn workspaces foreach --verbose run build:post-tsc ", diff --git a/packages/playground-next/.gitignore b/packages/playground-next/.gitignore new file mode 100644 index 000000000..5ef6a5207 --- /dev/null +++ b/packages/playground-next/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/packages/playground-next/README.md b/packages/playground-next/README.md new file mode 100644 index 000000000..e215bc4cc --- /dev/null +++ b/packages/playground-next/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/packages/playground-next/eslint.config.mjs b/packages/playground-next/eslint.config.mjs new file mode 100644 index 000000000..c85fb67c4 --- /dev/null +++ b/packages/playground-next/eslint.config.mjs @@ -0,0 +1,16 @@ +import { dirname } from "path"; +import { fileURLToPath } from "url"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname, +}); + +const eslintConfig = [ + ...compat.extends("next/core-web-vitals", "next/typescript"), +]; + +export default eslintConfig; diff --git a/packages/playground-next/next.config.ts b/packages/playground-next/next.config.ts new file mode 100644 index 000000000..e9ffa3083 --- /dev/null +++ b/packages/playground-next/next.config.ts @@ -0,0 +1,7 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ +}; + +export default nextConfig; diff --git a/packages/playground-next/package.json b/packages/playground-next/package.json new file mode 100644 index 000000000..9ec03864a --- /dev/null +++ b/packages/playground-next/package.json @@ -0,0 +1,27 @@ +{ + "name": "playground-next", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev --turbopack", + "build": "next build", + "start": "next start", + "lint": "next lint", + "allow-scripts": "echo 'NA'" + }, + "dependencies": { + "@metamask/sdk-react": "workspace:^", + "next": "15.1.4", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@eslint/eslintrc": "^3", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "15.1.4", + "typescript": "^5" + } +} diff --git a/packages/playground-next/public/file.svg b/packages/playground-next/public/file.svg new file mode 100644 index 000000000..004145cdd --- /dev/null +++ b/packages/playground-next/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/playground-next/public/globe.svg b/packages/playground-next/public/globe.svg new file mode 100644 index 000000000..567f17b0d --- /dev/null +++ b/packages/playground-next/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/playground-next/public/next.svg b/packages/playground-next/public/next.svg new file mode 100644 index 000000000..5174b28c5 --- /dev/null +++ b/packages/playground-next/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/playground-next/public/vercel.svg b/packages/playground-next/public/vercel.svg new file mode 100644 index 000000000..770539603 --- /dev/null +++ b/packages/playground-next/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/playground-next/public/window.svg b/packages/playground-next/public/window.svg new file mode 100644 index 000000000..b2b2a44f6 --- /dev/null +++ b/packages/playground-next/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/playground-next/src/app/favicon.ico b/packages/playground-next/src/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..718d6fea4835ec2d246af9800eddb7ffb276240c GIT binary patch literal 25931 zcmeHv30#a{`}aL_*G&7qml|y<+KVaDM2m#dVr!KsA!#An?kSQM(q<_dDNCpjEux83 zLb9Z^XxbDl(w>%i@8hT6>)&Gu{h#Oeyszu?xtw#Zb1mO{pgX9699l+Qppw7jXaYf~-84xW z)w4x8?=youko|}Vr~(D$UXIbiXABHh`p1?nn8Po~fxRJv}|0e(BPs|G`(TT%kKVJAdg5*Z|x0leQq0 zkdUBvb#>9F()jo|T~kx@OM8$9wzs~t2l;K=woNssA3l6|sx2r3+kdfVW@e^8e*E}v zA1y5{bRi+3Z`uD3{F7LgFJDdvm;nJilkzDku>BwXH(8ItVCXk*-lSJnR?-2UN%hJ){&rlvg`CDTj z)Bzo!3v7Ou#83zEDEFcKt(f1E0~=rqeEbTnMvWR#{+9pg%7G8y>u1OVRUSoox-ovF z2Ydma(;=YuBY(eI|04{hXzZD6_f(v~H;C~y5=DhAC{MMS>2fm~1H_t2$56pc$NH8( z5bH|<)71dV-_oCHIrzrT`2s-5w_+2CM0$95I6X8p^r!gHp+j_gd;9O<1~CEQQGS8) zS9Qh3#p&JM-G8rHekNmKVewU;pJRcTAog68KYo^dRo}(M>36U4Us zfgYWSiHZL3;lpWT=zNAW>Dh#mB!_@Lg%$ms8N-;aPqMn+C2HqZgz&9~Eu z4|Kp<`$q)Uw1R?y(~S>ePdonHxpV1#eSP1B;Ogo+-Pk}6#0GsZZ5!||ev2MGdh}_m z{DeR7?0-1^zVs&`AV6Vt;r3`I`OI_wgs*w=eO%_#7Kepl{B@xiyCANc(l zzIyd4y|c6PXWq9-|KM8(zIk8LPk(>a)zyFWjhT!$HJ$qX1vo@d25W<fvZQ2zUz5WRc(UnFMKHwe1| zWmlB1qdbiA(C0jmnV<}GfbKtmcu^2*P^O?MBLZKt|As~ge8&AAO~2K@zbXelK|4T<{|y4`raF{=72kC2Kn(L4YyenWgrPiv z@^mr$t{#X5VuIMeL!7Ab6_kG$&#&5p*Z{+?5U|TZ`B!7llpVmp@skYz&n^8QfPJzL z0G6K_OJM9x+Wu2gfN45phANGt{7=C>i34CV{Xqlx(fWpeAoj^N0Biu`w+MVcCUyU* zDZuzO0>4Z6fbu^T_arWW5n!E45vX8N=bxTVeFoep_G#VmNlQzAI_KTIc{6>c+04vr zx@W}zE5JNSU>!THJ{J=cqjz+4{L4A{Ob9$ZJ*S1?Ggg3klFp!+Y1@K+pK1DqI|_gq z5ZDXVpge8-cs!o|;K73#YXZ3AShj50wBvuq3NTOZ`M&qtjj#GOFfgExjg8Gn8>Vq5 z`85n+9|!iLCZF5$HJ$Iu($dm?8~-ofu}tEc+-pyke=3!im#6pk_Wo8IA|fJwD&~~F zc16osQ)EBo58U7XDuMexaPRjU@h8tXe%S{fA0NH3vGJFhuyyO!Uyl2^&EOpX{9As0 zWj+P>{@}jxH)8|r;2HdupP!vie{sJ28b&bo!8`D^x}TE$%zXNb^X1p@0PJ86`dZyj z%ce7*{^oo+6%&~I!8hQy-vQ7E)0t0ybH4l%KltWOo~8cO`T=157JqL(oq_rC%ea&4 z2NcTJe-HgFjNg-gZ$6!Y`SMHrlj}Etf7?r!zQTPPSv}{so2e>Fjs1{gzk~LGeesX%r(Lh6rbhSo_n)@@G-FTQy93;l#E)hgP@d_SGvyCp0~o(Y;Ee8{ zdVUDbHm5`2taPUOY^MAGOw*>=s7=Gst=D+p+2yON!0%Hk` zz5mAhyT4lS*T3LS^WSxUy86q&GnoHxzQ6vm8)VS}_zuqG?+3td68_x;etQAdu@sc6 zQJ&5|4(I?~3d-QOAODHpZ=hlSg(lBZ!JZWCtHHSj`0Wh93-Uk)_S%zsJ~aD>{`A0~ z9{AG(e|q3g5B%wYKRxiL2Y$8(4w6bzchKuloQW#e&S3n+P- z8!ds-%f;TJ1>)v)##>gd{PdS2Oc3VaR`fr=`O8QIO(6(N!A?pr5C#6fc~Ge@N%Vvu zaoAX2&(a6eWy_q&UwOhU)|P3J0Qc%OdhzW=F4D|pt0E4osw;%<%Dn58hAWD^XnZD= z>9~H(3bmLtxpF?a7su6J7M*x1By7YSUbxGi)Ot0P77`}P3{)&5Un{KD?`-e?r21!4vTTnN(4Y6Lin?UkSM z`MXCTC1@4A4~mvz%Rh2&EwY))LeoT=*`tMoqcEXI>TZU9WTP#l?uFv+@Dn~b(>xh2 z;>B?;Tz2SR&KVb>vGiBSB`@U7VIWFSo=LDSb9F{GF^DbmWAfpms8Sx9OX4CnBJca3 zlj9(x!dIjN?OG1X4l*imJNvRCk}F%!?SOfiOq5y^mZW)jFL@a|r-@d#f7 z2gmU8L3IZq0ynIws=}~m^#@&C%J6QFo~Mo4V`>v7MI-_!EBMMtb%_M&kvAaN)@ZVw z+`toz&WG#HkWDjnZE!6nk{e-oFdL^$YnbOCN}JC&{$#$O27@|Tn-skXr)2ml2~O!5 zX+gYoxhoc7qoU?C^3~&!U?kRFtnSEecWuH0B0OvLodgUAi}8p1 zrO6RSXHH}DMc$&|?D004DiOVMHV8kXCP@7NKB zgaZq^^O<7PoKEp72kby@W0Z!Y*Ay{&vfg#C&gG@YVR9g?FEocMUi1gSN$+V+ayF45{a zuDZDTN}mS|;BO%gEf}pjBfN2-gIrU#G5~cucA;dokXW89%>AyXJJI z9X4UlIWA|ZYHgbI z5?oFk@A=Ik7lrEQPDH!H+b`7_Y~aDb_qa=B2^Y&Ow41cU=4WDd40dp5(QS-WMN-=Y z9g;6_-JdNU;|6cPwf$ak*aJIcwL@1n$#l~zi{c{EW?T;DaW*E8DYq?Umtz{nJ&w-M zEMyTDrC&9K$d|kZe2#ws6)L=7K+{ zQw{XnV6UC$6-rW0emqm8wJoeZK)wJIcV?dST}Z;G0Arq{dVDu0&4kd%N!3F1*;*pW zR&qUiFzK=@44#QGw7k1`3t_d8&*kBV->O##t|tonFc2YWrL7_eqg+=+k;!F-`^b8> z#KWCE8%u4k@EprxqiV$VmmtiWxDLgnGu$Vs<8rppV5EajBXL4nyyZM$SWVm!wnCj-B!Wjqj5-5dNXukI2$$|Bu3Lrw}z65Lc=1G z^-#WuQOj$hwNGG?*CM_TO8Bg-1+qc>J7k5c51U8g?ZU5n?HYor;~JIjoWH-G>AoUP ztrWWLbRNqIjW#RT*WqZgPJXU7C)VaW5}MiijYbABmzoru6EmQ*N8cVK7a3|aOB#O& zBl8JY2WKfmj;h#Q!pN%9o@VNLv{OUL?rixHwOZuvX7{IJ{(EdPpuVFoQqIOa7giLVkBOKL@^smUA!tZ1CKRK}#SSM)iQHk)*R~?M!qkCruaS!#oIL1c z?J;U~&FfH#*98^G?i}pA{ z9Jg36t4=%6mhY(quYq*vSxptes9qy|7xSlH?G=S@>u>Ebe;|LVhs~@+06N<4CViBk zUiY$thvX;>Tby6z9Y1edAMQaiH zm^r3v#$Q#2T=X>bsY#D%s!bhs^M9PMAcHbCc0FMHV{u-dwlL;a1eJ63v5U*?Q_8JO zT#50!RD619#j_Uf))0ooADz~*9&lN!bBDRUgE>Vud-i5ck%vT=r^yD*^?Mp@Q^v+V zG#-?gKlr}Eeqifb{|So?HM&g91P8|av8hQoCmQXkd?7wIJwb z_^v8bbg`SAn{I*4bH$u(RZ6*xUhuA~hc=8czK8SHEKTzSxgbwi~9(OqJB&gwb^l4+m`k*Q;_?>Y-APi1{k zAHQ)P)G)f|AyjSgcCFps)Fh6Bca*Xznq36!pV6Az&m{O8$wGFD? zY&O*3*J0;_EqM#jh6^gMQKpXV?#1?>$ml1xvh8nSN>-?H=V;nJIwB07YX$e6vLxH( zqYwQ>qxwR(i4f)DLd)-$P>T-no_c!LsN@)8`e;W@)-Hj0>nJ-}Kla4-ZdPJzI&Mce zv)V_j;(3ERN3_@I$N<^|4Lf`B;8n+bX@bHbcZTopEmDI*Jfl)-pFDvo6svPRoo@(x z);_{lY<;);XzT`dBFpRmGrr}z5u1=pC^S-{ce6iXQlLGcItwJ^mZx{m$&DA_oEZ)B{_bYPq-HA zcH8WGoBG(aBU_j)vEy+_71T34@4dmSg!|M8Vf92Zj6WH7Q7t#OHQqWgFE3ARt+%!T z?oLovLVlnf?2c7pTc)~cc^($_8nyKwsN`RA-23ed3sdj(ys%pjjM+9JrctL;dy8a( z@en&CQmnV(()bu|Y%G1-4a(6x{aLytn$T-;(&{QIJB9vMox11U-1HpD@d(QkaJdEb zG{)+6Dos_L+O3NpWo^=gR?evp|CqEG?L&Ut#D*KLaRFOgOEK(Kq1@!EGcTfo+%A&I z=dLbB+d$u{sh?u)xP{PF8L%;YPPW53+@{>5W=Jt#wQpN;0_HYdw1{ksf_XhO4#2F= zyPx6Lx2<92L-;L5PD`zn6zwIH`Jk($?Qw({erA$^bC;q33hv!d!>%wRhj# zal^hk+WGNg;rJtb-EB(?czvOM=H7dl=vblBwAv>}%1@{}mnpUznfq1cE^sgsL0*4I zJ##!*B?=vI_OEVis5o+_IwMIRrpQyT_Sq~ZU%oY7c5JMIADzpD!Upz9h@iWg_>>~j zOLS;wp^i$-E?4<_cp?RiS%Rd?i;f*mOz=~(&3lo<=@(nR!_Rqiprh@weZlL!t#NCc zO!QTcInq|%#>OVgobj{~ixEUec`E25zJ~*DofsQdzIa@5^nOXj2T;8O`l--(QyU^$t?TGY^7#&FQ+2SS3B#qK*k3`ye?8jUYSajE5iBbJls75CCc(m3dk{t?- zopcER9{Z?TC)mk~gpi^kbbu>b-+a{m#8-y2^p$ka4n60w;Sc2}HMf<8JUvhCL0B&Btk)T`ctE$*qNW8L$`7!r^9T+>=<=2qaq-;ll2{`{Rg zc5a0ZUI$oG&j-qVOuKa=*v4aY#IsoM+1|c4Z)<}lEDvy;5huB@1RJPquU2U*U-;gu z=En2m+qjBzR#DEJDO`WU)hdd{Vj%^0V*KoyZ|5lzV87&g_j~NCjwv0uQVqXOb*QrQ zy|Qn`hxx(58c70$E;L(X0uZZ72M1!6oeg)(cdKO ze0gDaTz+ohR-#d)NbAH4x{I(21yjwvBQfmpLu$)|m{XolbgF!pmsqJ#D}(ylp6uC> z{bqtcI#hT#HW=wl7>p!38sKsJ`r8}lt-q%Keqy%u(xk=yiIJiUw6|5IvkS+#?JTBl z8H5(Q?l#wzazujH!8o>1xtn8#_w+397*_cy8!pQGP%K(Ga3pAjsaTbbXJlQF_+m+-UpUUent@xM zg%jqLUExj~o^vQ3Gl*>wh=_gOr2*|U64_iXb+-111aH}$TjeajM+I20xw(((>fej-@CIz4S1pi$(#}P7`4({6QS2CaQS4NPENDp>sAqD z$bH4KGzXGffkJ7R>V>)>tC)uax{UsN*dbeNC*v}#8Y#OWYwL4t$ePR?VTyIs!wea+ z5Urmc)X|^`MG~*dS6pGSbU+gPJoq*^a=_>$n4|P^w$sMBBy@f*Z^Jg6?n5?oId6f{ z$LW4M|4m502z0t7g<#Bx%X;9<=)smFolV&(V^(7Cv2-sxbxopQ!)*#ZRhTBpx1)Fc zNm1T%bONzv6@#|dz(w02AH8OXe>kQ#1FMCzO}2J_mST)+ExmBr9cva-@?;wnmWMOk z{3_~EX_xadgJGv&H@zK_8{(x84`}+c?oSBX*Ge3VdfTt&F}yCpFP?CpW+BE^cWY0^ zb&uBN!Ja3UzYHK-CTyA5=L zEMW{l3Usky#ly=7px648W31UNV@K)&Ub&zP1c7%)`{);I4b0Q<)B}3;NMG2JH=X$U zfIW4)4n9ZM`-yRj67I)YSLDK)qfUJ_ij}a#aZN~9EXrh8eZY2&=uY%2N0UFF7<~%M zsB8=erOWZ>Ct_#^tHZ|*q`H;A)5;ycw*IcmVxi8_0Xk}aJA^ath+E;xg!x+As(M#0=)3!NJR6H&9+zd#iP(m0PIW8$ z1Y^VX`>jm`W!=WpF*{ioM?C9`yOR>@0q=u7o>BP-eSHqCgMDj!2anwH?s%i2p+Q7D zzszIf5XJpE)IG4;d_(La-xenmF(tgAxK`Y4sQ}BSJEPs6N_U2vI{8=0C_F?@7<(G; zo$~G=8p+076G;`}>{MQ>t>7cm=zGtfbdDXm6||jUU|?X?CaE?(<6bKDYKeHlz}DA8 zXT={X=yp_R;HfJ9h%?eWvQ!dRgz&Su*JfNt!Wu>|XfU&68iRikRrHRW|ZxzRR^`eIGt zIeiDgVS>IeExKVRWW8-=A=yA`}`)ZkWBrZD`hpWIxBGkh&f#ijr449~m`j6{4jiJ*C!oVA8ZC?$1RM#K(_b zL9TW)kN*Y4%^-qPpMP7d4)o?Nk#>aoYHT(*g)qmRUb?**F@pnNiy6Fv9rEiUqD(^O zzyS?nBrX63BTRYduaG(0VVG2yJRe%o&rVrLjbxTaAFTd8s;<<@Qs>u(<193R8>}2_ zuwp{7;H2a*X7_jryzriZXMg?bTuegABb^87@SsKkr2)0Gyiax8KQWstw^v#ix45EVrcEhr>!NMhprl$InQMzjSFH54x5k9qHc`@9uKQzvL4ihcq{^B zPrVR=o_ic%Y>6&rMN)hTZsI7I<3&`#(nl+3y3ys9A~&^=4?PL&nd8)`OfG#n zwAMN$1&>K++c{^|7<4P=2y(B{jJsQ0a#U;HTo4ZmWZYvI{+s;Td{Yzem%0*k#)vjpB zia;J&>}ICate44SFYY3vEelqStQWFihx%^vQ@Do(sOy7yR2@WNv7Y9I^yL=nZr3mb zXKV5t@=?-Sk|b{XMhA7ZGB@2hqsx}4xwCW!in#C zI@}scZlr3-NFJ@NFaJlhyfcw{k^vvtGl`N9xSo**rDW4S}i zM9{fMPWo%4wYDG~BZ18BD+}h|GQKc-g^{++3MY>}W_uq7jGHx{mwE9fZiPCoxN$+7 zrODGGJrOkcPQUB(FD5aoS4g~7#6NR^ma7-!>mHuJfY5kTe6PpNNKC9GGRiu^L31uG z$7v`*JknQHsYB!Tm_W{a32TM099djW%5e+j0Ve_ct}IM>XLF1Ap+YvcrLV=|CKo6S zb+9Nl3_YdKP6%Cxy@6TxZ>;4&nTneadr z_ES90ydCev)LV!dN=#(*f}|ZORFdvkYBni^aLbUk>BajeWIOcmHP#8S)*2U~QKI%S zyrLmtPqb&TphJ;>yAxri#;{uyk`JJqODDw%(Z=2`1uc}br^V%>j!gS)D*q*f_-qf8&D;W1dJgQMlaH5er zN2U<%Smb7==vE}dDI8K7cKz!vs^73o9f>2sgiTzWcwY|BMYHH5%Vn7#kiw&eItCqa zIkR2~Q}>X=Ar8W|^Ms41Fm8o6IB2_j60eOeBB1Br!boW7JnoeX6Gs)?7rW0^5psc- zjS16yb>dFn>KPOF;imD}e!enuIniFzv}n$m2#gCCv4jM#ArwlzZ$7@9&XkFxZ4n!V zj3dyiwW4Ki2QG{@i>yuZXQizw_OkZI^-3otXC{!(lUpJF33gI60ak;Uqitp74|B6I zgg{b=Iz}WkhCGj1M=hu4#Aw173YxIVbISaoc z-nLZC*6Tgivd5V`K%GxhBsp@SUU60-rfc$=wb>zdJzXS&-5(NRRodFk;Kxk!S(O(a0e7oY=E( zAyS;Ow?6Q&XA+cnkCb{28_1N8H#?J!*$MmIwLq^*T_9-z^&UE@A(z9oGYtFy6EZef LrJugUA?W`A8`#=m literal 0 HcmV?d00001 diff --git a/packages/playground-next/src/app/globals.css b/packages/playground-next/src/app/globals.css new file mode 100644 index 000000000..e3734be15 --- /dev/null +++ b/packages/playground-next/src/app/globals.css @@ -0,0 +1,42 @@ +:root { + --background: #ffffff; + --foreground: #171717; +} + +@media (prefers-color-scheme: dark) { + :root { + --background: #0a0a0a; + --foreground: #ededed; + } +} + +html, +body { + max-width: 100vw; + overflow-x: hidden; +} + +body { + color: var(--foreground); + background: var(--background); + font-family: Arial, Helvetica, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +* { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +a { + color: inherit; + text-decoration: none; +} + +@media (prefers-color-scheme: dark) { + html { + color-scheme: dark; + } +} diff --git a/packages/playground-next/src/app/layout.tsx b/packages/playground-next/src/app/layout.tsx new file mode 100644 index 000000000..2be6aef14 --- /dev/null +++ b/packages/playground-next/src/app/layout.tsx @@ -0,0 +1,41 @@ +'use client'; + +import { Geist } from "next/font/google"; +import "./globals.css"; +import { MetaMaskProvider } from "@metamask/sdk-react"; +import { useEffect, useState } from "react"; + +const geist = Geist({ + variable: "--font-geist", + subsets: ["latin"], +}); + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + const [dappUrl, setDappUrl] = useState(""); + + useEffect(() => { + setDappUrl(window.location.href); + }, []); + + return ( + + + + <>{children} + + + + ); +} diff --git a/packages/playground-next/src/app/page.module.css b/packages/playground-next/src/app/page.module.css new file mode 100644 index 000000000..83ff5a1e2 --- /dev/null +++ b/packages/playground-next/src/app/page.module.css @@ -0,0 +1,35 @@ +.container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: 100vh; + padding: 20px; + gap: 20px; +} + +.button { + background: var(--foreground); + color: var(--background); + border: none; + padding: 12px 24px; + border-radius: 8px; + font-family: var(--font-geist); + cursor: pointer; + transition: opacity 0.2s; +} + +.button:hover { + opacity: 0.8; +} + +.address { + font-family: var(--font-geist); + background: var(--foreground); + color: var(--background); + padding: 12px 24px; + border-radius: 8px; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/packages/playground-next/src/app/page.tsx b/packages/playground-next/src/app/page.tsx new file mode 100644 index 000000000..f2683b8fc --- /dev/null +++ b/packages/playground-next/src/app/page.tsx @@ -0,0 +1,57 @@ +'use client'; + +import { useSDK } from '@metamask/sdk-react'; +import styles from './page.module.css'; +import { useState } from 'react'; + +interface AccountInfo { + account: string; + balance: string; +} + +export default function Home() { + const { sdk } = useSDK(); + const [account, setAccount] = useState(null); + + const connectWallet = async (): Promise => { + try { + const accounts = await sdk?.connect(); + + if (accounts?.[0]) { + const provider = sdk?.getProvider(); + const balance = await provider?.request({ + method: 'eth_getBalance', + params: [accounts[0], 'latest'] + }); + + setAccount({ + account: accounts[0], + balance: balance ? (parseInt(balance as string, 16)).toString() : '0' + }); + } + } catch (err) { + console.error('Failed to connect wallet:', err); + } + }; + + return ( +
+

Simple Web3 Dapp

+ + {!account ? ( + + ) : ( + <> +
+ Address: {account.account} +
+
+ Balance: {account.balance} Wei +
+ + )} +
+ ); +} diff --git a/packages/playground-next/tsconfig.json b/packages/playground-next/tsconfig.json new file mode 100644 index 000000000..c1334095f --- /dev/null +++ b/packages/playground-next/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/yarn.lock b/yarn.lock index 44a5bb269..bfa304464 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6568,6 +6568,15 @@ __metadata: languageName: node linkType: hard +"@emnapi/runtime@npm:^1.2.0": + version: 1.3.1 + resolution: "@emnapi/runtime@npm:1.3.1" + dependencies: + tslib: ^2.4.0 + checksum: 9a16ae7905a9c0e8956cf1854ef74e5087fbf36739abdba7aa6b308485aafdc993da07c19d7af104cd5f8e425121120852851bb3a0f78e2160e420a36d47f42f + languageName: node + linkType: hard + "@emotion/babel-plugin@npm:^11.11.0": version: 11.11.0 resolution: "@emotion/babel-plugin@npm:11.11.0" @@ -7073,6 +7082,13 @@ __metadata: languageName: node linkType: hard +"@eslint-community/regexpp@npm:^4.12.1": + version: 4.12.1 + resolution: "@eslint-community/regexpp@npm:4.12.1" + checksum: 0d628680e204bc316d545b4993d3658427ca404ae646ce541fcc65306b8c712c340e5e573e30fb9f85f4855c0c5f6dca9868931f2fcced06417fbe1a0c6cd2d6 + languageName: node + linkType: hard + "@eslint-community/regexpp@npm:^4.4.0": version: 4.5.1 resolution: "@eslint-community/regexpp@npm:4.5.1" @@ -7094,6 +7110,26 @@ __metadata: languageName: node linkType: hard +"@eslint/config-array@npm:^0.19.0": + version: 0.19.1 + resolution: "@eslint/config-array@npm:0.19.1" + dependencies: + "@eslint/object-schema": ^2.1.5 + debug: ^4.3.1 + minimatch: ^3.1.2 + checksum: 421aad712a5ef1a3d118b5e0857f79c080f9dd619a76ce19d20105d381521583786f7abb1195744af9e62a5124e6657066eb6780e920f4001846bd91c1a665f0 + languageName: node + linkType: hard + +"@eslint/core@npm:^0.10.0": + version: 0.10.0 + resolution: "@eslint/core@npm:0.10.0" + dependencies: + "@types/json-schema": ^7.0.15 + checksum: 851fa099b3fef00e7ff8ece14523aff0822d3e1b47b047ab0a0d898e80c1362a22aa8b7778727231c383246932ecb63de79b4448ec1e500901c578580b087573 + languageName: node + linkType: hard + "@eslint/eslintrc@npm:^0.4.3": version: 0.4.3 resolution: "@eslint/eslintrc@npm:0.4.3" @@ -7179,6 +7215,23 @@ __metadata: languageName: node linkType: hard +"@eslint/eslintrc@npm:^3, @eslint/eslintrc@npm:^3.2.0": + version: 3.2.0 + resolution: "@eslint/eslintrc@npm:3.2.0" + dependencies: + ajv: ^6.12.4 + debug: ^4.3.2 + espree: ^10.0.1 + globals: ^14.0.0 + ignore: ^5.2.0 + import-fresh: ^3.2.1 + js-yaml: ^4.1.0 + minimatch: ^3.1.2 + strip-json-comments: ^3.1.1 + checksum: c898e4d12f4c9a79a61ee3c91e38eea5627a04e021cb749191e8537445858bfe32f810eca0cb2dc9902b8ad8b65ca07ef7221dc4bad52afe60cbbf50ec56c236 + languageName: node + linkType: hard + "@eslint/js@npm:8.44.0": version: 8.44.0 resolution: "@eslint/js@npm:8.44.0" @@ -7207,6 +7260,30 @@ __metadata: languageName: node linkType: hard +"@eslint/js@npm:9.18.0": + version: 9.18.0 + resolution: "@eslint/js@npm:9.18.0" + checksum: a47cfcc684f87094992fe4a5c5e54018393231d8d42bd2150a08eb167813a6bf8d7c7ccbc9611933e5f782ff3b96a06c9be8d19342965cadd4530a45521b8981 + languageName: node + linkType: hard + +"@eslint/object-schema@npm:^2.1.5": + version: 2.1.5 + resolution: "@eslint/object-schema@npm:2.1.5" + checksum: 5facffc832bae93c510f4d38f0f1cbfebd3d7ec772ece6b801bd09bf2dce52e781f4dea500aa133d02257e04ed6a3958fa18cbaed1f9623974a804ee60a8ca54 + languageName: node + linkType: hard + +"@eslint/plugin-kit@npm:^0.2.5": + version: 0.2.5 + resolution: "@eslint/plugin-kit@npm:0.2.5" + dependencies: + "@eslint/core": ^0.10.0 + levn: ^0.4.1 + checksum: 423db33e67ff16f6db71bf8bfc8d5b0c2c4fe6f2209131e5886a573bf994bfc72ab4f825068d6521f186247731d4c9d48eb42a5e5ce389c6faa275752c0e9459 + languageName: node + linkType: hard + "@ethereumjs/common@npm:^3.2.0": version: 3.2.0 resolution: "@ethereumjs/common@npm:3.2.0" @@ -9099,6 +9176,23 @@ __metadata: languageName: node linkType: hard +"@humanfs/core@npm:^0.19.1": + version: 0.19.1 + resolution: "@humanfs/core@npm:0.19.1" + checksum: 611e0545146f55ddfdd5c20239cfb7911f9d0e28258787c4fc1a1f6214250830c9367aaaeace0096ed90b6739bee1e9c52ad5ba8adaf74ab8b449119303babfe + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.6": + version: 0.16.6 + resolution: "@humanfs/node@npm:0.16.6" + dependencies: + "@humanfs/core": ^0.19.1 + "@humanwhocodes/retry": ^0.3.0 + checksum: f9cb52bb235f8b9c6fcff43a7e500669a38f8d6ce26593404a9b56365a1644e0ed60c720dc65ff6a696b1f85f3563ab055bb554ec8674f2559085ba840e47710 + languageName: node + linkType: hard + "@humanwhocodes/config-array@npm:^0.11.10": version: 0.11.10 resolution: "@humanwhocodes/config-array@npm:0.11.10" @@ -9171,6 +9265,195 @@ __metadata: languageName: node linkType: hard +"@humanwhocodes/retry@npm:^0.3.0": + version: 0.3.1 + resolution: "@humanwhocodes/retry@npm:0.3.1" + checksum: 7e5517bb51dbea3e02ab6cacef59a8f4b0ca023fc4b0b8cbc40de0ad29f46edd50b897c6e7fba79366a0217e3f48e2da8975056f6c35cfe19d9cc48f1d03c1dd + languageName: node + linkType: hard + +"@humanwhocodes/retry@npm:^0.4.1": + version: 0.4.1 + resolution: "@humanwhocodes/retry@npm:0.4.1" + checksum: f11167c28e8266faba470fd273cbaafe2827523492bc18c5623015adb7ed66f46b2e542e3d756fed9ca614300249267814220c2f5f03a59e07fdfa64fc14ad52 + languageName: node + linkType: hard + +"@img/sharp-darwin-arm64@npm:0.33.5": + version: 0.33.5 + resolution: "@img/sharp-darwin-arm64@npm:0.33.5" + dependencies: + "@img/sharp-libvips-darwin-arm64": 1.0.4 + dependenciesMeta: + "@img/sharp-libvips-darwin-arm64": + optional: true + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@img/sharp-darwin-x64@npm:0.33.5": + version: 0.33.5 + resolution: "@img/sharp-darwin-x64@npm:0.33.5" + dependencies: + "@img/sharp-libvips-darwin-x64": 1.0.4 + dependenciesMeta: + "@img/sharp-libvips-darwin-x64": + optional: true + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@img/sharp-libvips-darwin-arm64@npm:1.0.4": + version: 1.0.4 + resolution: "@img/sharp-libvips-darwin-arm64@npm:1.0.4" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@img/sharp-libvips-darwin-x64@npm:1.0.4": + version: 1.0.4 + resolution: "@img/sharp-libvips-darwin-x64@npm:1.0.4" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-arm64@npm:1.0.4": + version: 1.0.4 + resolution: "@img/sharp-libvips-linux-arm64@npm:1.0.4" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-arm@npm:1.0.5": + version: 1.0.5 + resolution: "@img/sharp-libvips-linux-arm@npm:1.0.5" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-s390x@npm:1.0.4": + version: 1.0.4 + resolution: "@img/sharp-libvips-linux-s390x@npm:1.0.4" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-x64@npm:1.0.4": + version: 1.0.4 + resolution: "@img/sharp-libvips-linux-x64@npm:1.0.4" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linuxmusl-arm64@npm:1.0.4": + version: 1.0.4 + resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.0.4" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-libvips-linuxmusl-x64@npm:1.0.4": + version: 1.0.4 + resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.0.4" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-linux-arm64@npm:0.33.5": + version: 0.33.5 + resolution: "@img/sharp-linux-arm64@npm:0.33.5" + dependencies: + "@img/sharp-libvips-linux-arm64": 1.0.4 + dependenciesMeta: + "@img/sharp-libvips-linux-arm64": + optional: true + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-arm@npm:0.33.5": + version: 0.33.5 + resolution: "@img/sharp-linux-arm@npm:0.33.5" + dependencies: + "@img/sharp-libvips-linux-arm": 1.0.5 + dependenciesMeta: + "@img/sharp-libvips-linux-arm": + optional: true + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-s390x@npm:0.33.5": + version: 0.33.5 + resolution: "@img/sharp-linux-s390x@npm:0.33.5" + dependencies: + "@img/sharp-libvips-linux-s390x": 1.0.4 + dependenciesMeta: + "@img/sharp-libvips-linux-s390x": + optional: true + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-x64@npm:0.33.5": + version: 0.33.5 + resolution: "@img/sharp-linux-x64@npm:0.33.5" + dependencies: + "@img/sharp-libvips-linux-x64": 1.0.4 + dependenciesMeta: + "@img/sharp-libvips-linux-x64": + optional: true + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linuxmusl-arm64@npm:0.33.5": + version: 0.33.5 + resolution: "@img/sharp-linuxmusl-arm64@npm:0.33.5" + dependencies: + "@img/sharp-libvips-linuxmusl-arm64": 1.0.4 + dependenciesMeta: + "@img/sharp-libvips-linuxmusl-arm64": + optional: true + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-linuxmusl-x64@npm:0.33.5": + version: 0.33.5 + resolution: "@img/sharp-linuxmusl-x64@npm:0.33.5" + dependencies: + "@img/sharp-libvips-linuxmusl-x64": 1.0.4 + dependenciesMeta: + "@img/sharp-libvips-linuxmusl-x64": + optional: true + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-wasm32@npm:0.33.5": + version: 0.33.5 + resolution: "@img/sharp-wasm32@npm:0.33.5" + dependencies: + "@emnapi/runtime": ^1.2.0 + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@img/sharp-win32-ia32@npm:0.33.5": + version: 0.33.5 + resolution: "@img/sharp-win32-ia32@npm:0.33.5" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@img/sharp-win32-x64@npm:0.33.5": + version: 0.33.5 + resolution: "@img/sharp-win32-x64@npm:0.33.5" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@ioredis/commands@npm:^1.1.1": version: 1.2.0 resolution: "@ioredis/commands@npm:1.2.0" @@ -11900,6 +12183,13 @@ __metadata: languageName: node linkType: hard +"@next/env@npm:15.1.4": + version: 15.1.4 + resolution: "@next/env@npm:15.1.4" + checksum: bb26fa2184a81d0d5265962d4f162f32d5a5a19281af475ab32e13bd700b4cf32164ca4add9fd1f849f4c970bad7a7cca25ed3414e94396472a94e2d567c4600 + languageName: node + linkType: hard + "@next/eslint-plugin-next@npm:13.2.4": version: 13.2.4 resolution: "@next/eslint-plugin-next@npm:13.2.4" @@ -11909,6 +12199,15 @@ __metadata: languageName: node linkType: hard +"@next/eslint-plugin-next@npm:15.1.4": + version: 15.1.4 + resolution: "@next/eslint-plugin-next@npm:15.1.4" + dependencies: + fast-glob: 3.3.1 + checksum: f09cfb50cf26672df5cbeac9594ff4ce2196eeb3a3192f7f53b2b88770d7e40c5bd4a39e4129a7cae5d623d65c7f5f4d1580ba289a2922438073bae7326cae40 + languageName: node + linkType: hard + "@next/swc-android-arm-eabi@npm:13.2.4": version: 13.2.4 resolution: "@next/swc-android-arm-eabi@npm:13.2.4" @@ -11937,6 +12236,13 @@ __metadata: languageName: node linkType: hard +"@next/swc-darwin-arm64@npm:15.1.4": + version: 15.1.4 + resolution: "@next/swc-darwin-arm64@npm:15.1.4" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@next/swc-darwin-x64@npm:13.2.4": version: 13.2.4 resolution: "@next/swc-darwin-x64@npm:13.2.4" @@ -11951,6 +12257,13 @@ __metadata: languageName: node linkType: hard +"@next/swc-darwin-x64@npm:15.1.4": + version: 15.1.4 + resolution: "@next/swc-darwin-x64@npm:15.1.4" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@next/swc-freebsd-x64@npm:13.2.4": version: 13.2.4 resolution: "@next/swc-freebsd-x64@npm:13.2.4" @@ -11979,6 +12292,13 @@ __metadata: languageName: node linkType: hard +"@next/swc-linux-arm64-gnu@npm:15.1.4": + version: 15.1.4 + resolution: "@next/swc-linux-arm64-gnu@npm:15.1.4" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@next/swc-linux-arm64-musl@npm:13.2.4": version: 13.2.4 resolution: "@next/swc-linux-arm64-musl@npm:13.2.4" @@ -11993,6 +12313,13 @@ __metadata: languageName: node linkType: hard +"@next/swc-linux-arm64-musl@npm:15.1.4": + version: 15.1.4 + resolution: "@next/swc-linux-arm64-musl@npm:15.1.4" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "@next/swc-linux-x64-gnu@npm:13.2.4": version: 13.2.4 resolution: "@next/swc-linux-x64-gnu@npm:13.2.4" @@ -12007,6 +12334,13 @@ __metadata: languageName: node linkType: hard +"@next/swc-linux-x64-gnu@npm:15.1.4": + version: 15.1.4 + resolution: "@next/swc-linux-x64-gnu@npm:15.1.4" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@next/swc-linux-x64-musl@npm:13.2.4": version: 13.2.4 resolution: "@next/swc-linux-x64-musl@npm:13.2.4" @@ -12021,6 +12355,13 @@ __metadata: languageName: node linkType: hard +"@next/swc-linux-x64-musl@npm:15.1.4": + version: 15.1.4 + resolution: "@next/swc-linux-x64-musl@npm:15.1.4" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@next/swc-win32-arm64-msvc@npm:13.2.4": version: 13.2.4 resolution: "@next/swc-win32-arm64-msvc@npm:13.2.4" @@ -12035,6 +12376,13 @@ __metadata: languageName: node linkType: hard +"@next/swc-win32-arm64-msvc@npm:15.1.4": + version: 15.1.4 + resolution: "@next/swc-win32-arm64-msvc@npm:15.1.4" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@next/swc-win32-ia32-msvc@npm:13.2.4": version: 13.2.4 resolution: "@next/swc-win32-ia32-msvc@npm:13.2.4" @@ -12063,6 +12411,13 @@ __metadata: languageName: node linkType: hard +"@next/swc-win32-x64-msvc@npm:15.1.4": + version: 15.1.4 + resolution: "@next/swc-win32-x64-msvc@npm:15.1.4" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1": version: 5.1.1-v1 resolution: "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1" @@ -15456,6 +15811,13 @@ __metadata: languageName: node linkType: hard +"@rtsao/scc@npm:^1.1.0": + version: 1.1.0 + resolution: "@rtsao/scc@npm:1.1.0" + checksum: 17d04adf404e04c1e61391ed97bca5117d4c2767a76ae3e879390d6dec7b317fcae68afbf9e98badee075d0b64fa60f287729c4942021b4d19cd01db77385c01 + languageName: node + linkType: hard + "@rushstack/eslint-patch@npm:^1.1.0, @rushstack/eslint-patch@npm:^1.1.3": version: 1.3.2 resolution: "@rushstack/eslint-patch@npm:1.3.2" @@ -15463,6 +15825,13 @@ __metadata: languageName: node linkType: hard +"@rushstack/eslint-patch@npm:^1.10.3": + version: 1.10.5 + resolution: "@rushstack/eslint-patch@npm:1.10.5" + checksum: c7df90efeb77e4311f70549c1b0c41455e3a4f0c0cf2696e560d9a535f129d63ab84c98d0a3de95ed2d369d5281b541af819f99002bfd38e185e59c355b58d69 + languageName: node + linkType: hard + "@safe-global/safe-apps-provider@npm:0.18.3": version: 0.18.3 resolution: "@safe-global/safe-apps-provider@npm:0.18.3" @@ -17987,6 +18356,13 @@ __metadata: languageName: node linkType: hard +"@swc/counter@npm:0.1.3": + version: 0.1.3 + resolution: "@swc/counter@npm:0.1.3" + checksum: df8f9cfba9904d3d60f511664c70d23bb323b3a0803ec9890f60133954173047ba9bdeabce28cd70ba89ccd3fd6c71c7b0bd58be85f611e1ffbe5d5c18616598 + languageName: node + linkType: hard + "@swc/counter@npm:^0.1.1": version: 0.1.2 resolution: "@swc/counter@npm:0.1.2" @@ -18012,6 +18388,15 @@ __metadata: languageName: node linkType: hard +"@swc/helpers@npm:0.5.15": + version: 0.5.15 + resolution: "@swc/helpers@npm:0.5.15" + dependencies: + tslib: ^2.8.0 + checksum: 1a9e0dbb792b2d1e0c914d69c201dbc96af3a0e6e6e8cf5a7f7d6a5d7b0e8b762915cd4447acb6b040e2ecc1ed49822875a7239f99a2d63c96c3c3407fb6fccf + languageName: node + linkType: hard + "@swc/types@npm:^0.1.5": version: 0.1.5 resolution: "@swc/types@npm:0.1.5" @@ -18900,6 +19285,13 @@ __metadata: languageName: node linkType: hard +"@types/json-schema@npm:^7.0.15": + version: 7.0.15 + resolution: "@types/json-schema@npm:7.0.15" + checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98 + languageName: node + linkType: hard + "@types/json5@npm:^0.0.29": version: 0.0.29 resolution: "@types/json5@npm:0.0.29" @@ -19058,6 +19450,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^20": + version: 20.17.13 + resolution: "@types/node@npm:20.17.13" + dependencies: + undici-types: ~6.19.2 + checksum: 7a8deb319e7d93f756b29f8b079d6040e0ca1e22342f83cfbe15fbe69faa175edb32d7c6b97805a6df3d8c6f3817ca49b979039579ccd8fab4d2b4f9e4f6d024 + languageName: node + linkType: hard + "@types/node@npm:^20.4.1": version: 20.10.5 resolution: "@types/node@npm:20.10.5" @@ -19200,6 +19601,15 @@ __metadata: languageName: node linkType: hard +"@types/react-dom@npm:^19": + version: 19.0.3 + resolution: "@types/react-dom@npm:19.0.3" + peerDependencies: + "@types/react": ^19.0.0 + checksum: a253931fc3a41a74ef99a7380fa3fa02b94ddd1addba9fc0aea39c90ce3dfb22d60fbac292669de224b1ffb23836cde3cc78c2425f0c77593435b6368a9fd2ed + languageName: node + linkType: hard + "@types/react-native-background-timer@npm:^2.0.0": version: 2.0.2 resolution: "@types/react-native-background-timer@npm:2.0.2" @@ -19318,6 +19728,15 @@ __metadata: languageName: node linkType: hard +"@types/react@npm:^19": + version: 19.0.7 + resolution: "@types/react@npm:19.0.7" + dependencies: + csstype: ^3.0.2 + checksum: 594e06f9d6e4d771d7046876de25ad019a55963912514499b1a1c92ea3a404bf0153bfe1c037675feef67ece22fc9bceb0c9bdfd26e7f735145924d4e3d3d8e7 + languageName: node + linkType: hard + "@types/react@npm:~18.2.45": version: 18.2.79 resolution: "@types/react@npm:18.2.79" @@ -19720,6 +20139,27 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/eslint-plugin@npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0": + version: 8.20.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.20.0" + dependencies: + "@eslint-community/regexpp": ^4.10.0 + "@typescript-eslint/scope-manager": 8.20.0 + "@typescript-eslint/type-utils": 8.20.0 + "@typescript-eslint/utils": 8.20.0 + "@typescript-eslint/visitor-keys": 8.20.0 + graphemer: ^1.4.0 + ignore: ^5.3.1 + natural-compare: ^1.4.0 + ts-api-utils: ^2.0.0 + peerDependencies: + "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + checksum: f029bfcce3dc12d7b539f86142857d680e06d798eca213d9fb564685d12b479205b7f40b4996e30e3f7301c7bb6d15484741352f54ddd00d74a07ea2aca53cf6 + languageName: node + linkType: hard + "@typescript-eslint/eslint-plugin@npm:^6.10.0": version: 6.10.0 resolution: "@typescript-eslint/eslint-plugin@npm:6.10.0" @@ -19854,6 +20294,22 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/parser@npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0": + version: 8.20.0 + resolution: "@typescript-eslint/parser@npm:8.20.0" + dependencies: + "@typescript-eslint/scope-manager": 8.20.0 + "@typescript-eslint/types": 8.20.0 + "@typescript-eslint/typescript-estree": 8.20.0 + "@typescript-eslint/visitor-keys": 8.20.0 + debug: ^4.3.4 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + checksum: 00b265ed42ee1d8eb715f9978d701be0958baf7a5be9de74a1b58c09c78e3558e1e6352c4476ec8ea376c28f1437de0b58b3e1e2a9975c489f2ecd369a9050eb + languageName: node + linkType: hard + "@typescript-eslint/parser@npm:^6.10.0": version: 6.10.0 resolution: "@typescript-eslint/parser@npm:6.10.0" @@ -19986,6 +20442,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/scope-manager@npm:8.20.0" + dependencies: + "@typescript-eslint/types": 8.20.0 + "@typescript-eslint/visitor-keys": 8.20.0 + checksum: d90d89f3dc8394e44652526b88c81a977b251702a9dc5be89ac0bf7412d79d18879e03c2d6018980a09bc7c50d28dbf91ba06e056e081e6000783d69bd280761 + languageName: node + linkType: hard + "@typescript-eslint/type-utils@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/type-utils@npm:5.62.0" @@ -20054,6 +20520,21 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/type-utils@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/type-utils@npm:8.20.0" + dependencies: + "@typescript-eslint/typescript-estree": 8.20.0 + "@typescript-eslint/utils": 8.20.0 + debug: ^4.3.4 + ts-api-utils: ^2.0.0 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + checksum: 705a166dc2846f7fe79a123ee623da213a20289fba9c0cbbcc894fe7caaa1d4ddc81bf54db9dc918c29a34294a05768c38a4f00762ba3745e0e94e2e2963f104 + languageName: node + linkType: hard + "@typescript-eslint/types@npm:4.33.0": version: 4.33.0 resolution: "@typescript-eslint/types@npm:4.33.0" @@ -20096,6 +20577,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/types@npm:8.20.0" + checksum: 4cb0af48411f282db33e7110e2f97de874c637e7b90ded91b77304e96f49663ca4b7308afc569bdd93766fe5f2c194686e32078d5513b5ba4e7d56191998190c + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:4.33.0": version: 4.33.0 resolution: "@typescript-eslint/typescript-estree@npm:4.33.0" @@ -20205,6 +20693,24 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.20.0" + dependencies: + "@typescript-eslint/types": 8.20.0 + "@typescript-eslint/visitor-keys": 8.20.0 + debug: ^4.3.4 + fast-glob: ^3.3.2 + is-glob: ^4.0.3 + minimatch: ^9.0.4 + semver: ^7.6.0 + ts-api-utils: ^2.0.0 + peerDependencies: + typescript: ">=4.8.4 <5.8.0" + checksum: 9690df2d4ec90966b8d5752ad0f1658a951fe76ea3cae8e6935e698715a25c1eb0b118fa8e044065f04ea9f6bef41d991de5298590ef2a4aa98d435bf1df6e15 + languageName: node + linkType: hard + "@typescript-eslint/utils@npm:5.62.0, @typescript-eslint/utils@npm:^5.10.0, @typescript-eslint/utils@npm:^5.45.0, @typescript-eslint/utils@npm:^5.58.0": version: 5.62.0 resolution: "@typescript-eslint/utils@npm:5.62.0" @@ -20271,6 +20777,21 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/utils@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/utils@npm:8.20.0" + dependencies: + "@eslint-community/eslint-utils": ^4.4.0 + "@typescript-eslint/scope-manager": 8.20.0 + "@typescript-eslint/types": 8.20.0 + "@typescript-eslint/typescript-estree": 8.20.0 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.8.0" + checksum: 5c9d72eb0d4014e41de1faa4597371f19362ce47a491359be408bfba899277f8d5660f014651f7bd41435158ae4655ade205e92f175e2355ca51a07af35a53ed + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:4.33.0": version: 4.33.0 resolution: "@typescript-eslint/visitor-keys@npm:4.33.0" @@ -20331,6 +20852,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:8.20.0": + version: 8.20.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.20.0" + dependencies: + "@typescript-eslint/types": 8.20.0 + eslint-visitor-keys: ^4.2.0 + checksum: d0bf89e431a686197c517fbb7d63ce4c8ef31e6629a545fd08198c67810ddd68c047c01fcfed8ffc3fe438654a2647b3dedf28f04beac23a65614b2e788d929a + languageName: node + linkType: hard + "@ungap/structured-clone@npm:^1.2.0": version: 1.2.0 resolution: "@ungap/structured-clone@npm:1.2.0" @@ -22226,6 +22757,13 @@ __metadata: languageName: node linkType: hard +"aria-query@npm:^5.3.2": + version: 5.3.2 + resolution: "aria-query@npm:5.3.2" + checksum: d971175c85c10df0f6d14adfe6f1292409196114ab3c62f238e208b53103686f46cc70695a4f775b73bc65f6a09b6a092fd963c4f3a5a7d690c8fc5094925717 + languageName: node + linkType: hard + "array-buffer-byte-length@npm:^1.0.0": version: 1.0.0 resolution: "array-buffer-byte-length@npm:1.0.0" @@ -22246,6 +22784,16 @@ __metadata: languageName: node linkType: hard +"array-buffer-byte-length@npm:^1.0.2": + version: 1.0.2 + resolution: "array-buffer-byte-length@npm:1.0.2" + dependencies: + call-bound: ^1.0.3 + is-array-buffer: ^3.0.5 + checksum: 0ae3786195c3211b423e5be8dd93357870e6fb66357d81da968c2c39ef43583ef6eece1f9cb1caccdae4806739c65dea832b44b8593414313cd76a89795fca63 + languageName: node + linkType: hard + "array-flatten@npm:1.1.1": version: 1.1.1 resolution: "array-flatten@npm:1.1.1" @@ -22357,7 +22905,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.findlastindex@npm:^1.2.3": +"array.prototype.findlastindex@npm:^1.2.3, array.prototype.findlastindex@npm:^1.2.5": version: 1.2.5 resolution: "array.prototype.findlastindex@npm:1.2.5" dependencies: @@ -22419,6 +22967,18 @@ __metadata: languageName: node linkType: hard +"array.prototype.flatmap@npm:^1.3.3": + version: 1.3.3 + resolution: "array.prototype.flatmap@npm:1.3.3" + dependencies: + call-bind: ^1.0.8 + define-properties: ^1.2.1 + es-abstract: ^1.23.5 + es-shim-unscopables: ^1.0.2 + checksum: 11b4de09b1cf008be6031bb507d997ad6f1892e57dc9153583de6ebca0f74ea403fffe0f203461d359de05048d609f3f480d9b46fed4099652d8b62cc972f284 + languageName: node + linkType: hard + "array.prototype.map@npm:^1.0.5": version: 1.0.6 resolution: "array.prototype.map@npm:1.0.6" @@ -22541,6 +23101,21 @@ __metadata: languageName: node linkType: hard +"arraybuffer.prototype.slice@npm:^1.0.4": + version: 1.0.4 + resolution: "arraybuffer.prototype.slice@npm:1.0.4" + dependencies: + array-buffer-byte-length: ^1.0.1 + call-bind: ^1.0.8 + define-properties: ^1.2.1 + es-abstract: ^1.23.5 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.6 + is-array-buffer: ^3.0.4 + checksum: b1d1fd20be4e972a3779b1569226f6740170dca10f07aa4421d42cefeec61391e79c557cda8e771f5baefe47d878178cd4438f60916ce831813c08132bced765 + languageName: node + linkType: hard + "arrify@npm:^1.0.1": version: 1.0.1 resolution: "arrify@npm:1.0.1" @@ -22608,6 +23183,13 @@ __metadata: languageName: node linkType: hard +"ast-types-flow@npm:^0.0.8": + version: 0.0.8 + resolution: "ast-types-flow@npm:0.0.8" + checksum: 0a64706609a179233aac23817837abab614f3548c252a2d3d79ea1e10c74aa28a0846e11f466cf72771b6ed8713abc094dcf8c40c3ec4207da163efa525a94a8 + languageName: node + linkType: hard + "ast-types@npm:0.15.2": version: 0.15.2 resolution: "ast-types@npm:0.15.2" @@ -22795,6 +23377,13 @@ __metadata: languageName: node linkType: hard +"axe-core@npm:^4.10.0": + version: 4.10.2 + resolution: "axe-core@npm:4.10.2" + checksum: 2b9b1c93ea73ea9f206604e4e17bd771d2d835f077bde54517d73028b8865c69b209460e73d5b109968cbdb39ab3d28943efa5695189bd79e16421ce1706719e + languageName: node + linkType: hard + "axe-core@npm:^4.6.2": version: 4.7.2 resolution: "axe-core@npm:4.7.2" @@ -22830,6 +23419,13 @@ __metadata: languageName: node linkType: hard +"axobject-query@npm:^4.1.0": + version: 4.1.0 + resolution: "axobject-query@npm:4.1.0" + checksum: 7d1e87bf0aa7ae7a76cd39ab627b7c48fda3dc40181303d9adce4ba1d5b5ce73b5e5403ee6626ec8e91090448c887294d6144e24b6741a976f5be9347e3ae1df + languageName: node + linkType: hard + "b4a@npm:^1.6.4": version: 1.6.6 resolution: "b4a@npm:1.6.6" @@ -24352,6 +24948,16 @@ __metadata: languageName: node linkType: hard +"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1": + version: 1.0.1 + resolution: "call-bind-apply-helpers@npm:1.0.1" + dependencies: + es-errors: ^1.3.0 + function-bind: ^1.1.2 + checksum: 3c55343261bb387c58a4762d15ad9d42053659a62681ec5eb50690c6b52a4a666302a01d557133ce6533e8bd04530ee3b209f23dd06c9577a1925556f8fcccdf + languageName: node + linkType: hard + "call-bind@npm:^1.0.0, call-bind@npm:^1.0.2": version: 1.0.2 resolution: "call-bind@npm:1.0.2" @@ -24386,6 +24992,28 @@ __metadata: languageName: node linkType: hard +"call-bind@npm:^1.0.8": + version: 1.0.8 + resolution: "call-bind@npm:1.0.8" + dependencies: + call-bind-apply-helpers: ^1.0.0 + es-define-property: ^1.0.0 + get-intrinsic: ^1.2.4 + set-function-length: ^1.2.2 + checksum: aa2899bce917a5392fd73bd32e71799c37c0b7ab454e0ed13af7f6727549091182aade8bbb7b55f304a5bc436d543241c14090fb8a3137e9875e23f444f4f5a9 + languageName: node + linkType: hard + +"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3": + version: 1.0.3 + resolution: "call-bound@npm:1.0.3" + dependencies: + call-bind-apply-helpers: ^1.0.1 + get-intrinsic: ^1.2.6 + checksum: a93bbe0f2d0a2d6c144a4349ccd0593d5d0d5d9309b69101710644af8964286420062f2cc3114dca120b9bc8cc07507952d4b1b3ea7672e0d7f6f1675efedb32 + languageName: node + linkType: hard + "caller-callsite@npm:^2.0.0": version: 2.0.0 resolution: "caller-callsite@npm:2.0.0" @@ -24507,6 +25135,13 @@ __metadata: languageName: node linkType: hard +"caniuse-lite@npm:^1.0.30001579": + version: 1.0.30001692 + resolution: "caniuse-lite@npm:1.0.30001692" + checksum: 484113e3fabbe223fff0380c25c861da265a34c3f75bb5af1f254423b43e713a3c7f0c313167df52fb203f42ea68bd0df8a9e73642becfe1e9fa5734b5fc55a5 + languageName: node + linkType: hard + "caniuse-lite@npm:^1.0.30001640": version: 1.0.30001641 resolution: "caniuse-lite@npm:1.0.30001641" @@ -25848,6 +26483,17 @@ __metadata: languageName: node linkType: hard +"cross-spawn@npm:^7.0.6": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" + dependencies: + path-key: ^3.1.0 + shebang-command: ^2.0.0 + which: ^2.0.1 + checksum: 8d306efacaf6f3f60e0224c287664093fa9185680b2d195852ba9a863f85d02dcc737094c6e512175f8ee0161f9b87c73c6826034c2422e39de7d6569cf4503b + languageName: node + linkType: hard + "crypt@npm:0.0.2, crypt@npm:~0.0.1": version: 0.0.2 resolution: "crypt@npm:0.0.2" @@ -26336,6 +26982,17 @@ __metadata: languageName: node linkType: hard +"data-view-buffer@npm:^1.0.2": + version: 1.0.2 + resolution: "data-view-buffer@npm:1.0.2" + dependencies: + call-bound: ^1.0.3 + es-errors: ^1.3.0 + is-data-view: ^1.0.2 + checksum: 1e1cd509c3037ac0f8ba320da3d1f8bf1a9f09b0be09394b5e40781b8cc15ff9834967ba7c9f843a425b34f9fe14ce44cf055af6662c44263424c1eb8d65659b + languageName: node + linkType: hard + "data-view-byte-length@npm:^1.0.1": version: 1.0.1 resolution: "data-view-byte-length@npm:1.0.1" @@ -26347,6 +27004,17 @@ __metadata: languageName: node linkType: hard +"data-view-byte-length@npm:^1.0.2": + version: 1.0.2 + resolution: "data-view-byte-length@npm:1.0.2" + dependencies: + call-bound: ^1.0.3 + es-errors: ^1.3.0 + is-data-view: ^1.0.2 + checksum: 3600c91ced1cfa935f19ef2abae11029e01738de8d229354d3b2a172bf0d7e4ed08ff8f53294b715569fdf72dfeaa96aa7652f479c0f60570878d88e7e8bddf6 + languageName: node + linkType: hard + "data-view-byte-offset@npm:^1.0.0": version: 1.0.0 resolution: "data-view-byte-offset@npm:1.0.0" @@ -26358,6 +27026,17 @@ __metadata: languageName: node linkType: hard +"data-view-byte-offset@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-byte-offset@npm:1.0.1" + dependencies: + call-bound: ^1.0.2 + es-errors: ^1.3.0 + is-data-view: ^1.0.1 + checksum: 8dd492cd51d19970876626b5b5169fbb67ca31ec1d1d3238ee6a71820ca8b80cafb141c485999db1ee1ef02f2cc3b99424c5eda8d59e852d9ebb79ab290eb5ee + languageName: node + linkType: hard + "date-fns@npm:^2.29.3": version: 2.30.0 resolution: "date-fns@npm:2.30.0" @@ -26795,6 +27474,13 @@ __metadata: languageName: node linkType: hard +"detect-libc@npm:^2.0.3": + version: 2.0.3 + resolution: "detect-libc@npm:2.0.3" + checksum: 2ba6a939ae55f189aea996ac67afceb650413c7a34726ee92c40fb0deb2400d57ef94631a8a3f052055eea7efb0f99a9b5e6ce923415daa3e68221f963cfc27d + languageName: node + linkType: hard + "detect-newline@npm:^3.0.0": version: 3.1.0 resolution: "detect-newline@npm:3.1.0" @@ -27535,6 +28221,17 @@ __metadata: languageName: node linkType: hard +"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "dunder-proto@npm:1.0.1" + dependencies: + call-bind-apply-helpers: ^1.0.1 + es-errors: ^1.3.0 + gopd: ^1.2.0 + checksum: 149207e36f07bd4941921b0ca929e3a28f1da7bd6b6ff8ff7f4e2f2e460675af4576eeba359c635723dc189b64cdd4787e0255897d5b135ccc5d15cb8685fc90 + languageName: node + linkType: hard + "duplexer@npm:^0.1.2": version: 0.1.2 resolution: "duplexer@npm:0.1.2" @@ -28102,6 +28799,65 @@ __metadata: languageName: node linkType: hard +"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9": + version: 1.23.9 + resolution: "es-abstract@npm:1.23.9" + dependencies: + array-buffer-byte-length: ^1.0.2 + arraybuffer.prototype.slice: ^1.0.4 + available-typed-arrays: ^1.0.7 + call-bind: ^1.0.8 + call-bound: ^1.0.3 + data-view-buffer: ^1.0.2 + data-view-byte-length: ^1.0.2 + data-view-byte-offset: ^1.0.1 + es-define-property: ^1.0.1 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + es-set-tostringtag: ^2.1.0 + es-to-primitive: ^1.3.0 + function.prototype.name: ^1.1.8 + get-intrinsic: ^1.2.7 + get-proto: ^1.0.0 + get-symbol-description: ^1.1.0 + globalthis: ^1.0.4 + gopd: ^1.2.0 + has-property-descriptors: ^1.0.2 + has-proto: ^1.2.0 + has-symbols: ^1.1.0 + hasown: ^2.0.2 + internal-slot: ^1.1.0 + is-array-buffer: ^3.0.5 + is-callable: ^1.2.7 + is-data-view: ^1.0.2 + is-regex: ^1.2.1 + is-shared-array-buffer: ^1.0.4 + is-string: ^1.1.1 + is-typed-array: ^1.1.15 + is-weakref: ^1.1.0 + math-intrinsics: ^1.1.0 + object-inspect: ^1.13.3 + object-keys: ^1.1.1 + object.assign: ^4.1.7 + own-keys: ^1.0.1 + regexp.prototype.flags: ^1.5.3 + safe-array-concat: ^1.1.3 + safe-push-apply: ^1.0.0 + safe-regex-test: ^1.1.0 + set-proto: ^1.0.0 + string.prototype.trim: ^1.2.10 + string.prototype.trimend: ^1.0.9 + string.prototype.trimstart: ^1.0.8 + typed-array-buffer: ^1.0.3 + typed-array-byte-length: ^1.0.3 + typed-array-byte-offset: ^1.0.4 + typed-array-length: ^1.0.7 + unbox-primitive: ^1.1.0 + which-typed-array: ^1.1.18 + checksum: f3ee2614159ca197f97414ab36e3f406ee748ce2f97ffbf09e420726db5a442ce13f1e574601468bff6e6eb81588e6c9ce1ac6c03868a37c7cd48ac679f8485a + languageName: node + linkType: hard + "es-abstract@npm:^1.22.1": version: 1.22.3 resolution: "es-abstract@npm:1.22.3" @@ -28219,6 +28975,13 @@ __metadata: languageName: node linkType: hard +"es-define-property@npm:^1.0.1": + version: 1.0.1 + resolution: "es-define-property@npm:1.0.1" + checksum: 0512f4e5d564021c9e3a644437b0155af2679d10d80f21adaf868e64d30efdfbd321631956f20f42d655fedb2e3a027da479fad3fa6048f768eb453a80a5f80a + languageName: node + linkType: hard + "es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": version: 1.3.0 resolution: "es-errors@npm:1.3.0" @@ -28287,6 +29050,30 @@ __metadata: languageName: node linkType: hard +"es-iterator-helpers@npm:^1.2.1": + version: 1.2.1 + resolution: "es-iterator-helpers@npm:1.2.1" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.3 + define-properties: ^1.2.1 + es-abstract: ^1.23.6 + es-errors: ^1.3.0 + es-set-tostringtag: ^2.0.3 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.6 + globalthis: ^1.0.4 + gopd: ^1.2.0 + has-property-descriptors: ^1.0.2 + has-proto: ^1.2.0 + has-symbols: ^1.1.0 + internal-slot: ^1.1.0 + iterator.prototype: ^1.1.4 + safe-array-concat: ^1.1.3 + checksum: 952808dd1df3643d67ec7adf20c30b36e5eecadfbf36354e6f39ed3266c8e0acf3446ce9bc465e38723d613cb1d915c1c07c140df65bdce85da012a6e7bda62b + languageName: node + linkType: hard + "es-module-lexer@npm:^1.2.1": version: 1.3.0 resolution: "es-module-lexer@npm:1.3.0" @@ -28325,6 +29112,18 @@ __metadata: languageName: node linkType: hard +"es-set-tostringtag@npm:^2.1.0": + version: 2.1.0 + resolution: "es-set-tostringtag@npm:2.1.0" + dependencies: + es-errors: ^1.3.0 + get-intrinsic: ^1.2.6 + has-tostringtag: ^1.0.2 + hasown: ^2.0.2 + checksum: 789f35de4be3dc8d11fdcb91bc26af4ae3e6d602caa93299a8c45cf05d36cc5081454ae2a6d3afa09cceca214b76c046e4f8151e092e6fc7feeb5efb9e794fc6 + languageName: node + linkType: hard + "es-shim-unscopables@npm:^1.0.0": version: 1.0.0 resolution: "es-shim-unscopables@npm:1.0.0" @@ -28354,6 +29153,17 @@ __metadata: languageName: node linkType: hard +"es-to-primitive@npm:^1.3.0": + version: 1.3.0 + resolution: "es-to-primitive@npm:1.3.0" + dependencies: + is-callable: ^1.2.7 + is-date-object: ^1.0.5 + is-symbol: ^1.0.4 + checksum: 966965880356486cd4d1fe9a523deda2084c81b3702d951212c098f5f2ee93605d1b7c1840062efb48a07d892641c7ed1bc194db563645c0dd2b919cb6d65b93 + languageName: node + linkType: hard + "es5-ext@npm:^0.10.35, es5-ext@npm:^0.10.46, es5-ext@npm:^0.10.50, es5-ext@npm:^0.10.53, es5-ext@npm:^0.10.61, es5-ext@npm:~0.10.14, es5-ext@npm:~0.10.2, es5-ext@npm:~0.10.46": version: 0.10.62 resolution: "es5-ext@npm:0.10.62" @@ -28707,6 +29517,30 @@ __metadata: languageName: node linkType: hard +"eslint-config-next@npm:15.1.4": + version: 15.1.4 + resolution: "eslint-config-next@npm:15.1.4" + dependencies: + "@next/eslint-plugin-next": 15.1.4 + "@rushstack/eslint-patch": ^1.10.3 + "@typescript-eslint/eslint-plugin": ^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0 + "@typescript-eslint/parser": ^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint-import-resolver-node: ^0.3.6 + eslint-import-resolver-typescript: ^3.5.2 + eslint-plugin-import: ^2.31.0 + eslint-plugin-jsx-a11y: ^6.10.0 + eslint-plugin-react: ^7.37.0 + eslint-plugin-react-hooks: ^5.0.0 + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + typescript: ">=3.3.1" + peerDependenciesMeta: + typescript: + optional: true + checksum: 0b0ffa584083acfa276b2fb22a2f1d6bbb23aba5158ebe0a6309ad879bc9e727a1bc800cd6cd50e1e5eb3b9ca20ed3743a546839a57720d7b19bf2da2bed2aa5 + languageName: node + linkType: hard + "eslint-config-prettier@npm:^8.3.0": version: 8.8.0 resolution: "eslint-config-prettier@npm:8.8.0" @@ -28856,6 +29690,18 @@ __metadata: languageName: node linkType: hard +"eslint-module-utils@npm:^2.12.0": + version: 2.12.0 + resolution: "eslint-module-utils@npm:2.12.0" + dependencies: + debug: ^3.2.7 + peerDependenciesMeta: + eslint: + optional: true + checksum: be3ac52e0971c6f46daeb1a7e760e45c7c45f820c8cc211799f85f10f04ccbf7afc17039165d56cb2da7f7ca9cec2b3a777013cddf0b976784b37eb9efa24180 + languageName: node + linkType: hard + "eslint-module-utils@npm:^2.7.4": version: 2.8.0 resolution: "eslint-module-utils@npm:2.8.0" @@ -28995,6 +29841,35 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-import@npm:^2.31.0": + version: 2.31.0 + resolution: "eslint-plugin-import@npm:2.31.0" + dependencies: + "@rtsao/scc": ^1.1.0 + array-includes: ^3.1.8 + array.prototype.findlastindex: ^1.2.5 + array.prototype.flat: ^1.3.2 + array.prototype.flatmap: ^1.3.2 + debug: ^3.2.7 + doctrine: ^2.1.0 + eslint-import-resolver-node: ^0.3.9 + eslint-module-utils: ^2.12.0 + hasown: ^2.0.2 + is-core-module: ^2.15.1 + is-glob: ^4.0.3 + minimatch: ^3.1.2 + object.fromentries: ^2.0.8 + object.groupby: ^1.0.3 + object.values: ^1.2.0 + semver: ^6.3.1 + string.prototype.trimend: ^1.0.8 + tsconfig-paths: ^3.15.0 + peerDependencies: + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + checksum: b1d2ac268b3582ff1af2a72a2c476eae4d250c100f2e335b6e102036e4a35efa530b80ec578dfc36761fabb34a635b9bf5ab071abe9d4404a4bb054fdf22d415 + languageName: node + linkType: hard + "eslint-plugin-jest@npm:^24.4.0": version: 24.7.0 resolution: "eslint-plugin-jest@npm:24.7.0" @@ -29098,6 +29973,31 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-jsx-a11y@npm:^6.10.0": + version: 6.10.2 + resolution: "eslint-plugin-jsx-a11y@npm:6.10.2" + dependencies: + aria-query: ^5.3.2 + array-includes: ^3.1.8 + array.prototype.flatmap: ^1.3.2 + ast-types-flow: ^0.0.8 + axe-core: ^4.10.0 + axobject-query: ^4.1.0 + damerau-levenshtein: ^1.0.8 + emoji-regex: ^9.2.2 + hasown: ^2.0.2 + jsx-ast-utils: ^3.3.5 + language-tags: ^1.0.9 + minimatch: ^3.1.2 + object.fromentries: ^2.0.8 + safe-regex-test: ^1.0.3 + string.prototype.includes: ^2.0.1 + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + checksum: 0cc861398fa26ada61ed5703eef5b335495fcb96253263dcd5e399488ff019a2636372021baacc040e3560d1a34bfcd5d5ad9f1754f44cd0509c956f7df94050 + languageName: node + linkType: hard + "eslint-plugin-jsx-a11y@npm:^6.5.1": version: 6.7.1 resolution: "eslint-plugin-jsx-a11y@npm:6.7.1" @@ -29236,6 +30136,15 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-react-hooks@npm:^5.0.0": + version: 5.1.0 + resolution: "eslint-plugin-react-hooks@npm:5.1.0" + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + checksum: 14d2692214ea15b19ef330a9abf51cb8c1586339d9e758ebd61b182be68dd772af56462b04e4b9d2be923d72f46db61e8d32fcf37c248b04949c0b02f5bfb3c0 + languageName: node + linkType: hard + "eslint-plugin-react-native-globals@npm:^0.1.1": version: 0.1.2 resolution: "eslint-plugin-react-native-globals@npm:0.1.2" @@ -29333,6 +30242,34 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-react@npm:^7.37.0": + version: 7.37.4 + resolution: "eslint-plugin-react@npm:7.37.4" + dependencies: + array-includes: ^3.1.8 + array.prototype.findlast: ^1.2.5 + array.prototype.flatmap: ^1.3.3 + array.prototype.tosorted: ^1.1.4 + doctrine: ^2.1.0 + es-iterator-helpers: ^1.2.1 + estraverse: ^5.3.0 + hasown: ^2.0.2 + jsx-ast-utils: ^2.4.1 || ^3.0.0 + minimatch: ^3.1.2 + object.entries: ^1.1.8 + object.fromentries: ^2.0.8 + object.values: ^1.2.1 + prop-types: ^15.8.1 + resolve: ^2.0.0-next.5 + semver: ^6.3.1 + string.prototype.matchall: ^4.0.12 + string.prototype.repeat: ^1.0.0 + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + checksum: 8a37bdc9b347bf3a1273fef73dfbc39279cc3e58441940a5e13b3ba4e82b34132d1d1172db9d6746f153ee981280bd6bd06a9065fb453388c68f4bebe0d9f839 + languageName: node + linkType: hard + "eslint-plugin-storybook@npm:^0.6.15": version: 0.6.15 resolution: "eslint-plugin-storybook@npm:0.6.15" @@ -29388,6 +30325,16 @@ __metadata: languageName: node linkType: hard +"eslint-scope@npm:^8.2.0": + version: 8.2.0 + resolution: "eslint-scope@npm:8.2.0" + dependencies: + esrecurse: ^4.3.0 + estraverse: ^5.2.0 + checksum: 750eff4672ca2bf274ec0d1bbeae08aadd53c1907d5c6aff5564d8e047a5f49afa8ae6eee333cab637fd3ebcab2141659d8f2f040f6fdc982b0f61f8bf03136f + languageName: node + linkType: hard + "eslint-utils@npm:^2.0.0, eslint-utils@npm:^2.1.0": version: 2.1.0 resolution: "eslint-utils@npm:2.1.0" @@ -29436,6 +30383,13 @@ __metadata: languageName: node linkType: hard +"eslint-visitor-keys@npm:^4.2.0": + version: 4.2.0 + resolution: "eslint-visitor-keys@npm:4.2.0" + checksum: 779c604672b570bb4da84cef32f6abb085ac78379779c1122d7879eade8bb38ae715645324597cf23232d03cef06032c9844d25c73625bc282a5bfd30247e5b5 + languageName: node + linkType: hard + "eslint-webpack-plugin@npm:^3.1.1": version: 3.2.0 resolution: "eslint-webpack-plugin@npm:3.2.0" @@ -29692,6 +30646,66 @@ __metadata: languageName: node linkType: hard +"eslint@npm:^9": + version: 9.18.0 + resolution: "eslint@npm:9.18.0" + dependencies: + "@eslint-community/eslint-utils": ^4.2.0 + "@eslint-community/regexpp": ^4.12.1 + "@eslint/config-array": ^0.19.0 + "@eslint/core": ^0.10.0 + "@eslint/eslintrc": ^3.2.0 + "@eslint/js": 9.18.0 + "@eslint/plugin-kit": ^0.2.5 + "@humanfs/node": ^0.16.6 + "@humanwhocodes/module-importer": ^1.0.1 + "@humanwhocodes/retry": ^0.4.1 + "@types/estree": ^1.0.6 + "@types/json-schema": ^7.0.15 + ajv: ^6.12.4 + chalk: ^4.0.0 + cross-spawn: ^7.0.6 + debug: ^4.3.2 + escape-string-regexp: ^4.0.0 + eslint-scope: ^8.2.0 + eslint-visitor-keys: ^4.2.0 + espree: ^10.3.0 + esquery: ^1.5.0 + esutils: ^2.0.2 + fast-deep-equal: ^3.1.3 + file-entry-cache: ^8.0.0 + find-up: ^5.0.0 + glob-parent: ^6.0.2 + ignore: ^5.2.0 + imurmurhash: ^0.1.4 + is-glob: ^4.0.0 + json-stable-stringify-without-jsonify: ^1.0.1 + lodash.merge: ^4.6.2 + minimatch: ^3.1.2 + natural-compare: ^1.4.0 + optionator: ^0.9.3 + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true + bin: + eslint: bin/eslint.js + checksum: 5e05ae9d25a42ae8cad86a0118ea45107b42446f3614cd0ba822affa3eb85d746e0820529b1fde72820f24aa3c3447d3260505a5ee5e95be1b8b7455740a2256 + languageName: node + linkType: hard + +"espree@npm:^10.0.1, espree@npm:^10.3.0": + version: 10.3.0 + resolution: "espree@npm:10.3.0" + dependencies: + acorn: ^8.14.0 + acorn-jsx: ^5.3.2 + eslint-visitor-keys: ^4.2.0 + checksum: 63e8030ff5a98cea7f8b3e3a1487c998665e28d674af08b9b3100ed991670eb3cbb0e308c4548c79e03762753838fbe530c783f17309450d6b47a889fee72bef + languageName: node + linkType: hard + "espree@npm:^7.3.0, espree@npm:^7.3.1": version: 7.3.1 resolution: "espree@npm:7.3.1" @@ -30850,6 +31864,19 @@ __metadata: languageName: node linkType: hard +"fast-glob@npm:3.3.1": + version: 3.3.1 + resolution: "fast-glob@npm:3.3.1" + dependencies: + "@nodelib/fs.stat": ^2.0.2 + "@nodelib/fs.walk": ^1.2.3 + glob-parent: ^5.1.2 + merge2: ^1.3.0 + micromatch: ^4.0.4 + checksum: b6f3add6403e02cf3a798bfbb1183d0f6da2afd368f27456010c0bc1f9640aea308243d4cb2c0ab142f618276e65ecb8be1661d7c62a7b4e5ba774b9ce5432e5 + languageName: node + linkType: hard + "fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.5, fast-glob@npm:^3.3.1, fast-glob@npm:^3.3.2": version: 3.3.2 resolution: "fast-glob@npm:3.3.2" @@ -31065,6 +32092,15 @@ __metadata: languageName: node linkType: hard +"file-entry-cache@npm:^8.0.0": + version: 8.0.0 + resolution: "file-entry-cache@npm:8.0.0" + dependencies: + flat-cache: ^4.0.0 + checksum: f67802d3334809048c69b3d458f672e1b6d26daefda701761c81f203b80149c35dea04d78ea4238969dd617678e530876722a0634c43031a0957f10cc3ed190f + languageName: node + linkType: hard + "file-loader@npm:^6.2.0": version: 6.2.0 resolution: "file-loader@npm:6.2.0" @@ -31297,6 +32333,16 @@ __metadata: languageName: node linkType: hard +"flat-cache@npm:^4.0.0": + version: 4.0.1 + resolution: "flat-cache@npm:4.0.1" + dependencies: + flatted: ^3.2.9 + keyv: ^4.5.4 + checksum: 899fc86bf6df093547d76e7bfaeb900824b869d7d457d02e9b8aae24836f0a99fbad79328cfd6415ee8908f180699bf259dc7614f793447cb14f707caf5996f6 + languageName: node + linkType: hard + "flatted@npm:^3.1.0": version: 3.2.7 resolution: "flatted@npm:3.2.7" @@ -31304,6 +32350,13 @@ __metadata: languageName: node linkType: hard +"flatted@npm:^3.2.9": + version: 3.3.2 + resolution: "flatted@npm:3.3.2" + checksum: ac3c159742e01d0e860a861164bcfd35bb567ccbebb8a0dd041e61cf3c64a435b917dd1e7ed1c380c2ebca85735fb16644485ec33665bc6aafc3b316aa1eed44 + languageName: node + linkType: hard + "flow-enums-runtime@npm:^0.0.5": version: 0.0.5 resolution: "flow-enums-runtime@npm:0.0.5" @@ -31720,6 +32773,20 @@ __metadata: languageName: node linkType: hard +"function.prototype.name@npm:^1.1.8": + version: 1.1.8 + resolution: "function.prototype.name@npm:1.1.8" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.3 + define-properties: ^1.2.1 + functions-have-names: ^1.2.3 + hasown: ^2.0.2 + is-callable: ^1.2.7 + checksum: 3a366535dc08b25f40a322efefa83b2da3cd0f6da41db7775f2339679120ef63b6c7e967266182609e655b8f0a8f65596ed21c7fd72ad8bd5621c2340edd4010 + languageName: node + linkType: hard + "functional-red-black-tree@npm:^1.0.1": version: 1.0.1 resolution: "functional-red-black-tree@npm:1.0.1" @@ -31833,6 +32900,24 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7": + version: 1.2.7 + resolution: "get-intrinsic@npm:1.2.7" + dependencies: + call-bind-apply-helpers: ^1.0.1 + es-define-property: ^1.0.1 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + function-bind: ^1.1.2 + get-proto: ^1.0.0 + gopd: ^1.2.0 + has-symbols: ^1.1.0 + hasown: ^2.0.2 + math-intrinsics: ^1.1.0 + checksum: a1597b3b432074f805b6a0ba1182130dd6517c0ea0c4eecc4b8834c803913e1ea62dfc412865be795b3dacb1555a21775b70cf9af7a18b1454ff3414e5442d4a + languageName: node + linkType: hard + "get-nonce@npm:^1.0.0": version: 1.0.1 resolution: "get-nonce@npm:1.0.1" @@ -31882,6 +32967,16 @@ __metadata: languageName: node linkType: hard +"get-proto@npm:^1.0.0, get-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "get-proto@npm:1.0.1" + dependencies: + dunder-proto: ^1.0.1 + es-object-atoms: ^1.0.0 + checksum: 4fc96afdb58ced9a67558698b91433e6b037aaa6f1493af77498d7c85b141382cf223c0e5946f334fb328ee85dfe6edd06d218eaf09556f4bc4ec6005d7f5f7b + languageName: node + linkType: hard + "get-stream@npm:^4.0.0": version: 4.1.0 resolution: "get-stream@npm:4.1.0" @@ -31928,6 +33023,17 @@ __metadata: languageName: node linkType: hard +"get-symbol-description@npm:^1.1.0": + version: 1.1.0 + resolution: "get-symbol-description@npm:1.1.0" + dependencies: + call-bound: ^1.0.3 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.6 + checksum: 655ed04db48ee65ef2ddbe096540d4405e79ba0a7f54225775fef43a7e2afcb93a77d141c5f05fdef0afce2eb93bcbfb3597142189d562ac167ff183582683cd + languageName: node + linkType: hard + "get-tsconfig@npm:^4.5.0": version: 4.6.2 resolution: "get-tsconfig@npm:4.6.2" @@ -32203,6 +33309,13 @@ __metadata: languageName: node linkType: hard +"globals@npm:^14.0.0": + version: 14.0.0 + resolution: "globals@npm:14.0.0" + checksum: 534b8216736a5425737f59f6e6a5c7f386254560c9f41d24a9227d60ee3ad4a9e82c5b85def0e212e9d92162f83a92544be4c7fd4c902cb913736c10e08237ac + languageName: node + linkType: hard + "globalthis@npm:^1.0.0, globalthis@npm:^1.0.3": version: 1.0.3 resolution: "globalthis@npm:1.0.3" @@ -32212,6 +33325,16 @@ __metadata: languageName: node linkType: hard +"globalthis@npm:^1.0.4": + version: 1.0.4 + resolution: "globalthis@npm:1.0.4" + dependencies: + define-properties: ^1.2.1 + gopd: ^1.0.1 + checksum: 39ad667ad9f01476474633a1834a70842041f70a55571e8dcef5fb957980a92da5022db5430fca8aecc5d47704ae30618c0bc877a579c70710c904e9ef06108a + languageName: node + linkType: hard + "globalyzer@npm:0.1.0": version: 0.1.0 resolution: "globalyzer@npm:0.1.0" @@ -32305,6 +33428,13 @@ __metadata: languageName: node linkType: hard +"gopd@npm:^1.2.0": + version: 1.2.0 + resolution: "gopd@npm:1.2.0" + checksum: cc6d8e655e360955bdccaca51a12a474268f95bb793fc3e1f2bdadb075f28bfd1fd988dab872daf77a61d78cbaf13744bc8727a17cfb1d150d76047d805375f3 + languageName: node + linkType: hard + "graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.3, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" @@ -32470,6 +33600,15 @@ __metadata: languageName: node linkType: hard +"has-proto@npm:^1.2.0": + version: 1.2.0 + resolution: "has-proto@npm:1.2.0" + dependencies: + dunder-proto: ^1.0.0 + checksum: f55010cb94caa56308041d77967c72a02ffd71386b23f9afa8447e58bc92d49d15c19bf75173713468e92fe3fb1680b03b115da39c21c32c74886d1d50d3e7ff + languageName: node + linkType: hard + "has-symbols@npm:^1.0.1, has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": version: 1.0.3 resolution: "has-symbols@npm:1.0.3" @@ -32477,6 +33616,13 @@ __metadata: languageName: node linkType: hard +"has-symbols@npm:^1.1.0": + version: 1.1.0 + resolution: "has-symbols@npm:1.1.0" + checksum: b2316c7302a0e8ba3aaba215f834e96c22c86f192e7310bdf689dd0e6999510c89b00fbc5742571507cebf25764d68c988b3a0da217369a73596191ac0ce694b + languageName: node + linkType: hard + "has-tostringtag@npm:^1.0.0": version: 1.0.0 resolution: "has-tostringtag@npm:1.0.0" @@ -33349,6 +34495,17 @@ __metadata: languageName: node linkType: hard +"internal-slot@npm:^1.1.0": + version: 1.1.0 + resolution: "internal-slot@npm:1.1.0" + dependencies: + es-errors: ^1.3.0 + hasown: ^2.0.2 + side-channel: ^1.1.0 + checksum: 8e0991c2d048cc08dab0a91f573c99f6a4215075887517ea4fa32203ce8aea60fa03f95b177977fa27eb502e5168366d0f3e02c762b799691411d49900611861 + languageName: node + linkType: hard + "intl-messageformat@npm:^9.13.0": version: 9.13.0 resolution: "intl-messageformat@npm:9.13.0" @@ -33484,6 +34641,17 @@ __metadata: languageName: node linkType: hard +"is-array-buffer@npm:^3.0.5": + version: 3.0.5 + resolution: "is-array-buffer@npm:3.0.5" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.3 + get-intrinsic: ^1.2.6 + checksum: f137a2a6e77af682cdbffef1e633c140cf596f72321baf8bba0f4ef22685eb4339dde23dfe9e9ca430b5f961dee4d46577dcf12b792b68518c8449b134fb9156 + languageName: node + linkType: hard + "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" @@ -33516,6 +34684,15 @@ __metadata: languageName: node linkType: hard +"is-bigint@npm:^1.1.0": + version: 1.1.0 + resolution: "is-bigint@npm:1.1.0" + dependencies: + has-bigints: ^1.0.2 + checksum: ee1544f0e664f253306786ed1dce494b8cf242ef415d6375d8545b4d8816b0f054bd9f948a8988ae2c6325d1c28260dd02978236b2f7b8fb70dfc4838a6c9fa7 + languageName: node + linkType: hard + "is-binary-path@npm:~2.1.0": version: 2.1.0 resolution: "is-binary-path@npm:2.1.0" @@ -33535,6 +34712,16 @@ __metadata: languageName: node linkType: hard +"is-boolean-object@npm:^1.2.1": + version: 1.2.1 + resolution: "is-boolean-object@npm:1.2.1" + dependencies: + call-bound: ^1.0.2 + has-tostringtag: ^1.0.2 + checksum: 2672609f0f2536172873810a38ec006a415e43ddc6a240f7638a1659cb20dfa91cc75c8a1bed36247bb046aa8f0eab945f20d1203bc69606418bd129c745f861 + languageName: node + linkType: hard + "is-buffer@npm:~1.1.1, is-buffer@npm:~1.1.6": version: 1.1.6 resolution: "is-buffer@npm:1.1.6" @@ -33587,6 +34774,15 @@ __metadata: languageName: node linkType: hard +"is-core-module@npm:^2.15.1": + version: 2.16.1 + resolution: "is-core-module@npm:2.16.1" + dependencies: + hasown: ^2.0.2 + checksum: 6ec5b3c42d9cbf1ac23f164b16b8a140c3cec338bf8f884c076ca89950c7cc04c33e78f02b8cae7ff4751f3247e3174b2330f1fe4de194c7210deb8b1ea316a7 + languageName: node + linkType: hard + "is-data-view@npm:^1.0.1": version: 1.0.1 resolution: "is-data-view@npm:1.0.1" @@ -33596,6 +34792,17 @@ __metadata: languageName: node linkType: hard +"is-data-view@npm:^1.0.2": + version: 1.0.2 + resolution: "is-data-view@npm:1.0.2" + dependencies: + call-bound: ^1.0.2 + get-intrinsic: ^1.2.6 + is-typed-array: ^1.1.13 + checksum: 31600dd19932eae7fd304567e465709ffbfa17fa236427c9c864148e1b54eb2146357fcf3aed9b686dee13c217e1bb5a649cb3b9c479e1004c0648e9febde1b2 + languageName: node + linkType: hard + "is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": version: 1.0.5 resolution: "is-date-object@npm:1.0.5" @@ -33605,6 +34812,16 @@ __metadata: languageName: node linkType: hard +"is-date-object@npm:^1.1.0": + version: 1.1.0 + resolution: "is-date-object@npm:1.1.0" + dependencies: + call-bound: ^1.0.2 + has-tostringtag: ^1.0.2 + checksum: d6c36ab9d20971d65f3fc64cef940d57a4900a2ac85fb488a46d164c2072a33da1cb51eefcc039e3e5c208acbce343d3480b84ab5ff0983f617512da2742562a + languageName: node + linkType: hard + "is-deflate@npm:^1.0.0": version: 1.0.0 resolution: "is-deflate@npm:1.0.0" @@ -33660,6 +34877,15 @@ __metadata: languageName: node linkType: hard +"is-finalizationregistry@npm:^1.1.0": + version: 1.1.1 + resolution: "is-finalizationregistry@npm:1.1.1" + dependencies: + call-bound: ^1.0.3 + checksum: 38c646c506e64ead41a36c182d91639833311970b6b6c6268634f109eef0a1a9d2f1f2e499ef4cb43c744a13443c4cdd2f0812d5afdcee5e9b65b72b28c48557 + languageName: node + linkType: hard + "is-fullwidth-code-point@npm:^2.0.0": version: 2.0.0 resolution: "is-fullwidth-code-point@npm:2.0.0" @@ -33777,6 +35003,13 @@ __metadata: languageName: node linkType: hard +"is-map@npm:^2.0.3": + version: 2.0.3 + resolution: "is-map@npm:2.0.3" + checksum: e6ce5f6380f32b141b3153e6ba9074892bbbbd655e92e7ba5ff195239777e767a976dcd4e22f864accaf30e53ebf961ab1995424aef91af68788f0591b7396cc + languageName: node + linkType: hard + "is-module@npm:^1.0.0": version: 1.0.0 resolution: "is-module@npm:1.0.0" @@ -33817,6 +35050,16 @@ __metadata: languageName: node linkType: hard +"is-number-object@npm:^1.1.1": + version: 1.1.1 + resolution: "is-number-object@npm:1.1.1" + dependencies: + call-bound: ^1.0.3 + has-tostringtag: ^1.0.2 + checksum: 6517f0a0e8c4b197a21afb45cd3053dc711e79d45d8878aa3565de38d0102b130ca8732485122c7b336e98c27dacd5236854e3e6526e0eb30cae64956535662f + languageName: node + linkType: hard + "is-number@npm:^7.0.0": version: 7.0.0 resolution: "is-number@npm:7.0.0" @@ -33943,6 +35186,18 @@ __metadata: languageName: node linkType: hard +"is-regex@npm:^1.2.1": + version: 1.2.1 + resolution: "is-regex@npm:1.2.1" + dependencies: + call-bound: ^1.0.2 + gopd: ^1.2.0 + has-tostringtag: ^1.0.2 + hasown: ^2.0.2 + checksum: 99ee0b6d30ef1bb61fa4b22fae7056c6c9b3c693803c0c284ff7a8570f83075a7d38cda53b06b7996d441215c27895ea5d1af62124562e13d91b3dbec41a5e13 + languageName: node + linkType: hard + "is-regexp@npm:^1.0.0": version: 1.0.0 resolution: "is-regexp@npm:1.0.0" @@ -33971,6 +35226,13 @@ __metadata: languageName: node linkType: hard +"is-set@npm:^2.0.3": + version: 2.0.3 + resolution: "is-set@npm:2.0.3" + checksum: 36e3f8c44bdbe9496c9689762cc4110f6a6a12b767c5d74c0398176aa2678d4467e3bf07595556f2dba897751bde1422480212b97d973c7b08a343100b0c0dfe + languageName: node + linkType: hard + "is-shared-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "is-shared-array-buffer@npm:1.0.2" @@ -33989,6 +35251,15 @@ __metadata: languageName: node linkType: hard +"is-shared-array-buffer@npm:^1.0.4": + version: 1.0.4 + resolution: "is-shared-array-buffer@npm:1.0.4" + dependencies: + call-bound: ^1.0.3 + checksum: 1611fedc175796eebb88f4dfc393dd969a4a8e6c69cadaff424ee9d4464f9f026399a5f84a90f7c62d6d7ee04e3626a912149726de102b0bd6c1ee6a9868fa5a + languageName: node + linkType: hard + "is-stream@npm:^1.1.0": version: 1.1.0 resolution: "is-stream@npm:1.1.0" @@ -34019,6 +35290,16 @@ __metadata: languageName: node linkType: hard +"is-string@npm:^1.1.1": + version: 1.1.1 + resolution: "is-string@npm:1.1.1" + dependencies: + call-bound: ^1.0.3 + has-tostringtag: ^1.0.2 + checksum: 2eeaaff605250f5e836ea3500d33d1a5d3aa98d008641d9d42fb941e929ffd25972326c2ef912987e54c95b6f10416281aaf1b35cdf81992cfb7524c5de8e193 + languageName: node + linkType: hard + "is-subset@npm:^0.1.1": version: 0.1.1 resolution: "is-subset@npm:0.1.1" @@ -34035,6 +35316,17 @@ __metadata: languageName: node linkType: hard +"is-symbol@npm:^1.0.4, is-symbol@npm:^1.1.1": + version: 1.1.1 + resolution: "is-symbol@npm:1.1.1" + dependencies: + call-bound: ^1.0.2 + has-symbols: ^1.1.0 + safe-regex-test: ^1.1.0 + checksum: bfafacf037af6f3c9d68820b74be4ae8a736a658a3344072df9642a090016e281797ba8edbeb1c83425879aae55d1cb1f30b38bf132d703692b2570367358032 + languageName: node + linkType: hard + "is-text-path@npm:^1.0.1": version: 1.0.1 resolution: "is-text-path@npm:1.0.1" @@ -34062,6 +35354,15 @@ __metadata: languageName: node linkType: hard +"is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.15": + version: 1.1.15 + resolution: "is-typed-array@npm:1.1.15" + dependencies: + which-typed-array: ^1.1.16 + checksum: ea7cfc46c282f805d19a9ab2084fd4542fed99219ee9dbfbc26284728bd713a51eac66daa74eca00ae0a43b61322920ba334793607dc39907465913e921e0892 + languageName: node + linkType: hard + "is-typedarray@npm:1.0.0, is-typedarray@npm:^1.0.0": version: 1.0.0 resolution: "is-typedarray@npm:1.0.0" @@ -34092,6 +35393,13 @@ __metadata: languageName: node linkType: hard +"is-weakmap@npm:^2.0.2": + version: 2.0.2 + resolution: "is-weakmap@npm:2.0.2" + checksum: f36aef758b46990e0d3c37269619c0a08c5b29428c0bb11ecba7f75203442d6c7801239c2f31314bc79199217ef08263787f3837d9e22610ad1da62970d6616d + languageName: node + linkType: hard + "is-weakref@npm:^1.0.2": version: 1.0.2 resolution: "is-weakref@npm:1.0.2" @@ -34101,6 +35409,15 @@ __metadata: languageName: node linkType: hard +"is-weakref@npm:^1.1.0": + version: 1.1.0 + resolution: "is-weakref@npm:1.1.0" + dependencies: + call-bound: ^1.0.2 + checksum: 2a2f3a1746ee1baecf9ac6483d903cd3f8ef3cca88e2baa42f2e85ea064bd246d218eed5f6d479fc1c76dae2231e71133b6b86160e821d176932be9fae3da4da + languageName: node + linkType: hard + "is-weakset@npm:^2.0.1": version: 2.0.2 resolution: "is-weakset@npm:2.0.2" @@ -34111,6 +35428,16 @@ __metadata: languageName: node linkType: hard +"is-weakset@npm:^2.0.3": + version: 2.0.4 + resolution: "is-weakset@npm:2.0.4" + dependencies: + call-bound: ^1.0.3 + get-intrinsic: ^1.2.6 + checksum: 5c6c8415a06065d78bdd5e3a771483aa1cd928df19138aa73c4c51333226f203f22117b4325df55cc8b3085a6716870a320c2d757efee92d7a7091a039082041 + languageName: node + linkType: hard + "is-wsl@npm:^1.1.0": version: 1.1.0 resolution: "is-wsl@npm:1.1.0" @@ -34315,6 +35642,20 @@ __metadata: languageName: node linkType: hard +"iterator.prototype@npm:^1.1.4": + version: 1.1.5 + resolution: "iterator.prototype@npm:1.1.5" + dependencies: + define-data-property: ^1.1.4 + es-object-atoms: ^1.0.0 + get-intrinsic: ^1.2.6 + get-proto: ^1.0.0 + has-symbols: ^1.1.0 + set-function-name: ^2.0.2 + checksum: 7db23c42629ba4790e6e15f78b555f41dbd08818c85af306988364bd19d86716a1187cb333444f3a0036bfc078a0e9cb7ec67fef3a61662736d16410d7f77869 + languageName: node + linkType: hard + "jackspeak@npm:^2.0.3": version: 2.2.1 resolution: "jackspeak@npm:2.2.1" @@ -36692,6 +38033,13 @@ __metadata: languageName: node linkType: hard +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 9026b03edc2847eefa2e37646c579300a1f3a4586cfb62bf857832b60c852042d0d6ae55d1afb8926163fa54c2b01d83ae24705f34990348bdac6273a29d4581 + languageName: node + linkType: hard + "json-parse-better-errors@npm:^1.0.1": version: 1.0.2 resolution: "json-parse-better-errors@npm:1.0.2" @@ -36869,6 +38217,18 @@ __metadata: languageName: node linkType: hard +"jsx-ast-utils@npm:^3.3.5": + version: 3.3.5 + resolution: "jsx-ast-utils@npm:3.3.5" + dependencies: + array-includes: ^3.1.6 + array.prototype.flat: ^1.3.1 + object.assign: ^4.1.4 + object.values: ^1.1.6 + checksum: f4b05fa4d7b5234230c905cfa88d36dc8a58a6666975a3891429b1a8cdc8a140bca76c297225cb7a499fad25a2c052ac93934449a2c31a44fc9edd06c773780a + languageName: node + linkType: hard + "keccak@npm:^3.0.0, keccak@npm:^3.0.3": version: 3.0.4 resolution: "keccak@npm:3.0.4" @@ -36893,6 +38253,15 @@ __metadata: languageName: node linkType: hard +"keyv@npm:^4.5.4": + version: 4.5.4 + resolution: "keyv@npm:4.5.4" + dependencies: + json-buffer: 3.0.1 + checksum: 74a24395b1c34bd44ad5cb2b49140d087553e170625240b86755a6604cd65aa16efdbdeae5cdb17ba1284a0fbb25ad06263755dbc71b8d8b06f74232ce3cdd72 + languageName: node + linkType: hard + "keyvaluestorage-interface@npm:^1.0.0": version: 1.0.0 resolution: "keyvaluestorage-interface@npm:1.0.0" @@ -36937,6 +38306,13 @@ __metadata: languageName: node linkType: hard +"language-subtag-registry@npm:^0.3.20": + version: 0.3.23 + resolution: "language-subtag-registry@npm:0.3.23" + checksum: 0b64c1a6c5431c8df648a6d25594ff280613c886f4a1a542d9b864e5472fb93e5c7856b9c41595c38fac31370328fc79fcc521712e89ea6d6866cbb8e0995d81 + languageName: node + linkType: hard + "language-subtag-registry@npm:~0.3.2": version: 0.3.22 resolution: "language-subtag-registry@npm:0.3.22" @@ -36953,6 +38329,15 @@ __metadata: languageName: node linkType: hard +"language-tags@npm:^1.0.9": + version: 1.0.9 + resolution: "language-tags@npm:1.0.9" + dependencies: + language-subtag-registry: ^0.3.20 + checksum: 57c530796dc7179914dee71bc94f3747fd694612480241d0453a063777265dfe3a951037f7acb48f456bf167d6eb419d4c00263745326b3ba1cdcf4657070e78 + languageName: node + linkType: hard + "launch-editor@npm:^2.6.0": version: 2.6.0 resolution: "launch-editor@npm:2.6.0" @@ -37860,6 +39245,13 @@ __metadata: languageName: node linkType: hard +"math-intrinsics@npm:^1.1.0": + version: 1.1.0 + resolution: "math-intrinsics@npm:1.1.0" + checksum: 0e513b29d120f478c85a70f49da0b8b19bc638975eca466f2eeae0071f3ad00454c621bf66e16dd435896c208e719fc91ad79bbfba4e400fe0b372e7c1c9c9a2 + languageName: node + linkType: hard + "md5-file@npm:^3.2.3": version: 3.2.3 resolution: "md5-file@npm:3.2.3" @@ -39995,6 +41387,67 @@ __metadata: languageName: node linkType: hard +"next@npm:15.1.4": + version: 15.1.4 + resolution: "next@npm:15.1.4" + dependencies: + "@next/env": 15.1.4 + "@next/swc-darwin-arm64": 15.1.4 + "@next/swc-darwin-x64": 15.1.4 + "@next/swc-linux-arm64-gnu": 15.1.4 + "@next/swc-linux-arm64-musl": 15.1.4 + "@next/swc-linux-x64-gnu": 15.1.4 + "@next/swc-linux-x64-musl": 15.1.4 + "@next/swc-win32-arm64-msvc": 15.1.4 + "@next/swc-win32-x64-msvc": 15.1.4 + "@swc/counter": 0.1.3 + "@swc/helpers": 0.5.15 + busboy: 1.6.0 + caniuse-lite: ^1.0.30001579 + postcss: 8.4.31 + sharp: ^0.33.5 + styled-jsx: 5.1.6 + peerDependencies: + "@opentelemetry/api": ^1.1.0 + "@playwright/test": ^1.41.2 + babel-plugin-react-compiler: "*" + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + dependenciesMeta: + "@next/swc-darwin-arm64": + optional: true + "@next/swc-darwin-x64": + optional: true + "@next/swc-linux-arm64-gnu": + optional: true + "@next/swc-linux-arm64-musl": + optional: true + "@next/swc-linux-x64-gnu": + optional: true + "@next/swc-linux-x64-musl": + optional: true + "@next/swc-win32-arm64-msvc": + optional: true + "@next/swc-win32-x64-msvc": + optional: true + sharp: + optional: true + peerDependenciesMeta: + "@opentelemetry/api": + optional: true + "@playwright/test": + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + bin: + next: dist/bin/next + checksum: e9de936fe41bdddd50be283b6ce1f35ef434f0777026400a9119d91d0f99d0f7d7101599700de7502b0340c247691f98abea551c1738f158c89d4981d11fe1cf + languageName: node + linkType: hard + "next@npm:canary": version: 13.4.11-canary.0 resolution: "next@npm:13.4.11-canary.0" @@ -40549,6 +42002,13 @@ __metadata: languageName: node linkType: hard +"object-inspect@npm:^1.13.3": + version: 1.13.3 + resolution: "object-inspect@npm:1.13.3" + checksum: 8c962102117241e18ea403b84d2521f78291b774b03a29ee80a9863621d88265ffd11d0d7e435c4c2cea0dc2a2fbf8bbc92255737a05536590f2df2e8756f297 + languageName: node + linkType: hard + "object-is@npm:^1.0.2, object-is@npm:^1.1.5": version: 1.1.5 resolution: "object-is@npm:1.1.5" @@ -40608,6 +42068,20 @@ __metadata: languageName: node linkType: hard +"object.assign@npm:^4.1.7": + version: 4.1.7 + resolution: "object.assign@npm:4.1.7" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.3 + define-properties: ^1.2.1 + es-object-atoms: ^1.0.0 + has-symbols: ^1.1.0 + object-keys: ^1.1.1 + checksum: 60e07d2651cf4f5528c485f1aa4dbded9b384c47d80e8187cefd11320abb1aebebf78df5483451dfa549059f8281c21f7b4bf7d19e9e5e97d8d617df0df298de + languageName: node + linkType: hard + "object.entries@npm:^1.1.0, object.entries@npm:^1.1.1": version: 1.1.7 resolution: "object.entries@npm:1.1.7" @@ -40701,7 +42175,7 @@ __metadata: languageName: node linkType: hard -"object.groupby@npm:^1.0.1": +"object.groupby@npm:^1.0.1, object.groupby@npm:^1.0.3": version: 1.0.3 resolution: "object.groupby@npm:1.0.3" dependencies: @@ -40766,6 +42240,18 @@ __metadata: languageName: node linkType: hard +"object.values@npm:^1.2.1": + version: 1.2.1 + resolution: "object.values@npm:1.2.1" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.3 + define-properties: ^1.2.1 + es-object-atoms: ^1.0.0 + checksum: f9b9a2a125ccf8ded29414d7c056ae0d187b833ee74919821fc60d7e216626db220d9cb3cf33f965c84aaaa96133626ca13b80f3c158b673976dc8cfcfcd26bb + languageName: node + linkType: hard + "objectorarray@npm:^1.0.5": version: 1.0.5 resolution: "objectorarray@npm:1.0.5" @@ -41021,6 +42507,17 @@ __metadata: languageName: node linkType: hard +"own-keys@npm:^1.0.1": + version: 1.0.1 + resolution: "own-keys@npm:1.0.1" + dependencies: + get-intrinsic: ^1.2.6 + object-keys: ^1.1.1 + safe-push-apply: ^1.0.0 + checksum: cc9dd7d85c4ccfbe8109fce307d581ac7ede7b26de892b537873fbce2dc6a206d89aea0630dbb98e47ce0873517cefeaa7be15fcf94aaf4764a3b34b474a5b61 + languageName: node + linkType: hard + "p-finally@npm:^1.0.0": version: 1.0.0 resolution: "p-finally@npm:1.0.0" @@ -41734,6 +43231,24 @@ __metadata: languageName: node linkType: hard +"playground-next@workspace:packages/playground-next": + version: 0.0.0-use.local + resolution: "playground-next@workspace:packages/playground-next" + dependencies: + "@eslint/eslintrc": ^3 + "@metamask/sdk-react": "workspace:^" + "@types/node": ^20 + "@types/react": ^19 + "@types/react-dom": ^19 + eslint: ^9 + eslint-config-next: 15.1.4 + next: 15.1.4 + react: ^19.0.0 + react-dom: ^19.0.0 + typescript: ^5 + languageName: unknown + linkType: soft + "plist@npm:^3.0.5": version: 3.1.0 resolution: "plist@npm:3.1.0" @@ -42663,17 +44178,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^7.0.35": - version: 7.0.39 - resolution: "postcss@npm:7.0.39" - dependencies: - picocolors: ^0.2.1 - source-map: ^0.6.1 - checksum: 4ac793f506c23259189064bdc921260d869a115a82b5e713973c5af8e94fbb5721a5cc3e1e26840500d7e1f1fa42a209747c5b1a151918a9bc11f0d7ed9048e3 - languageName: node - linkType: hard - -"postcss@npm:^8.2.14, postcss@npm:^8.4.31, postcss@npm:~8.4.21": +"postcss@npm:8.4.31, postcss@npm:^8.2.14, postcss@npm:^8.4.31, postcss@npm:~8.4.21": version: 8.4.31 resolution: "postcss@npm:8.4.31" dependencies: @@ -42684,6 +44189,16 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^7.0.35": + version: 7.0.39 + resolution: "postcss@npm:7.0.39" + dependencies: + picocolors: ^0.2.1 + source-map: ^0.6.1 + checksum: 4ac793f506c23259189064bdc921260d869a115a82b5e713973c5af8e94fbb5721a5cc3e1e26840500d7e1f1fa42a209747c5b1a151918a9bc11f0d7ed9048e3 + languageName: node + linkType: hard + "postcss@npm:^8.3.5, postcss@npm:^8.4.12, postcss@npm:^8.4.21, postcss@npm:^8.4.23": version: 8.4.26 resolution: "postcss@npm:8.4.26" @@ -44840,6 +46355,22 @@ __metadata: languageName: node linkType: hard +"reflect.getprototypeof@npm:^1.0.6, reflect.getprototypeof@npm:^1.0.9": + version: 1.0.10 + resolution: "reflect.getprototypeof@npm:1.0.10" + dependencies: + call-bind: ^1.0.8 + define-properties: ^1.2.1 + es-abstract: ^1.23.9 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + get-intrinsic: ^1.2.7 + get-proto: ^1.0.1 + which-builtin-type: ^1.2.1 + checksum: ccc5debeb66125e276ae73909cecb27e47c35d9bb79d9cc8d8d055f008c58010ab8cb401299786e505e4aab733a64cba9daf5f312a58e96a43df66adad221870 + languageName: node + linkType: hard + "regenerate-unicode-properties@npm:^10.1.0": version: 10.1.0 resolution: "regenerate-unicode-properties@npm:10.1.0" @@ -44938,6 +46469,20 @@ __metadata: languageName: node linkType: hard +"regexp.prototype.flags@npm:^1.5.3": + version: 1.5.4 + resolution: "regexp.prototype.flags@npm:1.5.4" + dependencies: + call-bind: ^1.0.8 + define-properties: ^1.2.1 + es-errors: ^1.3.0 + get-proto: ^1.0.1 + gopd: ^1.2.0 + set-function-name: ^2.0.2 + checksum: 18cb667e56cb328d2dda569d7f04e3ea78f2683135b866d606538cf7b1d4271f7f749f09608c877527799e6cf350e531368f3c7a20ccd1bb41048a48926bdeeb + languageName: node + linkType: hard + "regexpp@npm:^3.0.0, regexpp@npm:^3.1.0": version: 3.2.0 resolution: "regexpp@npm:3.2.0" @@ -46074,6 +47619,19 @@ __metadata: languageName: node linkType: hard +"safe-array-concat@npm:^1.1.3": + version: 1.1.3 + resolution: "safe-array-concat@npm:1.1.3" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.2 + get-intrinsic: ^1.2.6 + has-symbols: ^1.1.0 + isarray: ^2.0.5 + checksum: 00f6a68140e67e813f3ad5e73e6dedcf3e42a9fa01f04d44b0d3f7b1f4b257af876832a9bfc82ac76f307e8a6cc652e3cf95876048a26cbec451847cf6ae3707 + languageName: node + linkType: hard + "safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": version: 5.1.2 resolution: "safe-buffer@npm:5.1.2" @@ -46109,6 +47667,16 @@ __metadata: languageName: node linkType: hard +"safe-push-apply@npm:^1.0.0": + version: 1.0.0 + resolution: "safe-push-apply@npm:1.0.0" + dependencies: + es-errors: ^1.3.0 + isarray: ^2.0.5 + checksum: 8c11cbee6dc8ff5cc0f3d95eef7052e43494591384015902e4292aef4ae9e539908288520ed97179cee17d6ffb450fe5f05a46ce7a1749685f7524fd568ab5db + languageName: node + linkType: hard + "safe-regex-test@npm:^1.0.0": version: 1.0.0 resolution: "safe-regex-test@npm:1.0.0" @@ -46131,6 +47699,17 @@ __metadata: languageName: node linkType: hard +"safe-regex-test@npm:^1.1.0": + version: 1.1.0 + resolution: "safe-regex-test@npm:1.1.0" + dependencies: + call-bound: ^1.0.2 + es-errors: ^1.3.0 + is-regex: ^1.2.1 + checksum: 3c809abeb81977c9ed6c869c83aca6873ea0f3ab0f806b8edbba5582d51713f8a6e9757d24d2b4b088f563801475ea946c8e77e7713e8c65cdd02305b6caedab + languageName: node + linkType: hard + "safe-stable-stringify@npm:^2.1.0, safe-stable-stringify@npm:^2.3.1, safe-stable-stringify@npm:^2.4.3": version: 2.4.3 resolution: "safe-stable-stringify@npm:2.4.3" @@ -46584,7 +48163,7 @@ __metadata: languageName: node linkType: hard -"set-function-length@npm:^1.2.1": +"set-function-length@npm:^1.2.1, set-function-length@npm:^1.2.2": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" dependencies: @@ -46621,6 +48200,17 @@ __metadata: languageName: node linkType: hard +"set-proto@npm:^1.0.0": + version: 1.0.0 + resolution: "set-proto@npm:1.0.0" + dependencies: + dunder-proto: ^1.0.1 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + checksum: ec27cbbe334598547e99024403e96da32aca3e530583e4dba7f5db1c43cbc4affa9adfbd77c7b2c210b9b8b2e7b2e600bad2a6c44fd62e804d8233f96bbb62f4 + languageName: node + linkType: hard + "setimmediate@npm:^1.0.4, setimmediate@npm:^1.0.5": version: 1.0.5 resolution: "setimmediate@npm:1.0.5" @@ -46670,6 +48260,75 @@ __metadata: languageName: node linkType: hard +"sharp@npm:^0.33.5": + version: 0.33.5 + resolution: "sharp@npm:0.33.5" + dependencies: + "@img/sharp-darwin-arm64": 0.33.5 + "@img/sharp-darwin-x64": 0.33.5 + "@img/sharp-libvips-darwin-arm64": 1.0.4 + "@img/sharp-libvips-darwin-x64": 1.0.4 + "@img/sharp-libvips-linux-arm": 1.0.5 + "@img/sharp-libvips-linux-arm64": 1.0.4 + "@img/sharp-libvips-linux-s390x": 1.0.4 + "@img/sharp-libvips-linux-x64": 1.0.4 + "@img/sharp-libvips-linuxmusl-arm64": 1.0.4 + "@img/sharp-libvips-linuxmusl-x64": 1.0.4 + "@img/sharp-linux-arm": 0.33.5 + "@img/sharp-linux-arm64": 0.33.5 + "@img/sharp-linux-s390x": 0.33.5 + "@img/sharp-linux-x64": 0.33.5 + "@img/sharp-linuxmusl-arm64": 0.33.5 + "@img/sharp-linuxmusl-x64": 0.33.5 + "@img/sharp-wasm32": 0.33.5 + "@img/sharp-win32-ia32": 0.33.5 + "@img/sharp-win32-x64": 0.33.5 + color: ^4.2.3 + detect-libc: ^2.0.3 + semver: ^7.6.3 + dependenciesMeta: + "@img/sharp-darwin-arm64": + optional: true + "@img/sharp-darwin-x64": + optional: true + "@img/sharp-libvips-darwin-arm64": + optional: true + "@img/sharp-libvips-darwin-x64": + optional: true + "@img/sharp-libvips-linux-arm": + optional: true + "@img/sharp-libvips-linux-arm64": + optional: true + "@img/sharp-libvips-linux-s390x": + optional: true + "@img/sharp-libvips-linux-x64": + optional: true + "@img/sharp-libvips-linuxmusl-arm64": + optional: true + "@img/sharp-libvips-linuxmusl-x64": + optional: true + "@img/sharp-linux-arm": + optional: true + "@img/sharp-linux-arm64": + optional: true + "@img/sharp-linux-s390x": + optional: true + "@img/sharp-linux-x64": + optional: true + "@img/sharp-linuxmusl-arm64": + optional: true + "@img/sharp-linuxmusl-x64": + optional: true + "@img/sharp-wasm32": + optional: true + "@img/sharp-win32-ia32": + optional: true + "@img/sharp-win32-x64": + optional: true + checksum: 04beae89910ac65c5f145f88de162e8466bec67705f497ace128de849c24d168993e016f33a343a1f3c30b25d2a90c3e62b017a9a0d25452371556f6cd2471e4 + languageName: node + linkType: hard + "shebang-command@npm:^1.2.0": version: 1.2.0 resolution: "shebang-command@npm:1.2.0" @@ -46716,6 +48375,41 @@ __metadata: languageName: node linkType: hard +"side-channel-list@npm:^1.0.0": + version: 1.0.0 + resolution: "side-channel-list@npm:1.0.0" + dependencies: + es-errors: ^1.3.0 + object-inspect: ^1.13.3 + checksum: 603b928997abd21c5a5f02ae6b9cc36b72e3176ad6827fab0417ead74580cc4fb4d5c7d0a8a2ff4ead34d0f9e35701ed7a41853dac8a6d1a664fcce1a044f86f + languageName: node + linkType: hard + +"side-channel-map@npm:^1.0.1": + version: 1.0.1 + resolution: "side-channel-map@npm:1.0.1" + dependencies: + call-bound: ^1.0.2 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.5 + object-inspect: ^1.13.3 + checksum: 42501371cdf71f4ccbbc9c9e2eb00aaaab80a4c1c429d5e8da713fd4d39ef3b8d4a4b37ed4f275798a65260a551a7131fd87fe67e922dba4ac18586d6aab8b06 + languageName: node + linkType: hard + +"side-channel-weakmap@npm:^1.0.2": + version: 1.0.2 + resolution: "side-channel-weakmap@npm:1.0.2" + dependencies: + call-bound: ^1.0.2 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.5 + object-inspect: ^1.13.3 + side-channel-map: ^1.0.1 + checksum: a815c89bc78c5723c714ea1a77c938377ea710af20d4fb886d362b0d1f8ac73a17816a5f6640f354017d7e292a43da9c5e876c22145bac00b76cfb3468001736 + languageName: node + linkType: hard + "side-channel@npm:^1.0.4": version: 1.0.4 resolution: "side-channel@npm:1.0.4" @@ -46739,6 +48433,19 @@ __metadata: languageName: node linkType: hard +"side-channel@npm:^1.1.0": + version: 1.1.0 + resolution: "side-channel@npm:1.1.0" + dependencies: + es-errors: ^1.3.0 + object-inspect: ^1.13.3 + side-channel-list: ^1.0.0 + side-channel-map: ^1.0.1 + side-channel-weakmap: ^1.0.2 + checksum: bf73d6d6682034603eb8e99c63b50155017ed78a522d27c2acec0388a792c3ede3238b878b953a08157093b85d05797217d270b7666ba1f111345fbe933380ff + languageName: node + linkType: hard + "signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" @@ -47687,6 +49394,17 @@ __metadata: languageName: node linkType: hard +"string.prototype.includes@npm:^2.0.1": + version: 2.0.1 + resolution: "string.prototype.includes@npm:2.0.1" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.3 + checksum: ed4b7058b092f30d41c4df1e3e805eeea92479d2c7a886aa30f42ae32fde8924a10cc99cccc99c29b8e18c48216608a0fe6bf887f8b4aadf9559096a758f313a + languageName: node + linkType: hard + "string.prototype.matchall@npm:^4.0.0 || ^3.0.1": version: 4.0.10 resolution: "string.prototype.matchall@npm:4.0.10" @@ -47724,6 +49442,27 @@ __metadata: languageName: node linkType: hard +"string.prototype.matchall@npm:^4.0.12": + version: 4.0.12 + resolution: "string.prototype.matchall@npm:4.0.12" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.3 + define-properties: ^1.2.1 + es-abstract: ^1.23.6 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + get-intrinsic: ^1.2.6 + gopd: ^1.2.0 + has-symbols: ^1.1.0 + internal-slot: ^1.1.0 + regexp.prototype.flags: ^1.5.3 + set-function-name: ^2.0.2 + side-channel: ^1.1.0 + checksum: 98a09d6af91bfc6ee25556f3d7cd6646d02f5f08bda55d45528ed273d266d55a71af7291fe3fc76854deffb9168cc1a917d0b07a7d5a178c7e9537c99e6d2b57 + languageName: node + linkType: hard + "string.prototype.matchall@npm:^4.0.6, string.prototype.matchall@npm:^4.0.8": version: 4.0.8 resolution: "string.prototype.matchall@npm:4.0.8" @@ -47762,6 +49501,16 @@ __metadata: languageName: node linkType: hard +"string.prototype.repeat@npm:^1.0.0": + version: 1.0.0 + resolution: "string.prototype.repeat@npm:1.0.0" + dependencies: + define-properties: ^1.1.3 + es-abstract: ^1.17.5 + checksum: 95dfc514ed7f328d80a066dabbfbbb1615c3e51490351085409db2eb7cbfed7ea29fdadaf277647fbf9f4a1e10e6dd9e95e78c0fd2c4e6bb6723ea6e59401004 + languageName: node + linkType: hard + "string.prototype.trim@npm:^1.2.1, string.prototype.trim@npm:^1.2.8": version: 1.2.8 resolution: "string.prototype.trim@npm:1.2.8" @@ -47773,6 +49522,21 @@ __metadata: languageName: node linkType: hard +"string.prototype.trim@npm:^1.2.10": + version: 1.2.10 + resolution: "string.prototype.trim@npm:1.2.10" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.2 + define-data-property: ^1.1.4 + define-properties: ^1.2.1 + es-abstract: ^1.23.5 + es-object-atoms: ^1.0.0 + has-property-descriptors: ^1.0.2 + checksum: 87659cd8561237b6c69f5376328fda934693aedde17bb7a2c57008e9d9ff992d0c253a391c7d8d50114e0e49ff7daf86a362f7961cf92f7564cd01342ca2e385 + languageName: node + linkType: hard + "string.prototype.trim@npm:^1.2.7": version: 1.2.7 resolution: "string.prototype.trim@npm:1.2.7" @@ -47829,6 +49593,18 @@ __metadata: languageName: node linkType: hard +"string.prototype.trimend@npm:^1.0.9": + version: 1.0.9 + resolution: "string.prototype.trimend@npm:1.0.9" + dependencies: + call-bind: ^1.0.8 + call-bound: ^1.0.2 + define-properties: ^1.2.1 + es-object-atoms: ^1.0.0 + checksum: cb86f639f41d791a43627784be2175daa9ca3259c7cb83e7a207a729909b74f2ea0ec5d85de5761e6835e5f443e9420c6ff3f63a845378e4a61dd793177bc287 + languageName: node + linkType: hard + "string.prototype.trimstart@npm:^1.0.6": version: 1.0.6 resolution: "string.prototype.trimstart@npm:1.0.6" @@ -48072,6 +49848,22 @@ __metadata: languageName: node linkType: hard +"styled-jsx@npm:5.1.6": + version: 5.1.6 + resolution: "styled-jsx@npm:5.1.6" + dependencies: + client-only: 0.0.1 + peerDependencies: + react: ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + peerDependenciesMeta: + "@babel/core": + optional: true + babel-plugin-macros: + optional: true + checksum: 879ad68e3e81adcf4373038aaafe55f968294955593660e173fbf679204aff158c59966716a60b29af72dc88795cfb2c479b6d2c3c87b2b2d282f3e27cc66461 + languageName: node + linkType: hard + "stylehacks@npm:^5.1.1": version: 5.1.1 resolution: "stylehacks@npm:5.1.1" @@ -49108,6 +50900,15 @@ __metadata: languageName: node linkType: hard +"ts-api-utils@npm:^2.0.0": + version: 2.0.0 + resolution: "ts-api-utils@npm:2.0.0" + peerDependencies: + typescript: ">=4.8.4" + checksum: f16f3e4e3308e7ad7ccf0bec3e0cb2e06b46c2d6919c40b6439e37912409c72f14340d231343b2b1b8cc17c2b8b01c5f2418690ea788312db6ca4e72cf2df6d8 + languageName: node + linkType: hard + "ts-dedent@npm:^2.0.0, ts-dedent@npm:^2.2.0": version: 2.2.0 resolution: "ts-dedent@npm:2.2.0" @@ -49267,6 +51068,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^2.8.0": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a + languageName: node + linkType: hard + "tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" @@ -49516,6 +51324,17 @@ __metadata: languageName: node linkType: hard +"typed-array-buffer@npm:^1.0.3": + version: 1.0.3 + resolution: "typed-array-buffer@npm:1.0.3" + dependencies: + call-bound: ^1.0.3 + es-errors: ^1.3.0 + is-typed-array: ^1.1.14 + checksum: 3fb91f0735fb413b2bbaaca9fabe7b8fc14a3fa5a5a7546bab8a57e755be0e3788d893195ad9c2b842620592de0e68d4c077d4c2c41f04ec25b8b5bb82fa9a80 + languageName: node + linkType: hard + "typed-array-byte-length@npm:^1.0.0": version: 1.0.0 resolution: "typed-array-byte-length@npm:1.0.0" @@ -49541,6 +51360,19 @@ __metadata: languageName: node linkType: hard +"typed-array-byte-length@npm:^1.0.3": + version: 1.0.3 + resolution: "typed-array-byte-length@npm:1.0.3" + dependencies: + call-bind: ^1.0.8 + for-each: ^0.3.3 + gopd: ^1.2.0 + has-proto: ^1.2.0 + is-typed-array: ^1.1.14 + checksum: cda9352178ebeab073ad6499b03e938ebc30c4efaea63a26839d89c4b1da9d2640b0d937fc2bd1f049eb0a38def6fbe8a061b601292ae62fe079a410ce56e3a6 + languageName: node + linkType: hard + "typed-array-byte-offset@npm:^1.0.0": version: 1.0.0 resolution: "typed-array-byte-offset@npm:1.0.0" @@ -49568,6 +51400,21 @@ __metadata: languageName: node linkType: hard +"typed-array-byte-offset@npm:^1.0.4": + version: 1.0.4 + resolution: "typed-array-byte-offset@npm:1.0.4" + dependencies: + available-typed-arrays: ^1.0.7 + call-bind: ^1.0.8 + for-each: ^0.3.3 + gopd: ^1.2.0 + has-proto: ^1.2.0 + is-typed-array: ^1.1.15 + reflect.getprototypeof: ^1.0.9 + checksum: 670b7e6bb1d3c2cf6160f27f9f529e60c3f6f9611c67e47ca70ca5cfa24ad95415694c49d1dbfeda016d3372cab7dfc9e38c7b3e1bb8d692cae13a63d3c144d7 + languageName: node + linkType: hard + "typed-array-length@npm:^1.0.4": version: 1.0.4 resolution: "typed-array-length@npm:1.0.4" @@ -49593,6 +51440,20 @@ __metadata: languageName: node linkType: hard +"typed-array-length@npm:^1.0.7": + version: 1.0.7 + resolution: "typed-array-length@npm:1.0.7" + dependencies: + call-bind: ^1.0.7 + for-each: ^0.3.3 + gopd: ^1.0.1 + is-typed-array: ^1.1.13 + possible-typed-array-names: ^1.0.0 + reflect.getprototypeof: ^1.0.6 + checksum: deb1a4ffdb27cd930b02c7030cb3e8e0993084c643208e52696e18ea6dd3953dfc37b939df06ff78170423d353dc8b10d5bae5796f3711c1b3abe52872b3774c + languageName: node + linkType: hard + "typed-query-selector@npm:^2.12.0": version: 2.12.0 resolution: "typed-query-selector@npm:2.12.0" @@ -49663,6 +51524,16 @@ __metadata: languageName: node linkType: hard +"typescript@npm:^5": + version: 5.7.3 + resolution: "typescript@npm:5.7.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 6c38b1e989918e576f0307e6ee013522ea480dfce5f3ca85c9b2d8adb1edeffd37f4f30cd68de0c38a44563d12ba922bdb7e36aa2dac9c51de5d561e6e9a2e9c + languageName: node + linkType: hard + "typescript@npm:^5.2.2": version: 5.2.2 resolution: "typescript@npm:5.2.2" @@ -49743,6 +51614,16 @@ __metadata: languageName: node linkType: hard +"typescript@patch:typescript@^5#~builtin": + version: 5.7.3 + resolution: "typescript@patch:typescript@npm%3A5.7.3#~builtin::version=5.7.3&hash=77c9e2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 633cd749d6cd7bc842c6b6245847173bba99742a60776fae3c0fbcc0d1733cd51a733995e5f4dadd8afb0e64e57d3c7dbbeae953a072ee303940eca69e22f311 + languageName: node + linkType: hard + "typescript@patch:typescript@^5.2.2#~builtin": version: 5.2.2 resolution: "typescript@patch:typescript@npm%3A5.2.2#~builtin::version=5.2.2&hash=77c9e2" @@ -49855,6 +51736,18 @@ __metadata: languageName: node linkType: hard +"unbox-primitive@npm:^1.1.0": + version: 1.1.0 + resolution: "unbox-primitive@npm:1.1.0" + dependencies: + call-bound: ^1.0.3 + has-bigints: ^1.0.2 + has-symbols: ^1.1.0 + which-boxed-primitive: ^1.1.1 + checksum: 729f13b84a5bfa3fead1d8139cee5c38514e63a8d6a437819a473e241ba87eeb593646568621c7fc7f133db300ef18d65d1a5a60dc9c7beb9000364d93c581df + languageName: node + linkType: hard + "unbzip2-stream@npm:1.4.3, unbzip2-stream@npm:^1.4.3": version: 1.4.3 resolution: "unbzip2-stream@npm:1.4.3" @@ -49886,7 +51779,7 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~6.19.8": +"undici-types@npm:~6.19.2, undici-types@npm:~6.19.8": version: 6.19.8 resolution: "undici-types@npm:6.19.8" checksum: de51f1b447d22571cf155dfe14ff6d12c5bdaec237c765085b439c38ca8518fc360e88c70f99469162bf2e14188a7b0bcb06e1ed2dc031042b984b0bb9544017 @@ -51603,6 +53496,19 @@ __metadata: languageName: node linkType: hard +"which-boxed-primitive@npm:^1.1.0, which-boxed-primitive@npm:^1.1.1": + version: 1.1.1 + resolution: "which-boxed-primitive@npm:1.1.1" + dependencies: + is-bigint: ^1.1.0 + is-boolean-object: ^1.2.1 + is-number-object: ^1.1.1 + is-string: ^1.1.1 + is-symbol: ^1.1.1 + checksum: ee41d0260e4fd39551ad77700c7047d3d281ec03d356f5e5c8393fe160ba0db53ef446ff547d05f76ffabfd8ad9df7c9a827e12d4cccdbc8fccf9239ff8ac21e + languageName: node + linkType: hard + "which-builtin-type@npm:^1.1.3": version: 1.1.3 resolution: "which-builtin-type@npm:1.1.3" @@ -51623,6 +53529,27 @@ __metadata: languageName: node linkType: hard +"which-builtin-type@npm:^1.2.1": + version: 1.2.1 + resolution: "which-builtin-type@npm:1.2.1" + dependencies: + call-bound: ^1.0.2 + function.prototype.name: ^1.1.6 + has-tostringtag: ^1.0.2 + is-async-function: ^2.0.0 + is-date-object: ^1.1.0 + is-finalizationregistry: ^1.1.0 + is-generator-function: ^1.0.10 + is-regex: ^1.2.1 + is-weakref: ^1.0.2 + isarray: ^2.0.5 + which-boxed-primitive: ^1.1.0 + which-collection: ^1.0.2 + which-typed-array: ^1.1.16 + checksum: 7a3617ba0e7cafb795f74db418df889867d12bce39a477f3ee29c6092aa64d396955bf2a64eae3726d8578440e26777695544057b373c45a8bcf5fbe920bf633 + languageName: node + linkType: hard + "which-collection@npm:^1.0.1": version: 1.0.1 resolution: "which-collection@npm:1.0.1" @@ -51635,6 +53562,18 @@ __metadata: languageName: node linkType: hard +"which-collection@npm:^1.0.2": + version: 1.0.2 + resolution: "which-collection@npm:1.0.2" + dependencies: + is-map: ^2.0.3 + is-set: ^2.0.3 + is-weakmap: ^2.0.2 + is-weakset: ^2.0.3 + checksum: c51821a331624c8197916598a738fc5aeb9a857f1e00d89f5e4c03dc7c60b4032822b8ec5696d28268bb83326456a8b8216344fb84270d18ff1d7628051879d9 + languageName: node + linkType: hard + "which-module@npm:^2.0.0": version: 2.0.1 resolution: "which-module@npm:2.0.1" @@ -51681,6 +53620,20 @@ __metadata: languageName: node linkType: hard +"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.18": + version: 1.1.18 + resolution: "which-typed-array@npm:1.1.18" + dependencies: + available-typed-arrays: ^1.0.7 + call-bind: ^1.0.8 + call-bound: ^1.0.3 + for-each: ^0.3.3 + gopd: ^1.2.0 + has-tostringtag: ^1.0.2 + checksum: d2feea7f51af66b3a240397aa41c796585033e1069f18e5b6d4cd3878538a1e7780596fd3ea9bf347c43d9e98e13be09b37d9ea3887cef29b11bc291fd47bb52 + languageName: node + linkType: hard + "which@npm:^1.2.9, which@npm:^1.3.1": version: 1.3.1 resolution: "which@npm:1.3.1" From d6ffb1ee4ea88acf6cd9fb6c1e21b340cc7aa559 Mon Sep 17 00:00:00 2001 From: abretonc7s Date: Wed, 15 Jan 2025 11:01:22 +0800 Subject: [PATCH 03/28] feat: cleanup --- .../services/RemoteCommunicationPostMessageStream/write.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/sdk/src/services/RemoteCommunicationPostMessageStream/write.ts b/packages/sdk/src/services/RemoteCommunicationPostMessageStream/write.ts index ffc92a600..79204316b 100644 --- a/packages/sdk/src/services/RemoteCommunicationPostMessageStream/write.ts +++ b/packages/sdk/src/services/RemoteCommunicationPostMessageStream/write.ts @@ -57,10 +57,6 @@ export async function write( deeplinkProtocolAvailable && mobileWeb && authorized; try { - console.warn( - `[RCPMS: _write()] triggeredInstaller=${triggeredInstaller} activeDeeplinkProtocol=${activeDeeplinkProtocol}`, - ); - if (!triggeredInstaller) { // The only reason not to send via network is because the rpc call will be sent in the deeplink instance.state.remote From c805f422e7b59b0eea091da89712461c6f917625 Mon Sep 17 00:00:00 2001 From: abretonc7s Date: Wed, 15 Jan 2025 11:31:53 +0800 Subject: [PATCH 04/28] feat: upgrade metamask/providers --- packages/playground-next/src/app/page.tsx | 82 ++++++++++++++------ packages/sdk/package.json | 4 +- packages/sdk/rollup.config.js | 2 + yarn.lock | 91 ++++++++++++++++++++++- 4 files changed, 154 insertions(+), 25 deletions(-) diff --git a/packages/playground-next/src/app/page.tsx b/packages/playground-next/src/app/page.tsx index f2683b8fc..7e1b5d714 100644 --- a/packages/playground-next/src/app/page.tsx +++ b/packages/playground-next/src/app/page.tsx @@ -2,7 +2,7 @@ import { useSDK } from '@metamask/sdk-react'; import styles from './page.module.css'; -import { useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; interface AccountInfo { account: string; @@ -10,46 +10,84 @@ interface AccountInfo { } export default function Home() { - const { sdk } = useSDK(); - const [account, setAccount] = useState(null); + const { sdk, connected, connecting, provider, account } = useSDK(); + const [accountInfo, setAccountInfo] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + const getBalance = useCallback(async (address: string): Promise => { + const balance = await provider?.request({ + method: 'eth_getBalance', + params: [address, 'latest'] + }); + return balance ? parseInt(balance as string, 16).toString() : '0'; + }, [provider]); const connectWallet = async (): Promise => { try { - const accounts = await sdk?.connect(); - - if (accounts?.[0]) { - const provider = sdk?.getProvider(); - const balance = await provider?.request({ - method: 'eth_getBalance', - params: [accounts[0], 'latest'] - }); - - setAccount({ - account: accounts[0], - balance: balance ? (parseInt(balance as string, 16)).toString() : '0' - }); - } + setIsLoading(true); + await sdk?.connect(); } catch (err) { console.error('Failed to connect wallet:', err); + } finally { + setIsLoading(false); } }; + const terminateConnection = async (): Promise => { + try { + setIsLoading(true); + await sdk?.terminate(); + setAccountInfo(null); + } catch (err) { + console.error('Failed to terminate connection:', err); + } finally { + setIsLoading(false); + } + }; + + useEffect(() => { + const updateAccountInfo = async () => { + if (connected && account) { + const balance = await getBalance(account); + setAccountInfo({ + account, + balance + }); + } else { + setAccountInfo(null); + } + }; + + updateAccountInfo(); + }, [connected, account, provider, getBalance]); + return (

Simple Web3 Dapp

- {!account ? ( - ) : ( <>
- Address: {account.account} + Address: {accountInfo?.account}
- Balance: {account.balance} Wei + Balance: {accountInfo?.balance} Wei
+ )}
diff --git a/packages/sdk/package.json b/packages/sdk/package.json index bc70ef57c..dcd3625ab 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/sdk", - "version": "0.31.4", + "version": "0.31.4-test", "description": "", "homepage": "https://github.com/MetaMask/metamask-sdk#readme", "bugs": { @@ -50,7 +50,7 @@ "dependencies": { "@babel/runtime": "^7.26.0", "@metamask/onboarding": "^1.0.1", - "@metamask/providers": "16.1.0", + "@metamask/providers": "^18.3.1", "@metamask/sdk-communication-layer": "workspace:*", "@metamask/sdk-install-modal-web": "workspace:*", "@paulmillr/qr": "^0.2.1", diff --git a/packages/sdk/rollup.config.js b/packages/sdk/rollup.config.js index 214fb2be1..d5938d728 100644 --- a/packages/sdk/rollup.config.js +++ b/packages/sdk/rollup.config.js @@ -23,6 +23,7 @@ const dependencies = Object.keys(packageJson.dependencies || {}); // Dependencies that should be bundled const bundledDeps = [ // '@metamask/sdk-communication-layer', + 'readable-stream', // Add other dependencies that should be bundled ]; @@ -58,6 +59,7 @@ const baseExternalDeps = [ ...sharedDeps, // Exclude shared deps from bundle '@react-native-async-storage/async-storage', 'extension-port-stream', + '@metamask/providers', ]; // Platform-specific externals diff --git a/yarn.lock b/yarn.lock index bfa304464..8dccf8055 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10979,6 +10979,17 @@ __metadata: languageName: node linkType: hard +"@metamask/json-rpc-engine@npm:^10.0.2": + version: 10.0.2 + resolution: "@metamask/json-rpc-engine@npm:10.0.2" + dependencies: + "@metamask/rpc-errors": ^7.0.2 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^11.0.1 + checksum: db561d6ffe4de041dc2fe79c6d1eb098bd9eb444864568c4781f3227e6c7e33563ac2858caadb14f6b58facbf189fe0f50725adbc29f3b2641b787e550e548e6 + languageName: node + linkType: hard + "@metamask/json-rpc-engine@npm:^7.0.0": version: 7.3.3 resolution: "@metamask/json-rpc-engine@npm:7.3.3" @@ -11024,6 +11035,18 @@ __metadata: languageName: node linkType: hard +"@metamask/json-rpc-middleware-stream@npm:^8.0.6": + version: 8.0.6 + resolution: "@metamask/json-rpc-middleware-stream@npm:8.0.6" + dependencies: + "@metamask/json-rpc-engine": ^10.0.2 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^11.0.1 + readable-stream: ^3.6.2 + checksum: e004de7a8090afc0441b9bf661106ac07a550862f6e824bfebcb14b46eea7551beeaeab4c39ac810beee0f53ad1032344a99eef1c0f5f118fe8d388e7e0c5014 + languageName: node + linkType: hard + "@metamask/network-controller@npm:^16.0.0": version: 16.0.0 resolution: "@metamask/network-controller@npm:16.0.0" @@ -11126,6 +11149,27 @@ __metadata: languageName: node linkType: hard +"@metamask/providers@npm:^18.3.1": + version: 18.3.1 + resolution: "@metamask/providers@npm:18.3.1" + dependencies: + "@metamask/json-rpc-engine": ^10.0.2 + "@metamask/json-rpc-middleware-stream": ^8.0.6 + "@metamask/object-multiplex": ^2.0.0 + "@metamask/rpc-errors": ^7.0.2 + "@metamask/safe-event-emitter": ^3.1.1 + "@metamask/utils": ^11.0.1 + detect-browser: ^5.2.0 + extension-port-stream: ^4.1.0 + fast-deep-equal: ^3.1.3 + is-stream: ^2.0.0 + readable-stream: ^3.6.2 + peerDependencies: + webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 + checksum: 626112e3bdaa3b63c041ac0d280777419109a1ed2a6cdd50c1b3c7700c53d2e342f93748244a58a74d2e94357fe9eed1137317acff4df9ee0586798e02cfe00d + languageName: node + linkType: hard + "@metamask/rpc-errors@npm:^6.0.0, @metamask/rpc-errors@npm:^6.1.0": version: 6.1.0 resolution: "@metamask/rpc-errors@npm:6.1.0" @@ -11146,6 +11190,16 @@ __metadata: languageName: node linkType: hard +"@metamask/rpc-errors@npm:^7.0.2": + version: 7.0.2 + resolution: "@metamask/rpc-errors@npm:7.0.2" + dependencies: + "@metamask/utils": ^11.0.1 + fast-safe-stringify: ^2.0.6 + checksum: 262a1ab57121e277eb979325d8e4335b9f4194c5acd0138ee0032db35b4e20ea0423badb5dad4bdf6abb85d22b476377f17911a54f82b3b1a2bdffc36654d028 + languageName: node + linkType: hard + "@metamask/safe-event-emitter@npm:2.0.0, @metamask/safe-event-emitter@npm:^2.0.0": version: 2.0.0 resolution: "@metamask/safe-event-emitter@npm:2.0.0" @@ -11842,7 +11896,7 @@ __metadata: "@metamask/eslint-config-nodejs": ^6.0.0 "@metamask/eslint-config-typescript": ^6.0.0 "@metamask/onboarding": ^1.0.1 - "@metamask/providers": 16.1.0 + "@metamask/providers": ^18.3.1 "@metamask/sdk-communication-layer": "workspace:*" "@metamask/sdk-install-modal-web": "workspace:*" "@paulmillr/qr": ^0.2.1 @@ -11911,6 +11965,13 @@ __metadata: languageName: unknown linkType: soft +"@metamask/superstruct@npm:^3.1.0": + version: 3.1.0 + resolution: "@metamask/superstruct@npm:3.1.0" + checksum: 00e4d0c0aae8b25ccc1885c1db0bb4ed1590010570140c255e4deee3bf8a10c859c8fce5e475b4ae09c8a56316207af87585b91f7f5a5c028d668ccd111f19e3 + languageName: node + linkType: hard + "@metamask/swappable-obj-proxy@npm:^2.1.0": version: 2.1.0 resolution: "@metamask/swappable-obj-proxy@npm:2.1.0" @@ -11918,6 +11979,23 @@ __metadata: languageName: node linkType: hard +"@metamask/utils@npm:^11.0.1": + version: 11.0.1 + resolution: "@metamask/utils@npm:11.0.1" + dependencies: + "@ethereumjs/tx": ^4.2.0 + "@metamask/superstruct": ^3.1.0 + "@noble/hashes": ^1.3.1 + "@scure/base": ^1.1.3 + "@types/debug": ^4.1.7 + debug: ^4.3.4 + pony-cause: ^2.1.10 + semver: ^7.5.4 + uuid: ^9.0.1 + checksum: a5072f87157f6763328767bf1ddc01deb94e13f32af58d0993e0450e7e211fb29882280a1013cbdc7752b152a662be3d9beef8129a9097dba7d465389c398b3c + languageName: node + linkType: hard + "@metamask/utils@npm:^3.0.1": version: 3.6.0 resolution: "@metamask/utils@npm:3.6.0" @@ -31798,6 +31876,17 @@ __metadata: languageName: node linkType: hard +"extension-port-stream@npm:^4.1.0": + version: 4.2.0 + resolution: "extension-port-stream@npm:4.2.0" + dependencies: + readable-stream: ^3.6.2 || ^4.4.2 + peerDependencies: + webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 + checksum: 85559c82e3f3aa21462e234b30b7d53872708893664cd03f2f848af556cf0730cf2243b089efc9d40bbe9a4f73bd8fd19684db5a985329b0c4402b4f2fe26358 + languageName: node + linkType: hard + "extract-zip@npm:2.0.1, extract-zip@npm:^2.0.1": version: 2.0.1 resolution: "extract-zip@npm:2.0.1" From 65c0e8098059802902a0bbd803206484de40a808 Mon Sep 17 00:00:00 2001 From: abretonc7s Date: Wed, 15 Jan 2025 19:47:28 +0800 Subject: [PATCH 05/28] feat: wip --- package.json | 1 + packages/multichainapi/.eslintrc.js | 45 ++ packages/multichainapi/jest.config.js | 7 + packages/multichainapi/package.json | 68 ++ packages/multichainapi/rollup.config.js | 73 ++ .../src/MultichainProvider.test.ts | 27 + .../multichainapi/src/constants/methods.ts | 167 ++++ .../multichainapi/src/constants/networks.ts | 13 + packages/multichainapi/src/index.ts | 19 + .../src/providers/BaseProvider.ts | 11 + .../src/providers/MultichainProvider.ts | 65 ++ .../providers/extensions/ExtensionProvider.ts | 147 ++++ packages/multichainapi/src/types.ts | 18 + .../multichainapi/src/utils/JsonHelpers.ts | 59 ++ .../src/utils/getCaip25FormattedAddresses.ts | 18 + packages/multichainapi/tsconfig.build.json | 4 + packages/multichainapi/tsconfig.eslint.json | 4 + packages/multichainapi/tsconfig.json | 13 + packages/sdk/package.json | 1 + yarn.lock | 750 +++++++++++++++++- 20 files changed, 1468 insertions(+), 42 deletions(-) create mode 100644 packages/multichainapi/.eslintrc.js create mode 100644 packages/multichainapi/jest.config.js create mode 100644 packages/multichainapi/package.json create mode 100644 packages/multichainapi/rollup.config.js create mode 100644 packages/multichainapi/src/MultichainProvider.test.ts create mode 100644 packages/multichainapi/src/constants/methods.ts create mode 100644 packages/multichainapi/src/constants/networks.ts create mode 100644 packages/multichainapi/src/index.ts create mode 100644 packages/multichainapi/src/providers/BaseProvider.ts create mode 100644 packages/multichainapi/src/providers/MultichainProvider.ts create mode 100644 packages/multichainapi/src/providers/extensions/ExtensionProvider.ts create mode 100644 packages/multichainapi/src/types.ts create mode 100644 packages/multichainapi/src/utils/JsonHelpers.ts create mode 100644 packages/multichainapi/src/utils/getCaip25FormattedAddresses.ts create mode 100644 packages/multichainapi/tsconfig.build.json create mode 100644 packages/multichainapi/tsconfig.eslint.json create mode 100644 packages/multichainapi/tsconfig.json diff --git a/package.json b/package.json index bf049cf85..ddd83c023 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "packages/sdk-socket-server-next", "packages/sdk-install-modal-web", "packages/sdk-communication-layer", + "packages/multichainapi", "packages/sdk", "packages/sdk-react", "packages/sdk-react-native", diff --git a/packages/multichainapi/.eslintrc.js b/packages/multichainapi/.eslintrc.js new file mode 100644 index 000000000..d4883a1e2 --- /dev/null +++ b/packages/multichainapi/.eslintrc.js @@ -0,0 +1,45 @@ +const path = require('path'); + +/** + * @type {import('eslint').Linter.Config} + */ +module.exports = { + extends: ['@metamask/eslint-config-typescript', '../../.eslintrc.js'], + root: true, + parser: '@typescript-eslint/parser', + parserOptions: { + project: [path.resolve(__dirname, 'tsconfig.eslint.json')], + }, + + ignorePatterns: [ + '.prettierrc.js', + '**/.eslintrc.js', + 'jest.config.ts', + '**/dist*/', + 'rollup.config.js', + '**/coverage/**', + ], + + overrides: [ + { + files: ['**/*.ts'], + rules: { + '@typescript-eslint/consistent-type-definitions': [ + 'error', + 'interface', + ], + '@typescript-eslint/no-floating-promises': 'error', + 'no-async-promise-executor': 'error', + 'import/no-named-as-default': 0, + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': ['error'], + }, + }, + { + files: ['**/*.d.ts'], + rules: { + 'import/unambiguous': 'off', + }, + }, + ], +}; diff --git a/packages/multichainapi/jest.config.js b/packages/multichainapi/jest.config.js new file mode 100644 index 000000000..b33d1cc06 --- /dev/null +++ b/packages/multichainapi/jest.config.js @@ -0,0 +1,7 @@ +/** @type {import('jest').Config} */ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/*.test.ts'], + collectCoverageFrom: ['src/**/*.ts', '!src/**/*.d.ts'], +}; diff --git a/packages/multichainapi/package.json b/packages/multichainapi/package.json new file mode 100644 index 000000000..a89a45d49 --- /dev/null +++ b/packages/multichainapi/package.json @@ -0,0 +1,68 @@ +{ + "name": "@metamask/multichainapi", + "version": "0.1.0", + "description": "CAIP-based multichain API for MetaMask", + "repository": { + "type": "git", + "url": "https://github.com/MetaMask/metamask-sdk", + "directory": "packages/multichainapi" + }, + "main": "dist/node/cjs/index.js", + "module": "dist/browser/es/index.js", + "browser": "dist/browser/es/index.js", + "types": "dist/types/src/index.d.ts", + "files": [ + "/dist" + ], + "scripts": { + "build:types": "tsc --project tsconfig.build.json --emitDeclarationOnly --outDir dist/types", + "build": "yarn build:types && rollup -c --bundleConfigAsCjs", + "build:clean": "yarn clean && yarn build", + "typecheck": "tsc --noEmit", + "clean": "rimraf ./dist", + "lint": "yarn lint:eslint && yarn lint:misc --check", + "lint:changelog": "../../scripts/validate-changelog.sh @metamask/multichainapi", + "lint:eslint": "eslint . --cache --ext js,ts", + "lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write", + "lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' --ignore-path ../../.gitignore", + "test": "jest", + "test:watch": "jest --watch" + }, + "dependencies": { + "@babel/runtime": "^7.26.0", + "@metamask/api-specs": "^0.10.13", + "@metamask/utils": "^11.0.1", + "@open-rpc/meta-schema": "^1.14.9", + "@types/chrome": "^0.0.296", + "debug": "^4.3.4", + "eventemitter2": "^6.4.9", + "tslib": "^2.6.2" + }, + "devDependencies": { + "@jest/globals": "^29.3.1", + "@lavamoat/allow-scripts": "^3.3.1", + "@metamask/auto-changelog": "3.1.0", + "@metamask/eslint-config": "^6.0.0", + "@metamask/eslint-config-typescript": "^6.0.0", + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-json": "^6.0.0", + "@rollup/plugin-node-resolve": "^15.0.2", + "@rollup/plugin-typescript": "^11.1.6", + "@types/debug": "^4.1.12", + "@types/jest": "^29.5.11", + "@types/node": "^20.1.3", + "@typescript-eslint/eslint-plugin": "^4.26.0", + "@typescript-eslint/parser": "^4.26.0", + "eslint": "^7.30.0", + "jest": "^29.3.1", + "prettier": "^2.3.0", + "rimraf": "^4.4.0", + "rollup": "^4.9.4", + "ts-jest": "^29.0.3", + "typescript": "^5.3.3" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + } +} diff --git a/packages/multichainapi/rollup.config.js b/packages/multichainapi/rollup.config.js new file mode 100644 index 000000000..fd7edc69b --- /dev/null +++ b/packages/multichainapi/rollup.config.js @@ -0,0 +1,73 @@ +import typescript from '@rollup/plugin-typescript'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import commonjs from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json'; +import terser from '@rollup/plugin-terser'; + +const packageJson = require('./package.json'); + +// Dependencies that should be external +const external = [ + ...Object.keys(packageJson.dependencies || {}), + ...Object.keys(packageJson.peerDependencies || {}), + ...Object.keys(packageJson.optionalDependencies || {}), +]; + +/** + * @type {import('rollup').RollupOptions[]} + */ +const configs = [ + // Node.js build + { + input: 'src/index.ts', + output: [ + { + file: packageJson.main, + format: 'cjs', + sourcemap: true, + exports: 'named', + }, + ], + external, + plugins: [ + typescript({ + tsconfig: './tsconfig.build.json', + }), + nodeResolve({ + preferBuiltins: true, + exportConditions: ['node'], + }), + commonjs(), + json(), + terser(), + ], + }, + // Browser build + { + input: 'src/index.ts', + output: [ + { + file: packageJson.module, + format: 'es', + sourcemap: true, + exports: 'named', + }, + ], + external, + plugins: [ + typescript({ + tsconfig: './tsconfig.build.json', + }), + nodeResolve({ + browser: true, + preferBuiltins: false, + exportConditions: ['browser'], + }), + commonjs(), + json(), + terser(), + ], + }, +]; + +export default configs; diff --git a/packages/multichainapi/src/MultichainProvider.test.ts b/packages/multichainapi/src/MultichainProvider.test.ts new file mode 100644 index 000000000..68289fb64 --- /dev/null +++ b/packages/multichainapi/src/MultichainProvider.test.ts @@ -0,0 +1,27 @@ +import { describe, expect, it } from '@jest/globals'; +import { MultichainProvider } from './providers/MultichainProvider'; + +describe('MultichainProvider', () => { + it('should create a session', async () => { + const provider = new MultichainProvider(); + const session = await provider.createSession('eip155:1', '0x123'); + + expect(session).toMatchObject({ + chainId: 'eip155:1', + account: '0x123', + }); + expect(session.id).toBeDefined(); + expect(session.expiry).toBeGreaterThan(Date.now()); + }); + + it('should revoke a session', async () => { + const provider = new MultichainProvider(); + const session = await provider.createSession('eip155:1', '0x123'); + + const result = await provider.revokeSession(session.id); + expect(result).toBe(true); + + const retrievedSession = await provider.getSession(session.id); + expect(retrievedSession).toBeUndefined(); + }); +}); diff --git a/packages/multichainapi/src/constants/methods.ts b/packages/multichainapi/src/constants/methods.ts new file mode 100644 index 000000000..f087ac260 --- /dev/null +++ b/packages/multichainapi/src/constants/methods.ts @@ -0,0 +1,167 @@ +// packages/multichainapi/src/constants/methods.ts +import MetaMaskOpenRPCDocument from '@metamask/api-specs'; +import { parseCaipAccountId, parseCaipChainId } from '@metamask/utils'; +import type { CaipAccountId, CaipChainId, Json } from '@metamask/utils'; + +/** + * Methods that require an account parameter. + */ +export const METHODS_REQUIRING_PARAM_INJECTION = { + eth_sendTransaction: true, + eth_signTypedData_v4: true, + personal_sign: true, + eth_getBalance: true, +} as const; + +/** + * Injects address and chainId (where applicable) into example params for a given method. + * @param method - The method to inject the address into. + * @param exampleParams - The example params to inject the address into. + * @param addressToInject - The address to inject. + * @param scopeToInject - The scope to inject the address into. + * @returns The updated example params with the address injected. + */ +export const injectParams = ( + method: string, + exampleParams: Json, + addressToInject: CaipAccountId, + scopeToInject: CaipChainId, +): Json => { + const { address: parsedAddress } = parseCaipAccountId(addressToInject); + const { reference: chainId } = parseCaipChainId(scopeToInject); + + if ( + !(method in METHODS_REQUIRING_PARAM_INJECTION) || + typeof exampleParams !== 'object' || + exampleParams === null || + !('method' in exampleParams) || + !('params' in exampleParams) || + !Array.isArray(exampleParams.params) + ) { + return exampleParams; + } + + switch (method) { + case 'eth_sendTransaction': + if ( + exampleParams.params.length > 0 && + typeof exampleParams.params[0] === 'object' && + exampleParams.params[0] !== null + ) { + return { + ...exampleParams, + params: [ + { + ...exampleParams.params[0], + from: parsedAddress, + to: parsedAddress, + value: '0x0', + }, + ...exampleParams.params.slice(1), + ], + }; + } + break; + + case 'personal_sign': + if (exampleParams.params.length >= 2) { + return { + ...exampleParams, + params: [ + exampleParams.params[0], + parsedAddress, + ...exampleParams.params.slice(2), + ] as Json[], + }; + } + break; + + case 'eth_signTypedData_v4': + if ( + exampleParams.params.length >= 2 && + typeof exampleParams.params[1] === 'object' && + exampleParams.params[1] !== null + ) { + const typedData = exampleParams.params[1]; + if ( + typeof typedData === 'object' && + typedData !== null && + 'domain' in typedData && + typeof typedData.domain === 'object' && + typedData.domain !== null + ) { + return { + ...exampleParams, + params: [ + parsedAddress, + { + ...typedData, + domain: { + ...typedData.domain, + chainId, + }, + }, + ], + }; + } + } + break; + + case 'eth_getBalance': + return { + ...exampleParams, + params: [parsedAddress, 'latest'], + }; + + default: + break; + } + + return exampleParams; +}; + +/** + * Known Wallet RPC methods. + */ +export const KnownWalletRpcMethods: string[] = [ + 'wallet_registerOnboarding', + 'wallet_scanQRCode', +]; + +/** + * Wallet methods that are EIP-155 compatible but not scoped to a specific chain. + */ +export const WalletEip155Methods = ['wallet_addEthereumChain']; + +/** + * EIP-155 specific notifications. + */ +export const Eip155Notifications = ['eth_subscription']; + +/** + * Methods that are only available in the EIP-1193 wallet provider. + */ +const Eip1193OnlyMethods = [ + 'wallet_switchEthereumChain', + 'wallet_getPermissions', + 'wallet_requestPermissions', + 'wallet_revokePermissions', + 'eth_requestAccounts', + 'eth_accounts', + 'eth_coinbase', + 'net_version', + 'metamask_logWeb3ShimUsage', + 'metamask_getProviderState', + 'metamask_sendDomainMetadata', + 'wallet_registerOnboarding', +]; + +/** + * All MetaMask methods, except for ones we have specified in the constants above. + */ +export const Eip155Methods = MetaMaskOpenRPCDocument.methods + // eslint-disable-next-line @typescript-eslint/no-shadow + .map(({ name }: { name: string }) => name) + .filter((method: string) => !WalletEip155Methods.includes(method)) + .filter((method: string) => !KnownWalletRpcMethods.includes(method)) + .filter((method: string) => !Eip1193OnlyMethods.includes(method)); diff --git a/packages/multichainapi/src/constants/networks.ts b/packages/multichainapi/src/constants/networks.ts new file mode 100644 index 000000000..1317a0aec --- /dev/null +++ b/packages/multichainapi/src/constants/networks.ts @@ -0,0 +1,13 @@ +// packages/multichainapi/src/constants/networks.ts +export const FEATURED_NETWORKS = { + 'eip155:1': 'Ethereum Mainnet', + 'eip155:59144': 'Linea Mainnet', + 'eip155:42161': 'Arbitrum One', + 'eip155:43114': 'Avalanche Network C-Chain', + 'eip155:56': 'BNB Chain', + 'eip155:10': 'OP Mainnet', + 'eip155:137': 'Polygon Mainnet', + 'eip155:324': 'zkSync Era Mainnet', + 'eip155:8453': 'Base Mainnet', + 'eip155:1337': 'Localhost', +} as const; diff --git a/packages/multichainapi/src/index.ts b/packages/multichainapi/src/index.ts new file mode 100644 index 000000000..aa89cd268 --- /dev/null +++ b/packages/multichainapi/src/index.ts @@ -0,0 +1,19 @@ +// packages/multichainapi/src/index.ts + +import { MultichainProvider } from './providers/MultichainProvider'; + +// This is the main "entry point" for the package. +export { MultichainProvider } from './providers/MultichainProvider'; +export type { SessionData, MethodParams, SessionEventData } from './types'; + +// Possibly export some helper function or "createMultichainAPI()" factory here: +export function createMultichainAPI() { + const provider = new MultichainProvider(); + // Return a simple object with convenience methods, or just the provider itself. + return provider; +} + +// Re-export any constants or utilities that might be helpful: +export * from './constants/networks'; +export * from './constants/methods'; +export * from './utils/getCaip25FormattedAddresses'; diff --git a/packages/multichainapi/src/providers/BaseProvider.ts b/packages/multichainapi/src/providers/BaseProvider.ts new file mode 100644 index 000000000..a63074ae2 --- /dev/null +++ b/packages/multichainapi/src/providers/BaseProvider.ts @@ -0,0 +1,11 @@ +// packages/multichainapi/src/providers/BaseProvider.ts +import type { MethodParams } from '../types'; + +export interface Provider { + connect(params: unknown): Promise; + disconnect(): void; + request(params: MethodParams): Promise; + onNotification(callback: (notification: unknown) => void): void; + removeNotificationListener(callback: (notification: unknown) => void): void; + removeAllNotificationListeners(): void; +} diff --git a/packages/multichainapi/src/providers/MultichainProvider.ts b/packages/multichainapi/src/providers/MultichainProvider.ts new file mode 100644 index 000000000..055e6a0cd --- /dev/null +++ b/packages/multichainapi/src/providers/MultichainProvider.ts @@ -0,0 +1,65 @@ +// packages/multichainapi/src/MultichainProvider.ts +import { EventEmitter2 } from 'eventemitter2'; +import type { SessionData, MethodParams, SessionEventData } from '../types'; +import { ExtensionProvider } from './extensions/ExtensionProvider'; +import { FEATURED_NETWORKS } from '../constants/networks'; +import { Eip155Methods } from '../constants/methods'; + +export class MultichainProvider extends EventEmitter2 { + private sessions: Map = new Map(); + private provider: ExtensionProvider; + + constructor() { + super(); + this.provider = new ExtensionProvider(); + } + + async connect(extensionId: string): Promise { + return this.provider.connect(extensionId); + } + + async createSession(chainId: string, account: string): Promise { + if (!FEATURED_NETWORKS[chainId as keyof typeof FEATURED_NETWORKS]) { + throw new Error(`Unsupported chainId: ${chainId}`); + } + + const session: SessionData = { + id: crypto.randomUUID(), + chainId, + account, + expiry: Date.now() + 3600000, // 1 hour from now + }; + + this.sessions.set(session.id, session); + this.emit('sessionChanged', { + type: 'created', + session, + } as SessionEventData); + + return session; + } + + async invokeMethod(params: MethodParams): Promise { + if (!Eip155Methods.includes(params.method)) { + throw new Error(`Unsupported method: ${params.method}`); + } + return this.provider.request(params); + } + + async getSession(sessionId: string): Promise { + return this.sessions.get(sessionId); + } + + async revokeSession(sessionId: string): Promise { + const session = this.sessions.get(sessionId); + if (session) { + this.sessions.delete(sessionId); + this.emit('sessionChanged', { + type: 'revoked', + session, + } as SessionEventData); + return true; + } + return false; + } +} diff --git a/packages/multichainapi/src/providers/extensions/ExtensionProvider.ts b/packages/multichainapi/src/providers/extensions/ExtensionProvider.ts new file mode 100644 index 000000000..29503e1ea --- /dev/null +++ b/packages/multichainapi/src/providers/extensions/ExtensionProvider.ts @@ -0,0 +1,147 @@ +/// +// packages/multichainapi/src/providers/ExtensionProvider.ts +import type { Provider } from '../BaseProvider'; +import type { MethodParams } from '../../types'; + +interface ExtensionResponse { + id?: number; + result?: unknown; + error?: { + message: string; + code?: number; + }; +} + +type NotificationCallback = (notification: unknown) => void; + +export class ExtensionProvider implements Provider { + #port: chrome.runtime.Port | null; + #requestMap: Map< + number, + { resolve: (value: unknown) => void; reject: (reason?: unknown) => void } + >; + #nextId: number; + #notificationCallbacks: Set; + + constructor() { + this.#port = null; + this.#requestMap = new Map(); + this.#nextId = 1; + this.#notificationCallbacks = new Set(); + } + + async connect(extensionId: string): Promise { + if (this.#port) { + this.disconnect(); + } + + this.#port = chrome.runtime.connect(extensionId); + let isConnected = true; + + this.#port.onDisconnect.addListener(() => { + isConnected = false; + const errorMessage = chrome.runtime.lastError + ? chrome.runtime.lastError.message + : 'Port disconnected unexpectedly.'; + console.error('Error connecting to extension:', errorMessage); + this.#port = null; + this.#requestMap.clear(); + }); + + // Wait for connection confirmation + await new Promise((resolve) => setTimeout(resolve, 5)); + + if (!isConnected) { + throw new Error( + 'Error connecting to MetaMask Multichain Provider. Extension not found or disabled.', + ); + } + + this.#port.onMessage.addListener(this.#handleMessage.bind(this)); + + try { + this.#port.postMessage('ping'); + return true; + } catch (error) { + console.error('Error sending message:', error); + return false; + } + } + + disconnect(): void { + if (this.#port) { + this.#port.disconnect(); + this.#port = null; + } + this.#requestMap.clear(); + this.removeAllNotificationListeners(); + } + + async request(params: MethodParams): Promise { + if (!this.#port) { + throw new Error('Not connected to extension. Call connect() first.'); + } + + const id = this.#nextId++; + const request = { + jsonrpc: '2.0', + id, + method: params.method, + params: params.params, + scope: params.chainId, // Include CAIP-2 chainId as scope + }; + + return new Promise((resolve, reject) => { + this.#requestMap.set(id, { resolve, reject }); + this.#port?.postMessage({ type: 'caip-request', data: request }); + + // Request timeout after 30 seconds + setTimeout(() => { + if (this.#requestMap.has(id)) { + this.#requestMap.delete(id); + reject(new Error('Request timeout')); + } + }, 30000); + }); + } + + #handleMessage(message: { data: ExtensionResponse }): void { + const { data } = message; + if (data.id && this.#requestMap.has(data.id)) { + const { resolve, reject } = this.#requestMap.get(data.id) ?? {}; + this.#requestMap.delete(data.id); + + if (resolve && reject) { + if (data.error) { + reject(new Error(data.error.message)); + } else { + resolve(data.result); + } + } + } else if (!data.id) { + this.#notifyCallbacks(data); + } + } + + onNotification(callback: NotificationCallback): void { + this.#notificationCallbacks.add(callback); + } + + removeNotificationListener(callback: NotificationCallback): void { + this.#notificationCallbacks.delete(callback); + } + + removeAllNotificationListeners(): void { + this.#notificationCallbacks.clear(); + } + + #notifyCallbacks(notification: unknown): void { + this.#notificationCallbacks.forEach((callback) => { + try { + callback(notification); + } catch (error) { + console.error('Error in notification callback:', error); + } + }); + } +} diff --git a/packages/multichainapi/src/types.ts b/packages/multichainapi/src/types.ts new file mode 100644 index 000000000..0b5cc690d --- /dev/null +++ b/packages/multichainapi/src/types.ts @@ -0,0 +1,18 @@ +// packages/multichainapi/src/types.ts +export interface SessionData { + id: string; + chainId: string; + account: string; + expiry: number; +} + +export interface MethodParams { + chainId: string; + method: string; + params: unknown[]; +} + +export interface SessionEventData { + type: 'created' | 'updated' | 'revoked'; + session: SessionData; +} diff --git a/packages/multichainapi/src/utils/JsonHelpers.ts b/packages/multichainapi/src/utils/JsonHelpers.ts new file mode 100644 index 000000000..ff1f66665 --- /dev/null +++ b/packages/multichainapi/src/utils/JsonHelpers.ts @@ -0,0 +1,59 @@ +// packages/multichainapi/src/utils/JsonHelpers.ts +import type { + ContentDescriptorObject, + ExampleObject, + ExamplePairingObject, + MethodObject, +} from '@open-rpc/meta-schema'; + +const paramsToObj = ( + params: any[], + methodParams: ContentDescriptorObject[], +): any => { + return params.reduce((acc, val, i) => { + const paramName = methodParams[i]?.name; + if (paramName) { + acc[paramName] = val; + } + return acc; + }, {}); +}; + +export const openRPCExampleToJSON = (method: MethodObject) => { + if (!method.examples || method.examples.length === 0) { + return { + method: method.name, + params: [], + }; + } + const examplePairing = method.examples?.[0]; + const ex = examplePairing as ExamplePairingObject; + const paramsFromExample = ex.params.map( + (example) => (example as ExampleObject).value, + ); + const params = + method.paramStructure === 'by-name' + ? paramsToObj( + paramsFromExample, + method.params as ContentDescriptorObject[], + ) + : paramsFromExample; + return { + method: method.name, + params, + }; +}; + +export const truncateJSON = ( + json: any, + maxLength = 100, +): { text: string; truncated: boolean } => { + const stringified = JSON.stringify(json).slice(0, maxLength); + if (stringified.length <= maxLength) { + return { text: stringified, truncated: false }; + } + return { + text: stringified.slice(0, maxLength), + truncated: true, + }; +}; diff --git a/packages/multichainapi/src/utils/getCaip25FormattedAddresses.ts b/packages/multichainapi/src/utils/getCaip25FormattedAddresses.ts new file mode 100644 index 000000000..e3c81761f --- /dev/null +++ b/packages/multichainapi/src/utils/getCaip25FormattedAddresses.ts @@ -0,0 +1,18 @@ +// packages/multichainapi/src/utils/getCaip25FormattedAddresses.ts +/** + * Formats addresses as [CAIP-10](https://chainagnostic.org/CAIPs/caip-10) addresses for it's respective request scope. See [CAIP-25](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-25.md) and . + * @param scope - The scope to create session for. + * @param addresses - The addresses to format. If address is empty, we remove it from the array. + * @returns The formatted addresses with the scope to create session for. + */ +export const getCaip25FormattedAddresses = ( + scope: string, + addresses: string[], +): string[] => { + return addresses.reduce((result, address) => { + if (address.length > 0) { + result.push(`${scope}:${address}`); + } + return result; + }, []); +}; diff --git a/packages/multichainapi/tsconfig.build.json b/packages/multichainapi/tsconfig.build.json new file mode 100644 index 000000000..8fa665bee --- /dev/null +++ b/packages/multichainapi/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["**/*.test.ts", "**/*.spec.ts", "**/__tests__/**"] +} diff --git a/packages/multichainapi/tsconfig.eslint.json b/packages/multichainapi/tsconfig.eslint.json new file mode 100644 index 000000000..4c130f7de --- /dev/null +++ b/packages/multichainapi/tsconfig.eslint.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "include": ["./src/**/*.ts", "./src/**/*.test.ts"] +} diff --git a/packages/multichainapi/tsconfig.json b/packages/multichainapi/tsconfig.json new file mode 100644 index 000000000..449951aeb --- /dev/null +++ b/packages/multichainapi/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "baseUrl": "./", + "outDir": "dist", + "rootDir": ".", + "paths": { + "@metamask/multichainapi/*": ["./src/*"] + } + }, + "include": ["src"], + "exclude": ["**/*.test.ts", "**/*.spec.ts"] +} diff --git a/packages/sdk/package.json b/packages/sdk/package.json index dcd3625ab..38651da27 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -49,6 +49,7 @@ }, "dependencies": { "@babel/runtime": "^7.26.0", + "@metamask/multichainapi": "workspace:*", "@metamask/onboarding": "^1.0.1", "@metamask/providers": "^18.3.1", "@metamask/sdk-communication-layer": "workspace:*", diff --git a/yarn.lock b/yarn.lock index 8dccf8055..77efecea6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10583,6 +10583,17 @@ __metadata: languageName: node linkType: hard +"@lavamoat/aa@npm:^4.3.1": + version: 4.3.1 + resolution: "@lavamoat/aa@npm:4.3.1" + dependencies: + resolve: 1.22.8 + bin: + lavamoat-ls: src/cli.js + checksum: 462e4e20c91f01f980f148f203864625f85336a58dc22159c498a9e9ba12d75753d0687494928bdf94df3bb10d1e45ab7ffbf25409bfbc290ac5a45dc8479554 + languageName: node + linkType: hard + "@lavamoat/allow-scripts@npm:^2.3.1": version: 2.3.1 resolution: "@lavamoat/allow-scripts@npm:2.3.1" @@ -10598,6 +10609,24 @@ __metadata: languageName: node linkType: hard +"@lavamoat/allow-scripts@npm:^3.3.1": + version: 3.3.1 + resolution: "@lavamoat/allow-scripts@npm:3.3.1" + dependencies: + "@lavamoat/aa": ^4.3.1 + "@npmcli/run-script": 8.1.0 + bin-links: 4.0.4 + npm-normalize-package-bin: 3.0.1 + type-fest: 4.30.0 + yargs: 17.7.2 + peerDependencies: + "@lavamoat/preinstall-always-fail": "*" + bin: + allow-scripts: src/cli.js + checksum: 8000926d9cc5f6098a044871037a6e38e4be6e1666fa0a081ca8e9c600ee83a3649ce0f9afe399eaf5cb7da05d9e04a91e190fb6981909fe0bd170d9beafd60a + languageName: node + linkType: hard + "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.4 resolution: "@leichtgewicht/ip-codec@npm:2.0.4" @@ -10654,6 +10683,13 @@ __metadata: languageName: node linkType: hard +"@metamask/api-specs@npm:^0.10.13": + version: 0.10.13 + resolution: "@metamask/api-specs@npm:0.10.13" + checksum: 5dbfc42bfec700d6048a880ca0330174d02771d58259ca27c2fccc6653e8a003172c22b5ae5ceb8258469f470c2fb0d0c8e8b2718f2895be78b0388930527984 + languageName: node + linkType: hard + "@metamask/auto-changelog@npm:3.1.0": version: 3.1.0 resolution: "@metamask/auto-changelog@npm:3.1.0" @@ -11047,6 +11083,42 @@ __metadata: languageName: node linkType: hard +"@metamask/multichainapi@workspace:*, @metamask/multichainapi@workspace:packages/multichainapi": + version: 0.0.0-use.local + resolution: "@metamask/multichainapi@workspace:packages/multichainapi" + dependencies: + "@babel/runtime": ^7.26.0 + "@jest/globals": ^29.3.1 + "@lavamoat/allow-scripts": ^3.3.1 + "@metamask/api-specs": ^0.10.13 + "@metamask/auto-changelog": 3.1.0 + "@metamask/eslint-config": ^6.0.0 + "@metamask/eslint-config-typescript": ^6.0.0 + "@metamask/utils": ^11.0.1 + "@open-rpc/meta-schema": ^1.14.9 + "@rollup/plugin-commonjs": ^25.0.7 + "@rollup/plugin-json": ^6.0.0 + "@rollup/plugin-node-resolve": ^15.0.2 + "@rollup/plugin-typescript": ^11.1.6 + "@types/chrome": ^0.0.296 + "@types/debug": ^4.1.12 + "@types/jest": ^29.5.11 + "@types/node": ^20.1.3 + "@typescript-eslint/eslint-plugin": ^4.26.0 + "@typescript-eslint/parser": ^4.26.0 + debug: ^4.3.4 + eslint: ^7.30.0 + eventemitter2: ^6.4.9 + jest: ^29.3.1 + prettier: ^2.3.0 + rimraf: ^4.4.0 + rollup: ^4.9.4 + ts-jest: ^29.0.3 + tslib: ^2.6.2 + typescript: ^5.3.3 + languageName: unknown + linkType: soft + "@metamask/network-controller@npm:^16.0.0": version: 16.0.0 resolution: "@metamask/network-controller@npm:16.0.0" @@ -11895,6 +11967,7 @@ __metadata: "@metamask/eslint-config": ^6.0.0 "@metamask/eslint-config-nodejs": ^6.0.0 "@metamask/eslint-config-typescript": ^6.0.0 + "@metamask/multichainapi": "workspace:*" "@metamask/onboarding": ^1.0.1 "@metamask/providers": ^18.3.1 "@metamask/sdk-communication-layer": "workspace:*" @@ -12635,6 +12708,19 @@ __metadata: languageName: node linkType: hard +"@npmcli/agent@npm:^2.0.0": + version: 2.2.2 + resolution: "@npmcli/agent@npm:2.2.2" + dependencies: + agent-base: ^7.1.0 + http-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.1 + lru-cache: ^10.0.1 + socks-proxy-agent: ^8.0.3 + checksum: 67de7b88cc627a79743c88bab35e023e23daf13831a8aa4e15f998b92f5507b644d8ffc3788afc8e64423c612e0785a6a92b74782ce368f49a6746084b50d874 + languageName: node + linkType: hard + "@npmcli/fs@npm:^1.0.0": version: 1.1.1 resolution: "@npmcli/fs@npm:1.1.1" @@ -12654,6 +12740,23 @@ __metadata: languageName: node linkType: hard +"@npmcli/git@npm:^5.0.0": + version: 5.0.8 + resolution: "@npmcli/git@npm:5.0.8" + dependencies: + "@npmcli/promise-spawn": ^7.0.0 + ini: ^4.1.3 + lru-cache: ^10.0.1 + npm-pick-manifest: ^9.0.0 + proc-log: ^4.0.0 + promise-inflight: ^1.0.1 + promise-retry: ^2.0.1 + semver: ^7.3.5 + which: ^4.0.0 + checksum: 8c1733b591e428719c60fceaca74b3355967f6ddbce851c0d163a3c2e8123aaa717361b8226f8f8e606685f14721ea97d8f99c4b5831bc9251007bb1a20663cd + languageName: node + linkType: hard + "@npmcli/move-file@npm:^1.0.1": version: 1.1.2 resolution: "@npmcli/move-file@npm:1.1.2" @@ -12671,6 +12774,21 @@ __metadata: languageName: node linkType: hard +"@npmcli/package-json@npm:^5.0.0": + version: 5.2.1 + resolution: "@npmcli/package-json@npm:5.2.1" + dependencies: + "@npmcli/git": ^5.0.0 + glob: ^10.2.2 + hosted-git-info: ^7.0.0 + json-parse-even-better-errors: ^3.0.0 + normalize-package-data: ^6.0.0 + proc-log: ^4.0.0 + semver: ^7.5.3 + checksum: f9f76428fb3b3350fe840f1fa49854d18ff1ecb82b426c9cf53a62a37389c357a89d64a07497f50b7fbf1c742f5a0cd349d8efdddef0bb6982497f8356c1f98a + languageName: node + linkType: hard + "@npmcli/promise-spawn@npm:^6.0.0": version: 6.0.2 resolution: "@npmcli/promise-spawn@npm:6.0.2" @@ -12680,6 +12798,29 @@ __metadata: languageName: node linkType: hard +"@npmcli/promise-spawn@npm:^7.0.0": + version: 7.0.2 + resolution: "@npmcli/promise-spawn@npm:7.0.2" + dependencies: + which: ^4.0.0 + checksum: 728256506ecbafb53064036e28c2815b9a9e9190ba7a48eec77b011a9f8a899515a6d96760dbde960bc1d3e5b828fd0b0b7fe3b512efaf049d299bacbd732fda + languageName: node + linkType: hard + +"@npmcli/run-script@npm:8.1.0": + version: 8.1.0 + resolution: "@npmcli/run-script@npm:8.1.0" + dependencies: + "@npmcli/node-gyp": ^3.0.0 + "@npmcli/package-json": ^5.0.0 + "@npmcli/promise-spawn": ^7.0.0 + node-gyp: ^10.0.0 + proc-log: ^4.0.0 + which: ^4.0.0 + checksum: 21adfb308b9064041d6d2f7f0d53924be0e1466d558de1c9802fab9eb84850bd8e04fdd5695924f331e1a36565461500d912e187909f91c03188cc763a106986 + languageName: node + linkType: hard + "@npmcli/run-script@npm:^6.0.0": version: 6.0.2 resolution: "@npmcli/run-script@npm:6.0.2" @@ -12693,6 +12834,13 @@ __metadata: languageName: node linkType: hard +"@open-rpc/meta-schema@npm:^1.14.9": + version: 1.14.9 + resolution: "@open-rpc/meta-schema@npm:1.14.9" + checksum: c810b7540c02ef6d81618004103652bbf6a32f584926bdbdeda99a037ca5c4eb4a45e47895ce9f7b9bdd13d359e43dee2046324d666eccd8eee693c736f96875 + languageName: node + linkType: hard + "@opentelemetry/api@npm:^1.4.0": version: 1.9.0 resolution: "@opentelemetry/api@npm:1.9.0" @@ -15686,6 +15834,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm-eabi@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.30.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@rollup/rollup-android-arm-eabi@npm:4.5.0": version: 4.5.0 resolution: "@rollup/rollup-android-arm-eabi@npm:4.5.0" @@ -15700,6 +15855,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-android-arm64@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-android-arm64@npm:4.30.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-android-arm64@npm:4.5.0": version: 4.5.0 resolution: "@rollup/rollup-android-arm64@npm:4.5.0" @@ -15714,6 +15876,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-arm64@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-darwin-arm64@npm:4.30.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-arm64@npm:4.5.0": version: 4.5.0 resolution: "@rollup/rollup-darwin-arm64@npm:4.5.0" @@ -15728,6 +15897,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-x64@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-darwin-x64@npm:4.30.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-x64@npm:4.5.0": version: 4.5.0 resolution: "@rollup/rollup-darwin-x64@npm:4.5.0" @@ -15742,6 +15918,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-freebsd-arm64@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.30.1" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-freebsd-x64@npm:4.26.0": version: 4.26.0 resolution: "@rollup/rollup-freebsd-x64@npm:4.26.0" @@ -15749,6 +15932,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-freebsd-x64@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-freebsd-x64@npm:4.30.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-linux-arm-gnueabihf@npm:4.26.0": version: 4.26.0 resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.26.0" @@ -15756,6 +15946,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-gnueabihf@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.30.1" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm-gnueabihf@npm:4.5.0": version: 4.5.0 resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.5.0" @@ -15770,6 +15967,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm-musleabihf@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.30.1" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-gnu@npm:4.26.0": version: 4.26.0 resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.26.0" @@ -15777,6 +15981,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-gnu@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.30.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-gnu@npm:4.5.0": version: 4.5.0 resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.5.0" @@ -15791,6 +16002,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-arm64-musl@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.30.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-arm64-musl@npm:4.5.0": version: 4.5.0 resolution: "@rollup/rollup-linux-arm64-musl@npm:4.5.0" @@ -15798,6 +16016,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-loongarch64-gnu@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.30.1" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-powerpc64le-gnu@npm:4.26.0": version: 4.26.0 resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.26.0" @@ -15805,6 +16030,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.30.1" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-riscv64-gnu@npm:4.26.0": version: 4.26.0 resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.26.0" @@ -15812,6 +16044,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-riscv64-gnu@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.30.1" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-s390x-gnu@npm:4.26.0": version: 4.26.0 resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.26.0" @@ -15819,6 +16058,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-s390x-gnu@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.30.1" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-gnu@npm:4.26.0": version: 4.26.0 resolution: "@rollup/rollup-linux-x64-gnu@npm:4.26.0" @@ -15826,6 +16072,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-gnu@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.30.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-gnu@npm:4.5.0": version: 4.5.0 resolution: "@rollup/rollup-linux-x64-gnu@npm:4.5.0" @@ -15840,6 +16093,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-linux-x64-musl@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.30.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@rollup/rollup-linux-x64-musl@npm:4.5.0": version: 4.5.0 resolution: "@rollup/rollup-linux-x64-musl@npm:4.5.0" @@ -15854,6 +16114,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-arm64-msvc@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.30.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-win32-arm64-msvc@npm:4.5.0": version: 4.5.0 resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.5.0" @@ -15868,6 +16135,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-ia32-msvc@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.30.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@rollup/rollup-win32-ia32-msvc@npm:4.5.0": version: 4.5.0 resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.5.0" @@ -15882,6 +16156,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-win32-x64-msvc@npm:4.30.1": + version: 4.30.1 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.30.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@rollup/rollup-win32-x64-msvc@npm:4.5.0": version: 4.5.0 resolution: "@rollup/rollup-win32-x64-msvc@npm:4.5.0" @@ -18880,6 +19161,16 @@ __metadata: languageName: node linkType: hard +"@types/chrome@npm:^0.0.296": + version: 0.0.296 + resolution: "@types/chrome@npm:0.0.296" + dependencies: + "@types/filesystem": "*" + "@types/har-format": "*" + checksum: 6be60b3661855e12ffa046e3fea0c11a65111ae4ecad4b73591427330a05e1ea20b496db9e56fd6a0ec9a87125d0f11394901f45bb269dd471f90ea737cf9626 + languageName: node + linkType: hard + "@types/color-convert@npm:*": version: 2.0.3 resolution: "@types/color-convert@npm:2.0.3" @@ -18972,6 +19263,15 @@ __metadata: languageName: node linkType: hard +"@types/debug@npm:^4.1.12": + version: 4.1.12 + resolution: "@types/debug@npm:4.1.12" + dependencies: + "@types/ms": "*" + checksum: 47876a852de8240bfdaf7481357af2b88cb660d30c72e73789abf00c499d6bc7cd5e52f41c915d1b9cd8ec9fef5b05688d7b7aef17f7f272c2d04679508d1053 + languageName: node + linkType: hard + "@types/debug@npm:^4.1.7": version: 4.1.8 resolution: "@types/debug@npm:4.1.8" @@ -19308,23 +19608,23 @@ __metadata: languageName: node linkType: hard -"@types/jest@npm:^29.5.12": - version: 29.5.12 - resolution: "@types/jest@npm:29.5.12" +"@types/jest@npm:^29.5.11, @types/jest@npm:^29.5.14": + version: 29.5.14 + resolution: "@types/jest@npm:29.5.14" dependencies: expect: ^29.0.0 pretty-format: ^29.0.0 - checksum: 19b1efdeed9d9a60a81edc8226cdeae5af7479e493eaed273e01243891c9651f7b8b4c08fc633a7d0d1d379b091c4179bbaa0807af62542325fd72f2dd17ce1c + checksum: 18dba4623f26661641d757c63da2db45e9524c9be96a29ef713c703a9a53792df9ecee9f7365a0858ddbd6440d98fe6b65ca67895ca5884b73cbc7ffc11f3838 languageName: node linkType: hard -"@types/jest@npm:^29.5.14": - version: 29.5.14 - resolution: "@types/jest@npm:29.5.14" +"@types/jest@npm:^29.5.12": + version: 29.5.12 + resolution: "@types/jest@npm:29.5.12" dependencies: expect: ^29.0.0 pretty-format: ^29.0.0 - checksum: 18dba4623f26661641d757c63da2db45e9524c9be96a29ef713c703a9a53792df9ecee9f7365a0858ddbd6440d98fe6b65ca67895ca5884b73cbc7ffc11f3838 + checksum: 19b1efdeed9d9a60a81edc8226cdeae5af7479e493eaed273e01243891c9651f7b8b4c08fc633a7d0d1d379b091c4179bbaa0807af62542325fd72f2dd17ce1c languageName: node linkType: hard @@ -22209,6 +22509,13 @@ __metadata: languageName: node linkType: hard +"abbrev@npm:^2.0.0": + version: 2.0.0 + resolution: "abbrev@npm:2.0.0" + checksum: 0e994ad2aa6575f94670d8a2149afe94465de9cedaaaac364e7fb43a40c3691c980ff74899f682f4ca58fa96b4cbd7421a015d3a6defe43a442117d7821a2f36 + languageName: node + linkType: hard + "abitype@npm:0.8.7": version: 0.8.7 resolution: "abitype@npm:0.8.7" @@ -22433,6 +22740,13 @@ __metadata: languageName: node linkType: hard +"agent-base@npm:^7.1.2": + version: 7.1.3 + resolution: "agent-base@npm:7.1.3" + checksum: 87bb7ee54f5ecf0ccbfcba0b07473885c43ecd76cb29a8db17d6137a19d9f9cd443a2a7c5fd8a3f24d58ad8145f9eb49116344a66b107e1aeab82cf2383f4753 + languageName: node + linkType: hard + "agentkeepalive@npm:^4.2.1": version: 4.3.0 resolution: "agentkeepalive@npm:4.3.0" @@ -24242,6 +24556,18 @@ __metadata: languageName: node linkType: hard +"bin-links@npm:4.0.4": + version: 4.0.4 + resolution: "bin-links@npm:4.0.4" + dependencies: + cmd-shim: ^6.0.0 + npm-normalize-package-bin: ^3.0.0 + read-cmd-shim: ^4.0.0 + write-file-atomic: ^5.0.0 + checksum: 9fca1fddaa3c1c9f7efd6fd7a6d991e3d8f6aaa9de5d0b9355469c2c594d8d06c9b2e0519bb0304202c14ddbe832d27b6d419d55cea4340e2c26116f9190e5c9 + languageName: node + linkType: hard + "binary-extensions@npm:^2.0.0": version: 2.2.0 resolution: "binary-extensions@npm:2.2.0" @@ -25006,6 +25332,26 @@ __metadata: languageName: node linkType: hard +"cacache@npm:^18.0.0": + version: 18.0.4 + resolution: "cacache@npm:18.0.4" + dependencies: + "@npmcli/fs": ^3.1.0 + fs-minipass: ^3.0.0 + glob: ^10.2.2 + lru-cache: ^10.0.1 + minipass: ^7.0.3 + minipass-collect: ^2.0.1 + minipass-flush: ^1.0.5 + minipass-pipeline: ^1.2.4 + p-map: ^4.0.0 + ssri: ^10.0.0 + tar: ^6.1.11 + unique-filename: ^3.0.0 + checksum: b7422c113b4ec750f33beeca0f426a0024c28e3172f332218f48f963e5b970647fa1ac05679fe5bb448832c51efea9fda4456b9a95c3a1af1105fe6c1833cde2 + languageName: node + linkType: hard + "cacache@npm:^18.0.2": version: 18.0.3 resolution: "cacache@npm:18.0.3" @@ -33291,6 +33637,22 @@ __metadata: languageName: node linkType: hard +"glob@npm:^10.3.10": + version: 10.4.5 + resolution: "glob@npm:10.4.5" + dependencies: + foreground-child: ^3.1.0 + jackspeak: ^3.1.2 + minimatch: ^9.0.4 + minipass: ^7.1.2 + package-json-from-dist: ^1.0.0 + path-scurry: ^1.11.1 + bin: + glob: dist/esm/bin.mjs + checksum: 0bc725de5e4862f9f387fd0f2b274baf16850dcd2714502ccf471ee401803997983e2c05590cb65f9675a3c6f2a58e7a53f9e365704108c6ad3cbf1d60934c4a + languageName: node + linkType: hard + "glob@npm:^6.0.1": version: 6.0.4 resolution: "glob@npm:6.0.4" @@ -33934,6 +34296,15 @@ __metadata: languageName: node linkType: hard +"hosted-git-info@npm:^7.0.0": + version: 7.0.2 + resolution: "hosted-git-info@npm:7.0.2" + dependencies: + lru-cache: ^10.0.1 + checksum: 467cf908a56556417b18e86ae3b8dee03c2360ef1d51e61c4028fe87f6f309b6ff038589c94b5666af207da9d972d5107698906aabeb78aca134641962a5c6f8 + languageName: node + linkType: hard + "hpack.js@npm:^2.1.6": version: 2.1.6 resolution: "hpack.js@npm:2.1.6" @@ -34201,6 +34572,16 @@ __metadata: languageName: node linkType: hard +"https-proxy-agent@npm:^7.0.1": + version: 7.0.6 + resolution: "https-proxy-agent@npm:7.0.6" + dependencies: + agent-base: ^7.1.2 + debug: 4 + checksum: b882377a120aa0544846172e5db021fa8afbf83fea2a897d397bd2ddd8095ab268c24bc462f40a15f2a8c600bf4aa05ce52927f70038d4014e68aefecfa94e8d + languageName: node + linkType: hard + "https-proxy-agent@npm:^7.0.2": version: 7.0.2 resolution: "https-proxy-agent@npm:7.0.2" @@ -34542,6 +34923,13 @@ __metadata: languageName: node linkType: hard +"ini@npm:^4.1.3": + version: 4.1.3 + resolution: "ini@npm:4.1.3" + checksum: 004b2be42388877c58add606149f1a0c7985c90a0ba5dbf45a4738fdc70b0798d922caecaa54617029626505898ac451ff0537a08b949836b49d3267f66542c9 + languageName: node + linkType: hard + "inline-style-prefixer@npm:^6.0.1": version: 6.0.4 resolution: "inline-style-prefixer@npm:6.0.4" @@ -35585,6 +35973,13 @@ __metadata: languageName: node linkType: hard +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + languageName: node + linkType: hard + "isobject@npm:^3.0.1": version: 3.0.1 resolution: "isobject@npm:3.0.1" @@ -35771,6 +36166,19 @@ __metadata: languageName: node linkType: hard +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" + dependencies: + "@isaacs/cliui": ^8.0.2 + "@pkgjs/parseargs": ^0.11.0 + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: be31027fc72e7cc726206b9f560395604b82e0fddb46c4cbf9f97d049bcef607491a5afc0699612eaa4213ca5be8fd3e1e7cd187b3040988b65c9489838a7c00 + languageName: node + linkType: hard + "jake@npm:^10.8.5": version: 10.8.7 resolution: "jake@npm:10.8.7" @@ -39137,6 +39545,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^10.2.0": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 6476138d2125387a6d20f100608c2583d415a4f64a0fecf30c9e2dda976614f09cad4baa0842447bd37dd459a7bd27f57d9d8f8ce558805abd487c583f3d774a + languageName: node + linkType: hard + "lru-cache@npm:^5.1.1": version: 5.1.1 resolution: "lru-cache@npm:5.1.1" @@ -39281,6 +39696,26 @@ __metadata: languageName: node linkType: hard +"make-fetch-happen@npm:^13.0.0": + version: 13.0.1 + resolution: "make-fetch-happen@npm:13.0.1" + dependencies: + "@npmcli/agent": ^2.0.0 + cacache: ^18.0.0 + http-cache-semantics: ^4.1.1 + is-lambda: ^1.0.1 + minipass: ^7.0.2 + minipass-fetch: ^3.0.0 + minipass-flush: ^1.0.5 + minipass-pipeline: ^1.2.4 + negotiator: ^0.6.3 + proc-log: ^4.2.0 + promise-retry: ^2.0.1 + ssri: ^10.0.0 + checksum: 5c9fad695579b79488fa100da05777213dd9365222f85e4757630f8dd2a21a79ddd3206c78cfd6f9b37346819681782b67900ac847a57cf04190f52dda5343fd + languageName: node + linkType: hard + "make-plural@npm:*": version: 7.3.0 resolution: "make-plural@npm:7.3.0" @@ -41088,7 +41523,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^7.0.3": +"minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": version: 7.1.2 resolution: "minipass@npm:7.1.2" checksum: 2bfd325b95c555f2b4d2814d49325691c7bee937d753814861b0b49d5edcda55cbbf22b6b6a60bb91eddac8668771f03c5ff647dcd9d0f798e9548b9cdc46ee3 @@ -41723,6 +42158,26 @@ __metadata: languageName: node linkType: hard +"node-gyp@npm:^10.0.0": + version: 10.3.1 + resolution: "node-gyp@npm:10.3.1" + dependencies: + env-paths: ^2.2.0 + exponential-backoff: ^3.1.1 + glob: ^10.3.10 + graceful-fs: ^4.2.6 + make-fetch-happen: ^13.0.0 + nopt: ^7.0.0 + proc-log: ^4.1.0 + semver: ^7.3.5 + tar: ^6.2.1 + which: ^4.0.0 + bin: + node-gyp: bin/node-gyp.js + checksum: 91b0690ab504fe051ad66863226dc5ecac72b8471f85e8428e4d5ca3217d3a2adfffae48cd555e8d009a4164689fff558b88d2bc9bfd246452a3336ab308cf99 + languageName: node + linkType: hard + "node-gyp@npm:^9.0.0, node-gyp@npm:latest": version: 9.4.0 resolution: "node-gyp@npm:9.4.0" @@ -41861,6 +42316,17 @@ __metadata: languageName: node linkType: hard +"nopt@npm:^7.0.0": + version: 7.2.1 + resolution: "nopt@npm:7.2.1" + dependencies: + abbrev: ^2.0.0 + bin: + nopt: bin/nopt.js + checksum: 6fa729cc77ce4162cfad8abbc9ba31d4a0ff6850c3af61d59b505653bef4781ec059f8890ecfe93ee8aa0c511093369cca88bfc998101616a2904e715bbbb7c9 + languageName: node + linkType: hard + "nopt@npm:~1.0.10": version: 1.0.10 resolution: "nopt@npm:1.0.10" @@ -41896,6 +42362,17 @@ __metadata: languageName: node linkType: hard +"normalize-package-data@npm:^6.0.0": + version: 6.0.2 + resolution: "normalize-package-data@npm:6.0.2" + dependencies: + hosted-git-info: ^7.0.0 + semver: ^7.3.5 + validate-npm-package-license: ^3.0.4 + checksum: ea35f8de68e03fc845f545c8197857c0cd256207fdb809ca63c2b39fe76ae77765ee939eb21811fb6c3b533296abf49ebe3cd617064f98a775adaccb24ff2e03 + languageName: node + linkType: hard + "normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": version: 3.0.0 resolution: "normalize-path@npm:3.0.0" @@ -41924,13 +42401,34 @@ __metadata: languageName: node linkType: hard -"npm-normalize-package-bin@npm:^3.0.0": +"npm-install-checks@npm:^6.0.0": + version: 6.3.0 + resolution: "npm-install-checks@npm:6.3.0" + dependencies: + semver: ^7.1.1 + checksum: 6c20dadb878a0d2f1f777405217b6b63af1299d0b43e556af9363ee6eefaa98a17dfb7b612a473a473e96faf7e789c58b221e0d8ffdc1d34903c4f71618df3b4 + languageName: node + linkType: hard + +"npm-normalize-package-bin@npm:3.0.1, npm-normalize-package-bin@npm:^3.0.0": version: 3.0.1 resolution: "npm-normalize-package-bin@npm:3.0.1" checksum: de416d720ab22137a36292ff8a333af499ea0933ef2320a8c6f56a73b0f0448227fec4db5c890d702e26d21d04f271415eab6580b5546456861cc0c19498a4bf languageName: node linkType: hard +"npm-package-arg@npm:^11.0.0": + version: 11.0.3 + resolution: "npm-package-arg@npm:11.0.3" + dependencies: + hosted-git-info: ^7.0.0 + proc-log: ^4.0.0 + semver: ^7.3.5 + validate-npm-package-name: ^5.0.0 + checksum: cc6f22c39201aa14dcceeddb81bfbf7fa0484f94bcd2b3ad038e18afec5167c843cdde90c897f6034dc368faa0100c1eeee6e3f436a89e0af32ba932af4a8c28 + languageName: node + linkType: hard + "npm-package-arg@npm:^7.0.0": version: 7.0.0 resolution: "npm-package-arg@npm:7.0.0" @@ -41943,6 +42441,18 @@ __metadata: languageName: node linkType: hard +"npm-pick-manifest@npm:^9.0.0": + version: 9.1.0 + resolution: "npm-pick-manifest@npm:9.1.0" + dependencies: + npm-install-checks: ^6.0.0 + npm-normalize-package-bin: ^3.0.0 + npm-package-arg: ^11.0.0 + semver: ^7.3.5 + checksum: cbaad1e1420869efa851e8ba5d725263f679779e15bfca3713ec3ee1e897efab254e75c5445f442ffc96453cdfb15d362d25b0c0fcb03b156fe1653f9220cc40 + languageName: node + linkType: hard + "npm-run-path@npm:^2.0.0": version: 2.0.2 resolution: "npm-run-path@npm:2.0.2" @@ -42748,6 +43258,13 @@ __metadata: languageName: node linkType: hard +"package-json-from-dist@npm:^1.0.0": + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 58ee9538f2f762988433da00e26acc788036914d57c71c246bf0be1b60cdbd77dd60b6a3e1a30465f0b248aeb80079e0b34cb6050b1dfa18c06953bb1cbc7602 + languageName: node + linkType: hard + "pako@npm:~0.2.0": version: 0.2.9 resolution: "pako@npm:0.2.9" @@ -43019,6 +43536,16 @@ __metadata: languageName: node linkType: hard +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: ^10.2.0 + minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 + checksum: 890d5abcd593a7912dcce7cf7c6bf7a0b5648e3dee6caf0712c126ca0a65c7f3d7b9d769072a4d1baf370f61ce493ab5b038d59988688e0c5f3f646ee3c69023 + languageName: node + linkType: hard + "path-strip-sep@npm:^1.0.17": version: 1.0.17 resolution: "path-strip-sep@npm:1.0.17" @@ -44470,6 +44997,13 @@ __metadata: languageName: node linkType: hard +"proc-log@npm:^4.0.0, proc-log@npm:^4.1.0, proc-log@npm:^4.2.0": + version: 4.2.0 + resolution: "proc-log@npm:4.2.0" + checksum: 98f6cd012d54b5334144c5255ecb941ee171744f45fca8b43b58ae5a0c1af07352475f481cadd9848e7f0250376ee584f6aa0951a856ff8f021bdfbff4eb33fc + languageName: node + linkType: hard + "process-es6@npm:^0.11.2, process-es6@npm:^0.11.6": version: 0.11.6 resolution: "process-es6@npm:0.11.6" @@ -46860,29 +47394,29 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.10.1, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.2": - version: 1.22.3 - resolution: "resolve@npm:1.22.3" +"resolve@npm:1.22.8, resolve@npm:^1.22.4": + version: 1.22.8 + resolution: "resolve@npm:1.22.8" dependencies: - is-core-module: ^2.12.0 + is-core-module: ^2.13.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: fb834b81348428cb545ff1b828a72ea28feb5a97c026a1cf40aa1008352c72811ff4d4e71f2035273dc536dcfcae20c13604ba6283c612d70fa0b6e44519c374 + checksum: f8a26958aa572c9b064562750b52131a37c29d072478ea32e129063e2da7f83e31f7f11e7087a18225a8561cfe8d2f0df9dbea7c9d331a897571c0a2527dbb4c languageName: node linkType: hard -"resolve@npm:^1.22.4": - version: 1.22.8 - resolution: "resolve@npm:1.22.8" +"resolve@npm:^1.1.7, resolve@npm:^1.10.0, resolve@npm:^1.10.1, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.2": + version: 1.22.3 + resolution: "resolve@npm:1.22.3" dependencies: - is-core-module: ^2.13.0 + is-core-module: ^2.12.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: f8a26958aa572c9b064562750b52131a37c29d072478ea32e129063e2da7f83e31f7f11e7087a18225a8561cfe8d2f0df9dbea7c9d331a897571c0a2527dbb4c + checksum: fb834b81348428cb545ff1b828a72ea28feb5a97c026a1cf40aa1008352c72811ff4d4e71f2035273dc536dcfcae20c13604ba6283c612d70fa0b6e44519c374 languageName: node linkType: hard @@ -46921,29 +47455,29 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.1.7#~builtin, resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.10.1#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.22.2#~builtin": - version: 1.22.3 - resolution: "resolve@patch:resolve@npm%3A1.22.3#~builtin::version=1.22.3&hash=c3c19d" +"resolve@patch:resolve@1.22.8#~builtin, resolve@patch:resolve@^1.22.4#~builtin": + version: 1.22.8 + resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=c3c19d" dependencies: - is-core-module: ^2.12.0 + is-core-module: ^2.13.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: ad59734723b596d0891321c951592ed9015a77ce84907f89c9d9307dd0c06e11a67906a3e628c4cae143d3e44898603478af0ddeb2bba3f229a9373efe342665 + checksum: 5479b7d431cacd5185f8db64bfcb7286ae5e31eb299f4c4f404ad8aa6098b77599563ac4257cb2c37a42f59dfc06a1bec2bcf283bb448f319e37f0feb9a09847 languageName: node linkType: hard -"resolve@patch:resolve@^1.22.4#~builtin": - version: 1.22.8 - resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=c3c19d" +"resolve@patch:resolve@^1.1.7#~builtin, resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.10.1#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.22.2#~builtin": + version: 1.22.3 + resolution: "resolve@patch:resolve@npm%3A1.22.3#~builtin::version=1.22.3&hash=c3c19d" dependencies: - is-core-module: ^2.13.0 + is-core-module: ^2.12.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: 5479b7d431cacd5185f8db64bfcb7286ae5e31eb299f4c4f404ad8aa6098b77599563ac4257cb2c37a42f59dfc06a1bec2bcf283bb448f319e37f0feb9a09847 + checksum: ad59734723b596d0891321c951592ed9015a77ce84907f89c9d9307dd0c06e11a67906a3e628c4cae143d3e44898603478af0ddeb2bba3f229a9373efe342665 languageName: node linkType: hard @@ -47598,6 +48132,78 @@ __metadata: languageName: node linkType: hard +"rollup@npm:^4.9.4": + version: 4.30.1 + resolution: "rollup@npm:4.30.1" + dependencies: + "@rollup/rollup-android-arm-eabi": 4.30.1 + "@rollup/rollup-android-arm64": 4.30.1 + "@rollup/rollup-darwin-arm64": 4.30.1 + "@rollup/rollup-darwin-x64": 4.30.1 + "@rollup/rollup-freebsd-arm64": 4.30.1 + "@rollup/rollup-freebsd-x64": 4.30.1 + "@rollup/rollup-linux-arm-gnueabihf": 4.30.1 + "@rollup/rollup-linux-arm-musleabihf": 4.30.1 + "@rollup/rollup-linux-arm64-gnu": 4.30.1 + "@rollup/rollup-linux-arm64-musl": 4.30.1 + "@rollup/rollup-linux-loongarch64-gnu": 4.30.1 + "@rollup/rollup-linux-powerpc64le-gnu": 4.30.1 + "@rollup/rollup-linux-riscv64-gnu": 4.30.1 + "@rollup/rollup-linux-s390x-gnu": 4.30.1 + "@rollup/rollup-linux-x64-gnu": 4.30.1 + "@rollup/rollup-linux-x64-musl": 4.30.1 + "@rollup/rollup-win32-arm64-msvc": 4.30.1 + "@rollup/rollup-win32-ia32-msvc": 4.30.1 + "@rollup/rollup-win32-x64-msvc": 4.30.1 + "@types/estree": 1.0.6 + fsevents: ~2.3.2 + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-loongarch64-gnu": + optional: true + "@rollup/rollup-linux-powerpc64le-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 4a3df04dc639f36cb2d7746c829c4957a3df54b449171280a108c32c4f578677207f330e358c48637d7414ef30c1542964641c82bebc0643d5d5baee4044542e + languageName: node + linkType: hard + "rpc-websockets@npm:^7.5.1": version: 7.5.1 resolution: "rpc-websockets@npm:7.5.1" @@ -48069,6 +48675,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.1.1, semver@npm:^7.6.3": + version: 7.6.3 + resolution: "semver@npm:7.6.3" + bin: + semver: bin/semver.js + checksum: 4110ec5d015c9438f322257b1c51fe30276e5f766a3f64c09edd1d7ea7118ecbc3f379f3b69032bacf13116dc7abc4ad8ce0d7e2bd642e26b0d271b56b61a7d8 + languageName: node + linkType: hard + "semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.0, semver@npm:^7.5.1, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4": version: 7.5.4 resolution: "semver@npm:7.5.4" @@ -48089,15 +48704,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.6.3": - version: 7.6.3 - resolution: "semver@npm:7.6.3" - bin: - semver: bin/semver.js - checksum: 4110ec5d015c9438f322257b1c51fe30276e5f766a3f64c09edd1d7ea7118ecbc3f379f3b69032bacf13116dc7abc4ad8ce0d7e2bd642e26b0d271b56b61a7d8 - languageName: node - linkType: hard - "semver@npm:~2.3.1": version: 2.3.2 resolution: "semver@npm:2.3.2" @@ -48902,6 +49508,17 @@ __metadata: languageName: node linkType: hard +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.5 + resolution: "socks-proxy-agent@npm:8.0.5" + dependencies: + agent-base: ^7.1.2 + debug: ^4.3.4 + socks: ^2.8.3 + checksum: b4fbcdb7ad2d6eec445926e255a1fb95c975db0020543fbac8dfa6c47aecc6b3b619b7fb9c60a3f82c9b2969912a5e7e174a056ae4d98cb5322f3524d6036e1d + languageName: node + linkType: hard + "socks@npm:^2.6.2": version: 2.7.1 resolution: "socks@npm:2.7.1" @@ -48922,6 +49539,16 @@ __metadata: languageName: node linkType: hard +"socks@npm:^2.8.3": + version: 2.8.3 + resolution: "socks@npm:2.8.3" + dependencies: + ip-address: ^9.0.5 + smart-buffer: ^4.2.0 + checksum: 7a6b7f6eedf7482b9e4597d9a20e09505824208006ea8f2c49b71657427f3c137ca2ae662089baa73e1971c62322d535d9d0cf1c9235cf6f55e315c18203eadd + languageName: node + linkType: hard + "sonic-boom@npm:^2.2.1": version: 2.8.0 resolution: "sonic-boom@npm:2.8.0" @@ -50440,6 +51067,20 @@ __metadata: languageName: node linkType: hard +"tar@npm:^6.2.1": + version: 6.2.1 + resolution: "tar@npm:6.2.1" + dependencies: + chownr: ^2.0.0 + fs-minipass: ^2.0.0 + minipass: ^5.0.0 + minizlib: ^2.1.1 + mkdirp: ^1.0.3 + yallist: ^4.0.0 + checksum: f1322768c9741a25356c11373bce918483f40fa9a25c69c59410c8a1247632487edef5fe76c5f12ac51a6356d2f1829e96d2bc34098668a2fc34d76050ac2b6c + languageName: node + linkType: hard + "tdigest@npm:^0.1.1": version: 0.1.2 resolution: "tdigest@npm:0.1.2" @@ -51297,6 +51938,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:4.30.0": + version: 4.30.0 + resolution: "type-fest@npm:4.30.0" + checksum: 2ce3b08265acbdf864267e1468cdcc8dbfa4e86c2fd5e4622a20a83358b5e21fcb49a41beada95d29d8ff1ed8aacb27d10ec0b7623d546f9399b529a153724b0 + languageName: node + linkType: hard + "type-fest@npm:^0.12.0": version: 0.12.0 resolution: "type-fest@npm:0.12.0" @@ -51613,7 +52261,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5": +"typescript@npm:^5, typescript@npm:^5.3.3": version: 5.7.3 resolution: "typescript@npm:5.7.3" bin: @@ -51703,7 +52351,7 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@^5#~builtin": +"typescript@patch:typescript@^5#~builtin, typescript@patch:typescript@^5.3.3#~builtin": version: 5.7.3 resolution: "typescript@patch:typescript@npm%3A5.7.3#~builtin::version=5.7.3&hash=77c9e2" bin: @@ -52566,7 +53214,7 @@ __metadata: languageName: node linkType: hard -"validate-npm-package-license@npm:^3.0.1": +"validate-npm-package-license@npm:^3.0.1, validate-npm-package-license@npm:^3.0.4": version: 3.0.4 resolution: "validate-npm-package-license@npm:3.0.4" dependencies: @@ -52585,6 +53233,13 @@ __metadata: languageName: node linkType: hard +"validate-npm-package-name@npm:^5.0.0": + version: 5.0.1 + resolution: "validate-npm-package-name@npm:5.0.1" + checksum: 0d583a1af23aeffea7748742cf22b6802458736fb8b60323ba5949763824d46f796474b0e1b9206beb716f9d75269e19dbd7795d6b038b29d561be95dd827381 + languageName: node + linkType: hard + "valtio@npm:1.11.2": version: 1.11.2 resolution: "valtio@npm:1.11.2" @@ -53756,6 +54411,17 @@ __metadata: languageName: node linkType: hard +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: ^3.1.1 + bin: + node-which: bin/which.js + checksum: f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 + languageName: node + linkType: hard + "wide-align@npm:^1.1.5": version: 1.1.5 resolution: "wide-align@npm:1.1.5" From f03d7bd654787a85aa82792f15f25e87f9857861 Mon Sep 17 00:00:00 2001 From: abretonc7s Date: Thu, 16 Jan 2025 22:45:28 +0800 Subject: [PATCH 06/28] feat: wip --- package.json | 2 +- packages/multichainapi/package.json | 1 + .../multichainapi/src/MetamaskMultichain.ts | 179 ++++ .../src/MultichainProvider.test.ts | 27 - packages/multichainapi/src/index.ts | 12 +- .../src/providers/ExtensionProvider.ts | 274 +++++ .../src/providers/MultichainProvider.ts | 65 -- .../providers/extensions/ExtensionProvider.ts | 147 --- packages/multichainapi/src/types.ts | 44 +- packages/multichainapi/src/walletDiscovery.ts | 106 ++ packages/multichainapi/tsconfig.json | 1 + packages/playground-next/next.config.ts | 3 +- packages/playground-next/package.json | 8 + packages/playground-next/src/app/globals.css | 693 ++++++++++++ packages/playground-next/src/app/page.tsx | 998 +++++++++++++++++- packages/playground-next/src/app/page_sdk.tsx | 95 ++ .../src/components/DynamicInputs.tsx | 70 ++ .../src/components/WalletList.css | 82 ++ .../src/components/WalletList.tsx | 74 ++ packages/playground-next/tsconfig.json | 15 +- yarn.lock | 147 ++- 21 files changed, 2740 insertions(+), 303 deletions(-) create mode 100644 packages/multichainapi/src/MetamaskMultichain.ts delete mode 100644 packages/multichainapi/src/MultichainProvider.test.ts create mode 100644 packages/multichainapi/src/providers/ExtensionProvider.ts delete mode 100644 packages/multichainapi/src/providers/MultichainProvider.ts delete mode 100644 packages/multichainapi/src/providers/extensions/ExtensionProvider.ts create mode 100644 packages/multichainapi/src/walletDiscovery.ts create mode 100644 packages/playground-next/src/app/page_sdk.tsx create mode 100644 packages/playground-next/src/components/DynamicInputs.tsx create mode 100644 packages/playground-next/src/components/WalletList.css create mode 100644 packages/playground-next/src/components/WalletList.tsx diff --git a/package.json b/package.json index 149bb4822..f738ce2ba 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "postinstall": "patch-package", "link-packages": "./scripts/link-packages.sh", "prepare": "husky install", - "dev:core": "turbo run dev --parallel --filter=@metamask/sdk-communication-layer --filter=@metamask/sdk --filter=@metamask/sdk-react", + "dev:core": "turbo run dev --parallel --filter=@metamask/sdk-communication-layer --filter=@metamask/multichainapi --filter=@metamask/sdk --filter=@metamask/sdk-react", "lint": "yarn workspaces foreach --no-private run lint", "lint:changelogs": "yarn workspaces foreach --no-private run lint:changelog", "lint:eslint": "yarn workspaces foreach --no-private run lint:eslint", diff --git a/packages/multichainapi/package.json b/packages/multichainapi/package.json index a89a45d49..39b5efafd 100644 --- a/packages/multichainapi/package.json +++ b/packages/multichainapi/package.json @@ -47,6 +47,7 @@ "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.2", + "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", "@types/debug": "^4.1.12", "@types/jest": "^29.5.11", diff --git a/packages/multichainapi/src/MetamaskMultichain.ts b/packages/multichainapi/src/MetamaskMultichain.ts new file mode 100644 index 000000000..3bf304e2a --- /dev/null +++ b/packages/multichainapi/src/MetamaskMultichain.ts @@ -0,0 +1,179 @@ +// packages/multichainapi/src/providers/MultichainProvider.ts +import type { Json } from '@metamask/utils'; +import { ExtensionProvider } from './providers/ExtensionProvider'; +import { MultichainEvents, ScopedProperties, ScopeObject, SessionData, SessionEventData, SessionProperties } from './types'; + +export interface CreateSessionParams { + requiredScopes?: Record; + optionalScopes?: Record; + scopedProperties?: ScopedProperties; + sessionProperties?: SessionProperties; +} + +export interface CreateSessionResult { + sessionId?: string; + sessionScopes: Record; + scopedProperties?: ScopedProperties; + sessionProperties?: SessionProperties; +} + + + +/** + * A CAIP-25-compliant provider that uses ExtensionProvider for transport. + */ +export class MetamaskMultichain { + private readonly sessions: Map = new Map(); + private readonly provider: ExtensionProvider; + private readonly listeners: { + sessionChanged: Set<(data: SessionEventData) => void>; + notification: Set<(data: unknown) => void>; + } = { + sessionChanged: new Set(), + notification: new Set() + }; + + constructor() { + this.provider = new ExtensionProvider(); + + this.provider.onNotification((notification) => { + this.notify('notification', notification); + }); + } + + public addListener( + event: K, + listener: MultichainEvents[K] + ): void { + this.listeners[event].add(listener); + } + + public removeListener( + event: K, + listener: MultichainEvents[K] + ): void { + this.listeners[event].delete(listener); + } + + private notify(event: 'sessionChanged', data: SessionEventData): void; + private notify(event: 'notification', data: unknown): void; + private notify(event: keyof MultichainEvents, data: unknown): void { + if (event === 'sessionChanged') { + this.listeners.sessionChanged.forEach(listener => listener(data as SessionEventData)); + } else { + this.listeners.notification.forEach(listener => listener(data)); + } + } + + public async connect({ extensionId }: { extensionId: string }): Promise { + console.debug('[Caip25MultichainProvider] Connecting...'); + return this.provider.connect({ extensionId }); + } + + public disconnect(): void { + console.debug('[Caip25MultichainProvider] Disconnecting...'); + this.provider.disconnect(); + } + + /** + * Create or update a CAIP-25 session. + */ + public async createSession({ + requiredScopes, + optionalScopes, + scopedProperties, + sessionProperties, + }: CreateSessionParams): Promise { + console.debug('[Caip25MultichainProvider] createSession'); + + const result = (await this.provider.request({ + method: 'wallet_createSession', + params: { + requiredScopes, + optionalScopes, + scopedProperties, + sessionProperties, + }, + })) as CreateSessionResult; + + console.debug('[Caip25MultichainProvider] wallet_createSession response:', result); + + const sessionId = result.sessionId ?? 'SINGLE_SESSION_ONLY'; + const sessionRecord: SessionData = { + sessionId: result.sessionId, + sessionScopes: result.sessionScopes, + scopedProperties: result.scopedProperties, + sessionProperties: result.sessionProperties, + expiry: result.sessionProperties?.expiry as string | undefined, + }; + + this.sessions.set(sessionId, sessionRecord); + + this.notify('sessionChanged', { + type: 'created', + session: sessionRecord, + }); + + return result; + } + + /** + * Revoke a CAIP-25 session. + */ + public async revokeSession({ sessionId }: { sessionId?: string }): Promise { + const idToUse = sessionId ?? 'SINGLE_SESSION_ONLY'; + const session = this.sessions.get(idToUse); + if (!session) { + console.debug('[Caip25MultichainProvider] No session found to revoke for:', idToUse); + return false; + } + + console.debug('[Caip25MultichainProvider] Revoking session:', idToUse); + + await this.provider.request({ + method: 'wallet_revokeSession', + params: sessionId ? [sessionId] : [], + }); + + this.sessions.delete(idToUse); + this.notify('sessionChanged', { + type: 'revoked', + session: session, + }); + + return true; + } + + /** + * Retrieve a stored session record, defaulting to single-session usage if none is specified. + */ + public async getSession({ sessionId }: { sessionId?: string }): Promise { + const idToUse = sessionId ?? 'SINGLE_SESSION_ONLY'; + const session = this.sessions.get(idToUse); + if (!session) { + console.debug('[Caip25MultichainProvider] Session not found:', idToUse); + return null; + } + return session; + } + + /** + * Invoke a method (CAIP-25 style) within a particular scope. + */ + public async invokeMethod({ + scope, + request, + }: { + scope: string; + request: { method: string; params: Json[] }; + }): Promise { + console.debug('[Caip25MultichainProvider] Invoking method:', request.method, 'on scope:', scope); + + const result = (await this.provider.request({ + method: 'wallet_invokeMethod', + params: { scope, request }, + })) as Json; + + return result; + } +} diff --git a/packages/multichainapi/src/MultichainProvider.test.ts b/packages/multichainapi/src/MultichainProvider.test.ts deleted file mode 100644 index 68289fb64..000000000 --- a/packages/multichainapi/src/MultichainProvider.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { describe, expect, it } from '@jest/globals'; -import { MultichainProvider } from './providers/MultichainProvider'; - -describe('MultichainProvider', () => { - it('should create a session', async () => { - const provider = new MultichainProvider(); - const session = await provider.createSession('eip155:1', '0x123'); - - expect(session).toMatchObject({ - chainId: 'eip155:1', - account: '0x123', - }); - expect(session.id).toBeDefined(); - expect(session.expiry).toBeGreaterThan(Date.now()); - }); - - it('should revoke a session', async () => { - const provider = new MultichainProvider(); - const session = await provider.createSession('eip155:1', '0x123'); - - const result = await provider.revokeSession(session.id); - expect(result).toBe(true); - - const retrievedSession = await provider.getSession(session.id); - expect(retrievedSession).toBeUndefined(); - }); -}); diff --git a/packages/multichainapi/src/index.ts b/packages/multichainapi/src/index.ts index aa89cd268..55f2bbb9f 100644 --- a/packages/multichainapi/src/index.ts +++ b/packages/multichainapi/src/index.ts @@ -1,19 +1,19 @@ // packages/multichainapi/src/index.ts -import { MultichainProvider } from './providers/MultichainProvider'; +import { MetamaskMultichain } from './MetamaskMultichain'; // This is the main "entry point" for the package. -export { MultichainProvider } from './providers/MultichainProvider'; -export type { SessionData, MethodParams, SessionEventData } from './types'; +export * from './MetamaskMultichain'; -// Possibly export some helper function or "createMultichainAPI()" factory here: export function createMultichainAPI() { - const provider = new MultichainProvider(); - // Return a simple object with convenience methods, or just the provider itself. + const provider = new MetamaskMultichain(); return provider; } // Re-export any constants or utilities that might be helpful: export * from './constants/networks'; export * from './constants/methods'; +export * from './walletDiscovery'; export * from './utils/getCaip25FormattedAddresses'; +export * from './utils/JsonHelpers'; +export * from './types'; diff --git a/packages/multichainapi/src/providers/ExtensionProvider.ts b/packages/multichainapi/src/providers/ExtensionProvider.ts new file mode 100644 index 000000000..d07ca6aea --- /dev/null +++ b/packages/multichainapi/src/providers/ExtensionProvider.ts @@ -0,0 +1,274 @@ +// packages/multichainapi/src/providers/ExtensionProvider.ts + +/// +import type { Provider } from './BaseProvider'; +import type { MethodParams } from '../types'; + +interface ExtensionResponse { + id?: number; + result?: unknown; + error?: { + message: string; + code?: number; + }; +} + +type NotificationCallback = (notification: unknown) => void; + +interface ConnectParams { + extensionId: string; +} + +export class ExtensionProvider implements Provider { + #port: chrome.runtime.Port | null; + #requestMap: Map void; reject: (r?: unknown) => void }>; + #nextId: number; + #notificationCallbacks: Set; + #fallbackMode: boolean; + + constructor() { + this.#port = null; + this.#requestMap = new Map(); + this.#nextId = 1; + this.#notificationCallbacks = new Set(); + this.#fallbackMode = false; + console.debug('[ExtensionProvider] Initialized'); + } + + public async connect({ extensionId }: ConnectParams): Promise { + console.debug('[ExtensionProvider] Attempting to connect:', extensionId); + + // Clear any existing state first + if (this.#port) { + console.debug('[ExtensionProvider] Existing connection found, disconnecting'); + this.disconnect(); + } + + // Attempt chromium connection if available + const canUseChrome = typeof chrome !== 'undefined' + && chrome.runtime + && typeof chrome.runtime.connect === 'function'; + + if (canUseChrome) { + return this.#connectChromium({ extensionId }); + } + + // Otherwise fallback approach + this.#fallbackMode = true; + return this.#connectFallback({ extensionId }); + } + + public disconnect(): void { + console.debug('[ExtensionProvider] Disconnecting'); + if (this.#port) { + this.#port.disconnect(); + this.#port = null; + } + this.#requestMap.clear(); + this.removeAllNotificationListeners(); + this.#fallbackMode = false; + console.debug('[ExtensionProvider] Disconnected and reset'); + } + + public async request(params: MethodParams): Promise { + if (!this.#fallbackMode) { + return this.#requestChromium(params); + } + return this.#requestFallback(params); + } + + public onNotification(callback: NotificationCallback): void { + console.debug('[ExtensionProvider] Adding notification listener'); + this.#notificationCallbacks.add(callback); + } + + public removeNotificationListener(callback: NotificationCallback): void { + console.debug('[ExtensionProvider] Removing notification listener'); + this.#notificationCallbacks.delete(callback); + } + + public removeAllNotificationListeners(): void { + console.debug('[ExtensionProvider] Removing all notification listeners'); + this.#notificationCallbacks.clear(); + } + + // ========================================================================= + // Private: Chromium-Connection Logic + // ========================================================================= + + async #connectChromium({ extensionId }: ConnectParams): Promise { + console.debug('[ExtensionProvider] #connectChromium to:', extensionId); + + this.#port = chrome.runtime.connect(extensionId); + + let isConnected = true; + this.#port.onDisconnect.addListener(() => { + isConnected = false; + const errorMessage = chrome.runtime.lastError + ? chrome.runtime.lastError.message + : 'Port disconnected unexpectedly.'; + console.error('[ExtensionProvider] Chromium connection error:', errorMessage); + this.#port = null; + this.#requestMap.clear(); + }); + + // Wait briefly to confirm + await new Promise((resolve) => setTimeout(resolve, 5)); + + if (!isConnected) { + console.error('[ExtensionProvider] Connect failed - port disconnected'); + throw new Error('Error connecting; extension not found or disabled.'); + } + + this.#port.onMessage.addListener(this.#handleChromiumMessage.bind(this)); + + try { + console.debug('[ExtensionProvider] Pinging extension to verify'); + this.#port.postMessage('ping'); + return true; + } catch (err) { + console.error('[ExtensionProvider] Ping error:', err); + return false; + } + } + + #requestChromium(params: MethodParams): Promise { + if (!this.#port) { + console.error('[ExtensionProvider] requestChromium failed - no port'); + throw new Error('Not connected to extension. Call connect() first.'); + } + + const id = this.#nextId++; + const request = { + jsonrpc: '2.0', + id, + method: params.method, + params: params.params, + scope: params.chainId, + }; + + console.debug('[ExtensionProvider] Sending chromium request:', request); + + return new Promise((resolve, reject) => { + this.#requestMap.set(id, { resolve, reject }); + this.#port?.postMessage({ type: 'caip-request', data: request }); + + setTimeout(() => { + if (this.#requestMap.has(id)) { + console.warn('[ExtensionProvider] Request timeout for id:', id); + this.#requestMap.delete(id); + reject(new Error('Request timeout')); + } + }, 30000); + }); + } + + #handleChromiumMessage(message: { data: ExtensionResponse }): void { + const { data } = message; + console.debug('[ExtensionProvider] Received chromium message:', data); + this.#handleResponse(data); + } + + // ========================================================================= + // Private: Fallback-Connection Logic + // ========================================================================= + + async #connectFallback({ extensionId }: ConnectParams): Promise { + console.debug('[ExtensionProvider] #connectFallback to:', extensionId); + + // Possibly store extensionId or post a request event + window.postMessage( + { + type: 'MULTICHAIN_CONNECT_REQUEST', + extensionId, + }, + '*', + ); + + // Listen for events from extension + window.addEventListener('message', this.#handleFallbackMessage.bind(this)); + + // Example: immediately assume success for demonstration + return true; + } + + #requestFallback(params: MethodParams): Promise { + const id = this.#nextId++; + const request = { + jsonrpc: '2.0', + id, + method: params.method, + params: params.params, + scope: params.chainId, + }; + + console.debug('[ExtensionProvider] Sending fallback request:', request); + + return new Promise((resolve, reject) => { + this.#requestMap.set(id, { resolve, reject }); + + window.postMessage( + { + type: 'caip-request', + data: request, + }, + '*', + ); + + setTimeout(() => { + if (this.#requestMap.has(id)) { + console.warn('[ExtensionProvider] Request timeout for id:', id); + this.#requestMap.delete(id); + reject(new Error('Request timeout')); + } + }, 30000); + }); + } + + #handleFallbackMessage(event: MessageEvent): void { + if (event.data?.type !== 'caip-response') { + return; + } + const response = event.data?.data as ExtensionResponse; + console.debug('[ExtensionProvider] Received fallback message:', response); + this.#handleResponse(response); + } + + // ========================================================================= + // Private: Shared Response Handling + // ========================================================================= + + #handleResponse(data: ExtensionResponse): void { + if (data.id && this.#requestMap.has(data.id)) { + const { resolve, reject } = this.#requestMap.get(data.id) ?? {}; + this.#requestMap.delete(data.id); + + if (resolve && reject) { + if (data.error) { + console.error('[ExtensionProvider] Request error for id:', data.id, data.error); + reject(new Error(data.error.message)); + } else { + console.debug('[ExtensionProvider] Request success for id:', data.id); + resolve(data.result); + } + } + } else if (!data.id) { + console.debug('[ExtensionProvider] Received notification'); + this.#notifyCallbacks(data); + } + } + + #notifyCallbacks(notification: unknown): void { + console.debug('[ExtensionProvider] Notifying callbacks:', { + callbackCount: this.#notificationCallbacks.size, + }); + + this.#notificationCallbacks.forEach((callback) => { + try { + callback(notification); + } catch (error) { + console.error('[ExtensionProvider] Error in notification callback:', error); + } + }); + } +} diff --git a/packages/multichainapi/src/providers/MultichainProvider.ts b/packages/multichainapi/src/providers/MultichainProvider.ts deleted file mode 100644 index 055e6a0cd..000000000 --- a/packages/multichainapi/src/providers/MultichainProvider.ts +++ /dev/null @@ -1,65 +0,0 @@ -// packages/multichainapi/src/MultichainProvider.ts -import { EventEmitter2 } from 'eventemitter2'; -import type { SessionData, MethodParams, SessionEventData } from '../types'; -import { ExtensionProvider } from './extensions/ExtensionProvider'; -import { FEATURED_NETWORKS } from '../constants/networks'; -import { Eip155Methods } from '../constants/methods'; - -export class MultichainProvider extends EventEmitter2 { - private sessions: Map = new Map(); - private provider: ExtensionProvider; - - constructor() { - super(); - this.provider = new ExtensionProvider(); - } - - async connect(extensionId: string): Promise { - return this.provider.connect(extensionId); - } - - async createSession(chainId: string, account: string): Promise { - if (!FEATURED_NETWORKS[chainId as keyof typeof FEATURED_NETWORKS]) { - throw new Error(`Unsupported chainId: ${chainId}`); - } - - const session: SessionData = { - id: crypto.randomUUID(), - chainId, - account, - expiry: Date.now() + 3600000, // 1 hour from now - }; - - this.sessions.set(session.id, session); - this.emit('sessionChanged', { - type: 'created', - session, - } as SessionEventData); - - return session; - } - - async invokeMethod(params: MethodParams): Promise { - if (!Eip155Methods.includes(params.method)) { - throw new Error(`Unsupported method: ${params.method}`); - } - return this.provider.request(params); - } - - async getSession(sessionId: string): Promise { - return this.sessions.get(sessionId); - } - - async revokeSession(sessionId: string): Promise { - const session = this.sessions.get(sessionId); - if (session) { - this.sessions.delete(sessionId); - this.emit('sessionChanged', { - type: 'revoked', - session, - } as SessionEventData); - return true; - } - return false; - } -} diff --git a/packages/multichainapi/src/providers/extensions/ExtensionProvider.ts b/packages/multichainapi/src/providers/extensions/ExtensionProvider.ts deleted file mode 100644 index 29503e1ea..000000000 --- a/packages/multichainapi/src/providers/extensions/ExtensionProvider.ts +++ /dev/null @@ -1,147 +0,0 @@ -/// -// packages/multichainapi/src/providers/ExtensionProvider.ts -import type { Provider } from '../BaseProvider'; -import type { MethodParams } from '../../types'; - -interface ExtensionResponse { - id?: number; - result?: unknown; - error?: { - message: string; - code?: number; - }; -} - -type NotificationCallback = (notification: unknown) => void; - -export class ExtensionProvider implements Provider { - #port: chrome.runtime.Port | null; - #requestMap: Map< - number, - { resolve: (value: unknown) => void; reject: (reason?: unknown) => void } - >; - #nextId: number; - #notificationCallbacks: Set; - - constructor() { - this.#port = null; - this.#requestMap = new Map(); - this.#nextId = 1; - this.#notificationCallbacks = new Set(); - } - - async connect(extensionId: string): Promise { - if (this.#port) { - this.disconnect(); - } - - this.#port = chrome.runtime.connect(extensionId); - let isConnected = true; - - this.#port.onDisconnect.addListener(() => { - isConnected = false; - const errorMessage = chrome.runtime.lastError - ? chrome.runtime.lastError.message - : 'Port disconnected unexpectedly.'; - console.error('Error connecting to extension:', errorMessage); - this.#port = null; - this.#requestMap.clear(); - }); - - // Wait for connection confirmation - await new Promise((resolve) => setTimeout(resolve, 5)); - - if (!isConnected) { - throw new Error( - 'Error connecting to MetaMask Multichain Provider. Extension not found or disabled.', - ); - } - - this.#port.onMessage.addListener(this.#handleMessage.bind(this)); - - try { - this.#port.postMessage('ping'); - return true; - } catch (error) { - console.error('Error sending message:', error); - return false; - } - } - - disconnect(): void { - if (this.#port) { - this.#port.disconnect(); - this.#port = null; - } - this.#requestMap.clear(); - this.removeAllNotificationListeners(); - } - - async request(params: MethodParams): Promise { - if (!this.#port) { - throw new Error('Not connected to extension. Call connect() first.'); - } - - const id = this.#nextId++; - const request = { - jsonrpc: '2.0', - id, - method: params.method, - params: params.params, - scope: params.chainId, // Include CAIP-2 chainId as scope - }; - - return new Promise((resolve, reject) => { - this.#requestMap.set(id, { resolve, reject }); - this.#port?.postMessage({ type: 'caip-request', data: request }); - - // Request timeout after 30 seconds - setTimeout(() => { - if (this.#requestMap.has(id)) { - this.#requestMap.delete(id); - reject(new Error('Request timeout')); - } - }, 30000); - }); - } - - #handleMessage(message: { data: ExtensionResponse }): void { - const { data } = message; - if (data.id && this.#requestMap.has(data.id)) { - const { resolve, reject } = this.#requestMap.get(data.id) ?? {}; - this.#requestMap.delete(data.id); - - if (resolve && reject) { - if (data.error) { - reject(new Error(data.error.message)); - } else { - resolve(data.result); - } - } - } else if (!data.id) { - this.#notifyCallbacks(data); - } - } - - onNotification(callback: NotificationCallback): void { - this.#notificationCallbacks.add(callback); - } - - removeNotificationListener(callback: NotificationCallback): void { - this.#notificationCallbacks.delete(callback); - } - - removeAllNotificationListeners(): void { - this.#notificationCallbacks.clear(); - } - - #notifyCallbacks(notification: unknown): void { - this.#notificationCallbacks.forEach((callback) => { - try { - callback(notification); - } catch (error) { - console.error('Error in notification callback:', error); - } - }); - } -} diff --git a/packages/multichainapi/src/types.ts b/packages/multichainapi/src/types.ts index 0b5cc690d..7132ad4ae 100644 --- a/packages/multichainapi/src/types.ts +++ b/packages/multichainapi/src/types.ts @@ -1,18 +1,50 @@ // packages/multichainapi/src/types.ts + +import { CaipAccountId, Json } from "@metamask/utils"; + + +/** + * Interfaces for CAIP-based Scopes and Sessions + */ +export interface ScopeObject { + references?: string[]; + methods?: string[]; + notifications?: string[]; + accounts?: CaipAccountId[]; +} + +export interface ScopedProperties { + [scopeString: string]: Json; +} + +export interface SessionProperties { + [key: string]: Json; +} + + +/** + * Represents a tracked session in local store. + */ export interface SessionData { - id: string; - chainId: string; - account: string; - expiry: number; + sessionId?: string; + sessionScopes: Record; + scopedProperties?: ScopedProperties; + sessionProperties?: SessionProperties; + expiry?: string; } export interface MethodParams { - chainId: string; + chainId?: string; method: string; - params: unknown[]; + params?: unknown[] | Record; } export interface SessionEventData { type: 'created' | 'updated' | 'revoked'; session: SessionData; } + +export interface MultichainEvents { + sessionChanged: (event: SessionEventData) => void; + notification: (notification: unknown) => void; +} diff --git a/packages/multichainapi/src/walletDiscovery.ts b/packages/multichainapi/src/walletDiscovery.ts new file mode 100644 index 000000000..eaaeb5056 --- /dev/null +++ b/packages/multichainapi/src/walletDiscovery.ts @@ -0,0 +1,106 @@ +export enum CAIP294EventNames { + Announce = 'caip294:wallet_announce', + Request = 'caip294:wallet_prompt', +} + +export interface CAIP294ProviderInfo { + providerId: string; + name: string; + icon: string; + rdns: string; +} + +export interface CAIP294ProviderDetail { + info: CAIP294ProviderInfo; + provider: unknown; +} + +export interface WalletInfo { + name: string; + icon: string; + rdns: string; + providerId: string; +} + +export interface WalletDiscoveryOptions { + timeout?: number; + filterPredicate?: (wallet: WalletInfo) => boolean; +} + +interface CAIP294AnnounceParams { + name: string; + icon: string; + rdns: string; + uuid: string; + extensionId?: string; +} + +interface CAIP294AnnounceEvent { + id: number; + jsonrpc: string; + method: string; + params: CAIP294AnnounceParams; +} + +export function discoverWallets(options: WalletDiscoveryOptions = {}): Promise { + const { + timeout = 500, + filterPredicate = () => true, + } = options; + + console.log('discoverWallets', options); + return new Promise((resolve, reject) => { + const discoveredWallets: WalletInfo[] = []; + + const handleAnnouncement = (event: Event) => { + const customEvent = event as CustomEvent; + const params = customEvent.detail.params; + + if (params) { + const walletInfo: WalletInfo = { + name: params.name, + icon: params.icon, + rdns: params.rdns, + providerId: params.extensionId || params.uuid, + }; + + if (filterPredicate(walletInfo)) { + discoveredWallets.push(walletInfo); + } + } + }; + + window.addEventListener(CAIP294EventNames.Announce, handleAnnouncement); + + window.dispatchEvent(new CustomEvent(CAIP294EventNames.Request, { + detail: { + id: 1, + jsonrpc: '2.0', + method: 'wallet_prompt', + params: {}, + }, + })); + + const timeoutId = setTimeout(() => { + window.removeEventListener(CAIP294EventNames.Announce, handleAnnouncement); + resolve(discoveredWallets); + }, timeout); + + return () => { + clearTimeout(timeoutId); + window.removeEventListener(CAIP294EventNames.Announce, handleAnnouncement); + }; + }); +} + +// Utility functions for common filtering scenarios +export const walletFilters = { + isMetaMask: (wallet: WalletInfo) => + wallet.name.toLowerCase().includes('metamask'), + + byName: (name: string) => (wallet: WalletInfo) => + wallet.name.toLowerCase().includes(name.toLowerCase()), + + byRdns: (rdns: string) => (wallet: WalletInfo) => + wallet.rdns === rdns, +}; diff --git a/packages/multichainapi/tsconfig.json b/packages/multichainapi/tsconfig.json index 449951aeb..cecfd8d95 100644 --- a/packages/multichainapi/tsconfig.json +++ b/packages/multichainapi/tsconfig.json @@ -4,6 +4,7 @@ "baseUrl": "./", "outDir": "dist", "rootDir": ".", + "declaration": true, "paths": { "@metamask/multichainapi/*": ["./src/*"] } diff --git a/packages/playground-next/next.config.ts b/packages/playground-next/next.config.ts index e9ffa3083..b8b2a9a3a 100644 --- a/packages/playground-next/next.config.ts +++ b/packages/playground-next/next.config.ts @@ -1,7 +1,8 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + reactStrictMode: false, + /* other config options here */ }; export default nextConfig; diff --git a/packages/playground-next/package.json b/packages/playground-next/package.json index 9ec03864a..2eebf9427 100644 --- a/packages/playground-next/package.json +++ b/packages/playground-next/package.json @@ -10,7 +10,12 @@ "allow-scripts": "echo 'NA'" }, "dependencies": { + "@metamask/api-specs": "^0.10.13", + "@metamask/multichainapi": "workspace:^", "@metamask/sdk-react": "workspace:^", + "@metamask/utils": "^11.0.1", + "@open-rpc/meta-schema": "^1.14.9", + "@open-rpc/schema-utils-js": "^2.0.5", "next": "15.1.4", "react": "^19.0.0", "react-dom": "^19.0.0" @@ -22,6 +27,9 @@ "@types/react-dom": "^19", "eslint": "^9", "eslint-config-next": "15.1.4", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-prettier": "^5.2.2", + "prettier": "^3.4.2", "typescript": "^5" } } diff --git a/packages/playground-next/src/app/globals.css b/packages/playground-next/src/app/globals.css index e3734be15..d75b54772 100644 --- a/packages/playground-next/src/app/globals.css +++ b/packages/playground-next/src/app/globals.css @@ -40,3 +40,696 @@ a { color-scheme: dark; } } + +body { + margin: 0; + display: flex; + justify-content: center; + min-height: 100vh; + background-color: #f5f7fa; + color: #2d3748; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; +} + +.App { + max-width: 1200px; + width: 100%; + padding: 2rem; +} + +/* Section styling */ +section { + background: white; + border-radius: 8px; + padding: 2rem; + margin: 1.5rem 0; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +/* Headings */ +h1 { + color: #1a365d; + font-size: 2.5rem; + margin-bottom: 2rem; + text-align: center; +} + +h2 { + color: #2c5282; + font-size: 1.8rem; + margin-bottom: 1.5rem; +} + +h3 { + color: #2b6cb0; + font-size: 1.4rem; + margin: 1rem 0; +} + +/* Form elements */ +input[type="text"], +select, +textarea { + padding: 0.5rem; + border: 1px solid #cbd5e0; + border-radius: 4px; + margin: 0.5rem; + font-size: 1rem; +} + +textarea { + font-family: monospace; + background-color: #f7fafc; +} + +/* Buttons */ +button { + background-color: #4299e1; + color: white; + padding: 0.6rem 1.2rem; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 1rem; + margin: 0.5rem; + transition: background-color 0.2s; +} + +button:hover { + background-color: #3182ce; +} + +button#clear-state-btn { + background-color: #e53e3e; +} + +button#clear-state-btn:hover { + background-color: #c53030; +} + +button:disabled { + background-color: #a0aec0; + cursor: not-allowed; + opacity: 0.7; +} + +button:disabled:hover { + background-color: #a0aec0; +} + +.code-left-align { + text-align: left; + display: block; + width: 100%; + background-color: #f7fafc; + padding: 1rem; + border-radius: 4px; + border: 1px solid #edf2f7; + overflow-x: auto; + box-sizing: border-box; +} + +pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; +} + +/* Checkbox containers */ +label { + display: inline-flex; + align-items: center; + margin: 0.5rem; + cursor: pointer; +} + +input[type="checkbox"] { + margin-right: 0.5rem; +} + +/* Connection status indicator */ +.connection-status { + display: flex; + align-items: center; + padding: 1rem; + background-color: #f7fafc; + border-radius: 4px; + margin: 1rem 0; +} + +.status-indicator { + width: 10px; + height: 10px; + border-radius: 50%; + margin-right: 8px; +} + +.status-connected { + background-color: #48bb78; +} + +.status-disconnected { + background-color: #e53e3e; +} + +/* Method invocation section */ +.method-container { + border: 1px solid #e2e8f0; + border-radius: 4px; + padding: 1rem; + margin: 1rem 0; +} + +.method-result { + margin-top: 1rem; + padding: 1rem; + background-color: #f7fafc; + border-radius: 4px; +} + +.App-logo { + height: 40vmin; + pointer-events: none; +} + +@media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; + width: 100%; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +/* Session controls */ +.session-controls { + display: flex; + margin: 1.5rem 0; +} + +.session-result { + margin: 0 0 20px 0; + padding: 1.5rem; + background-color: #f7fafc; + border-radius: 4px; + border: 1px solid #e2e8f0; + overflow-wrap: break-word; + word-wrap: break-word; + word-break: break-word; + max-height: 300px; + overflow-y: auto; +} + +.session-result.expanded { + height: 900px; +} + +.session-result-toggle { + position: absolute; + bottom: 0; + left: 0; + right: 0; + padding: 0.5rem; + background: linear-gradient(transparent, #f7fafc); + text-align: center; + cursor: pointer; + border: none; + width: 100%; + color: #4299e1; + font-weight: 500; +} + +.session-result-toggle:hover { + background: linear-gradient(transparent, #edf2f7); +} + +.session-result pre { + white-space: pre-wrap; + word-wrap: break-word; + max-width: 100%; +} + +.session-result > div { + margin-bottom: 1.5rem; +} + +.session-result > div:last-child { + margin-bottom: 0; +} + +.session-result h4 { + color: #4a5568; + margin: 0 0 0.75rem 0; + font-size: 1rem; + font-weight: 600; +} + +.create-session-container { + margin: 0 0 1.5rem 0; + padding: 0 0 1.5rem 0; +} + +.session-divider { + height: 1px; + background: linear-gradient(to right, transparent, #e2e8f0, transparent); + margin: 1.5rem 0; +} + +/* Notifications section */ +.notifications-section { + background: white; + border-radius: 8px; + padding: 2rem; +} + +.notifications-section h2 { + text-align: left; + font-size: 1.5rem; + margin-bottom: 1.5rem; +} + +.notification-container { + margin-bottom: 2rem; + padding: 1rem; + background-color: white; + border-radius: 4px; + border: 1px solid #e2e8f0; + max-height: 300px; + overflow-y: auto; +} + +.notification-container h3 { + color: #4a5568; + font-size: 1.1rem; + margin: 0 0 1rem 0; + text-align: left; +} + +.notification-container details { + margin-top: 0; +} + +.notification-container .code-left-align { + background-color: #f7fafc; +} + +.notification-container pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; + max-width: 100%; +} + +.notification-container details .code-left-align { + max-height: 200px; + overflow-y: auto; +} + +.notifications-section h1 { + font-size: 1.5rem; + text-align: left; + color: #2d3748; + margin: 1rem 0; +} + +.result-item { + margin-bottom: 1.5rem; +} + +.result-item:last-child { + margin-bottom: 0; +} + +.result-summary { + cursor: pointer; + padding: 0.5rem; + background-color: white; + border: 1px solid #e2e8f0; + border-radius: 4px; + font-family: monospace; + white-space: normal; + overflow-wrap: break-word; + word-wrap: break-word; + word-break: break-word; + max-width: 100%; +} + +.result-summary:hover { + background-color: #f7fafc; +} + +details { + margin-top: 0.5rem; +} + +details > .code-left-align { + margin-top: 0.5rem; +} + +details summary { + list-style: none; +} + +details summary::-webkit-details-marker { + display: none; +} + +details summary::before { + content: 'â–¶'; + display: inline-block; + margin-right: 0.5rem; + transition: transform 0.2s; +} + +details[open] summary::before { + transform: rotate(90deg); +} + +.scopes-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1.5rem; + margin-top: 1rem; +} + +@media (max-width: 1200px) { + .scopes-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 800px) { + .scopes-grid { + grid-template-columns: 1fr; + } +} + +.scope-card .collapsible-section { + border: 1px solid #e2e8f0; + border-radius: 4px; + overflow: hidden; +} + +.scope-card .collapsible-section summary { + padding: 0.75rem; + background-color: #f7fafc; + cursor: pointer; + font-weight: 500; +} + +.scope-card .collapsible-section summary:hover { + background-color: #edf2f7; +} + +.scope-card .collapsible-content { + padding: 1rem; + background-color: white; +} + +.scope-card .collapsible-content textarea { + margin: 0; +} + +.scope-card { + background: white; + border: 1px solid #e2e8f0; + border-radius: 8px; + padding: 1.5rem; + display: flex; + flex-direction: column; + gap: 1rem; + overflow: hidden; +} + +.scope-card h3 { + margin: 0; + padding-bottom: 0.5rem; + border-bottom: 1px solid #e2e8f0; +} + +.scope-card select { + width: 100%; + padding: 0.75rem; + background-color: #f7fafc; + border: 1px solid #e2e8f0; + border-radius: 4px; + font-family: monospace; + font-size: 0.9rem; + color: #4a5568; + cursor: pointer; + margin: 0; +} + +.scope-card select:hover { + background-color: #edf2f7; +} + +.scope-card select option { + padding: 0.5rem; + font-family: monospace; +} + +.scope-card .method-container { + margin: 0; +} + +.scope-card textarea { + width: 100%; + margin: 0.5rem 0; + box-sizing: border-box; +} + +.scope-card .method-result { + margin: 0; +} + +.scope-card button { + align-self: flex-start; + margin: 0; +} + +.result-method { + font-weight: 600; + margin-right: 1rem; +} + +.result-preview { + color: #4a5568; + font-family: monospace; + font-size: 0.9rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + max-width: calc(100% - 150px); +} + +.result-item-small { + background-color: #f7fafc; + padding: 1rem; + border-radius: 4px; + border: 1px solid #e2e8f0; +} + +.result-item-small h5 { + margin: 0 0 0.5rem 0; + color: #4a5568; + font-size: 0.9rem; +} + +.result-item-small pre { + margin: 0; + font-size: 0.9rem; +} + +.scope-card .collapsible-section summary { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.75rem; + background-color: #f7fafc; + cursor: pointer; + font-weight: normal; + overflow: hidden; +} + +.scope-card-title { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin: 0; + padding: 10px 0; +} + +.session-info { + text-align: left; + margin-top: 20px; + height: fit-content; +} + +.session-result { + margin: 0 0 20px 0; + padding: 1.5rem; + background-color: #f7fafc; + border-radius: 4px; + border: 1px solid #e2e8f0; + overflow-wrap: break-word; + word-wrap: break-word; + word-break: break-word; + max-height: 300px; + overflow-y: auto; +} + +.connection-list { + list-style: none; + padding: 0; + margin: 0; +} + +.connection-list li { + padding: 0.5rem; + background-color: #f5f5f5; + border: 1px solid #e2e8f0; + border-radius: 4px; + margin-bottom: 0.5rem; + font-family: monospace; +} + +.connection-list li:last-child { + margin-bottom: 0; +} + +.session-lifecycle-buttons { + display: flex; + gap: 1rem; + margin-top: 1rem; + flex-wrap: wrap; +} + +.notification-container { + margin-bottom: 2rem; + padding: 1rem; + background-color: white; + border-radius: 4px; + border: 1px solid #e2e8f0; + max-height: 300px; + overflow-y: auto; + text-align: left; +} + +.session-results-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1.5rem; + margin-top: 1.5rem; +} + +@media (max-width: 800px) { + .session-results-grid { + grid-template-columns: 1fr; + } +} + +.results-container { + position: static; + margin-bottom: 20px; +} + +.results-label { + display: none; +} + +.results-section { + margin-bottom: 20px; +} + +.results-section h3 { + margin-bottom: 10px; +} + +.session-result, +.notification-container { + margin-top: 0; +} + +.app-subtitle { + text-align: center; +} + +.session-layout { + display: flex; + gap: 20px; + margin-bottom: 20px; +} + +.session-column { + flex: 0 0 50%; +} + +.timestamp { + margin-right: 10px; + color: #666; +} + +.method-name { + margin-right: 10px; + font-weight: bold; +} + +.code-method { + font-family: 'Courier New'; + font-weight: bold; +} + +.scope-header { + display: flex; + justify-content: space-between; + align-items: center; +} + +.invoke-all-button { + margin-bottom: 1rem; +} + +.result-header { + margin-bottom: 0.5rem; +} + +.result-params { + font-size: 0.85rem; + color: #666; + font-family: monospace; + margin: 0.25rem 0; + word-break: break-all; + white-space: normal; +} + +.collapsible-section summary .result-params { + margin: 0.25rem 0; +} + +.result-item-small .result-params { + max-width: 100%; +} diff --git a/packages/playground-next/src/app/page.tsx b/packages/playground-next/src/app/page.tsx index 7e1b5d714..d50fd3ccb 100644 --- a/packages/playground-next/src/app/page.tsx +++ b/packages/playground-next/src/app/page.tsx @@ -1,43 +1,278 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ 'use client'; -import { useSDK } from '@metamask/sdk-react'; -import styles from './page.module.css'; +import { CAIP294EventNames, createMultichainAPI, discoverWallets, FEATURED_NETWORKS, injectParams, METHODS_REQUIRING_PARAM_INJECTION, openRPCExampleToJSON, SessionData, truncateJSON } from '@metamask/multichainapi'; +import { CaipAccountId, CaipChainId, Json, parseCaipAccountId } from '@metamask/utils'; +import { MethodObject, OpenrpcDocument } from '@open-rpc/meta-schema'; import { useCallback, useEffect, useState } from 'react'; +import DynamicInputs, { INPUT_LABEL_TYPE } from '../components/DynamicInputs'; +import WalletList, { WalletMapEntry } from '../components/WalletList'; +import { MetaMaskOpenRPCDocument } from '@metamask/api-specs'; +import { parseOpenRPCDocument } from '@open-rpc/schema-utils-js'; + +import styles from './page.module.css'; + +type NetworkId = keyof typeof FEATURED_NETWORKS; interface AccountInfo { account: string; balance: string; + chainId: NetworkId; + sessionId: string; +} + +interface SessionMethodResult { + timestamp: number; + method: string; + data: unknown; +} + +interface WalletHistoryEntry { + timestamp: number; + data: unknown; +} + +const defaultSessionsScopes: Record = { + 'eip155:1': '', + 'eip155:59144': '', + 'eip155:42161': '', + 'eip155:43114': '', + 'eip155:56': '', + 'eip155:10': '', + 'eip155:137': '', + 'eip155:324': '', + 'eip155:8453': '', + 'eip155:1337': '', +}; + +interface ConnectWalletParams { + extensionId: string; } export default function Home() { - const { sdk, connected, connecting, provider, account } = useSDK(); - const [accountInfo, setAccountInfo] = useState(null); + const [api, setApi] = useState | null>(null); + const [accountInfo, setAccountInfo] = useState([]); const [isLoading, setIsLoading] = useState(false); + const [extensionId, setExtensionId] = useState('nfdjnfhlblppdgdplngdjgpifllaamoc'); + const [selectedChains, setSelectedChains] = useState>({ + 'eip155:1': true, + 'eip155:59144': true, + 'eip155:42161': false, + 'eip155:43114': false, + 'eip155:56': false, + 'eip155:10': false, + 'eip155:137': false, + 'eip155:324': false, + 'eip155:8453': false, + 'eip155:1337': false, + }); + const [walletSessionChangedHistory, setWalletSessionChangedHistory] = + useState([]); + const [walletNotifyHistory, setWalletNotifyHistory] = useState([]); + const [invokeMethodRequests, setInvokeMethodRequests] = useState< + Record + >({}); + const [metamaskOpenrpcDocument, setMetamaskOpenrpcDocument] = + useState(); + const [sessionMethodHistory, setSessionMethodHistory] = useState([]); + const [selectedAccounts, setSelectedAccounts] = useState< + Record + >({}); + const [selectedMethods, setSelectedMethods] = useState< + Record + >({}); + const [invokeMethodResults, setInvokeMethodResults] = useState< + Record> + >({}); + const [sessionsScopes, setSessionsScopes] = useState>(defaultSessionsScopes); + const [addresses, setAddresses] = useState(['']); + const [walletMapEntries, setWalletMapEntries] = useState< + Record + >({}); + const [currentSession, setCurrentSession] = useState(null); - const getBalance = useCallback(async (address: string): Promise => { - const balance = await provider?.request({ - method: 'eth_getBalance', - params: [address, 'latest'] - }); - return balance ? parseInt(balance as string, 16).toString() : '0'; - }, [provider]); + // Add computed property for connection status + const isConnected = Boolean(currentSession?.sessionId); + + // Initialize API + useEffect(() => { + const multichain = createMultichainAPI(); + setApi(multichain); + }, []); + + useEffect(() => { + let mounted = true; + + const discoverAvailableWallets = async () => { + console.log('discoverAvailableWallets'); + + // Add debug listener to see if events are being fired + const debugListener = (e: Event) => { + console.log('Raw wallet event received:', e); + }; + window.addEventListener(CAIP294EventNames.Announce, debugListener); + + const wallets = await discoverWallets({ + timeout: 3000, // Increased timeout to ensure we don't miss announcements + filterPredicate: (wallet) => { + console.log('Filtering wallet:', wallet); + return true; + } + }); + + console.log('Discovered wallets:', wallets); + + if (mounted) { + const entries = wallets.reduce>((acc, wallet) => ({ + ...acc, + [wallet.providerId]: { + params: { + name: wallet.name, + uuid: wallet.providerId, + rdns: wallet.rdns, + icon: wallet.icon, + extensionId: wallet.providerId + } + } + }), {}); + setWalletMapEntries(entries); + } + + // Cleanup debug listener + window.removeEventListener(CAIP294EventNames.Announce, debugListener); + }; + + discoverAvailableWallets().catch(console.error); + + return () => { + mounted = false; + }; + }, []); + + useEffect(() => { + parseOpenRPCDocument(MetaMaskOpenRPCDocument as OpenrpcDocument) + .then((parsedOpenRPCDocument) => { + console.log('parsedOpenRPCDocument', parsedOpenRPCDocument); + setMetamaskOpenrpcDocument(parsedOpenRPCDocument); + }) + .catch(() => { + console.error('Error parsing metamask openrpc document'); + }); + }, []); + + const handleClearInvokeResults = () => { + setInvokeMethodResults({}); + }; + + const setInitialMethodsAndAccounts = useCallback((currentSession: SessionData) => { + const initialSelectedMethods: Record = {}; + const initialSelectedAccounts: Record = {}; + + Object.entries(currentSession.sessionScopes).forEach( + ([scope, details]: [string, any]) => { + if (details.accounts && details.accounts.length > 0) { + initialSelectedAccounts[scope] = details.accounts[0]; + } + initialSelectedMethods[scope] = 'eth_blockNumber'; + const example = metamaskOpenrpcDocument?.methods.find( + (method) => (method as MethodObject).name === 'eth_blockNumber', + ); + + const defaultRequest = { + method: 'wallet_invokeMethod', + params: { + scope, + request: openRPCExampleToJSON(example as MethodObject), + }, + }; + + setInvokeMethodRequests((prev) => ({ + ...prev, + [scope]: JSON.stringify(defaultRequest, null, 2), + })); + }, + ); + setSelectedMethods(initialSelectedMethods); + setSelectedAccounts(initialSelectedAccounts); + }, [metamaskOpenrpcDocument]); + + + const connectWallet = useCallback(async ({ extensionId }: ConnectWalletParams): Promise => { + if (!api) { + console.debug('[Wallet] Cannot connect - API not initialized'); + return; + } - const connectWallet = async (): Promise => { try { setIsLoading(true); - await sdk?.connect(); - } catch (err) { - console.error('Failed to connect wallet:', err); + console.debug('[Wallet] Attempting to connect to extension:', extensionId); + const connected = await api.connect({ extensionId }); + + if (!connected) { + console.debug('[Wallet] Connection failed - received false from api.connect'); + throw new Error('Failed to connect to extension'); + } + console.debug('[Wallet] Successfully connected to extension'); + + // Create sessions for all selected chains + const selectedChainIds = Object.entries(selectedChains) + .filter(([_, isSelected]) => isSelected) + .map(([chainId]) => chainId as NetworkId); + + console.debug('[Wallet] Creating sessions for chains:', selectedChainIds); + + const newSessions = { ...defaultSessionsScopes }; + const newAccountInfo: AccountInfo[] = []; + + for (const chainId of selectedChainIds) { + try { + const session = await api.createSession({ + optionalScopes: { + [chainId]: { + methods: ['eth_getBalance'], + accounts: [`${chainId}:0x0`] + } + } + }); + newSessions[chainId] = session.sessionId ?? ''; + setCurrentSession(session); + } catch (err) { + console.error(`Failed to create session for ${chainId}:`, err); + } + } + + setSessionsScopes(newSessions); + setAccountInfo(newAccountInfo); + } catch (error) { + console.error('[Wallet] Connection error:', error); + throw error; } finally { setIsLoading(false); + console.debug('[Wallet] Connection attempt completed'); } - }; + }, [api, selectedChains]); + + useEffect(() => { + if (currentSession?.sessionScopes) { + setInitialMethodsAndAccounts(currentSession); + } + }, [currentSession, setInitialMethodsAndAccounts]); + const terminateConnection = async (): Promise => { + if (!api) return; + try { setIsLoading(true); - await sdk?.terminate(); - setAccountInfo(null); + + // Revoke all sessions + await Promise.all( + Object.values(sessionsScopes).map((sessionId) => api.revokeSession(sessionId)) + ); + + setAccountInfo([]); + setSessionsScopes(defaultSessionsScopes); + setCurrentSession(null); // Clear the current session instead of setting isConnected } catch (err) { console.error('Failed to terminate connection:', err); } finally { @@ -45,51 +280,720 @@ export default function Home() { } }; - useEffect(() => { - const updateAccountInfo = async () => { - if (connected && account) { - const balance = await getBalance(account); - setAccountInfo({ - account, - balance - }); - } else { - setAccountInfo(null); + const handleWalletListClick = useCallback( + async (newExtensionId: string): Promise => { + console.debug('[Wallet] Wallet selection clicked:', newExtensionId); + setExtensionId(newExtensionId); + try { + await connectWallet({ extensionId: newExtensionId }); + console.debug('[Wallet] Connection successful for:', newExtensionId); + } catch (error) { + console.error('[Wallet] Error in handleWalletListClick:', error); } - }; + }, + [connectWallet], + ); - updateAccountInfo(); - }, [connected, account, provider, getBalance]); + const handleCreateSession = async () => { + const selectedChainsArray = Object.keys(selectedChains).filter( + (chain) => selectedChains[chain as NetworkId], + ) as NetworkId[]; + + try { + if (!api) return; + + const result = await api.createSession({ + optionalScopes: selectedChainsArray.reduce((acc, chainId) => ({ + ...acc, + [chainId]: { + methods: ['eth_getBalance'], + accounts: addresses + } + }), {}) + }); + + setSessionMethodHistory((prev) => [ + { timestamp: Date.now(), method: 'wallet_createSession', data: result }, + ...prev, + ]); + } catch (error) { + console.error('Error creating session:', error); + } + }; + + const handleGetSession = async () => { + try { + if (!api || !currentSession?.sessionId) return; + const result = await api.getSession({ sessionId: currentSession.sessionId }); + setSessionMethodHistory((prev) => [ + { timestamp: Date.now(), method: 'wallet_getSession', data: result }, + ...prev, + ]); + } catch (error) { + console.error('Error getting session:', error); + } + }; + + const handleRevokeSession = async () => { + if (!api || !currentSession?.sessionId) return; + + try { + const result = await api.revokeSession({ sessionId: currentSession.sessionId }); + setSessionMethodHistory((prev) => [ + { timestamp: Date.now(), method: 'wallet_revokeSession', data: result }, + ...prev, + ]); + } catch (error) { + console.error('Error revoking session:', error); + } + }; + + + const handleResetState = () => { + setSelectedMethods({}); + setInvokeMethodResults({}); + setWalletSessionChangedHistory([]); + setWalletNotifyHistory([]); + setSessionMethodHistory([]); + setSelectedChains({ + 'eip155:1': false, + 'eip155:59144': false, + 'eip155:42161': false, + 'eip155:43114': false, + 'eip155:56': false, + 'eip155:10': false, + 'eip155:137': false, + 'eip155:324': false, + 'eip155:8453': false, + 'eip155:1337': false, + }); + }; + + + const handleSessionChangedNotification = useCallback( + (notification: any) => { + setWalletSessionChangedHistory((prev) => { + const timestamp = Date.now(); + if (prev.some((entry) => entry.timestamp === timestamp)) { + return prev; + } + return [{ timestamp, data: notification }, ...prev]; + }); + + if (notification.params?.sessionScopes) { + setSelectedChains(notification.params.sessionScopes); + setInitialMethodsAndAccounts(notification.params.sessionScopes); + } + }, + [ + setWalletSessionChangedHistory, + setSelectedChains, + setInitialMethodsAndAccounts, + ], + ); + + + const handleInvokeAllMethods = async () => { + const scopesWithMethods = Object.entries(selectedMethods) + .filter(([_, method]) => method) + .map(([scope, method]) => ({ scope, method })); + + await Promise.all( + scopesWithMethods.map(async ({ scope, method }) => { + const scopeToInvoke = scope as keyof typeof selectedChains; + return handleInvokeMethod(scopeToInvoke, method); + }), + ); + }; + + const handleMethodSelect = ( + evt: React.ChangeEvent, + scope: CaipChainId, + ) => { + const selectedMethod = evt.target.value; + setSelectedMethods((prev) => ({ + ...prev, + [scope]: selectedMethod, + })); + + const example = metamaskOpenrpcDocument?.methods.find( + (method) => (method as MethodObject).name === selectedMethod, + ); + + if (example) { + let exampleParams: Json = openRPCExampleToJSON(example as MethodObject); + const selectedAddress = selectedAccounts[scope]; + + if ( + selectedAddress && + selectedMethod in METHODS_REQUIRING_PARAM_INJECTION + ) { + exampleParams = injectParams( + selectedMethod, + exampleParams, + selectedAddress, + scope, + ); + } + + const defaultRequest = { + method: 'wallet_invokeMethod', + params: { + scope, + request: exampleParams, + }, + }; + + setInvokeMethodRequests((prev) => ({ + ...prev, + [scope]: JSON.stringify(defaultRequest, null, 2), + })); + } + }; + + + const handleInvokeMethod = async (scope: CaipChainId, method: string) => { + const requestObject = JSON.parse(invokeMethodRequests[scope] ?? '{}'); + try { + if (!api) return; + const { params } = requestObject.params.request; + const result = await api.invokeMethod({ + scope, + request: { + method, + params, + } + }); + + setInvokeMethodResults((prev) => { + const scopeResults = prev[scope] ?? {}; + const methodResults = scopeResults[method] ?? []; + return { + ...prev, + [scope]: { + ...scopeResults, + [method]: [ + ...methodResults, + { result, request: requestObject.params.request }, + ], + }, + }; + }); + } catch (error) { + setInvokeMethodResults((prev) => { + const scopeResults = prev[scope] ?? {}; + const methodResults = scopeResults[method] ?? []; + return { + ...prev, + [scope]: { + ...scopeResults, + [method]: [ + ...methodResults, + { result: error, request: requestObject.params.request }, + ], + }, + }; + }); + console.error('Error invoking method:', error); + } + }; return (
-

Simple Web3 Dapp

- - {!connected ? ( - - ) : ( +

MetaMask MultiChain API Test Dapp

+ +
+ setExtensionId(e.target.value)} + disabled={isConnected} + /> +
+ +
+
+

Detected Wallets

+
+
+ +
+
+ +
+
+

Session Lifecycle

+
+
+
+

Create Session

+ {Object.entries(FEATURED_NETWORKS).map( + ([chainId, networkName]) => ( + + ), + )} +
+ selectedChains[chain as NetworkId])} + setInputArray={(newArray) => { + // Convert array back to record + const newSelectedChains = { ...selectedChains }; + Object.keys(selectedChains).forEach(chain => { + newSelectedChains[chain as NetworkId] = Array.isArray(newArray) ? newArray.includes(chain) : false; + }); + setSelectedChains(newSelectedChains); + }} + label={INPUT_LABEL_TYPE.SCOPE} + /> +
+
+ +
+
+ + + +
+
+ + {currentSession && ( +
+

Connected Accounts

+
    + {currentSession?.sessionScopes && Object.values(currentSession.sessionScopes) + .flatMap((scope) => scope.accounts ?? []) + .map( + (account) => + parseCaipAccountId(account).address, + ) + .filter((address: string) => address !== '') + .filter( + (address: string, index: number, array: string[]) => + array.indexOf(address) === index, + ) + .map((address: string) => ( +
  • {address}
  • + )) ||
  • No accounts connected
  • } +
+ +

Connected Chains

+
    + {Object.keys(currentSession?.sessionScopes ?? {}).map( + (chain: string) =>
  • {chain}
  • , + ) ??
  • No chains connected
  • } +
+
+ )} +
+ +
+ {/* Session Results */} +
+

Session Lifecycle method results

+
+ {sessionMethodHistory.length > 0 ? ( + sessionMethodHistory.map( + ({ timestamp, method, data }, index) => ( +
+ + + {new Date(timestamp).toLocaleString()} + + {method} + {truncateJSON(data).text} + + +
+                              {JSON.stringify(data, null, 2)}
+                            
+
+
+ ), + ) + ) : ( +

No session method calls

+ )} +
+
+ + {/* Session Changes */} +
+

+ wallet_sessionChanged{' '} +

+
+ {walletSessionChangedHistory.length > 0 ? ( + walletSessionChangedHistory.map( + ({ timestamp, data }, index) => ( +
+ + + {new Date(timestamp).toLocaleString()} + + {truncateJSON(data).text} + + +
+                              {JSON.stringify(data, null, 2)}
+                            
+
+
+ ), + ) + ) : ( +

No session changes detected

+ )} +
+
+
+
+
+
+
+ + {isConnected && ( <> -
- Address: {accountInfo?.account} +
+

Select Networks

+ {(Object.entries(FEATURED_NETWORKS) as [NetworkId, string][]).map(([chainId, networkName]) => ( + + ))}
-
- Balance: {accountInfo?.balance} Wei +
+ {accountInfo.map((info) => ( +
+

{FEATURED_NETWORKS[info.chainId]}

+
+ Address: {info.account} +
+
+ Balance: {info.balance} Wei +
+
+ ))}
+ + +
+

Session Method History

+ {sessionMethodHistory.map((entry) => ( +
+ + {new Date(entry.timestamp).toLocaleString()} - {entry.method} + +
{JSON.stringify(entry.data, null, 2)}
+
+ ))} +
)} + {currentSession?.sessionScopes && isConnected && ( +
+
+
+

Connected Scopes

+ +
+ +
+ {Object.entries(currentSession.sessionScopes).map( + ([scope, details]: [string, any]) => ( +
+

+ {FEATURED_NETWORKS[ + scope as keyof typeof FEATURED_NETWORKS + ] + ? `${ + FEATURED_NETWORKS[ + scope as keyof typeof FEATURED_NETWORKS + ] + } (${scope})` + : scope} +

+ + + + + +
+ Invoke Method Request +
+