diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f36cfe5cc..e112f4d5d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -315,6 +315,55 @@ jobs: with: name: build-tbtc-bridge-v1 path: connect-loader/apps/connect-v1/dist + + sky-bridge-v1: + name: "USDS Bridge v1" + runs-on: "ubuntu-latest" + concurrency: + group: ${{ github.ref }}-${{inputs.name}}-sky-bridge-v1 + cancel-in-progress: true + environment: ${{inputs.environment}} + outputs: + pkg-version: ${{ steps.set-version.outputs._PKG_VERSION }} + steps: + - name: Set up Node environment + uses: actions/setup-node@v3 + with: + node-version: v18.17.1 + - name: Checkout Custom Wormhole Connect Loader + uses: actions/checkout@v3 + with: + ref: ${{ inputs.project-branch }} + path: connect-loader + - name: Setup Git + run: | + pushd connect-loader + git config user.name "xLabs CI" + git config user.email "devops@xlabs.xyz" + - name: Set Portal Bridge Version + id: set-version + run: | + pushd connect-loader/apps/connect-v1 + echo "_PKG_VERSION=$(node -p -e "require('./package.json').version")-${{inputs.separator}}$(echo ${{ github.sha }} | cut -c -10)" >> "${GITHUB_OUTPUT}" + - name: Build Custom Wormhole Connect Loader + env: + PUBLIC_URL: "${{ inputs.public-url }}" + VITE_PUBLIC_URL: ${{ inputs.public-url }} + VITE_APP_VERSION: ${{ steps.set-version.outputs._PKG_VERSION }} + VITE_APP_CLUSTER: ${{ vars.REACT_APP_CLUSTER }} + # VITE_APP_JS_WC_INTEGRITY_SHA_384: ${{ steps.wormhole-connect.outputs._JS_SHA_384 }} + # VITE_APP_CSS_WC_INTEGRITY_SHA_384: ${{ steps.wormhole-connect.outputs._CSS_SHA_384 }} + VITE_APP_WALLET_CONNECT_PROJECT_ID: ${{ secrets.REACT_APP_WALLET_CONNECT_PROJECT_ID }} + run: | + pushd connect-loader/apps/connect-v1 + npm ci + echo 'VITE_APP_VERSION=$npm_package_version' > .env + npm run build:sky-bridge + - name: Upload Portal Bridge Artifact + uses: actions/upload-artifact@v3 + with: + name: build-sky-bridge-v1 + path: connect-loader/apps/connect-v1/dist token-bridge-v1: name: "Token Bridge v1" @@ -372,6 +421,7 @@ jobs: - usdc-bridge - token-bridge - tbtc-bridge-v1 + - sky-bridge-v1 - token-bridge-v1 - rewards-dashboard - redirects @@ -393,6 +443,11 @@ jobs: with: name: build-tbtc-bridge-v1 path: tbtc-bridge + - name: Download Artifact + uses: actions/download-artifact@v3 + with: + name: build-sky-bridge-v1 + path: sky-bridge - name: Download Artifact uses: actions/download-artifact@v3 with: diff --git a/apps/connect-v1/package-lock.json b/apps/connect-v1/package-lock.json index c20eace01..4e9e81f05 100644 --- a/apps/connect-v1/package-lock.json +++ b/apps/connect-v1/package-lock.json @@ -14,7 +14,7 @@ "@mui/icons-material": "^5.14.11", "@mui/material": "^5.12.1", "@tanstack/react-query": "^5.14.2", - "@wormhole-foundation/wormhole-connect": "^0.3.22-beta.6-development", + "@wormhole-foundation/wormhole-connect": "^0.3.23-beta.0-development", "aptos": "^1.21.0", "bech32": "^2.0.0", "dompurify": "^3.0.6", @@ -17948,9 +17948,9 @@ } }, "node_modules/@wormhole-foundation/wormhole-connect": { - "version": "0.3.22-beta.6-development", - "resolved": "https://registry.npmjs.org/@wormhole-foundation/wormhole-connect/-/wormhole-connect-0.3.22-beta.6-development.tgz", - "integrity": "sha512-zD4Uy8e44m3mv6PvhAVvwKaAHbGyrLb9EfN7Nf8HVTEHkYUmEogGdHwG5unubwkIuuVELeSa4nsnMIAVEVHPvQ==", + "version": "0.3.23-beta.0-development", + "resolved": "https://registry.npmjs.org/@wormhole-foundation/wormhole-connect/-/wormhole-connect-0.3.23-beta.0-development.tgz", + "integrity": "sha512-dwWqupHqjd8s+r8lIcF5xKqFLAI+VDteaaBqMqdHs2jiXpFICDUlldPTIMfQHG/n3n57QJbHDOp4qTBlPvuIug==", "dependencies": { "@certusone/wormhole-sdk": "^0.10.10", "@coral-xyz/anchor": "^0.29.0", diff --git a/apps/connect-v1/package.json b/apps/connect-v1/package.json index b8879dad1..833ef5fba 100644 --- a/apps/connect-v1/package.json +++ b/apps/connect-v1/package.json @@ -12,6 +12,10 @@ "dev:token-bridge:mainnet": "cross-env VITE_APP_CLUSTER=mainnet npm run dev:token-bridge", "dev:token-bridge:testnet": "cross-env VITE_APP_CLUSTER=testnet npm run dev:token-bridge", "build:token-bridge": "cross-env VITE_APP_CLUSTER=mainnet tsc && cross-env VITE_APP_CLUSTER=mainnet vite build --config ./vite.token-bridge.config.ts", + "dev:sky-bridge": "vite --config ./vite.sky-bridge.config.ts", + "dev:sky-bridge:mainnet": "cross-env VITE_APP_CLUSTER=mainnet npm run dev:sky-bridge", + "dev:sky-bridge:testnet": "cross-env VITE_APP_CLUSTER=testnet npm run dev:sky-bridge", + "build:sky-bridge": "cross-env VITE_APP_CLUSTER=mainnet tsc && cross-env VITE_APP_CLUSTER=mainnet vite build --config ./vite.sky-bridge.config.ts", "dev": "npm run dev:token-bridge:testnet", "start": "npm run dev", "build": "tsc && vite build", @@ -30,7 +34,7 @@ "@mui/icons-material": "^5.14.11", "@mui/material": "^5.12.1", "@tanstack/react-query": "^5.14.2", - "@wormhole-foundation/wormhole-connect": "^0.3.22-beta.6-development", + "@wormhole-foundation/wormhole-connect": "^0.3.23-beta.0-development", "aptos": "^1.21.0", "bech32": "^2.0.0", "dompurify": "^3.0.6", diff --git a/apps/connect-v1/src/env/sky-bridge.mainnet.ts b/apps/connect-v1/src/env/sky-bridge.mainnet.ts new file mode 100644 index 000000000..152398d0a --- /dev/null +++ b/apps/connect-v1/src/env/sky-bridge.mainnet.ts @@ -0,0 +1,77 @@ +import { ENV as ENV_BASE } from "./sky-bridge"; +import { mergeDeep } from "../utils/mergeDeep"; +import type { WormholeConnectConfig } from "@wormhole-foundation/wormhole-connect"; +import { Env, MAINNET_RPCS } from "./common"; + +export const ENV: Env = { + ...ENV_BASE, + wormholeConnectConfig: mergeDeep( + ENV_BASE.wormholeConnectConfig, + { + rpcs: MAINNET_RPCS, + networks: [ + "ethereum", + "solana", + ], + tokensConfig: { + USDSsolana: { + key: 'USDSsolana', + symbol: 'USDS', + nativeChain: 'solana', + tokenId: { + chain: 'solana', + address: 'USDSwr9ApdHk5bvJKMjzff41FfuX8bSxdKcR81vTwcA', + }, + icon: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' id='USDS-Coin' version='1.1' viewBox='0 0 1000 1000'%3E%3Cdefs%3E%3Cstyle%3E .cls-1 %7B fill: url(%23radial-gradient); %7D .cls-1, .cls-2 %7B stroke-width: 0px; %7D .cls-2 %7B fill: %23fff; %7D %3C/style%3E%3CradialGradient id='radial-gradient' cx='976.2772395' cy='23.9735075' fx='976.2772395' fy='23.9735075' r='2.0690868' gradientTransform='translate(-18064.581412 757167.6887207) rotate(-90) scale(774.3790283)' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23ffd232'/%3E%3Cstop offset='1' stop-color='%23ff6d6d'/%3E%3C/radialGradient%3E%3C/defs%3E%3Cg id='USDS-Coin-2'%3E%3Ccircle id='Element' class='cls-1' cx='500' cy='500' r='500'/%3E%3Cpath id='Element-2' class='cls-2' d='M308.7752075,631.4499512h-71.1536255c5.8073578,111.0870361,98.7437439,207.6535034,263.558075,207.6535034,164.0899963,0,268.643158-90.0327148,268.643158-206.2026367,0-220.7210693-333.2608948-208.3778076-333.2608948-336.1646118,0-35.5768127,26.8637085-77.6894531,89.3042297-77.6894531,69.7028198,0,151.7467651,54.4559021,157.5562134,124.1566467h70.427124c-7.2602539-112.5398407-116.8963623-190.9537048-256.2999573-190.9537048-144.4844666,0-253.3941803,84.2232666-253.3941803,203.2969055,0,227.2569885,333.26091,197.4875183,333.26091,337.6174622,0,43.5634766-26.8637085,79.8667603-94.387207,79.8667603-84.2232971,0-169.1729736-58.8104248-174.2539062-141.5808716h.000061ZM368.3120117,313.4359436c0,172.8010559,330.3572388,138.677124,330.3572388,323.0970154,0,55.1802368-36.3032837,103.8267212-79.8667603,116.1679077,15.2468872-14.5205078,26.8637085-46.4672241,26.8637085-76.9609985,0-170.6238403-331.0836487-147.3901978-331.0836487-322.370575,0-58.812439,37.7561035-106.0060425,84.9496765-120.5264893-18.1526489,21.7807007-31.2202454,50.0972595-31.2202454,80.5931396h.0000305Z'/%3E%3C/g%3E%3C/svg%3E", + coinGeckoId: 'usds', + decimals: { + default: 6, + }, + }, + + USDSethereum: { + key: 'USDSethereum', + symbol: 'USDS', + nativeChain: 'ethereum', + tokenId: { + chain: 'ethereum', + address: '0xdC035D45d973E3EC169d2276DDab16f1e407384F', + }, + icon: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' id='USDS-Coin' version='1.1' viewBox='0 0 1000 1000'%3E%3Cdefs%3E%3Cstyle%3E .cls-1 %7B fill: url(%23radial-gradient); %7D .cls-1, .cls-2 %7B stroke-width: 0px; %7D .cls-2 %7B fill: %23fff; %7D %3C/style%3E%3CradialGradient id='radial-gradient' cx='976.2772395' cy='23.9735075' fx='976.2772395' fy='23.9735075' r='2.0690868' gradientTransform='translate(-18064.581412 757167.6887207) rotate(-90) scale(774.3790283)' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23ffd232'/%3E%3Cstop offset='1' stop-color='%23ff6d6d'/%3E%3C/radialGradient%3E%3C/defs%3E%3Cg id='USDS-Coin-2'%3E%3Ccircle id='Element' class='cls-1' cx='500' cy='500' r='500'/%3E%3Cpath id='Element-2' class='cls-2' d='M308.7752075,631.4499512h-71.1536255c5.8073578,111.0870361,98.7437439,207.6535034,263.558075,207.6535034,164.0899963,0,268.643158-90.0327148,268.643158-206.2026367,0-220.7210693-333.2608948-208.3778076-333.2608948-336.1646118,0-35.5768127,26.8637085-77.6894531,89.3042297-77.6894531,69.7028198,0,151.7467651,54.4559021,157.5562134,124.1566467h70.427124c-7.2602539-112.5398407-116.8963623-190.9537048-256.2999573-190.9537048-144.4844666,0-253.3941803,84.2232666-253.3941803,203.2969055,0,227.2569885,333.26091,197.4875183,333.26091,337.6174622,0,43.5634766-26.8637085,79.8667603-94.387207,79.8667603-84.2232971,0-169.1729736-58.8104248-174.2539062-141.5808716h.000061ZM368.3120117,313.4359436c0,172.8010559,330.3572388,138.677124,330.3572388,323.0970154,0,55.1802368-36.3032837,103.8267212-79.8667603,116.1679077,15.2468872-14.5205078,26.8637085-46.4672241,26.8637085-76.9609985,0-170.6238403-331.0836487-147.3901978-331.0836487-322.370575,0-58.812439,37.7561035-106.0060425,84.9496765-120.5264893-18.1526489,21.7807007-31.2202454,50.0972595-31.2202454,80.5931396h.0000305Z'/%3E%3C/g%3E%3C/svg%3E", + coinGeckoId: 'usds', + decimals: { + default: 18, + }, + }, + }, + nttGroups: { + USDS: { + nttManagers: [ + { + chainName: 'ethereum', + address: '0x7d4958454a3f520bDA8be764d06591B054B0bf33', + tokenKey: 'USDSethereum', + transceivers: [ + { + address: '0x16D2b6c87A18cB59DD59EFa3aa50055667cf481d', + type: 'wormhole', + }, + ], + }, + { + chainName: 'solana', + address: 'STTUVCMPuNbk21y1J6nqEGXSQ8HKvFmFBKnCvKHTrWn', + tokenKey: 'USDSsolana', + transceivers: [ + { + address: '4ZQYCg7ZiVeNp9DxUbgc4b9JpLXoX1RXYfMXS5saXpkC', + type: 'wormhole', + }, + ], + } + ] + }, + }, + } + ), +}; diff --git a/apps/connect-v1/src/env/sky-bridge.testnet.ts b/apps/connect-v1/src/env/sky-bridge.testnet.ts new file mode 100644 index 000000000..4438bd61c --- /dev/null +++ b/apps/connect-v1/src/env/sky-bridge.testnet.ts @@ -0,0 +1,17 @@ +import { ENV as ENV_BASE } from "./sky-bridge"; +import { mergeDeep } from "../utils/mergeDeep"; +import type { WormholeConnectConfig } from "@wormhole-foundation/wormhole-connect"; +import { Env } from "./common"; + +export const ENV: Env = { + ...ENV_BASE, + wormholeConnectConfig: mergeDeep( + ENV_BASE.wormholeConnectConfig, + { + networks: [ + "goerli", + "solana", + ], + } + ), +}; diff --git a/apps/connect-v1/src/env/sky-bridge.ts b/apps/connect-v1/src/env/sky-bridge.ts new file mode 100644 index 000000000..1f1966c5c --- /dev/null +++ b/apps/connect-v1/src/env/sky-bridge.ts @@ -0,0 +1,25 @@ +import { type WormholeConnectConfig } from "@wormhole-foundation/wormhole-connect"; +import { Env, PUBLIC_URL, wormholeConnectConfigCommon } from "./common"; + +export const ENV: Env = { + PUBLIC_URL, + navBar: [ + { label: "Home", href: `${PUBLIC_URL}/` }, + // { + // label: "Staking", + // href: "https://www.tally.xyz/gov/wormhole", + // isBlank: true, + // }, + { label: "USDC", href: `${PUBLIC_URL}/usdc-bridge` }, + { label: "tBTC", href: `${PUBLIC_URL}/tbtc-bridge` }, + { label: "Rewards", href: `${PUBLIC_URL}/rewards-dashboard` }, + ], + redirects: undefined, + wormholeConnectConfig: { + ...wormholeConnectConfigCommon, + pageHeader: { + text: "USDS Transfer", + align: "center", + }, + } as WormholeConnectConfig, +}; diff --git a/apps/connect-v1/vite.sky-bridge.config.ts b/apps/connect-v1/vite.sky-bridge.config.ts new file mode 100644 index 000000000..46a16454f --- /dev/null +++ b/apps/connect-v1/vite.sky-bridge.config.ts @@ -0,0 +1,84 @@ +import { defineConfig } from "vite"; +import viteConfig from "./vite.config"; +import { createHtmlPlugin } from "vite-plugin-html"; +import { resolve } from "path"; +import packageJson from "./package.json"; +const PUBLIC_URL = viteConfig.base; + +// https://vitejs.dev/config/ +export default defineConfig({ + ...viteConfig, + resolve: { + ...viteConfig.resolve, + alias: [ + ...((viteConfig.resolve?.alias as []) || []), + { + find: "@env", + replacement: resolve( + __dirname, + `./src/env/sky-bridge.${process.env.VITE_APP_CLUSTER === "mainnet" ? "mainnet" : "testnet"}.ts` + ), + }, + ], + }, + define: {}, + base: `${PUBLIC_URL}/sky-bridge/`, + plugins: [ + ...(viteConfig.plugins as []), + createHtmlPlugin({ + inject: { + tags: [ + { + injectTo: "head-prepend", + tag: "meta", + attrs: { + name: "Token Bridge", + content: `v${process.env.VITE_APP_VERSION || "0.0.0"}`, + }, + }, + { + injectTo: "head-prepend", + tag: "meta", + attrs: { + name: "Wormhole connect", + content: `v${packageJson.dependencies["@wormhole-foundation/wormhole-connect"]}`, + }, + }, + { + injectTo: "head-prepend", + tag: "title", + children: "Token Bridge", + }, + { + injectTo: "head-prepend", + tag: "meta", + attrs: { "og:title": "Portal Token Bridge" }, + }, + { + injectTo: "head-prepend", + tag: "meta", + attrs: { "og:url": "https://portalbridge.com" }, + }, + { + injectTo: "head-prepend", + tag: "meta", + attrs: { + name: "description", + content: + "Portal is a bridge that offers unlimited transfers across chains for tokens and NFTs wrapped by Wormhole.", + }, + }, + { + injectTo: "head-prepend", + tag: "meta", + attrs: { + property: "og:description", + content: + "Portal is a bridge that offers unlimited transfers across chains for tokens and NFTs wrapped by Wormhole.", + }, + }, + ], + }, + }), + ], +});