Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hydration migration #1333

Merged
merged 28 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4600846
Migration WIP
jvonasek May 22, 2024
848cbf6
Migration WIP
jvonasek May 23, 2024
3d447cb
removed debug
jvonasek May 23, 2024
94e5f4f
update trigger/target urls
jvonasek May 23, 2024
dbb8107
added more LS keys
jvonasek May 23, 2024
08caad5
added more LS keys
jvonasek May 23, 2024
1a49fcb
fixed query param parsing
jvonasek May 23, 2024
9c37d13
removed deprecated toast check
jvonasek May 23, 2024
d7137a2
Merge remote-tracking branch 'origin/master' into hydration-migration
jvonasek May 29, 2024
9ae1f34
Updated migration modals visuals
jvonasek May 29, 2024
854b071
update param key
jvonasek May 29, 2024
720b4ae
Allow user to cancel migration and stay on old domain
jvonasek May 30, 2024
38f5c76
force migration modal on every visit
jvonasek May 31, 2024
f03202e
Update WalletConnect project ID
jvonasek Jun 3, 2024
7f059b1
updated prod URL for referrals
jvonasek Jun 3, 2024
f33928e
Merge remote-tracking branch 'origin/master' into hydration-migration
jvonasek Jun 3, 2024
df81759
configured migration via env variables
jvonasek Jun 3, 2024
bb67a6c
fix hostname check
jvonasek Jun 3, 2024
3772521
Added banner to reverse import from new domain
jvonasek Jun 3, 2024
c98010a
Formatting
jvonasek Jun 3, 2024
828bbd6
Fix toast store init
jvonasek Jun 4, 2024
48d1041
Merge remote-tracking branch 'origin/master' into hydration-migration
jvonasek Jun 4, 2024
b5a13ee
Updated migration banner styles
jvonasek Jun 4, 2024
6065885
Use zustand for migration completed flag
jvonasek Jun 4, 2024
9672ae0
update .env
jvonasek Jun 4, 2024
a0eaf7e
Merge branch 'master' into hydration-migration
jvonasek Jun 5, 2024
ef870de
merge with rebrand
jvonasek Jun 5, 2024
19f1756
Merge branch 'master' into hydration-migration
jvonasek Jun 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ VITE_GRAFANA_URL=https://grafana-api.play.hydration.cloud/api/ds/query
VITE_GRAFANA_DSN=11
VITE_ENV=development
VITE_TRSRY_ADDR=7L53bUTBopuwFt3mKUfmkzgGLayYa1Yvn1hAg9v5UMrQzTfh
VITE_WC_PROJECT_ID=c47a5369367ec2dad6b49c478eb772f9
VITE_WC_PROJECT_ID=265a3fea03b46c14a46a201fbd6c552e
VITE_HDX_CAIP_ID=polkadot:afdc188f45c71dacbaa0b62e16a91f72
VITE_STABLECOIN_ASSET_ID=10
VITE_FF_SETTINGS_ENABLED=true
Expand All @@ -17,4 +17,6 @@ VITE_EVM_CHAIN_ID=222222
VITE_EVM_PROVIDER_URL=https://rpc.nice.hydration.cloud
VITE_EVM_EXPLORER_URL=https://explorer.nice.hydration.cloud
VITE_EVM_NATIVE_ASSET_ID=20
VITE_MIGRATION_TRIGGER_DOMAIN="deploy-preview-1333--testnet-hydra-app.netlify.app"
VITE_MIGRATION_TARGET_DOMAIN="deploy-preview-1334--testnet-hydra-app.netlify.app"

8 changes: 5 additions & 3 deletions .env.production
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
VITE_PROVIDER_URL=wss://rpc.hydradx.cloud
VITE_DOMAIN_URL=https://app.hydradx.io
VITE_DOMAIN_URL=https://app.hydration.net
VITE_INDEXER_URL=https://explorer.hydradx.cloud/graphql
VITE_SQUID_URL=https://hydra-data-squid.play.hydration.cloud/graphql
VITE_GRAFANA_URL=https://grafana.hydradx.cloud/api/ds/query
VITE_GRAFANA_DSN=10
VITE_ENV=production
VITE_TRSRY_ADDR=7L53bUTBopuwFt3mKUfmkzgGLayYa1Yvn1hAg9v5UMrQzTfh
VITE_WC_PROJECT_ID=c47a5369367ec2dad6b49c478eb772f9
VITE_WC_PROJECT_ID=265a3fea03b46c14a46a201fbd6c552e
VITE_HDX_CAIP_ID=polkadot:afdc188f45c71dacbaa0b62e16a91f72
VITE_STABLECOIN_ASSET_ID=10
VITE_FF_SETTINGS_ENABLED=false
Expand All @@ -16,4 +16,6 @@ VITE_REFERENDUM_DATA_URL=https://hydradx.subsquare.io/api/democracy/referendums
VITE_EVM_CHAIN_ID=222222
VITE_EVM_PROVIDER_URL=https://rpc.hydradx.cloud
VITE_EVM_EXPLORER_URL=https://explorer.evm.hydration.cloud
VITE_EVM_NATIVE_ASSET_ID=20
VITE_EVM_NATIVE_ASSET_ID=20
VITE_MIGRATION_TRIGGER_DOMAIN="app.hydradx.io"
VITE_MIGRATION_TARGET_DOMAIN="app.hydration.net"
4 changes: 3 additions & 1 deletion .env.rococo
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ VITE_GRAFANA_URL=https://grafana-api.play.hydration.cloud/api/ds/query
VITE_GRAFANA_DSN=11
VITE_ENV=rococo
VITE_TRSRY_ADDR=7L53bUTBopuwFt3mKUfmkzgGLayYa1Yvn1hAg9v5UMrQzTfh
VITE_WC_PROJECT_ID=c47a5369367ec2dad6b49c478eb772f9
VITE_WC_PROJECT_ID=265a3fea03b46c14a46a201fbd6c552e
VITE_HDX_CAIP_ID=polkadot:afdc188f45c71dacbaa0b62e16a91f72
VITE_STABLECOIN_ASSET_ID=10
VITE_FF_SETTINGS_ENABLED=false
Expand All @@ -17,3 +17,5 @@ VITE_EVM_CHAIN_ID=
VITE_EVM_PROVIDER_URL=
VITE_EVM_EXPLORER_URL=
VITE_EVM_NATIVE_ASSET_ID=20
VITE_MIGRATION_TRIGGER_DOMAIN=""
VITE_MIGRATION_TARGET_DOMAIN=""
256 changes: 256 additions & 0 deletions src/assets/icons/migration/MigrationLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 19 additions & 16 deletions src/components/AppProviders/AppProviders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { theme } from "theme"
import * as React from "react"
import * as Apps from "@galacticcouncil/apps"
import { createComponent } from "@lit-labs/react"
import { MigrationProvider } from "sections/migration/MigrationProvider"

const AppsPersistenceProvider = createComponent({
tagName: "gc-database-provider",
Expand All @@ -18,21 +19,23 @@ const AppsPersistenceProvider = createComponent({

export const AppProviders: FC<PropsWithChildren> = ({ children }) => {
return (
<TooltipProvider>
<RpcProvider>
<InvalidateOnBlock>
<ToastProvider>
<SkeletonTheme
baseColor={`rgba(${theme.rgbColors.white}, 0.12)`}
highlightColor={`rgba(${theme.rgbColors.white}, 0.24)`}
borderRadius={4}
>
<AppsPersistenceProvider>{children}</AppsPersistenceProvider>
<Transactions />
</SkeletonTheme>
</ToastProvider>
</InvalidateOnBlock>
</RpcProvider>
</TooltipProvider>
<MigrationProvider>
<TooltipProvider>
<RpcProvider>
<InvalidateOnBlock>
<ToastProvider>
<SkeletonTheme
baseColor={`rgba(${theme.rgbColors.white}, 0.12)`}
highlightColor={`rgba(${theme.rgbColors.white}, 0.24)`}
borderRadius={4}
>
<AppsPersistenceProvider>{children}</AppsPersistenceProvider>
<Transactions />
</SkeletonTheme>
</ToastProvider>
</InvalidateOnBlock>
</RpcProvider>
</TooltipProvider>
</MigrationProvider>
)
}
26 changes: 22 additions & 4 deletions src/components/WarningMessage/WarningMessage.styled.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
import { css } from "@emotion/react"
import styled from "@emotion/styled"
import { theme } from "theme"

export const SWarningMessageContainer = styled.div`
background: linear-gradient(90deg, #ff1f7a 41.09%, #57b3eb 100%);
type WarningMessageVariant = "pink" | "gradient"

const getStylesByVariant = (variant: WarningMessageVariant) => {
switch (variant) {
case "pink":
return css`
background: #dfb1f3;
color: #240e32;
`
case "gradient":
return css`
background: linear-gradient(90deg, #ff1f7a 41.09%, #57b3eb 100%);
color: ${theme.colors.white};
`
}
}

export const SWarningMessageContainer = styled.div<{
variant?: WarningMessageVariant
}>`
${({ variant = "gradient" }) => getStylesByVariant(variant)}

width: 100%;
cursor: pointer;
Expand All @@ -14,8 +34,6 @@ export const SWarningMessageContainer = styled.div`

padding: 8px;
z-index: ${theme.zIndices.header};

color: ${theme.colors.white};
`

export const SWarningMessageContent = styled.div`
Expand Down
10 changes: 9 additions & 1 deletion src/i18n/locales/en/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -896,5 +896,13 @@
"banner.newFarms.link": "Go to Liquidity \u2192",
"searchFilter.empty.title": "No results found",
"searchFilter.empty.desc": "Didn't find what you're looking for?",
"searchFilter.empty.link": "Join the Telegram"
"searchFilter.empty.link": "Join the Telegram",
"migration.export.title": "HydraDX is now Hydration",
"migration.export.description": "As part of the rebranding, this app has moved to app.hydration.net.",
"migration.export.question": "Would you like to migrate all past app settings to the new app?",
"migration.export.button": "Migrate Settings",
"migration.import.title": "Do you wish to overwrite your settings?",
"migration.import.description": "You already transferred your settings on {{ date, dd/MM/yyyy hh:mm:ss }}. Do you wish to overwrite your current settings?",
"migration.import.button": "Overwrite Settings",
"migration.warning.text": "You can transfer Your app settings from HydraDX to Hydration"
}
73 changes: 73 additions & 0 deletions src/sections/migration/MigrationProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { FC, PropsWithChildren, useState } from "react"
import { useLocation } from "react-use"
import {
MIGRATION_COMPLETE_FLAG,
MIGRATION_LS_KEYS,
MIGRATION_QUERY_PARAM,
MIGRATION_TARGET_DOMAIN,
MIGRATION_TRIGGER_DOMAIN,
serializeLocalStorage,
} from "sections/migration/MigrationProvider.utils"
import { MigrationWarning } from "sections/migration/components/MigrationWarning"
import { MigrationExportModal } from "./components/MigrationExportModal"
import { MigrationImportModal } from "./components/MigrationImportModal"

export const MigrationProvider: FC<PropsWithChildren> = ({ children }) => {
const { search, hostname } = useLocation()

const [migrationCanceled, setMigrationCanceled] = useState(false)

const paramKey = `?${MIGRATION_QUERY_PARAM}=`
const data = search?.replace(paramKey, "") ?? ""

const shouldExport = MIGRATION_TRIGGER_DOMAIN === hostname
const shouldImport =
MIGRATION_TARGET_DOMAIN === hostname && search?.startsWith(paramKey)

if (shouldImport) {
return <MigrationImportModal data={data} />
}

if (shouldExport && !migrationCanceled) {
return (
<MigrationExportModal
data={serializeLocalStorage(MIGRATION_LS_KEYS)}
onCancel={() => {
const qs = new URLSearchParams(search)
const from = qs.get("from")

if (from) {
window.location.href = `https://${from}`
} else {
setMigrationCanceled(true)
}
}}
/>
)
}

