From f795b9fd5b45099e57803d318015e7397ed5b345 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 Jul 2024 17:21:35 -0500 Subject: [PATCH 01/11] Bump the npm_and_yarn group across 1 directory with 11 updates (#557) Bumps the npm_and_yarn group with 11 updates in the / directory: | Package | From | To | | --- | --- | --- | | [express](https://github.com/expressjs/express) | `4.18.2` | `4.19.2` | | [debug](https://github.com/debug-js/debug) | `4.3.4` | `4.3.5` | | [zod](https://github.com/colinhacks/zod) | `3.22.4` | `3.23.8` | | [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) | `7.21.4` | `7.23.2` | | [braces](https://github.com/micromatch/braces) | `3.0.2` | `3.0.3` | | [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) | `4.2.2` | `4.4.0` | | [follow-redirects](https://github.com/follow-redirects/follow-redirects) | `1.15.3` | `1.15.6` | | [jose](https://github.com/panva/jose) | `4.15.4` | `4.15.9` | | [postcss](https://github.com/postcss/postcss) | `8.4.23` | `8.4.31` | | [semver](https://github.com/npm/node-semver) | `5.7.1` | `5.7.2` | | [ws](https://github.com/websockets/ws) | `6.2.2` | `6.2.3` | Updates `express` from 4.18.2 to 4.19.2 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2) Updates `debug` from 4.3.4 to 4.3.5 - [Release notes](https://github.com/debug-js/debug/releases) - [Commits](https://github.com/debug-js/debug/compare/4.3.4...4.3.5) Updates `zod` from 3.22.4 to 3.23.8 - [Release notes](https://github.com/colinhacks/zod/releases) - [Changelog](https://github.com/colinhacks/zod/blob/main/CHANGELOG.md) - [Commits](https://github.com/colinhacks/zod/compare/v3.22.4...v3.23.8) Updates `@babel/traverse` from 7.21.4 to 7.23.2 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse) Updates `braces` from 3.0.2 to 3.0.3 - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) Updates `fast-xml-parser` from 4.2.2 to 4.4.0 - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/4.2.2...v4.4.0) Updates `follow-redirects` from 1.15.3 to 1.15.6 - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.3...v1.15.6) Updates `jose` from 4.15.4 to 4.15.9 - [Release notes](https://github.com/panva/jose/releases) - [Changelog](https://github.com/panva/jose/blob/v4.15.9/CHANGELOG.md) - [Commits](https://github.com/panva/jose/compare/v4.15.4...v4.15.9) Updates `postcss` from 8.4.23 to 8.4.31 - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.4.23...8.4.31) Updates `semver` from 5.7.1 to 5.7.2 - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2) Updates `ws` from 6.2.2 to 6.2.3 - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/6.2.2...6.2.3) --- updated-dependencies: - dependency-name: express dependency-type: direct:production dependency-group: npm_and_yarn - dependency-name: debug dependency-type: direct:production dependency-group: npm_and_yarn - dependency-name: zod dependency-type: direct:production dependency-group: npm_and_yarn - dependency-name: "@babel/traverse" dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: braces dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: fast-xml-parser dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: follow-redirects dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: jose dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: postcss dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: semver dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: ws dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- apps/distributor/package.json | 4 +- apps/next/package.json | 2 +- packages/api/package.json | 4 +- packages/app/package.json | 4 +- packages/contracts/package.json | 2 +- packages/playwright/package.json | 2 +- packages/ui/package.json | 2 +- packages/wagmi/package.json | 2 +- packages/webauthn-authenticator/package.json | 2 +- yarn.lock | 364 +++++++------------ 10 files changed, 138 insertions(+), 250 deletions(-) diff --git a/apps/distributor/package.json b/apps/distributor/package.json index 6cce24853..40f447539 100644 --- a/apps/distributor/package.json +++ b/apps/distributor/package.json @@ -24,7 +24,7 @@ "@supabase/supabase-js": "2.44.2", "@wagmi/core": "^2.10.5", "app": "workspace:*", - "express": "^4.18.2", + "express": "^4.19.2", "pino": "^8.16.1", "viem": "^2.13.7" }, @@ -32,7 +32,7 @@ "@types/bun": "latest", "@types/express": "^4", "@types/supertest": "^2.0.16", - "debug": "^4.3.4", + "debug": "^4.3.5", "dotenv-cli": "^7.3.0", "supertest": "^6.3.3", "typescript": "^5.5.3" diff --git a/apps/next/package.json b/apps/next/package.json index fe680dbd3..65c27f771 100644 --- a/apps/next/package.json +++ b/apps/next/package.json @@ -40,7 +40,7 @@ "react-native-web": "~0.19.10", "sharp": "0.32.6", "vercel": "^33.5.2", - "zod": "^3.22.4" + "zod": "^3.23.8" }, "devDependencies": { "@next/bundle-analyzer": "^13.4.19", diff --git a/packages/api/package.json b/packages/api/package.json index a51863290..2338ecf64 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -14,10 +14,10 @@ "@trpc/server": "11.0.0-next-beta.264", "@wagmi/core": "^2.10.5", "app": "workspace:*", - "debug": "^4.3.4", + "debug": "^4.3.5", "p-queue": "^8.0.1", "superjson": "^1.13.1", "viem": "^2.13.7", - "zod": "^3.22.4" + "zod": "^3.23.8" } } diff --git a/packages/app/package.json b/packages/app/package.json index 24d412e3c..30c4098f2 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -62,7 +62,7 @@ "superjson": "^1.13.1", "viem": "^2.13.7", "wagmi": "^2.9.10", - "zod": "^3.22.4" + "zod": "^3.23.8" }, "devDependencies": { "@babel/plugin-syntax-import-attributes": "^7.24.7", @@ -72,7 +72,7 @@ "@types/jsonwebtoken": "^9.0.2", "@types/react": "^18.2.15", "babel-preset-expo": "~11.0.0", - "debug": "^4.3.4", + "debug": "^4.3.5", "eslint": "^8.46.0", "eslint-config-custom": "workspace:*", "eslint-plugin-testing-library": "^6.2.2", diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 13e503499..db30751d3 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -32,7 +32,7 @@ "@supabase/supabase-js": "2.44.2", "@types/bun": "latest", "@uniswap/v3-periphery": "^1.4.4", - "debug": "^4.3.4", + "debug": "^4.3.5", "solhint": "^3.6.2", "zx": "^8.1.2" } diff --git a/packages/playwright/package.json b/packages/playwright/package.json index b6004d6e6..945c47a11 100644 --- a/packages/playwright/package.json +++ b/packages/playwright/package.json @@ -14,7 +14,7 @@ "@wagmi/core": "^2.10.5", "app": "workspace:*", "cbor": "^9.0.1", - "debug": "^4.3.4", + "debug": "^4.3.5", "dotenv-cli": "^7.3.0", "extract-zip": "^2.0.1", "jsonwebtoken": "^9.0.2", diff --git a/packages/ui/package.json b/packages/ui/package.json index e983f63ae..54a3f9833 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -38,7 +38,7 @@ "react-hook-form": "^7.48.2", "solito": "^4.0.1", "tamagui": "^1.101.7", - "zod": "^3.22.4" + "zod": "^3.23.8" }, "devDependencies": { "@tamagui/build": "^1.101.7", diff --git a/packages/wagmi/package.json b/packages/wagmi/package.json index 1ab86d70b..2189b22bb 100644 --- a/packages/wagmi/package.json +++ b/packages/wagmi/package.json @@ -12,7 +12,7 @@ }, "devDependencies": { "@wagmi/cli": "^2.1.8", - "debug": "^4.3.4", + "debug": "^4.3.5", "globby": "^14.0.0", "typescript": "^5.5.3" }, diff --git a/packages/webauthn-authenticator/package.json b/packages/webauthn-authenticator/package.json index 0ace61e84..07d2cb95e 100644 --- a/packages/webauthn-authenticator/package.json +++ b/packages/webauthn-authenticator/package.json @@ -17,7 +17,7 @@ "dependencies": { "@scure/base": "^1.1.5", "cbor": "^9.0.1", - "debug": "^4.3.4" + "debug": "^4.3.5" }, "devDependencies": { "@rollup/plugin-commonjs": "^25.0.7", diff --git a/yarn.lock b/yarn.lock index 9fa7a6f23..ba84f33a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -40,7 +40,7 @@ __metadata: "@types/debug": "npm:^4" "@vitest/coverage-v8": "npm:^0.34.6" cbor: "npm:^9.0.1" - debug: "npm:^4.3.4" + debug: "npm:^4.3.5" rollup: "npm:^4.6.1" rollup-plugin-polyfill-node: "npm:^0.13.0" typescript: "npm:^5.5.3" @@ -125,7 +125,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.18.6, @babel/code-frame@npm:^7.21.4": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.18.6": version: 7.21.4 resolution: "@babel/code-frame@npm:7.21.4" dependencies: @@ -134,16 +134,6 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.23.4": - version: 7.23.4 - resolution: "@babel/code-frame@npm:7.23.4" - dependencies: - "@babel/highlight": "npm:^7.23.4" - chalk: "npm:^2.4.2" - checksum: 5a210e42b0c3138f3870e452c7b6d06ddcfc43cba824231ef3023fffd1cb0613d00ea07c7d87d0718e14e830f891b86de56aac5cd034d41128383919c84ff4f6 - languageName: node - linkType: hard - "@babel/code-frame@npm:^7.24.7": version: 7.24.7 resolution: "@babel/code-frame@npm:7.24.7" @@ -210,7 +200,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.20.0, @babel/generator@npm:^7.21.4": +"@babel/generator@npm:^7.20.0": version: 7.21.4 resolution: "@babel/generator@npm:7.21.4" dependencies: @@ -246,18 +236,6 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.23.4": - version: 7.23.4 - resolution: "@babel/generator@npm:7.23.4" - dependencies: - "@babel/types": "npm:^7.23.4" - "@jridgewell/gen-mapping": "npm:^0.3.2" - "@jridgewell/trace-mapping": "npm:^0.3.17" - jsesc: "npm:^2.5.1" - checksum: 7b45b64505bfb3ddbdeaae01288d2814e0e8d1299b3485983f4abc6563d6c10837979f00021308c78c33564d33e6d715e63aed64ac407ed8440b76f6eeb79019 - languageName: node - linkType: hard - "@babel/generator@npm:^7.24.7": version: 7.24.7 resolution: "@babel/generator@npm:7.24.7" @@ -1020,17 +998,6 @@ __metadata: languageName: node linkType: hard -"@babel/highlight@npm:^7.23.4": - version: 7.23.4 - resolution: "@babel/highlight@npm:7.23.4" - dependencies: - "@babel/helper-validator-identifier": "npm:^7.22.20" - chalk: "npm:^2.4.2" - js-tokens: "npm:^4.0.0" - checksum: 62fef9b5bcea7131df4626d009029b1ae85332042f4648a4ce6e740c3fd23112603c740c45575caec62f260c96b11054d3be5987f4981a5479793579c3aac71f - languageName: node - linkType: hard - "@babel/highlight@npm:^7.24.7": version: 7.24.7 resolution: "@babel/highlight@npm:7.24.7" @@ -1052,7 +1019,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.23.4": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7": version: 7.23.4 resolution: "@babel/parser@npm:7.23.4" bin: @@ -1061,7 +1028,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.6, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.20.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.4": +"@babel/parser@npm:^7.1.6, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.20.0, @babel/parser@npm:^7.20.7": version: 7.21.4 resolution: "@babel/parser@npm:7.21.4" bin: @@ -2712,43 +2679,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.20.0, @babel/traverse@npm:^7.20.5, @babel/traverse@npm:^7.20.7, @babel/traverse@npm:^7.21.2": - version: 7.21.4 - resolution: "@babel/traverse@npm:7.21.4" - dependencies: - "@babel/code-frame": "npm:^7.21.4" - "@babel/generator": "npm:^7.21.4" - "@babel/helper-environment-visitor": "npm:^7.18.9" - "@babel/helper-function-name": "npm:^7.21.0" - "@babel/helper-hoist-variables": "npm:^7.18.6" - "@babel/helper-split-export-declaration": "npm:^7.18.6" - "@babel/parser": "npm:^7.21.4" - "@babel/types": "npm:^7.21.4" - debug: "npm:^4.1.0" - globals: "npm:^11.1.0" - checksum: 22f3bf1d2acad9f7e85842361afff219f406408f680304be8f78348351a27f90fb66aef2afb03263d3f2b79d12462728e19de571ed19b646bdfb458c6ca5e25b - languageName: node - linkType: hard - -"@babel/traverse@npm:^7.23.3": - version: 7.23.4 - resolution: "@babel/traverse@npm:7.23.4" - dependencies: - "@babel/code-frame": "npm:^7.23.4" - "@babel/generator": "npm:^7.23.4" - "@babel/helper-environment-visitor": "npm:^7.22.20" - "@babel/helper-function-name": "npm:^7.23.0" - "@babel/helper-hoist-variables": "npm:^7.22.5" - "@babel/helper-split-export-declaration": "npm:^7.22.6" - "@babel/parser": "npm:^7.23.4" - "@babel/types": "npm:^7.23.4" - debug: "npm:^4.1.0" - globals: "npm:^11.1.0" - checksum: 0ff190a793d94c8ee3ff24bbe7d086c6401a84fa16f97d3c695c31aa42270916d937ae5994e315ba797e8f3728840e4d68866ad4d82a01132312d07ac45ca9d0 - languageName: node - linkType: hard - -"@babel/traverse@npm:^7.24.7": +"@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.20.0, @babel/traverse@npm:^7.20.5, @babel/traverse@npm:^7.20.7, @babel/traverse@npm:^7.21.2, @babel/traverse@npm:^7.23.3, @babel/traverse@npm:^7.24.7": version: 7.24.7 resolution: "@babel/traverse@npm:7.24.7" dependencies: @@ -6001,11 +5932,11 @@ __metadata: "@trpc/server": "npm:11.0.0-next-beta.264" "@wagmi/core": "npm:^2.10.5" app: "workspace:*" - debug: "npm:^4.3.4" + debug: "npm:^4.3.5" p-queue: "npm:^8.0.1" superjson: "npm:^1.13.1" viem: "npm:^2.13.7" - zod: "npm:^3.22.4" + zod: "npm:^3.23.8" languageName: unknown linkType: soft @@ -6018,7 +5949,7 @@ __metadata: "@supabase/supabase-js": "npm:2.44.2" "@types/bun": "npm:latest" "@uniswap/v3-periphery": "npm:^1.4.4" - debug: "npm:^4.3.4" + debug: "npm:^4.3.5" solhint: "npm:^3.6.2" zx: "npm:^8.1.2" languageName: unknown @@ -6041,7 +5972,7 @@ __metadata: "@wagmi/core": "npm:^2.10.5" app: "workspace:*" cbor: "npm:^9.0.1" - debug: "npm:^4.3.4" + debug: "npm:^4.3.5" dotenv-cli: "npm:^7.3.0" extract-zip: "npm:^2.0.1" jsonwebtoken: "npm:^9.0.2" @@ -6115,7 +6046,7 @@ __metadata: solito: "npm:^4.0.1" tamagui: "npm:^1.101.7" typescript: "npm:^5.5.3" - zod: "npm:^3.22.4" + zod: "npm:^3.23.8" languageName: unknown linkType: soft @@ -6127,7 +6058,7 @@ __metadata: "@wagmi/cli": "npm:^2.1.8" "@wagmi/core": "npm:^2.10.5" change-case: "npm:^5.4.2" - debug: "npm:^4.3.4" + debug: "npm:^4.3.5" globby: "npm:^14.0.0" permissionless: "npm:^0.1.14" typescript: "npm:^5.5.3" @@ -13725,7 +13656,7 @@ __metadata: base64-arraybuffer: "npm:^1.0.2" burnt: "npm:^0.12.1" cbor: "npm:^9.0.1" - debug: "npm:^4.3.4" + debug: "npm:^4.3.5" dnum: "npm:^2.9.0" eslint: "npm:^8.46.0" eslint-config-custom: "workspace:*" @@ -13753,7 +13684,7 @@ __metadata: typescript: "npm:^5.5.3" viem: "npm:^2.13.7" wagmi: "npm:^2.9.10" - zod: "npm:^3.22.4" + zod: "npm:^3.23.8" languageName: unknown linkType: soft @@ -14698,6 +14629,26 @@ __metadata: languageName: node linkType: hard +"body-parser@npm:1.20.2": + version: 1.20.2 + resolution: "body-parser@npm:1.20.2" + dependencies: + bytes: "npm:3.1.2" + content-type: "npm:~1.0.5" + debug: "npm:2.6.9" + depd: "npm:2.0.0" + destroy: "npm:1.2.0" + http-errors: "npm:2.0.0" + iconv-lite: "npm:0.4.24" + on-finished: "npm:2.4.1" + qs: "npm:6.11.0" + raw-body: "npm:2.5.2" + type-is: "npm:~1.6.18" + unpipe: "npm:1.0.0" + checksum: 3cf171b82190cf91495c262b073e425fc0d9e25cc2bf4540d43f7e7bbca27d6a9eae65ca367b6ef3993eea261159d9d2ab37ce444e8979323952e12eb3df319a + languageName: node + linkType: hard + "boolbase@npm:^1.0.0": version: 1.0.0 resolution: "boolbase@npm:1.0.0" @@ -14774,16 +14725,7 @@ __metadata: languageName: node linkType: hard -"braces@npm:^3.0.2, braces@npm:~3.0.2": - version: 3.0.2 - resolution: "braces@npm:3.0.2" - dependencies: - fill-range: "npm:^7.0.1" - checksum: 966b1fb48d193b9d155f810e5efd1790962f2c4e0829f8440b8ad236ba009222c501f70185ef732fef17a4c490bb33a03b90dab0631feafbdf447da91e8165b1 - languageName: node - linkType: hard - -"braces@npm:^3.0.3": +"braces@npm:^3.0.2, braces@npm:^3.0.3, braces@npm:~3.0.2": version: 3.0.3 resolution: "braces@npm:3.0.3" dependencies: @@ -16132,7 +16074,7 @@ __metadata: languageName: node linkType: hard -"content-type@npm:~1.0.4": +"content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 585847d98dc7fb8035c02ae2cb76c7a9bd7b25f84c447e5ed55c45c2175e83617c8813871b4ee22f368126af6b2b167df655829007b21aa10302873ea9c62662 @@ -16195,6 +16137,13 @@ __metadata: languageName: node linkType: hard +"cookie@npm:0.6.0": + version: 0.6.0 + resolution: "cookie@npm:0.6.0" + checksum: c1f8f2ea7d443b9331680598b0ae4e6af18a618c37606d1bbdc75bec8361cce09fe93e727059a673f2ba24467131a9fb5a4eec76bb1b149c1b3e1ccb268dc583 + languageName: node + linkType: hard + "cookie@npm:^0.4.1": version: 0.4.2 resolution: "cookie@npm:0.4.2" @@ -16636,7 +16585,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:^4": +"debug@npm:^4, debug@npm:^4.3.5": version: 4.3.5 resolution: "debug@npm:4.3.5" dependencies: @@ -17099,9 +17048,9 @@ __metadata: "@types/supertest": "npm:^2.0.16" "@wagmi/core": "npm:^2.10.5" app: "workspace:*" - debug: "npm:^4.3.4" + debug: "npm:^4.3.5" dotenv-cli: "npm:^7.3.0" - express: "npm:^4.18.2" + express: "npm:^4.19.2" pino: "npm:^8.16.1" supertest: "npm:^6.3.3" typescript: "npm:^5.5.3" @@ -19795,6 +19744,45 @@ __metadata: languageName: node linkType: hard +"express@npm:^4.19.2": + version: 4.19.2 + resolution: "express@npm:4.19.2" + dependencies: + accepts: "npm:~1.3.8" + array-flatten: "npm:1.1.1" + body-parser: "npm:1.20.2" + content-disposition: "npm:0.5.4" + content-type: "npm:~1.0.4" + cookie: "npm:0.6.0" + cookie-signature: "npm:1.0.6" + debug: "npm:2.6.9" + depd: "npm:2.0.0" + encodeurl: "npm:~1.0.2" + escape-html: "npm:~1.0.3" + etag: "npm:~1.8.1" + finalhandler: "npm:1.2.0" + fresh: "npm:0.5.2" + http-errors: "npm:2.0.0" + merge-descriptors: "npm:1.0.1" + methods: "npm:~1.1.2" + on-finished: "npm:2.4.1" + parseurl: "npm:~1.3.3" + path-to-regexp: "npm:0.1.7" + proxy-addr: "npm:~2.0.7" + qs: "npm:6.11.0" + range-parser: "npm:~1.2.1" + safe-buffer: "npm:5.2.1" + send: "npm:0.18.0" + serve-static: "npm:1.15.0" + setprototypeof: "npm:1.2.0" + statuses: "npm:2.0.1" + type-is: "npm:~1.6.18" + utils-merge: "npm:1.0.1" + vary: "npm:~1.1.2" + checksum: 3fcd792536f802c059789ef48db3851b87e78fba103423e524144d79af37da7952a2b8d4e1a007f423329c7377d686d9476ac42e7d9ea413b80345d495e30a3a + languageName: node + linkType: hard + "extension-port-stream@npm:^3.0.0": version: 3.0.0 resolution: "extension-port-stream@npm:3.0.0" @@ -19936,25 +19924,14 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:^4.0.12": - version: 4.2.2 - resolution: "fast-xml-parser@npm:4.2.2" - dependencies: - strnum: "npm:^1.0.5" - bin: - fxparser: src/cli/cli.js - checksum: a46345ac4b901ff38f3f852bf71137835b7abbac790b2f3db21b0ff2ccae61ccb7191f588fd0a56fd160e1cc44d77c239816a09dff2748a24ec3eeaa4ba3166b - languageName: node - linkType: hard - -"fast-xml-parser@npm:^4.2.4": - version: 4.3.6 - resolution: "fast-xml-parser@npm:4.3.6" +"fast-xml-parser@npm:^4.0.12, fast-xml-parser@npm:^4.2.4": + version: 4.4.0 + resolution: "fast-xml-parser@npm:4.4.0" dependencies: strnum: "npm:^1.0.5" bin: fxparser: src/cli/cli.js - checksum: 3e431e594960f04996e60a01fb51d8f4346138a7ba60d97244bf7866a3072eaf2f6dc73008d7b07871b98b606a8d7db955efdeae787992f685dd0e5bcc67c36a + checksum: f1592fa810d3923c46c7037d5adf1c309580d1d14780312019f33e4967f6ffcb5632168a5e889fe9d30794f6a087a0a095bb21cdf62320a96c6b304395212658 languageName: node linkType: hard @@ -20087,15 +20064,6 @@ __metadata: languageName: node linkType: hard -"fill-range@npm:^7.0.1": - version: 7.0.1 - resolution: "fill-range@npm:7.0.1" - dependencies: - to-regex-range: "npm:^5.0.1" - checksum: e260f7592fd196b4421504d3597cc76f4a1ca7a9488260d533b611fc3cefd61e9a9be1417cb82d3b01ad9f9c0ff2dbf258e1026d2445e26b0cf5148ff4250429 - languageName: node - linkType: hard - "fill-range@npm:^7.1.1": version: 7.1.1 resolution: "fill-range@npm:7.1.1" @@ -20323,12 +20291,12 @@ __metadata: linkType: hard "follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.9": - version: 1.15.3 - resolution: "follow-redirects@npm:1.15.3" + version: 1.15.6 + resolution: "follow-redirects@npm:1.15.6" peerDependenciesMeta: debug: optional: true - checksum: 60d98693f4976892f8c654b16ef6d1803887a951898857ab0cdc009570b1c06314ad499505b7a040ac5b98144939f8597766e5e6a6859c0945d157b473aa6f5f + checksum: 70c7612c4cab18e546e36b991bbf8009a1a41cf85354afe04b113d1117569abf760269409cb3eb842d9f7b03d62826687086b081c566ea7b1e6613cf29030bf7 languageName: node linkType: hard @@ -23402,9 +23370,9 @@ __metadata: linkType: hard "jose@npm:^4.14.4": - version: 4.15.4 - resolution: "jose@npm:4.15.4" - checksum: 20fa941597150dffc7af3f41d994500cc3e71cd650b755243dbd80d91cf26c1053f95b78af588f05cfc4371e492a67c5c7a48f689b8605145a8fe28b484d725b + version: 4.15.9 + resolution: "jose@npm:4.15.9" + checksum: 256234b6f85cdc080b1331f2d475bd58c8ccf459cb20f70ac5e4200b271bce10002b1c2f8e5b96dd975d83065ae5a586d52cdf89d28471d56de5d297992f9905 languageName: node linkType: hard @@ -25718,7 +25686,7 @@ __metadata: react-native-web: "npm:~0.19.10" sharp: "npm:0.32.6" vercel: "npm:^33.5.2" - zod: "npm:^3.22.4" + zod: "npm:^3.23.8" languageName: unknown linkType: soft @@ -27664,7 +27632,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:8.4.31, postcss@npm:^8.4.31": +"postcss@npm:8.4.31": version: 8.4.31 resolution: "postcss@npm:8.4.31" dependencies: @@ -27675,18 +27643,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.21": - version: 8.4.23 - resolution: "postcss@npm:8.4.23" - dependencies: - nanoid: "npm:^3.3.6" - picocolors: "npm:^1.0.0" - source-map-js: "npm:^1.0.2" - checksum: 4171086e54a90b5d9e7e043b3ea4acf5dce808f3501ebf7bf10caaff73f69a5c8d0dff7036752a648beb6317777d144af5b5b8b3ef9a84428630308735df07c2 - languageName: node - linkType: hard - -"postcss@npm:^8.4.38": +"postcss@npm:^8.4.21, postcss@npm:^8.4.31, postcss@npm:^8.4.38, postcss@npm:~8.4.32": version: 8.4.39 resolution: "postcss@npm:8.4.39" dependencies: @@ -27697,17 +27654,6 @@ __metadata: languageName: node linkType: hard -"postcss@npm:~8.4.32": - version: 8.4.38 - resolution: "postcss@npm:8.4.38" - dependencies: - nanoid: "npm:^3.3.7" - picocolors: "npm:^1.0.0" - source-map-js: "npm:^1.2.0" - checksum: 6e44a7ed835ffa9a2b096e8d3e5dfc6bcf331a25c48aeb862dd54e3aaecadf814fa22be224fd308f87d08adf2299164f88c5fd5ab1c4ef6cbd693ceb295377f4 - languageName: node - linkType: hard - "postgres-array@npm:3.0.2, postgres-array@npm:~3.0.1": version: 3.0.2 resolution: "postgres-array@npm:3.0.2" @@ -28481,6 +28427,18 @@ __metadata: languageName: node linkType: hard +"raw-body@npm:2.5.2": + version: 2.5.2 + resolution: "raw-body@npm:2.5.2" + dependencies: + bytes: "npm:3.1.2" + http-errors: "npm:2.0.0" + iconv-lite: "npm:0.4.24" + unpipe: "npm:1.0.0" + checksum: 863b5171e140546a4d99f349b720abac4410338e23df5e409cfcc3752538c9caf947ce382c89129ba976f71894bd38b5806c774edac35ebf168d02aa1ac11a95 + languageName: node + linkType: hard + "rc@npm:1.2.8, rc@npm:^1.2.7, rc@npm:^1.2.8, rc@npm:~1.2.7": version: 1.2.8 resolution: "rc@npm:1.2.8" @@ -29981,7 +29939,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.3.0": +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.3.0, semver@npm:^5.5.0, semver@npm:^5.6.0": version: 5.7.2 resolution: "semver@npm:5.7.2" bin: @@ -29990,7 +29948,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:6.3.1, semver@npm:^6.1.0, semver@npm:^6.3.1": +"semver@npm:6.3.1, semver@npm:^6.0.0, semver@npm:^6.1.0, semver@npm:^6.1.1, semver@npm:^6.1.2, semver@npm:^6.2.0, semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" bin: @@ -30041,36 +29999,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.x, 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" - dependencies: - lru-cache: "npm:^6.0.0" - bin: - semver: bin/semver.js - checksum: 985dec0d372370229a262c737063860fabd4a1c730662c1ea3200a2f649117761a42184c96df62a0e885e76fbd5dace41087d6c1ac0351b13c0df5d6bcb1b5ac - languageName: node - linkType: hard - -"semver@npm:^5.5.0, semver@npm:^5.6.0": - version: 5.7.1 - resolution: "semver@npm:5.7.1" - bin: - semver: ./bin/semver - checksum: fbc71cf00736480ca0dd67f2527cda6e0fde5447af00bd2ce06cb522d510216603a63ed0c6c87d8904507c1a4e8113e628a71424ebd9e0fd7d345ee8ed249690 - languageName: node - linkType: hard - -"semver@npm:^6.0.0, semver@npm:^6.1.1, semver@npm:^6.1.2, semver@npm:^6.2.0, semver@npm:^6.3.0": - version: 6.3.0 - resolution: "semver@npm:6.3.0" - bin: - semver: ./bin/semver.js - checksum: 8dd72e7c7cdbd8cff66b5530eeff9eec2342b127eef2c956259cdf66b85addf4829e6e4a045ca30d974d075595b0b03faa6318a597307eb3984649516b98b501 - languageName: node - linkType: hard - -"semver@npm:^7.3.4": +"semver@npm:7.x, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.1, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4": version: 7.6.2 resolution: "semver@npm:7.6.2" bin: @@ -30079,39 +30008,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.5, semver@npm:^7.3.7": - version: 7.5.0 - resolution: "semver@npm:7.5.0" - dependencies: - lru-cache: "npm:^6.0.0" - bin: - semver: bin/semver.js - checksum: 5aaa7675f8439b845db0a383f1420217a206fa084f2bc4ebc4bb31c0a50b02e9c922be3da274214ba7d9870d77f63085ac163f84f6ac910346675e9ac8681bf8 - languageName: node - linkType: hard - -"semver@npm:^7.3.8": - version: 7.5.1 - resolution: "semver@npm:7.5.1" - dependencies: - lru-cache: "npm:^6.0.0" - bin: - semver: bin/semver.js - checksum: 01fcb5ff66fb8cb9ff54e898ac9786fbafec65f93d0df910ea9300451719b204b1c5e8007c99c1abb410eb60f84497a1f8c02b1a0e97880842b7f6075e1d82b6 - languageName: node - linkType: hard - -"semver@npm:^7.5.1": - version: 7.6.0 - resolution: "semver@npm:7.6.0" - dependencies: - lru-cache: "npm:^6.0.0" - bin: - semver: bin/semver.js - checksum: 1b41018df2d8aca5a1db4729985e8e20428c650daea60fcd16e926e9383217d00f574fab92d79612771884a98d2ee2a1973f49d630829a8d54d6570defe62535 - languageName: node - linkType: hard - "send@npm:0.18.0, send@npm:^0.18.0": version: 0.18.0 resolution: "send@npm:0.18.0" @@ -34468,7 +34364,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.13.0, ws@npm:^8.12.1": +"ws@npm:8.13.0": version: 8.13.0 resolution: "ws@npm:8.13.0" peerDependencies: @@ -34484,11 +34380,11 @@ __metadata: linkType: hard "ws@npm:^6.2.2": - version: 6.2.2 - resolution: "ws@npm:6.2.2" + version: 6.2.3 + resolution: "ws@npm:6.2.3" dependencies: async-limiter: "npm:~1.0.0" - checksum: bb791ac02ad7e59fd4208cc6dd3a5bf7a67dff4611a128ed33365996f9fc24fa0d699043559f1798b4bc8045639fd21a1fd3ceca81de560124444abd8e321afc + checksum: 19f8d1608317f4c98f63da6eebaa85260a6fe1ba459cbfedd83ebe436368177fb1e2944761e2392c6b7321cbb7a375c8a81f9e1be35d555b6b4647eb61eadd46 languageName: node linkType: hard @@ -34507,22 +34403,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.11.0": - version: 8.14.2 - resolution: "ws@npm:8.14.2" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 815ff01d9bc20a249b2228825d9739268a03a4408c2e0b14d49b0e2ae89d7f10847e813b587ba26992bdc33e9d03bed131e4cae73ff996baf789d53e99c31186 - languageName: node - linkType: hard - -"ws@npm:^8.14.2": +"ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.14.2": version: 8.16.0 resolution: "ws@npm:8.16.0" peerDependencies: @@ -34813,13 +34694,20 @@ __metadata: languageName: node linkType: hard -"zod@npm:3.22.4, zod@npm:^3.22.2, zod@npm:^3.22.4": +"zod@npm:3.22.4, zod@npm:^3.22.2": version: 3.22.4 resolution: "zod@npm:3.22.4" checksum: 73622ca36a916f785cf528fe612a884b3e0f183dbe6b33365a7d0fc92abdbedf7804c5e2bd8df0a278e1472106d46674281397a3dd800fa9031dc3429758c6ac languageName: node linkType: hard +"zod@npm:^3.23.8": + version: 3.23.8 + resolution: "zod@npm:3.23.8" + checksum: 846fd73e1af0def79c19d510ea9e4a795544a67d5b34b7e1c4d0425bf6bfd1c719446d94cdfa1721c1987d891321d61f779e8236fde517dc0e524aa851a6eff1 + languageName: node + linkType: hard + "zustand@npm:4.4.1, zustand@npm:^4.3.8": version: 4.4.1 resolution: "zustand@npm:4.4.1" From f1a8492d8c03fbeae5887661dd58939f1d4bd384 Mon Sep 17 00:00:00 2001 From: youngkidwarrior Date: Fri, 28 Jun 2024 02:53:00 -0700 Subject: [PATCH 02/11] Use query params for search state --- packages/app/components/SearchBar.tsx | 42 ++- .../__snapshots__/screen.test.tsx.snap | 112 +------- .../app/features/activity/screen.test.tsx | 4 + .../send/__snapshots__/screen.test.tsx.snap | 263 ++---------------- packages/app/features/send/screen.test.tsx | 17 +- packages/app/routers/params.tsx | 10 +- 6 files changed, 68 insertions(+), 380 deletions(-) diff --git a/packages/app/components/SearchBar.tsx b/packages/app/components/SearchBar.tsx index 28e0308eb..67afde381 100644 --- a/packages/app/components/SearchBar.tsx +++ b/packages/app/components/SearchBar.tsx @@ -17,10 +17,10 @@ import { SearchSchema, useTagSearch } from 'app/provider/tag-search' import { FormProvider } from 'react-hook-form' import { SchemaForm } from 'app/utils/SchemaForm' import { useThemeSetting } from '@tamagui/next-theme' -import { IconX } from 'app/components/icons' -import { useState } from 'react' +import { useEffect, useState } from 'react' import type { Functions } from '@my/supabase/database.types' import { useSearchResultHref } from 'app/utils/useSearchResultHref' +import { useRootScreenParams } from 'app/routers/params' type SearchResultsType = Functions<'tag_search'>[number] type SearchResultsKeysType = keyof SearchResultsType @@ -249,6 +249,21 @@ function SearchResultRow({ function Search() { const { form } = useTagSearch() + const [queryParams, setRootParams] = useRootScreenParams() + const { search } = queryParams + + useEffect(() => { + const subscription = form.watch(({ query }) => { + setRootParams( + { + ...queryParams, + search: query, + }, + { webBehavior: 'replace' } + ) + }) + return () => subscription.unsubscribe() + }, [form, setRootParams, queryParams]) return ( <> @@ -259,7 +274,7 @@ function Search() { { // noop }} @@ -283,27 +298,6 @@ function Search() { {({ query }) => query} - ) diff --git a/packages/app/features/activity/__snapshots__/screen.test.tsx.snap b/packages/app/features/activity/__snapshots__/screen.test.tsx.snap index 640f3fab5..60d4a47be 100644 --- a/packages/app/features/activity/__snapshots__/screen.test.tsx.snap +++ b/packages/app/features/activity/__snapshots__/screen.test.tsx.snap @@ -196,6 +196,9 @@ exports[`ActivityScreen renders activity screen: ActivityScreen 1`] = ` { "next": [Function], }, + { + "next": [Function], + }, ], "subscribe": [Function], "unsubscribe": [Function], @@ -265,115 +268,6 @@ exports[`ActivityScreen renders activity screen: ActivityScreen 1`] = ` /> - - - - - - - ({ usePathname: jest.fn(), })) +jest.mock('app/routers/params', () => ({ + useRootScreenParams: jest.fn().mockReturnValue([{ search: '' }, jest.fn()]), +})) + jest.mock('app/utils/supabase/useSupabase', () => ({ useSupabase: jest.fn().mockReturnValue({ rpc: jest.fn().mockReturnValue({ diff --git a/packages/app/features/send/__snapshots__/screen.test.tsx.snap b/packages/app/features/send/__snapshots__/screen.test.tsx.snap index 05f6fa966..3f1412c60 100644 --- a/packages/app/features/send/__snapshots__/screen.test.tsx.snap +++ b/packages/app/features/send/__snapshots__/screen.test.tsx.snap @@ -38,7 +38,7 @@ exports[`SendScreen should render /send check when no send account: render 1`] = cancelable={true} disabled={false} focusable={true} - id=":r3:" + id=":r4:" minPressDuration={0} onBlur={[Function]} onFocus={[Function]} @@ -556,7 +556,7 @@ exports[`SendScreen should render with search when on /send and no recipient in control={ { "_defaultValues": { - "query": "", + "query": "test", }, "_disableForm": [Function], "_executeSchema": [Function], @@ -568,7 +568,7 @@ exports[`SendScreen should render with search when on /send and no recipient in "ref": { "name": "query", }, - "value": "", + "value": "test", }, }, }, @@ -587,7 +587,7 @@ exports[`SendScreen should render with search when on /send and no recipient in "touchedFields": {}, }, "_formValues": { - "query": "", + "query": "test", }, "_getDirty": [Function], "_getFieldArray": [Function], @@ -653,6 +653,9 @@ exports[`SendScreen should render with search when on /send and no recipient in { "next": [Function], }, + { + "next": [Function], + }, ], "subscribe": [Function], "unsubscribe": [Function], @@ -698,8 +701,8 @@ exports[`SendScreen should render with search when on /send and no recipient in "color": "#FFFFFF", "fontFamily": "System", "fontSize": 19.2, - "fontStyle": "italic", - "fontWeight": "normal", + "fontStyle": "normal", + "fontWeight": "bold", "height": 44, "minWidth": 0, "paddingLeft": 16, @@ -707,7 +710,7 @@ exports[`SendScreen should render with search when on /send and no recipient in "position": "relative", } } - value="" + value="test" /> - - - - - - - @@ -935,7 +829,7 @@ exports[`SendScreen should render with search when on /send and no recipient in control={ { "_defaultValues": { - "query": "", + "query": "test", }, "_disableForm": [Function], "_executeSchema": [Function], @@ -947,7 +841,7 @@ exports[`SendScreen should render with search when on /send and no recipient in "ref": { "name": "query", }, - "value": "test", + "value": "testtest", }, }, }, @@ -971,7 +865,7 @@ exports[`SendScreen should render with search when on /send and no recipient in }, }, "_formValues": { - "query": "test", + "query": "testtest", }, "_getDirty": [Function], "_getFieldArray": [Function], @@ -1037,6 +931,9 @@ exports[`SendScreen should render with search when on /send and no recipient in { "next": [Function], }, + { + "next": [Function], + }, ], "subscribe": [Function], "unsubscribe": [Function], @@ -1091,7 +988,7 @@ exports[`SendScreen should render with search when on /send and no recipient in "position": "relative", } } - value="test" + value="testtest" /> - - - - - - - - - test - + test ({ usePathname: jest.fn().mockReturnValue('/send'), })) -// const params = {} - jest.mock('solito', () => { // console.log('mock solito') const mockCreateParam = jest.fn(() => { @@ -56,10 +55,22 @@ jest.mock('app/utils/supabase/useSupabase', () => ({ }), })) +jest.mock('app/routers/params', () => ({ + useSendScreenParams: jest + .fn() + .mockReturnValue([ + { idType: 'tag', recipient: 'test', amount: 'test', sendToken: 'test', note: 'test' }, + jest.fn(), + ]), + useRootScreenParams: jest.fn().mockReturnValue([{ search: 'test' }, jest.fn()]), +})) + import { SendScreen } from './screen' import { usePathname } from 'expo-router' import { useProfileLookup } from 'app/utils/useProfileLookup' +// @ts-expect-error mock +usePathname.mockReturnValue('/send') describe('SendScreen', () => { it('should render with search when on /send and no recipient in params', async () => { jest.useFakeTimers() @@ -77,7 +88,7 @@ describe('SendScreen', () => { expect(tree).toMatchSnapshot('render') expect(await screen.findByText('SEARCH BY')).toBeOnTheScreen() - expect(solito.createParam).toHaveBeenCalled() + expect(params.useRootScreenParams).toHaveBeenCalled() const searchBy = await screen.findByRole('search', { name: 'query' }) const user = userEvent.setup() diff --git a/packages/app/routers/params.tsx b/packages/app/routers/params.tsx index 018a3f337..87557624b 100644 --- a/packages/app/routers/params.tsx +++ b/packages/app/routers/params.tsx @@ -2,7 +2,7 @@ import type { Enums } from '@my/supabase/database.types' import { baseMainnet, usdcAddress } from '@my/wagmi' import { createParam } from 'solito' -export type RootParams = { nav?: 'home' | 'settings'; token?: string } +export type RootParams = { nav?: 'home' | 'settings'; token?: string; search?: string } const { useParam: useRootParam, useParams: useRootParams } = createParam() @@ -18,15 +18,23 @@ const useToken = () => { return [token, setTokenParam] as const } +const useSearch = () => { + const [search, setSearchParam] = useRootParam('search') + + return [search, setSearchParam] as const +} + export const useRootScreenParams = () => { const { setParams } = useRootParams() const [nav] = useNav() const [token] = useToken() + const [search] = useSearch() return [ { nav, token, + search, }, setParams, ] as const From b60c841a736ddc5eb754758c1f23682c99bf20c9 Mon Sep 17 00:00:00 2001 From: youngkidwarrior Date: Thu, 4 Jul 2024 09:58:28 -0700 Subject: [PATCH 03/11] Send to external EOA --- packages/app/components/SearchBar.tsx | 98 ++++- .../__snapshots__/screen.test.tsx.snap | 361 +++++++++++++++--- .../app/features/activity/screen.test.tsx | 5 +- packages/app/features/send/SendAmountForm.tsx | 4 +- .../send/__snapshots__/screen.test.tsx.snap | 17 +- packages/app/features/send/confirm/screen.tsx | 59 ++- packages/app/features/send/screen.tsx | 9 +- packages/app/routers/params.tsx | 3 +- .../app/utils/useSearchResultHref.test.tsx | 12 + packages/app/utils/useSearchResultHref.tsx | 21 +- .../tests/activity.onboarded.spec.ts | 2 +- .../playwright/tests/send.onboarded.spec.ts | 44 ++- 12 files changed, 550 insertions(+), 85 deletions(-) diff --git a/packages/app/components/SearchBar.tsx b/packages/app/components/SearchBar.tsx index 67afde381..b2c3e2541 100644 --- a/packages/app/components/SearchBar.tsx +++ b/packages/app/components/SearchBar.tsx @@ -2,6 +2,7 @@ import { Avatar, Button, ButtonText, + Card, H4, Paragraph, ScrollView, @@ -11,6 +12,7 @@ import { XStack, YStack, isWeb, + useMedia, } from '@my/ui' import { Link } from 'solito/link' import { SearchSchema, useTagSearch } from 'app/provider/tag-search' @@ -20,7 +22,10 @@ import { useThemeSetting } from '@tamagui/next-theme' import { useEffect, useState } from 'react' import type { Functions } from '@my/supabase/database.types' import { useSearchResultHref } from 'app/utils/useSearchResultHref' +import { type Address, isAddress } from 'viem' import { useRootScreenParams } from 'app/routers/params' +import { IconAccount } from './icons' +import { shorten } from 'app/utils/strings' type SearchResultsType = Functions<'tag_search'>[number] type SearchResultsKeysType = keyof SearchResultsType @@ -35,9 +40,11 @@ const formatResultsKey = (str: string): string => { } function SearchResults() { - const { form, results, isLoading, error } = useTagSearch() + const { results, isLoading, error } = useTagSearch() + const [queryParams] = useRootScreenParams() + const { search: query } = queryParams + const [resultsFilter, setResultsFilter] = useState(null) - const query = form.watch('query', '') if (isLoading) { return ( @@ -48,6 +55,28 @@ function SearchResults() { if (!results || error) { return null } + + if (isAddress(query ?? '')) { + return ( + + + + + + ) + } + const matchesCount = Object.values(results).filter( (value) => Array.isArray(value) && value.length ).length @@ -107,7 +136,6 @@ function SearchResults() { key={`${key}-${item.tag_name}-${item.send_id}`} keyField={key as SearchResultsKeysType} profile={item} - query={query} /> ))} @@ -174,19 +202,73 @@ function SearchFilterButton({ ) } +const AddressSearchResultRow = ({ address }: { address: Address }) => { + const href = useSearchResultHref() + const { gtMd } = useMedia() + + return ( + + + + + + + + + + + External Address + + + {gtMd ? address : shorten(address, 6, 6)} + + + + + + ) +} + function SearchResultRow({ keyField, profile, - query, }: { keyField: SearchResultsKeysType profile: SearchResultCommonType - query: string }) { + const [queryParams] = useRootScreenParams() + const { search: query } = queryParams const href = useSearchResultHref(profile) + const { resolvedTheme } = useThemeSetting() const rowBC = resolvedTheme?.startsWith('dark') ? '$metalTouch' : '$gray2Light' + if (!query) return null + return ( { const subscription = form.watch(({ query }) => { @@ -274,7 +356,7 @@ function Search() { { // noop }} @@ -282,7 +364,7 @@ function Search() { props={{ query: { accessibilityRole: 'search', - placeholder: 'Sendtag, Phone, Send ID', + placeholder: 'Sendtag, Phone, Send ID, Address', pr: '$size.3.5', }, }} diff --git a/packages/app/features/activity/__snapshots__/screen.test.tsx.snap b/packages/app/features/activity/__snapshots__/screen.test.tsx.snap index 60d4a47be..5fe6bc08b 100644 --- a/packages/app/features/activity/__snapshots__/screen.test.tsx.snap +++ b/packages/app/features/activity/__snapshots__/screen.test.tsx.snap @@ -99,7 +99,7 @@ exports[`ActivityScreen renders activity screen: ActivityScreen 1`] = ` control={ { "_defaultValues": { - "query": "", + "query": "test", }, "_disableForm": [Function], "_executeSchema": [Function], @@ -111,7 +111,7 @@ exports[`ActivityScreen renders activity screen: ActivityScreen 1`] = ` "ref": { "name": "query", }, - "value": "", + "value": "test", }, }, }, @@ -130,7 +130,7 @@ exports[`ActivityScreen renders activity screen: ActivityScreen 1`] = ` "touchedFields": {}, }, "_formValues": { - "query": "", + "query": "test", }, "_getDirty": [Function], "_getFieldArray": [Function], @@ -222,7 +222,7 @@ exports[`ActivityScreen renders activity screen: ActivityScreen 1`] = ` onBlur={[Function]} onChangeText={[Function]} onFocus={[Function]} - placeholder="Sendtag, Phone, Send ID" + placeholder="Sendtag, Phone, Send ID, Address" placeholderTextColor="#081619" readOnly={false} style={ @@ -244,8 +244,8 @@ exports[`ActivityScreen renders activity screen: ActivityScreen 1`] = ` "color": "#FFFFFF", "fontFamily": "System", "fontSize": 19.2, - "fontStyle": "italic", - "fontWeight": "normal", + "fontStyle": "normal", + "fontWeight": "bold", "height": 44, "minWidth": 0, "paddingLeft": 16, @@ -253,7 +253,7 @@ exports[`ActivityScreen renders activity screen: ActivityScreen 1`] = ` "position": "relative", } } - value="" + value="test" /> + + + + + tag + + + + + + + + + + + + + + + + + ?? + + + + + + + + + test + + + + /test + + + + + + + + + ({ })) jest.mock('app/routers/params', () => ({ - useRootScreenParams: jest.fn().mockReturnValue([{ search: '' }, jest.fn()]), + useRootScreenParams: jest.fn().mockReturnValue([{ search: 'test' }, jest.fn()]), })) jest.mock('app/utils/supabase/useSupabase', () => ({ @@ -31,6 +31,7 @@ jest.mock('app/utils/supabase/useSupabase', () => ({ }, ], phone_matches: [], + address_matches: [], }, ], error: null, @@ -75,7 +76,7 @@ describe('ActivityScreen', () => { ) - const searchInput = screen.getByPlaceholderText('Sendtag, Phone, Send ID') + const searchInput = screen.getByPlaceholderText('Sendtag, Phone, Send ID, Address') fireEvent.changeText(searchInput, 'test') await act(async () => { jest.advanceTimersByTime(2000) diff --git a/packages/app/features/send/SendAmountForm.tsx b/packages/app/features/send/SendAmountForm.tsx index 27305dae6..9e8ef5bbc 100644 --- a/packages/app/features/send/SendAmountForm.tsx +++ b/packages/app/features/send/SendAmountForm.tsx @@ -24,7 +24,7 @@ const SendAmountSchema = z.object({ token: formFields.coin, }) -export function SendAmountForm({ profile }: { profile: Functions<'profile_lookup'>[number] }) { +export function SendAmountForm() { const form = useForm>() const { data: sendAccount } = useSendAccount() const router = useRouter() @@ -158,7 +158,7 @@ export function SendAmountForm({ profile }: { profile: Functions<'profile_lookup > {({ amount, token }) => ( - + {amount} - test + + test + ['data']> - export function SendConfirmScreen() { const [queryParams] = useSendScreenParams() const { recipient, idType, sendToken, amount } = queryParams const { data: profile, isLoading, error } = useProfileLookup(idType ?? 'tag', recipient ?? '') + const router = useRouter() useEffect(() => { - if (!profile || !recipient) + if ((!profile && !recipient) || !isAddress(recipient ?? '')) router.replace({ pathname: '/send', query: { @@ -62,20 +62,28 @@ export function SendConfirmScreen() { }) }, [profile, recipient, idType, router, sendToken, amount]) if (error) throw new Error(error.message) - if (isLoading || !profile) return - return + if ((isLoading && !profile) || !isAddress(recipient ?? '')) return + return } -export function SendConfirm({ profile }: { profile: ProfileProp }) { +export function SendConfirm() { const queryClient = useQueryClient() const { data: sendAccount } = useSendAccount() + + const [queryParams] = useSendScreenParams() + const { sendToken, recipient, idType } = queryParams + + const { + data: profile, + isLoading: isProfileLoading, + error: profileError, + } = useProfileLookup(idType ?? 'tag', recipient ?? '') + const webauthnCreds = sendAccount?.send_account_credentials .filter((c) => !!c.webauthn_credentials) .map((c) => c.webauthn_credentials as NonNullable) ?? [] const [sentTxHash, setSentTxHash] = useState() - const [queryParams] = useSendScreenParams() - const { sendToken, recipient, idType } = queryParams const router = useRouter() const { data: balance, isLoading: balanceIsLoading } = useBalance({ @@ -96,7 +104,7 @@ export function SendConfirm({ profile }: { profile: ProfileProp }) { const { data: userOp } = useGenerateTransferUserOp({ sender: sendAccount?.address, // @ts-expect-error some work to do here - to: profile?.address, + to: profile?.address ?? recipient, token: sendToken === 'eth' ? undefined : sendToken, amount: BigInt(amount), nonce: nonce ?? 0n, @@ -198,7 +206,8 @@ export function SendConfirm({ profile }: { profile: ProfileProp }) { } }, [sentTxHash, transfers, router, sendToken, tokenActivityError, dataFirstFetch, dataUpdatedAt]) - if (balanceIsLoading || nonceIsLoading) return + if (balanceIsLoading || nonceIsLoading || isProfileLoading) + return return ( - + @@ -369,10 +378,19 @@ export function SendConfirm({ profile }: { profile: ProfileProp }) { ) } -export function SendRecipient({ profile, ...props }: YStackProps & { profile: ProfileProp }) { +export function SendRecipient({ ...props }: YStackProps) { const [queryParams] = useSendScreenParams() - + const { recipient, idType } = queryParams const router = useRouter() + const { data: profile, isLoading, error } = useProfileLookup(idType ?? 'tag', recipient ?? '') + + if (isLoading) return + if (error) throw new Error(error.message) + + const href = + idType === 'address' + ? `${baseMainnet.blockExplorers.default.url}/address/${recipient}` + : `/profile/${recipient}` return ( @@ -410,7 +428,7 @@ export function SendRecipient({ profile, ...props }: YStackProps & { profile: Pr $theme-light={{ bc: '$gray3Light' }} f={1} > - + @@ -427,7 +445,16 @@ export function SendRecipient({ profile, ...props }: YStackProps & { profile: Pr lineHeight="$1" color="$color11" > - {profile?.tag ? `/${profile?.tag}` : `#${profile?.sendid}`} + {(() => { + switch (true) { + case idType === 'address': + return shorten(recipient, 6, 6) + case !!profile?.tag: + return `/${profile?.tag}` + default: + return `#${profile?.sendid}` + } + })()} diff --git a/packages/app/features/send/screen.tsx b/packages/app/features/send/screen.tsx index eb6614050..386b52601 100644 --- a/packages/app/features/send/screen.tsx +++ b/packages/app/features/send/screen.tsx @@ -18,12 +18,17 @@ import { useProfileLookup } from 'app/utils/useProfileLookup' import { useState } from 'react' import { SendAmountForm } from './SendAmountForm' import { SendRecipient } from './confirm/screen' +import { type Address, isAddress } from 'viem' export const SendScreen = () => { const [{ recipient, idType }] = useSendScreenParams() const { data: profile, isLoading, error } = useProfileLookup(idType ?? 'tag', recipient ?? '') if (isLoading) return if (error) throw new Error(error.message) + + if (idType === 'address' && isAddress(recipient as Address)) { + return + } if (!profile) return ( @@ -41,7 +46,7 @@ export const SendScreen = () => { return return ( - + // // // @@ -74,7 +79,7 @@ function NoSendAccount({ profile }: { profile: Functions<'profile_lookup'>[numbe const [clicked, setClicked] = useState(false) return ( - +

No send account

diff --git a/packages/app/routers/params.tsx b/packages/app/routers/params.tsx index 87557624b..9694c8874 100644 --- a/packages/app/routers/params.tsx +++ b/packages/app/routers/params.tsx @@ -1,6 +1,7 @@ import type { Enums } from '@my/supabase/database.types' import { baseMainnet, usdcAddress } from '@my/wagmi' import { createParam } from 'solito' +import type { Address } from 'viem' export type RootParams = { nav?: 'home' | 'settings'; token?: string; search?: string } @@ -66,7 +67,7 @@ export const useRewardsScreenParams = () => { } export type SendScreenParams = { - idType?: Enums<'lookup_type_enum'> + idType?: Enums<'lookup_type_enum'> | Address recipient?: string amount?: string sendToken?: `0x${string}` | 'eth' diff --git a/packages/app/utils/useSearchResultHref.test.tsx b/packages/app/utils/useSearchResultHref.test.tsx index 74696b3d4..43a813060 100644 --- a/packages/app/utils/useSearchResultHref.test.tsx +++ b/packages/app/utils/useSearchResultHref.test.tsx @@ -4,6 +4,9 @@ import { useSearchResultHref } from './useSearchResultHref' import { usePathname } from 'app/utils/usePathname.native' import type { SearchResultCommonType } from 'app/components/SearchBar' import type { SendScreenParams } from 'app/routers/params' +import { baseMainnet } from '@my/wagmi' +import { useRootScreenParams } from 'app/routers/params' +import { zeroAddress } from 'viem' const sendParams: SendScreenParams = { idType: 'tag', @@ -14,6 +17,7 @@ const sendParams: SendScreenParams = { jest.mock('app/routers/params', () => ({ useSendScreenParams: jest.fn().mockReturnValue([sendParams]), + useRootScreenParams: jest.fn().mockReturnValue([{ search: 'alice' }]), })) jest.mock('expo-router', () => ({ @@ -42,6 +46,14 @@ describe('useSearchResultHref', () => { const href = useSearchResultHref(item) expect(href).toBe('/profile/12530') }) + it('should return basescan link for EOA for activity screen', () => { + //@ts-expect-error mock + useRootScreenParams.mockReturnValueOnce([{ search: zeroAddress }]) + // @ts-expect-error mock + usePathname.mockReturnValue('/activity') + const href = useSearchResultHref() + expect(href).toBe(`${baseMainnet.blockExplorers.default.url}/address/${zeroAddress}`) + }) it('should return the correct href for send screen', () => { // @ts-expect-error mock usePathname.mockReturnValue('/send') diff --git a/packages/app/utils/useSearchResultHref.tsx b/packages/app/utils/useSearchResultHref.tsx index c222d8487..91524cf57 100644 --- a/packages/app/utils/useSearchResultHref.tsx +++ b/packages/app/utils/useSearchResultHref.tsx @@ -1,10 +1,27 @@ -import { useSendScreenParams } from 'app/routers/params' +import { useRootScreenParams, useSendScreenParams } from 'app/routers/params' import { usePathname } from 'app/utils/usePathname' import type { SearchResultCommonType } from 'app/components/SearchBar' +import { isAddress } from 'viem' +import { baseMainnet } from '@my/wagmi' -export const useSearchResultHref = (profile: SearchResultCommonType) => { +export const useSearchResultHref = (profile?: SearchResultCommonType) => { + const [queryParams] = useRootScreenParams() + const { search: query } = queryParams const path = usePathname() const [sendParams] = useSendScreenParams() + if (!profile) { + switch (true) { + case !query || !isAddress(query): + return '' + case path === '/activity': + return `${baseMainnet.blockExplorers.default.url}/address/${query}` + case path === '/send': + return `/send?recipient=${query}&idType=address` + default: { + throw new Error(`Unhandled path: ${path}`) + } + } + } switch (path) { case '/activity': diff --git a/packages/playwright/tests/activity.onboarded.spec.ts b/packages/playwright/tests/activity.onboarded.spec.ts index 89ed5360b..8b03b4156 100644 --- a/packages/playwright/tests/activity.onboarded.spec.ts +++ b/packages/playwright/tests/activity.onboarded.spec.ts @@ -111,7 +111,7 @@ test('can search on activity page', async ({ page, context }) => { }) await expect(activityHeading(page)).toBeVisible() const isLoading = page.getByRole('progressbar', { name: 'Loading' }) - const searchInput = page.getByPlaceholder('Sendtag, Phone, Send ID') + const searchInput = page.getByPlaceholder('Sendtag, Phone, Send ID, Address') await searchInput.fill('test') await expect(searchInput).toHaveValue('test') await page.waitForResponse(`${SUPABASE_URL}/rest/v1/rpc/tag_search*`) diff --git a/packages/playwright/tests/send.onboarded.spec.ts b/packages/playwright/tests/send.onboarded.spec.ts index fff96f440..bbdd45b94 100644 --- a/packages/playwright/tests/send.onboarded.spec.ts +++ b/packages/playwright/tests/send.onboarded.spec.ts @@ -12,6 +12,7 @@ import { erc20Abi, formatUnits, parseUnits, zeroAddress } from 'viem' import { ProfilePage } from './fixtures/profiles' import { SendPage } from './fixtures/send' import { sendTokenAddresses, testBaseClient, usdcAddress } from './fixtures/viem' +import { shorten } from 'app/utils/strings' const test = mergeTests(sendAccountTest, snapletTest) @@ -40,7 +41,9 @@ const tokens = [ }, ] as { symbol: string; address: `0x${string}`; decimals: number }[] -const idTypes = ['tag', 'sendid'] as const +const idTypes = ['tag', 'sendid', 'address'] as const + +const testEOA = zeroAddress.replace('0x0', '0x1') for (const token of tokens) { test(`can send ${token.symbol} starting from profile page`, async ({ page, seed, supabase }) => { @@ -91,7 +94,17 @@ for (const token of tokens) { assert(!!recvAccount, 'send account not found') const tag = plan.tags[0] - const query = isSendId ? profile?.sendId.toString() : tag?.name + const query = (() => { + switch (idType) { + case 'sendid': + return profile?.sendId.toString() + case 'address': + return testEOA + default: + return tag?.name + } + })() + assert(!!query, 'query not found') // goto send page @@ -105,7 +118,7 @@ for (const token of tokens) { await expect(page).toHaveURL(/\/send/) // fill search input - const searchInput = page.getByPlaceholder('Sendtag, Phone, Send ID') + const searchInput = page.getByPlaceholder('Sendtag, Phone, Send ID, Address') await expect(searchInput).toBeVisible() await searchInput.fill(query) await expect(searchInput).toHaveValue(query) @@ -128,10 +141,31 @@ for (const token of tokens) { timeout: 5000, }) - const counterparty = isSendId ? profile.name : `/${tag?.name}` await expect(page.getByTestId('SendForm')).toHaveText( - new RegExp(isSendId ? `#${profile.sendId}` : `/${tag?.name}`) + new RegExp( + (() => { + switch (idType) { + case 'address': + return shorten(testEOA, 6, 6) + case 'sendid': + return `#${profile.sendId}` + default: + return `/${tag?.name}` + } + })() + ) ) + + const counterparty = (() => { + switch (idType) { + case 'address': + return testEOA + case 'sendid': + return `#${profile.sendId}` + default: + return `/${tag?.name}` + } + })() await handleTokenTransfer({ token, supabase, page, counterparty, recvAccount, profile }) }) } From 95962d5053eb9d9257e82f87e3fd904a3d9662f2 Mon Sep 17 00:00:00 2001 From: youngkidwarrior Date: Tue, 9 Jul 2024 12:28:57 -0700 Subject: [PATCH 04/11] Filter out paymaster txs --- .../app/features/home/TokenDetailsHistory.tsx | 38 ++++++++++--------- packages/app/utils/activity.ts | 5 +++ 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/packages/app/features/home/TokenDetailsHistory.tsx b/packages/app/features/home/TokenDetailsHistory.tsx index baa792884..1465ce670 100644 --- a/packages/app/features/home/TokenDetailsHistory.tsx +++ b/packages/app/features/home/TokenDetailsHistory.tsx @@ -5,6 +5,8 @@ import { Fragment } from 'react' import { useTokenActivityFeed } from './utils/useTokenActivityFeed' import { RowLabel, AnimateEnter } from './TokenDetails' import { TokenActivityRow } from './TokenActivityRow' +import { baseMainnet, tokenPaymasterAddress } from '@my/wagmi' +import { isPaymasterEvent } from 'app/utils/activity' export const TokenDetailsHistory = ({ coin }: { coin: coins[number] }) => { const result = useTokenActivityFeed({ @@ -42,23 +44,25 @@ export const TokenDetailsHistory = ({ coin }: { coin: coins[number] }) => { default: { let lastDate: string | undefined return pages?.map((activities) => { - return activities?.map((activity) => { - const date = activity.created_at.toLocaleDateString() - const isNewDate = !lastDate || date !== lastDate - if (isNewDate) { - lastDate = date - } - return ( - - {isNewDate ? {lastDate} : null} - - - - - ) - }) + return activities + ?.filter((activity) => !isPaymasterEvent(activity)) + .map((activity) => { + const date = activity.created_at.toLocaleDateString() + const isNewDate = !lastDate || date !== lastDate + if (isNewDate) { + lastDate = date + } + return ( + + {isNewDate ? {lastDate} : null} + + + + + ) + }) }) } } diff --git a/packages/app/utils/activity.ts b/packages/app/utils/activity.ts index 491b4c3ff..fbfe476f5 100644 --- a/packages/app/utils/activity.ts +++ b/packages/app/utils/activity.ts @@ -183,3 +183,8 @@ export function userNameFromActivityUser( return '' } } + +export const isPaymasterEvent = (event: Activity) => + labelAddress(event.data.t) === 'Paymaster' || + labelAddress(event.data.f) === 'Paymaster' || + labelAddress(event.data.sender) === 'Paymaster' From 46e7e0fbcd886506f657894343b2b8a87b358c26 Mon Sep 17 00:00:00 2001 From: youngkidwarrior Date: Tue, 9 Jul 2024 13:46:39 -0700 Subject: [PATCH 05/11] Whoops: Remove uneccessary isAddess checks --- packages/app/features/send/confirm/screen.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/app/features/send/confirm/screen.tsx b/packages/app/features/send/confirm/screen.tsx index 9e2340a01..bab715847 100644 --- a/packages/app/features/send/confirm/screen.tsx +++ b/packages/app/features/send/confirm/screen.tsx @@ -50,7 +50,7 @@ export function SendConfirmScreen() { const router = useRouter() useEffect(() => { - if ((!profile && !recipient) || !isAddress(recipient ?? '')) + if (!profile && !recipient) router.replace({ pathname: '/send', query: { @@ -62,7 +62,7 @@ export function SendConfirmScreen() { }) }, [profile, recipient, idType, router, sendToken, amount]) if (error) throw new Error(error.message) - if ((isLoading && !profile) || !isAddress(recipient ?? '')) return + if (isLoading && !profile) return return } From 19426fda539ba5b530cbda6cc890fc3e7c0344d6 Mon Sep 17 00:00:00 2001 From: Big Boss Date: Tue, 9 Jul 2024 16:03:02 -0500 Subject: [PATCH 06/11] fix sign up spec, docs (#561) * fix sign up spec, docs * add direnv to recs --- .vscode/extensions.json | 3 +- docs/testing-like-a-playwright-boss.md | 65 +++++++++++++++++++ .../features/auth/sign-up/sign-up-form.tsx | 1 + packages/playwright/package.json | 2 +- .../playwright/tests/sign-up.anon.spec.ts | 9 +-- yarn.lock | 30 ++++----- 6 files changed, 87 insertions(+), 23 deletions(-) create mode 100644 docs/testing-like-a-playwright-boss.md diff --git a/.vscode/extensions.json b/.vscode/extensions.json index f0448fb53..a8ff3b517 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -7,6 +7,7 @@ "yoavbls.pretty-ts-errors", "dbaeumer.vscode-eslint", "usernamehw.errorlens", - "naumovs.color-highlight" + "naumovs.color-highlight", + "mkhl.direnv" ] } diff --git a/docs/testing-like-a-playwright-boss.md b/docs/testing-like-a-playwright-boss.md new file mode 100644 index 000000000..07761e931 --- /dev/null +++ b/docs/testing-like-a-playwright-boss.md @@ -0,0 +1,65 @@ + +# Testing Like a Playwright Boss + +This is a guide to testing like a playwright boss. It dives into how to leverage playwrght to test Send app. It also covers how to debug and troubleshoot tests. + +## Setup + +Ensure you have already followed the [CONTRIBUTING](/CONTRIBUTING.md) guide. + +- Install [VSCode](https://code.visualstudio.com/): A code editor that supports running and debugging Playwright tests. +- Install ["ms-playwright.playwright"](https://marketplace.visualstudio.com/items?itemName=ms-playwright.playwright): A VSCode extension that provides syntax highlighting and code completion for Playwright tests. +- Install [direnv](https://direnv.net/): A tool that loads environment variables from `.envrc` files. +- Install ["mkhl.direnv"](https://marketplace.visualstudio.com/items?itemName=mkhl.direnv): A VSCode extension that load environment variables from `.envrc` files into the VSCode environment. +- Install browsers: + - Using VSCode: Press Shift+Command+P to open the Command Palette in VSCode, type 'Playwright' and select 'Install Playwright Browsers'. + - Using the Playwright CLI: Run `npx playwright install chromium firefox webkit` to install the browsers. +Once those are installed, you will need to allow the `.envrc` file to load environment variables. Any time it changes, it should prompt you to reload the VSCode environment. + +For the rest of the guide, we will assume you are using VSCode. + +### Running Tests + +You'll want to visit the **Testing** tab in the VSCode sidebar. From there, in the **Test Explorer** panel, you can run and debug tests. + +There should be icons for running and debugging tests. Typically, I only run one test at a time. There are also a number of settings that are available for Playwright when running from VSCode. You can find them at the bottom of the **Testing** sidebar. + +A few of my favorite settings are: + +- **Projects**: This is where you can select which projects to run tests for. Typically, I select one, either chromium or firefox. +- **Settings**: This is where you can select which settings to use for the test run such as running the browser in headless mode or not. +- **Tools**: + - **Pick Locator** allows you to select which locator to use for finding elements on the page from the currently running test and open browser. + - **Record New**: Gives you the ability to record a new test + - **Record at Cursor**: Gives you the ability to record a test which will input at the current editor's pane cursor position. + +### Debugging Tests + +When debugging tests, you can use the **Debug Console** to see the output of the test. You can also use the **Debug Console** to interact with the browser. + +This runs Playwright in debug mode which will pause at breakpoints and allow you to interact with the browser. It also removes the global timeout which is set by default to 30 seconds. This is useful for debugging tests as it allows you to run tests for longer periods of time. + +You also have access to the console developer tools which can be useful for debugging to see what is happening in the browser. + +### Writing Tests + +Playwright tests are written in TypeScript. You can find the test files in the [`/packages/playwright/tests`](/packages/playwright) directory. There are a number of examples of tests in there. Send app leverages a number of fixtures to make testing easier. These fixtures are located in the [`/packages/playwright/tests/fixtures`](/packages/playwright/tests/fixtures) directory. + +#### Considerations + +You want to put yourself in the shoes of a user, not a developer. However, you should isolate the feature you are testing as much as possible. E.g. auth vs onboarding vs sending tokens. They are all different features and should be tested separately. Use fixtures to isolate them and reuse them across tests. + +#### Test Recording + +Use the **Record New** button or **Record at Cursor** to record a new tests or use the pick locator to select the locator to use for the test. This way you can easily interact with the browser and see what is happening. + +## Non-VSCode Setup (Playwright CLI) + +Running playwright tests in VSCode is a great way to get started, but you can also leverage the playwright CLI to run tests and debug them. You can use the [**Playwright Inspector**](https://playwright.dev/docs/inspector) to debug tests. To start Playwright in debug mode, you can run the following command: + +```shell +cd packages/playwright +npx playwright test --debug +``` + +This will run the tests in debug mode and pause at breakpoints. There should be a popup which gives you commands during this interactive debugging session. diff --git a/packages/app/features/auth/sign-up/sign-up-form.tsx b/packages/app/features/auth/sign-up/sign-up-form.tsx index 80a946840..957406a63 100644 --- a/packages/app/features/auth/sign-up/sign-up-form.tsx +++ b/packages/app/features/auth/sign-up/sign-up-form.tsx @@ -103,6 +103,7 @@ export const SignUpForm = () => { ai={'center'} > submit()} br="$3" bc={'$green9Light'} diff --git a/packages/playwright/package.json b/packages/playwright/package.json index 945c47a11..3411fb26c 100644 --- a/packages/playwright/package.json +++ b/packages/playwright/package.json @@ -7,7 +7,7 @@ "@faker-js/faker": "^8.1.0", "@my/snaplet": "workspace:*", "@my/supabase": "workspace:*", - "@playwright/test": "^1.41.1", + "@playwright/test": "^1.45.1", "@supabase/supabase-js": "2.44.2", "@types/jsonwebtoken": "^9.0.2", "@types/pg": "^8", diff --git a/packages/playwright/tests/sign-up.anon.spec.ts b/packages/playwright/tests/sign-up.anon.spec.ts index c0e40f3de..d9a3430aa 100644 --- a/packages/playwright/tests/sign-up.anon.spec.ts +++ b/packages/playwright/tests/sign-up.anon.spec.ts @@ -1,4 +1,4 @@ -import { expect, test as baseTest, mergeTests } from '@playwright/test' +import { expect, test as baseTest, mergeTests, type Expect, type Page } from '@playwright/test' import { test as snapletTest } from '@my/playwright/fixtures/snaplet' import { test as webauthnTest } from '@my/playwright/fixtures/webauthn' import { countries } from 'app/utils/country' @@ -17,14 +17,11 @@ test.beforeEach(async ({ page }) => { const randomCountry = () => countries[Math.floor(Math.random() * countries.length)] as (typeof countries)[number] -const signUp = async (page, phone, expect) => { +const signUp = async (page: Page, phone: string, expect: Expect) => { await page.getByLabel('Phone number').fill(phone) - const captcha = page - .frameLocator('iframe[title="Widget containing a Cloudflare security challenge"]') - .locator('#success') - await expect(captcha).toBeVisible() const signUpButton = page.getByRole('button', { name: 'Sign Up' }) await expect(signUpButton).toBeVisible() + await expect(signUpButton).toBeEnabled() await signUpButton.click() const otpInput = page.getByLabel('One-time Password') await expect(otpInput).toBeVisible() diff --git a/yarn.lock b/yarn.lock index ba84f33a1..d3b814ca0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5965,7 +5965,7 @@ __metadata: "@faker-js/faker": "npm:^8.1.0" "@my/snaplet": "workspace:*" "@my/supabase": "workspace:*" - "@playwright/test": "npm:^1.41.1" + "@playwright/test": "npm:^1.45.1" "@supabase/supabase-js": "npm:2.44.2" "@types/jsonwebtoken": "npm:^9.0.2" "@types/pg": "npm:^8" @@ -6645,14 +6645,14 @@ __metadata: languageName: node linkType: hard -"@playwright/test@npm:^1.41.1": - version: 1.41.1 - resolution: "@playwright/test@npm:1.41.1" +"@playwright/test@npm:^1.45.1": + version: 1.45.1 + resolution: "@playwright/test@npm:1.45.1" dependencies: - playwright: "npm:1.41.1" + playwright: "npm:1.45.1" bin: playwright: cli.js - checksum: 68d652462cf1cfcaa91886937a5d860c4ec4caefadf30ba6eb41f498e01ea097b084b956439b112eaa4e5a52a7421d100d3f125f5c1d864468bbe40389c2c9fd + checksum: 718316ae739438f686914350beb3aeded6c96d7adfe1b65509fc50c4e322172fe58b7c9f215c3d5bef52a263839b83162f843027ae8d8e96970b3dd8f87211d2 languageName: node linkType: hard @@ -27486,27 +27486,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.41.1": - version: 1.41.1 - resolution: "playwright-core@npm:1.41.1" +"playwright-core@npm:1.45.1": + version: 1.45.1 + resolution: "playwright-core@npm:1.45.1" bin: playwright-core: cli.js - checksum: 12019f53bda0f0fcef9a9b68f5bcf3b7169330d657e091617b103e841963142c4101e8ced110fe92b0b8f0e3df698eb2f37af5189fe45e00e7549b2f8a22a6ed + checksum: 206a5ecd2de7b8cefa5136331fa22012416b37eb2c471e3105c09a8a17a10621efa900acb6a780314f06aa2a3d6651aad3a323fa360d046ccce8f3844b3ca615 languageName: node linkType: hard -"playwright@npm:1.41.1": - version: 1.41.1 - resolution: "playwright@npm:1.41.1" +"playwright@npm:1.45.1": + version: 1.45.1 + resolution: "playwright@npm:1.45.1" dependencies: fsevents: "npm:2.3.2" - playwright-core: "npm:1.41.1" + playwright-core: "npm:1.45.1" dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: 7667d73e406549156200d0d1b6361eadc4037816e9020e68e86d4249e302963e6e645cb95de2da8cadb5e52080f9f25020e65dc020655ae0e52d2a12d7a03642 + checksum: 092d510a79ca8fb1d0c1a83460735b9eaf02261a48df2ae1b025f95ee31e2be9d962ddc62c7e5c0d2c44e5b982b66aaf3fe24243f736ab14dbfd2d6e88897824 languageName: node linkType: hard From 67067499f2dff6a8f8f2e56573c4e53325293ebb Mon Sep 17 00:00:00 2001 From: youngkidwarrior Date: Tue, 9 Jul 2024 14:06:56 -0700 Subject: [PATCH 07/11] Filter Paymster txs form api in token history --- .../app/features/home/TokenDetailsHistory.tsx | 37 +++++++++---------- .../home/utils/useTokenActivityFeed.ts | 10 +++++ packages/app/utils/activity.ts | 5 --- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/packages/app/features/home/TokenDetailsHistory.tsx b/packages/app/features/home/TokenDetailsHistory.tsx index 1465ce670..547d054e2 100644 --- a/packages/app/features/home/TokenDetailsHistory.tsx +++ b/packages/app/features/home/TokenDetailsHistory.tsx @@ -6,7 +6,6 @@ import { useTokenActivityFeed } from './utils/useTokenActivityFeed' import { RowLabel, AnimateEnter } from './TokenDetails' import { TokenActivityRow } from './TokenActivityRow' import { baseMainnet, tokenPaymasterAddress } from '@my/wagmi' -import { isPaymasterEvent } from 'app/utils/activity' export const TokenDetailsHistory = ({ coin }: { coin: coins[number] }) => { const result = useTokenActivityFeed({ @@ -44,25 +43,23 @@ export const TokenDetailsHistory = ({ coin }: { coin: coins[number] }) => { default: { let lastDate: string | undefined return pages?.map((activities) => { - return activities - ?.filter((activity) => !isPaymasterEvent(activity)) - .map((activity) => { - const date = activity.created_at.toLocaleDateString() - const isNewDate = !lastDate || date !== lastDate - if (isNewDate) { - lastDate = date - } - return ( - - {isNewDate ? {lastDate} : null} - - - - - ) - }) + return activities.map((activity) => { + const date = activity.created_at.toLocaleDateString() + const isNewDate = !lastDate || date !== lastDate + if (isNewDate) { + lastDate = date + } + return ( + + {isNewDate ? {lastDate} : null} + + + + + ) + }) }) } } diff --git a/packages/app/features/home/utils/useTokenActivityFeed.ts b/packages/app/features/home/utils/useTokenActivityFeed.ts index 94924bc15..2174023df 100644 --- a/packages/app/features/home/utils/useTokenActivityFeed.ts +++ b/packages/app/features/home/utils/useTokenActivityFeed.ts @@ -1,10 +1,12 @@ import type { PgBytea } from '@my/supabase/database.types' +import { tokenPaymasterAddress } from '@my/wagmi' import type { PostgrestError } from '@supabase/postgrest-js' import { useInfiniteQuery, type InfiniteData, type UseInfiniteQueryResult, } from '@tanstack/react-query' +import { hexToBytea } from 'app/utils/hexToBytea' import { useSupabase } from 'app/utils/supabase/useSupabase' import { throwIf } from 'app/utils/throwIf' import { EventArraySchema, Events, type Activity } from 'app/utils/zod/activity' @@ -37,8 +39,16 @@ export function useTokenActivityFeed(params: { query = query.eq('event_name', Events.SendAccountReceive) } + const pgPaymasterCondValues = Object.values(tokenPaymasterAddress) + .map((a) => `${hexToBytea(a)}`) + .join(',') + const { data, error } = await query .or('from_user.not.is.null, to_user.not.is.null') // only show activities with a send app user + .or( + // Filter out paymaster fees for gas + `data->t.is.null, data->f.is.null, and(data->>t.not.in.(${pgPaymasterCondValues}), data->>f.not.in.(${pgPaymasterCondValues}))` + ) .order('created_at', { ascending: false }) .range(from, to) throwIf(error) diff --git a/packages/app/utils/activity.ts b/packages/app/utils/activity.ts index fbfe476f5..491b4c3ff 100644 --- a/packages/app/utils/activity.ts +++ b/packages/app/utils/activity.ts @@ -183,8 +183,3 @@ export function userNameFromActivityUser( return '' } } - -export const isPaymasterEvent = (event: Activity) => - labelAddress(event.data.t) === 'Paymaster' || - labelAddress(event.data.f) === 'Paymaster' || - labelAddress(event.data.sender) === 'Paymaster' From b74787568c424c8e2074dbdbb492bebe32495e01 Mon Sep 17 00:00:00 2001 From: Big Boss Date: Tue, 9 Jul 2024 20:46:28 -0500 Subject: [PATCH 08/11] bb/send to address dialog (#565) * add external address send confirm * fix playwright spec --- packages/app/components/SearchBar.tsx | 101 ++++++++++++++++-- .../playwright/tests/send.onboarded.spec.ts | 38 ++++++- 2 files changed, 126 insertions(+), 13 deletions(-) diff --git a/packages/app/components/SearchBar.tsx b/packages/app/components/SearchBar.tsx index b2c3e2541..95972c468 100644 --- a/packages/app/components/SearchBar.tsx +++ b/packages/app/components/SearchBar.tsx @@ -1,3 +1,4 @@ +import type { Functions } from '@my/supabase/database.types' import { Avatar, Button, @@ -14,18 +15,22 @@ import { isWeb, useMedia, } from '@my/ui' -import { Link } from 'solito/link' +import { ExternalLink } from '@tamagui/lucide-icons' +import { useThemeSetting } from '@tamagui/next-theme' import { SearchSchema, useTagSearch } from 'app/provider/tag-search' -import { FormProvider } from 'react-hook-form' +import { useRootScreenParams } from 'app/routers/params' import { SchemaForm } from 'app/utils/SchemaForm' -import { useThemeSetting } from '@tamagui/next-theme' -import { useEffect, useState } from 'react' -import type { Functions } from '@my/supabase/database.types' +import { shorten } from 'app/utils/strings' import { useSearchResultHref } from 'app/utils/useSearchResultHref' +import * as Linking from 'expo-linking' +import { useEffect, useState } from 'react' +import { FormProvider } from 'react-hook-form' +import { Pressable } from 'react-native' +import { Link } from 'solito/link' +import { useRouter } from 'solito/router' +import { Adapt, Dialog, Sheet } from 'tamagui' import { type Address, isAddress } from 'viem' -import { useRootScreenParams } from 'app/routers/params' import { IconAccount } from './icons' -import { shorten } from 'app/utils/strings' type SearchResultsType = Functions<'tag_search'>[number] type SearchResultsKeysType = keyof SearchResultsType @@ -204,11 +209,17 @@ function SearchFilterButton({ const AddressSearchResultRow = ({ address }: { address: Address }) => { const href = useSearchResultHref() + const router = useRouter() const { gtMd } = useMedia() + const [sendConfirmDialogIsOpen, setSendConfirmDialogIsOpen] = useState(false) return ( - + setSendConfirmDialogIsOpen(true)} + accessibilityRole="link" + accessibilityLabel={address} + > {
- + + setSendConfirmDialogIsOpen(false)} + onConfirm={() => router.push(href)} + address={address} + /> ) } +function ConfirmSendDialog({ isOpen, onClose, onConfirm, address }) { + return ( + + + + + + + + + + + + + + + Confirm External Send + + Please confirm you agree to the following before sending: + + 1. The external address is on Base Network. + + + 2. I have double checked the address: + + + + + 3. I understand that if I make any mistakes, there is no way to recover the funds. + + + + + + + + + + + + + ) +} + function SearchResultRow({ keyField, profile, diff --git a/packages/playwright/tests/send.onboarded.spec.ts b/packages/playwright/tests/send.onboarded.spec.ts index bbdd45b94..223e136dd 100644 --- a/packages/playwright/tests/send.onboarded.spec.ts +++ b/packages/playwright/tests/send.onboarded.spec.ts @@ -43,7 +43,7 @@ const tokens = [ const idTypes = ['tag', 'sendid', 'address'] as const -const testEOA = zeroAddress.replace('0x0', '0x1') +const testEOA = zeroAddress.replace('0x0', '0x1') as `0x${string}` for (const token of tokens) { test(`can send ${token.symbol} starting from profile page`, async ({ page, seed, supabase }) => { @@ -87,12 +87,21 @@ for (const token of tokens) { : [userOnboarded] ) const profile = plan.profiles[0] + const tag = plan.tags[0] + assert(!!profile, 'profile not found') assert(!!profile.name, 'profile name not found') assert(!!profile.sendId, 'profile send id not found') - const recvAccount = plan.sendAccounts[0] - assert(!!recvAccount, 'send account not found') - const tag = plan.tags[0] + + const recvAccount: { address: `0x${string}` } = (() => { + switch (idType) { + case 'address': + return { address: testEOA } + default: + assert(!!plan.sendAccounts[0], 'send account not found') + return { address: plan.sendAccounts[0].address as `0x${string}` } + } + })() const query = (() => { switch (idType) { @@ -123,12 +132,33 @@ for (const token of tokens) { await searchInput.fill(query) await expect(searchInput).toHaveValue(query) + let blockExplorerPagePromise: Promise | null = null + + if (idType === 'address') { + blockExplorerPagePromise = page.context().waitForEvent('page') + } + // click user await page .getByTestId('searchResults') .getByRole('link', { name: query, exact: false }) .click() + if (idType === 'address' && !!blockExplorerPagePromise) { + // confirm sending to external address + const dialog = page.getByRole('dialog', { name: 'Confirm External Send' }) + await expect(dialog).toBeVisible() + const blockExplorerButton = dialog.getByRole('button', { name: query }) + await expect(blockExplorerButton).toBeVisible() + await blockExplorerButton.click() + const blockExplorerPage = await blockExplorerPagePromise + await expect(blockExplorerPage).toHaveURL(new RegExp(`/address/${query}`)) + await blockExplorerPage.close() + const confirmButton = dialog.getByRole('button', { name: 'I Agree & Continue' }) + await expect(confirmButton).toBeVisible() + await confirmButton.click() + } + await expect(page).toHaveURL(/\/send/) await expect(() => { From 3c584ae8ec8f31b1dbc551320bdb45cf02df764a Mon Sep 17 00:00:00 2001 From: Big Boss Date: Tue, 9 Jul 2024 21:04:27 -0500 Subject: [PATCH 09/11] sendid spec tweaks, bold button text (#566) --- packages/app/components/SearchBar.tsx | 1 + .../playwright/tests/send.onboarded.spec.ts | 100 +----------------- 2 files changed, 2 insertions(+), 99 deletions(-) diff --git a/packages/app/components/SearchBar.tsx b/packages/app/components/SearchBar.tsx index 95972c468..0515dd256 100644 --- a/packages/app/components/SearchBar.tsx +++ b/packages/app/components/SearchBar.tsx @@ -310,6 +310,7 @@ function ConfirmSendDialog({ isOpen, onClose, onConfirm, address }) { } }} fontFamily={'$mono'} + fontWeight={'bold'} iconAfter={} mt="$4" > diff --git a/packages/playwright/tests/send.onboarded.spec.ts b/packages/playwright/tests/send.onboarded.spec.ts index 223e136dd..7a577a56a 100644 --- a/packages/playwright/tests/send.onboarded.spec.ts +++ b/packages/playwright/tests/send.onboarded.spec.ts @@ -191,7 +191,7 @@ for (const token of tokens) { case 'address': return testEOA case 'sendid': - return `#${profile.sendId}` + return profile.name default: return `/${tag?.name}` } @@ -201,104 +201,6 @@ for (const token of tokens) { } } -test.skip('can send USDC to user on profile', async ({ page, seed }) => { - const plan = await seed.users([userOnboarded]) - const tag = plan.tags[0] - const profile = plan.profiles[0] - assert(!!tag?.name, 'tag not found') - assert(!!profile?.name, 'profile name not found') - assert(!!profile?.about, 'profile about not found') - const profilePage = new ProfilePage(page, { - name: profile.name, - about: profile.about, - }) - await profilePage.visit(tag.name, expect) - await expect(profilePage.sendButton).toBeVisible() - await profilePage.sendButton.click() - - // @todo create send form fixture - const sendDialog = page.getByTestId('sendDialogContainer') - await expect(sendDialog).toBeVisible() - const amountInput = sendDialog.getByLabel('Amount') - await expect(amountInput).toBeVisible() - await amountInput.fill('5') - const tokenSelect = sendDialog.getByRole('combobox') // @todo when tamagui supports this , { name: 'Token' }) - await expect(tokenSelect).toBeVisible() - await tokenSelect.selectOption('USDC') - const sendDialogButton = sendDialog.getByRole('button', { name: 'Send' }) - expect(sendDialogButton).toBeVisible() - await sendDialogButton.click() - await expect(sendDialog.getByText(/Sent user op [0-9a-f]+/).first()).toBeVisible({ - timeout: 20000, - }) - await expect(sendDialog.getByRole('link', { name: 'View on Otterscan' })).toBeVisible() -}) - -test.skip('can send USDC to user on profile using paymaster', async ({ - page, - seed, - supabase, - setEthBalance, -}) => { - const { data: sendAccount, error } = await supabase.from('send_accounts').select('*').single() - if (error) { - log('error fetching send account', error) - throw error - } - assert(!!sendAccount, 'no send account found') - assert(sendAccount.address !== zeroAddress, 'send account address is zero') - - await setEthBalance({ address: sendAccount.address, value: 0n }) // set balance to 0 ETH - - const plan = await seed.users([userOnboarded]) - const tag = plan.tags[0] - const profile = plan.profiles[0] - assert(!!tag?.name, 'tag not found') - assert(!!profile?.name, 'profile name not found') - assert(!!profile?.about, 'profile about not found') - const profilePage = new ProfilePage(page, { - name: profile.name, - about: profile.about, - }) - await profilePage.visit(tag.name, expect) - await expect(profilePage.sendButton).toBeVisible() - await profilePage.sendButton.click() - - // @todo create send form fixture - const sendDialog = page.getByTestId('sendDialogContainer') - await expect(sendDialog).toBeVisible() - const amountInput = sendDialog.getByLabel('Amount') - await expect(amountInput).toBeVisible() - await amountInput.fill('5') - const tokenSelect = sendDialog.getByRole('combobox') // @todo when tamagui supports this , { name: 'Token' }) - await expect(tokenSelect).toBeVisible() - await tokenSelect.selectOption('USDC') - const sendDialogButton = sendDialog.getByRole('button', { name: 'Send' }) - expect(sendDialogButton).toBeVisible() - const usdcBalBefore = await testBaseClient.readContract({ - address: usdcAddress[testBaseClient.chain.id], - abi: erc20Abi, - functionName: 'balanceOf', - args: [sendAccount.address], - }) - await sendDialogButton.click() - await expect(sendDialog.getByText(/Sent user op [0-9a-f]+/).first()).toBeVisible({ - timeout: 20000, - }) - await expect(sendDialog.getByRole('link', { name: 'View on Otterscan' })).toBeVisible() - - const usdcBalAfter = await testBaseClient.readContract({ - address: usdcAddress[testBaseClient.chain.id], - abi: erc20Abi, - functionName: 'balanceOf', - args: [sendAccount.address], - }) - expect(Number(formatUnits(usdcBalBefore, 6)) - Number(formatUnits(usdcBalAfter, 6))).toBeCloseTo( - 5, - 0 - ) // allow for ยข10 for gas -}) - /** * Handles the transfer process for a specified token. * From 53d89062fe0b56ea1279268debaae2728094dc51 Mon Sep 17 00:00:00 2001 From: Big Boss Date: Tue, 9 Jul 2024 21:18:54 -0500 Subject: [PATCH 10/11] fix the block explorer url (#567) --- packages/app/components/SearchBar.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/app/components/SearchBar.tsx b/packages/app/components/SearchBar.tsx index 0515dd256..a7cd2a4bc 100644 --- a/packages/app/components/SearchBar.tsx +++ b/packages/app/components/SearchBar.tsx @@ -31,6 +31,7 @@ import { useRouter } from 'solito/router' import { Adapt, Dialog, Sheet } from 'tamagui' import { type Address, isAddress } from 'viem' import { IconAccount } from './icons' +import { baseMainnet } from '@my/wagmi' type SearchResultsType = Functions<'tag_search'>[number] type SearchResultsKeysType = keyof SearchResultsType @@ -301,12 +302,12 @@ function ConfirmSendDialog({ isOpen, onClose, onConfirm, address }) { onPress={() => { if (isWeb) { window.open( - `https://basescan.org/address/${address}`, + `${baseMainnet.blockExplorers.default.url}/address/${address}`, '_blank', 'noopener,noreferrer' ) } else { - Linking.openURL(`https://basescan.org/address/${address}`) + Linking.openURL(`${baseMainnet.blockExplorers.default.url}/address/${address}`) } }} fontFamily={'$mono'} From 8102d4199c805decadccc230373b95294965f134 Mon Sep 17 00:00:00 2001 From: Big Boss Date: Tue, 9 Jul 2024 21:22:41 -0500 Subject: [PATCH 11/11] run deploy staging on self-hosted (#568) --- .github/workflows/deploy-staging.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index 7e80dbb84..6fc972be2 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -38,7 +38,7 @@ concurrency: jobs: deploy: - runs-on: ubuntu-latest + runs-on: self-hosted steps: - uses: actions/checkout@v4 with: