Skip to content

Commit

Permalink
feat: handle companion app in manifest (#512)
Browse files Browse the repository at this point in the history
* adjust default port for apps

* define connect iframe url during build

* add new env to template

* add script to dynamically create manifest

* dynamically bundle connect iframe url

* provide env variable

* remove manifest from git

* make sure correct build happens during dev

* only create inline source maps in development

* add default connect url for tests

* use correct iframe url in e2e tests

* provide env for all steps of live tests

* add some output to manifest util

* add some debug output

* desparate fix
  • Loading branch information
frontendphil authored Jan 10, 2025
1 parent 995a206 commit ec1ef85
Show file tree
Hide file tree
Showing 14 changed files with 102 additions and 50 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/live-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ jobs:
playwright-e2e:
timeout-minutes: 60
runs-on: ubuntu-latest
env:
CONNECT_IFRAME_URL: https://connect.pilot.gnosisguild.org
if: github.event.deployment_status.state == 'success'
defaults:
run:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/prod-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ jobs:
build:
runs-on: ubuntu-latest
name: Build Extension
env:
CONNECT_IFRAME_URL: https://connect.pilot.gnosisguild.org
defaults:
run:
working-directory: ./deployables/extension
Expand All @@ -26,9 +28,7 @@ jobs:
pnpm build
- name: Update manifest.json with release tag
env:
RELEASE_TAG: ${{ github.event.release.tag_name }}
run: node ./manifest-util.js ./public/manifest.json
run: pnpm update-manifest -v ${{ github.event.release.tag_name }}

- name: Create extension zip file
run: pnpm zip
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ on:
jobs:
extension:
runs-on: ubuntu-latest
env:
CONNECT_IFRAME_URL: http://localhost
defaults:
run:
working-directory: ./deployables/extension
Expand Down
3 changes: 3 additions & 0 deletions deployables/app/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export default defineConfig(({ isSsrBuild }) => ({
}
: undefined,
},
server: {
port: 3040,
},
css: {
postcss: {
plugins: [tailwindcss, autoprefixer],
Expand Down
3 changes: 3 additions & 0 deletions deployables/extension/.env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Run `pnpm dev` in /example-app to start the example app locally
PLAYWRIGHT_TEST_BASE_URL=http://localhost:3030
# run `pnpm dev`` in /app to start the connect app locally
CONNECT_IFRAME_URL=http://localhost:3040/

# ... or use the deployed version of the example app
#PLAYWRIGHT_TEST_BASE_URL=https://zodiac-pilot-example-app.vercel.app
# CONNECT_IFRAME_URL=https://app.pilot.gnosisguild.org/
1 change: 1 addition & 0 deletions deployables/extension/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
public/_metadata
public/manifest.json

zodiac-pilot.zip

Expand Down
2 changes: 1 addition & 1 deletion deployables/extension/e2e/utils/mockWeb3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const mockWeb3 = async (

const getConnectFrame = (page: Page) => {
const frame = page.frame({
url: 'https://connect.pilot.gnosisguild.org/',
url: process.env.CONNECT_IFRAME_URL,
})

invariant(frame != null, 'Connect iframe not found')
Expand Down
6 changes: 4 additions & 2 deletions deployables/extension/esbuild.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,16 @@ esbuild
/** IMPORTANT: For scripts that are injected into other apps, it's crucial we build to IIFE format to avoid global scope clashes. */
format: 'iife',
treeShaking: true,
minify: process.env.NODE_ENV === 'production',
sourcemap: process.env.NODE_ENV !== 'production' ? 'inline' : 'linked',
minify: process.env.NODE_ENV !== 'development',
sourcemap: process.env.NODE_ENV === 'development' ? 'inline' : 'linked',
loader: {
'.svg': 'file',
'.woff': 'file',
'.woff2': 'file',
'.png': 'file',
'.html': 'text',
},

target: ['chrome96'],
outdir: './public/build',
publicPath: '/build',
Expand All @@ -59,6 +60,7 @@ esbuild
? `"http://127.0.0.1:${SERVE_PORT}/esbuild"`
: 'false',
global: 'window',
'process.env.CONNECT_IFRAME_URL': `"${process.env.CONNECT_IFRAME_URL}"`,
},
plugins: [
plugin(stdLibBrowser),
Expand Down
68 changes: 50 additions & 18 deletions deployables/extension/manifest-util.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,67 @@
import { invariant } from '@epic-web/invariant'
import chalk from 'chalk'
import { config } from 'dotenv'
import fs from 'fs'
import { parseArgs } from 'node:util'

config()

// this script is used to update the release value
// in the manifest.json when released through github
// actions. Meant to be used as a cli script:
//
// node manifest-util.js ./public/manifest.json

const main = () => {
const manifestPath = process.argv[2]
const releaseTag = process.env.RELEASE_TAG
if (!manifestPath) {
return console.log('Please provide a path to the manifest file.')
}
if (!releaseTag) {
return console.log('Please provide a RELEASE_TAG env variable.')
}

updateManifest(manifestPath, releaseTag)
}
const updateManifest = (templateFileName, outFileName, version) => {
const iframeUrl = process.env.CONNECT_IFRAME_URL

const updateManifest = (manifestFilename, releaseTag) => {
const version = releaseTag.replace('v', '')
invariant(iframeUrl != null, 'CONNECT_IFRAME_URL is missing')

try {
const data = fs.readFileSync(manifestFilename)
console.log(chalk.white.bold('Manifest template file:'))
console.log(new URL(templateFileName, import.meta.url).pathname)

const data = fs
.readFileSync(templateFileName)
.toString()
.replaceAll('<CONNECT_IFRAME_URL>', iframeUrl)

const manifest = JSON.parse(data)
manifest['version'] = version
fs.writeFileSync(manifestFilename, JSON.stringify(manifest))
manifest['version'] = version.replace('v', '')

console.log(chalk.white.bold('\nWriting manifest to:'))
console.log(new URL(outFileName, import.meta.url).pathname)

fs.writeFileSync(outFileName, JSON.stringify(manifest, undefined, 2))
} catch (error) {
console.log(error)
}
}

main()
const {
values: { template, outFile, version },
} = parseArgs({
options: {
template: {
type: 'string',
short: 't',
description: 'Path to the template file',
},
outFile: {
type: 'string',
short: 'o',
description: 'Path to the output file',
},
version: {
type: 'string',
short: 'v',
description: 'Version to update the manifest to',
default: 'v0.0.0',
},
},
})

invariant(template != null, 'Path to template file missing')
invariant(outFile != null, 'Path to output file missing')

updateManifest(template, outFile, version)
18 changes: 10 additions & 8 deletions deployables/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
"sideEffects": false,
"scripts": {
"clean": "rimraf public/build",
"prebuild": "pnpm clean",
"build": "NODE_ENV=production node esbuild.mjs",
"update-manifest": "node manifest-util.js -t ./src/manifest.template.json -o ./public/manifest.json",
"prebuild": "pnpm clean && pnpm update-manifest",
"build": "node esbuild.mjs",
"zip": "mv public zodiac-pilot && zip -vr zodiac-pilot.zip zodiac-pilot/ -x \"*.DS_Store\" && mv zodiac-pilot public",
"predev": "pnpm clean",
"dev": "NODE_ENV=development node esbuild.mjs",
"dev": "NODE_ENV=development pnpm build",
"test:unit": "vitest",
"test:e2e": "PW_CHROMIUM_ATTACH_TO_OTHER=1 playwright test --headed",
"test:e2e:ui": "pnpm test:e2e --ui",
Expand Down Expand Up @@ -56,6 +57,7 @@
"@zodiac/test-utils": "workspace:*",
"@zodiac/typescript-config": "workspace:*",
"autoprefixer": "^10.4.20",
"chalk": "^5.4.1",
"classnames": "^2.3.1",
"copy-to-clipboard": "^3.3.1",
"dotenv": "^16.0.1",
Expand Down Expand Up @@ -89,14 +91,14 @@
"dependencies": {
"@epic-web/invariant": "^1.0.0",
"@headlessui/react": "^2.2.0",
"@zodiac/chains": "workspace:*",
"@zodiac/schema": "workspace:*",
"@zodiac/ui": "workspace:*",
"date-fns": "^4.1.0",
"lucide-react": "^0.470.0",
"react-toastify": "11.0.2",
"react-router": "7.1.1",
"react-stick": "^5.0.6",
"zod": "^3.23.8",
"@zodiac/ui": "workspace:*",
"@zodiac/schema": "workspace:*",
"@zodiac/chains": "workspace:*"
"react-toastify": "11.0.2",
"zod": "^3.23.8"
}
}
13 changes: 7 additions & 6 deletions deployables/extension/src/connect/contentScripts/dApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import {
} from '@/messages'
import { invariant } from '@epic-web/invariant'

const CONNECT_IFRAME_URL = process.env.CONNECT_IFRAME_URL

invariant(CONNECT_IFRAME_URL != null, 'CONNECT_IFRAME_URL is required')

const ensureIframe = () => {
let node: HTMLIFrameElement | null = document.querySelector(
'iframe[src="https://connect.pilot.gnosisguild.org/"]',
`iframe[src="${CONNECT_IFRAME_URL}"]`,
)

if (!node) {
node = document.createElement('iframe')
node.src = 'https://connect.pilot.gnosisguild.org/'
node.src = CONNECT_IFRAME_URL
node.style.display = 'none'

const parent = document.body || document.documentElement
Expand All @@ -37,10 +41,7 @@ chrome.runtime.onConnect.addListener((port) => {
'cannot access connect iframe window',
)

iframe.contentWindow.postMessage(
message,
'https://connect.pilot.gnosisguild.org/',
)
iframe.contentWindow.postMessage(message, CONNECT_IFRAME_URL)

// wait for response
const handleResponse = (event: MessageEvent<ConnectedWalletMessage>) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "Zodiac Pilot",
"description": "Simulate dApp interactions and record transactions",
"version": "0.0.0",
"version": "<VERSION>",
"manifest_version": 3,
"icons": {
"16": "zodiac16.png",
Expand Down Expand Up @@ -34,27 +34,19 @@
"content_scripts": [
{
"matches": ["<all_urls>"],
"exclude_globs": [
"https://connect.pilot.gnosisguild.org/",
"about:*",
"chrome:*"
],
"exclude_globs": ["<CONNECT_IFRAME_URL>/", "about:*", "chrome:*"],
"run_at": "document_start",
"js": ["build/connect/contentScripts/dApp.js"]
},
{
"matches": ["https://connect.pilot.gnosisguild.org/"],
"matches": ["<CONNECT_IFRAME_URL>/"],
"run_at": "document_start",
"all_frames": true,
"js": ["build/connect/contentScripts/connectIframe.js"]
},
{
"matches": ["<all_urls>"],
"exclude_globs": [
"https://connect.pilot.gnosisguild.org/",
"about:*",
"chrome:*"
],
"exclude_globs": ["<CONNECT_IFRAME_URL>/", "about:*", "chrome:*"],
"run_at": "document_start",
"js": ["build/monitor/contentScript/main.js"]
}
Expand Down
3 changes: 3 additions & 0 deletions deployables/landing-page/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ export default defineConfig({
},
}),
],
server: {
port: 3050,
},
css: {
postcss: {
plugins: [tailwindcss, autoprefixer],
Expand Down
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ec1ef85

Please sign in to comment.