diff --git a/src/constants/misc.ts b/src/constants/misc.ts index 06d2003db7c..14b4a25763d 100644 --- a/src/constants/misc.ts +++ b/src/constants/misc.ts @@ -5,8 +5,8 @@ export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' // TODO(WEB-1984): Convert the deadline to minutes and remove unecessary conversions from // seconds to minutes in the codebase. -// 30 minutes, denominated in seconds -export const DEFAULT_DEADLINE_FROM_NOW = 60 * 30 +// 10 minutes, denominated in seconds +export const DEFAULT_DEADLINE_FROM_NOW = 60 * 10 export const L2_DEADLINE_FROM_NOW = 60 * 5 // transaction popup dismisal amounts diff --git a/src/state/migrations.test.ts b/src/state/migrations.test.ts index a23723e183c..7c99f600061 100644 --- a/src/state/migrations.test.ts +++ b/src/state/migrations.test.ts @@ -13,7 +13,7 @@ const defaultState = { user: {}, _persist: { rehydrated: true, - version: 0, + version: 1, }, application: { chainId: null, diff --git a/src/state/migrations.ts b/src/state/migrations.ts index f7d78e46a15..143c0e6f193 100644 --- a/src/state/migrations.ts +++ b/src/state/migrations.ts @@ -2,19 +2,21 @@ import { createMigrate, MigrationManifest, PersistedState, PersistMigrate } from import { MigrationConfig } from 'redux-persist/es/createMigrate' import { migration0 } from './migrations/0' +import { migration1 } from './migrations/1' import { legacyLocalStorageMigration } from './migrations/legacy' /** * These run once per state re-hydration when a version mismatch is detected. * Keep them as lightweight as possible. * - * Migration functions should not assume that any value exists in localStorage previously, - * because a user may be visiting the site for the first time or have cleared their localStorage. + * Migration functions should not assume that any value exists in the persisted data previously, + * because a user may be visiting the site for the first time or have cleared their data. */ // The target version number is the key export const migrations: MigrationManifest = { 0: migration0, + 1: migration1, } // We use a custom migration function for the initial state, because redux-persist diff --git a/src/state/migrations/1.test.ts b/src/state/migrations/1.test.ts new file mode 100644 index 00000000000..30c77054f46 --- /dev/null +++ b/src/state/migrations/1.test.ts @@ -0,0 +1,85 @@ +import { createMigrate } from 'redux-persist' +import { RouterPreference } from 'state/routing/types' +import { SlippageTolerance } from 'state/user/types' + +import { migration1, PersistAppStateV1 } from './1' + +const previousState: PersistAppStateV1 = { + user: { + userLocale: null, + userRouterPreference: RouterPreference.API, + userHideClosedPositions: false, + userSlippageTolerance: SlippageTolerance.Auto, + userSlippageToleranceHasBeenMigratedToAuto: true, + userDeadline: 1800, + tokens: {}, + pairs: {}, + timestamp: Date.now(), + hideBaseWalletBanner: false, + }, + _persist: { + version: 0, + rehydrated: true, + }, +} + +describe('migration to v1', () => { + it('should migrate the default deadline', async () => { + const migrator = createMigrate( + { + 1: migration1, + }, + { debug: false } + ) + const result: any = await migrator(previousState, 1) + expect(result?.user?.userDeadline).toEqual(600) + expect(result?._persist.version).toEqual(1) + + expect(result?.user?.userLocale).toEqual(null) + expect(result?.user?.userRouterPreference).toEqual(RouterPreference.API) + expect(result?.user?.userHideClosedPositions).toEqual(false) + expect(result?.user?.userSlippageTolerance).toEqual(SlippageTolerance.Auto) + expect(result?.user?.userSlippageToleranceHasBeenMigratedToAuto).toEqual(true) + expect(result?.user?.tokens).toEqual({}) + expect(result?.user?.pairs).toEqual({}) + expect(result?.user?.timestamp).toEqual(previousState.user?.timestamp) + expect(result?.user?.hideBaseWalletBanner).toEqual(false) + }) + + it('should not migrate a non-default value', async () => { + const migrator = createMigrate( + { + 1: migration1, + }, + { debug: false } + ) + const result: any = await migrator( + { + ...previousState, + user: { + ...previousState.user, + userDeadline: 300, + }, + } as PersistAppStateV1, + 1 + ) + expect(result?.user?.userDeadline).toEqual(300) + }) + + it('should not migrate if user state is not set', async () => { + const migrator = createMigrate( + { + 1: migration1, + }, + { debug: false } + ) + const result: any = await migrator( + { + ...previousState, + user: undefined, + } as PersistAppStateV1, + 1 + ) + expect(result?.user?.userDeadline).toBeUndefined() + }) +}) diff --git a/src/state/migrations/1.ts b/src/state/migrations/1.ts new file mode 100644 index 00000000000..a0a8f493abe --- /dev/null +++ b/src/state/migrations/1.ts @@ -0,0 +1,28 @@ +import { DEFAULT_DEADLINE_FROM_NOW } from 'constants/misc' +import { PersistState } from 'redux-persist' +import { UserState } from 'state/user/reducer' + +export type PersistAppStateV1 = { + _persist: PersistState +} & { user?: UserState } + +/** + * Migration to change the default user deadline from 30 minutes to 10 minutes. + * We only migrate if the saved deadline is the old default. + */ +export const migration1 = (state: PersistAppStateV1 | undefined) => { + if (state?.user && state.user?.userDeadline === 1800) { + return { + ...state, + user: { + ...state.user, + userDeadline: DEFAULT_DEADLINE_FROM_NOW, + }, + _persist: { + ...state._persist, + version: 1, + }, + } + } + return state +} diff --git a/src/state/reducer.ts b/src/state/reducer.ts index 963ad4f74f8..d884eb11cde 100644 --- a/src/state/reducer.ts +++ b/src/state/reducer.ts @@ -44,7 +44,7 @@ export type AppState = ReturnType const persistConfig: PersistConfig = { key: 'interface', - version: 0, // see migrations.ts for more details about this version + version: 1, // see migrations.ts for more details about this version storage: localForage.createInstance({ name: 'redux', }),