const shouldShowWarning =
MIGRATION_TARGET_DOMAIN === hostname &&
!localStorage.getItem(MIGRATION_COMPLETE_FLAG) &&
vkulinich-cl marked this conversation as resolved.
Show resolved Hide resolved
!migrationCanceled

return (
<>
{shouldShowWarning && (
<MigrationWarning
onClick={() =>
(window.location.href = `https://${MIGRATION_TRIGGER_DOMAIN}?from=${MIGRATION_TARGET_DOMAIN}`)
}
onClose={() => {
setMigrationCanceled(true)
localStorage.setItem(
MIGRATION_COMPLETE_FLAG,
new Date().toISOString(),
)
}}
/>
)}
{children}
</>
)
}
45 changes: 45 additions & 0 deletions src/sections/migration/MigrationProvider.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Buffer } from "buffer"

export const MIGRATION_LS_KEYS = [
"external-tokens",
"address-book",
"toasts",
"rpcUrl",
"hydradx-rpc-list",
"referral-codes",
"dca.settings",
"trade.settings",
]
export const MIGRATION_COMPLETE_FLAG = "__migration-completed"
export const MIGRATION_QUERY_PARAM = "migration"
export const MIGRATION_TRIGGER_DOMAIN = import.meta.env
.VITE_MIGRATION_TRIGGER_DOMAIN as string

export const MIGRATION_TARGET_DOMAIN = import.meta.env
.VITE_MIGRATION_TARGET_DOMAIN

export const serializeLocalStorage = (keys: string[]): string => {
const data: { [key: string]: any } = {}

keys.forEach((key) => {
const value = localStorage.getItem(key)
if (value) {
data[key] = JSON.parse(value)
}
})

const json = JSON.stringify(data)
return Buffer.from(json, "binary").toString("base64")
}

export const importToLocalStorage = (data: string) => {
const json = Buffer.from(data, "base64").toString("utf-8")
const ls = JSON.parse(json)

const keys = Object.keys(ls)

keys.forEach((key) => {
const value = ls[key]
localStorage.setItem(key, JSON.stringify(value))
})
}
58 changes: 58 additions & 0 deletions src/sections/migration/components/MigrationExportModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { FC } from "react"
import { Button } from "components/Button/Button"
import { Modal } from "components/Modal/Modal"
import { Text } from "components/Typography/Text/Text"
import {
MIGRATION_QUERY_PARAM,
MIGRATION_TARGET_DOMAIN,
} from "sections/migration/MigrationProvider.utils"
import MigrationLogo from "assets/icons/migration/MigrationLogo.svg?react"
import { useTranslation } from "react-i18next"
import { Separator } from "components/Separator/Separator"

export const MigrationExportModal: FC<{
data: string
onCancel: () => void
}> = ({ data, onCancel }) => {
const { t } = useTranslation()

return (
<Modal open headerVariant="FontOver">
jvonasek marked this conversation as resolved.
Show resolved Hide resolved
<MigrationLogo sx={{ mx: "auto" }} />
<Text tAlign="center" font="FontOver" fs={19} sx={{ mt: 12 }}>
{t("migration.export.title")}
</Text>
<Text
tAlign="center"
sx={{ mt: 12, maxWidth: 500, mx: "auto" }}
color="basic400"
>
{t("migration.export.description")}
</Text>
<Text
tAlign="center"
sx={{ mt: 12, maxWidth: 500, mx: "auto" }}
color="basic400"
>
{t("migration.export.question")}
</Text>
<Separator
sx={{ mx: [-20, -32], mt: ["auto", 50], mb: [12, 30], width: "auto" }}
color="darkBlue401"
/>
<div sx={{ flex: "row", justify: "space-between" }}>
<Button onClick={onCancel}>{t("toast.close")}</Button>

<Button
variant="primary"
onClick={() => {
const targetUrl = `https://${MIGRATION_TARGET_DOMAIN}?${MIGRATION_QUERY_PARAM}=${data}`
window.location.href = targetUrl
}}
>
{t("migration.export.button")}
</Button>
</div>
</Modal>
)
}
Loading
Loading