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

chore: add remote config variable for decentralised phone verification paths #3603

Merged
merged 13 commits into from
Mar 31, 2023
15 changes: 10 additions & 5 deletions src/account/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
} from 'src/app/actions'
import {
hapticFeedbackEnabledSelector,
odisV1EOLSelector,
phoneNumberVerifiedSelector,
sessionIdSelector,
supportedBiometryTypeSelector,
Expand Down Expand Up @@ -100,6 +101,7 @@ interface StateProps {
supportedBiometryType: BIOMETRY_TYPE | null
shouldShowRecoveryPhraseInSettings: boolean
hapticFeedbackEnabled: boolean
odisV1EOL: boolean
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: seems simpler, no?

Suggested change
odisV1EOL: boolean
odisV1Enabled: boolean

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol, yes this is better. i updated

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol sorry, even more 2nd thoughts: decentralizedVerificationEnabled instead?
super nit 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol, i'm also fine with that. updated

}

type OwnProps = NativeStackScreenProps<StackParamList, Screens.Settings>
Expand All @@ -125,6 +127,7 @@ const mapStateToProps = (state: RootState): StateProps => {
supportedBiometryType: supportedBiometryTypeSelector(state),
shouldShowRecoveryPhraseInSettings: shouldShowRecoveryPhraseInSettingsSelector(state),
hapticFeedbackEnabled: hapticFeedbackEnabledSelector(state),
odisV1EOL: odisV1EOLSelector(state),
}
}

Expand Down Expand Up @@ -248,11 +251,13 @@ export class Account extends React.Component<Props, State> {
)}
</RevokePhoneNumber>
</View>
<View style={styles.devSettingsItem}>
<TouchableOpacity onPress={this.showConfirmRevokeModal}>
<Text>Revoke Number Verification (on-chain)</Text>
</TouchableOpacity>
</View>
{!this.props.odisV1EOL && (
<View style={styles.devSettingsItem}>
<TouchableOpacity onPress={this.showConfirmRevokeModal}>
<Text>Revoke Number Verification (on-chain)</Text>
</TouchableOpacity>
</View>
)}
<View style={styles.devSettingsItem}>
<TouchableOpacity onPress={this.resetAppOpenedState}>
<Text>Reset app opened state</Text>
Expand Down
2 changes: 2 additions & 0 deletions src/app/reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export interface State {
networkTimeoutSeconds: number
celoNews: CeloNewsConfig
hapticFeedbackEnabled: boolean
odisV1EOL: boolean
}

const initialState = {
Expand Down Expand Up @@ -101,6 +102,7 @@ const initialState = {
networkTimeoutSeconds: REMOTE_CONFIG_VALUES_DEFAULTS.networkTimeoutSeconds,
celoNews: JSON.parse(REMOTE_CONFIG_VALUES_DEFAULTS.celoNews),
hapticFeedbackEnabled: true,
odisV1EOL: REMOTE_CONFIG_VALUES_DEFAULTS.odisV1EOL,
}

export const appReducer = (
Expand Down
15 changes: 15 additions & 0 deletions src/app/saga.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
getLastTimeBackgrounded,
getRequirePinOnAppOpen,
inviterAddressSelector,
odisV1EOLSelector,
shouldRunVerificationMigrationSelector,
} from 'src/app/selectors'
import { handleDappkitDeepLink } from 'src/dappkit/dappkit'
Expand Down Expand Up @@ -408,6 +409,7 @@ describe('runCentralPhoneVerificationMigration', () => {

await expectSaga(runCentralPhoneVerificationMigration)
.provide([
[select(odisV1EOLSelector), false],
[select(dataEncryptionKeySelector), 'someDEK'],
[select(shouldRunVerificationMigrationSelector), true],
[select(inviterAddressSelector), '0x123'],
Expand Down Expand Up @@ -439,6 +441,7 @@ describe('runCentralPhoneVerificationMigration', () => {

await expectSaga(runCentralPhoneVerificationMigration)
.provide([
[select(odisV1EOLSelector), false],
[select(dataEncryptionKeySelector), 'someDEK'],
[select(shouldRunVerificationMigrationSelector), true],
[select(inviterAddressSelector), undefined],
Expand Down Expand Up @@ -469,12 +472,22 @@ describe('runCentralPhoneVerificationMigration', () => {
it('should not run if migration conditions are not met', async () => {
await expectSaga(runCentralPhoneVerificationMigration)
.provide([
[select(odisV1EOLSelector), false],
[select(dataEncryptionKeySelector), 'someDEK'],
[select(shouldRunVerificationMigrationSelector), false],
])
.not.put(phoneNumberVerificationMigrated())
.run()

await expectSaga(runCentralPhoneVerificationMigration)
.provide([
[select(odisV1EOLSelector), true],
[select(dataEncryptionKeySelector), 'someDEK'],
[select(shouldRunVerificationMigrationSelector), true],
])
.not.put(phoneNumberVerificationMigrated())
.run()

expect(mockFetch).not.toHaveBeenCalled()
})

Expand All @@ -483,6 +496,7 @@ describe('runCentralPhoneVerificationMigration', () => {
it('should not run if migration conditions there is no signed message', async () => {
await expectSaga(runCentralPhoneVerificationMigration)
.provide([
[select(odisV1EOLSelector), false],
[select(dataEncryptionKeySelector), 'someDEK'],
[select(shouldRunVerificationMigrationSelector), true],
[select(inviterAddressSelector), undefined],
Expand All @@ -500,6 +514,7 @@ describe('runCentralPhoneVerificationMigration', () => {
it('should not run if no DEK can be found', async () => {
await expectSaga(runCentralPhoneVerificationMigration)
.provide([
[select(odisV1EOLSelector), false],
[select(dataEncryptionKeySelector), null],
[select(shouldRunVerificationMigrationSelector), true],
])
Expand Down
5 changes: 4 additions & 1 deletion src/app/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
googleMobileServicesAvailableSelector,
huaweiMobileServicesAvailableSelector,
inviterAddressSelector,
odisV1EOLSelector,
sentryNetworkErrorsSelector,
shouldRunVerificationMigrationSelector,
} from 'src/app/selectors'
Expand Down Expand Up @@ -212,6 +213,7 @@ export interface RemoteConfigValues {
dappsFilterEnabled: boolean
dappsSearchEnabled: boolean
requireCPV: boolean
odisV1EOL: boolean
}

export function* appRemoteFeatureFlagSaga() {
Expand Down Expand Up @@ -384,8 +386,9 @@ export function* handleSetAppState(action: SetAppState) {
}

export function* runCentralPhoneVerificationMigration() {
const odisV1EOL = yield select(odisV1EOLSelector)
const shouldRunVerificationMigration = yield select(shouldRunVerificationMigrationSelector)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We should update shouldRunVerificationMigrationSelector instead and add the new condition there?
Otherwise this selector name becomes a bit misleading.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah oops, yes you're right. updated!

if (!shouldRunVerificationMigration) {
if (odisV1EOL || !shouldRunVerificationMigration) {
return
}

Expand Down
2 changes: 2 additions & 0 deletions src/app/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,5 @@ export const networkTimeoutSecondsSelector = (state: RootState) => state.app.net
export const celoNewsConfigSelector = (state: RootState) => state.app.celoNews

export const hapticFeedbackEnabledSelector = (state: RootState) => state.app.hapticFeedbackEnabled

export const odisV1EOLSelector = (state: RootState) => state.app.odisV1EOL
1 change: 1 addition & 0 deletions src/firebase/firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ export async function fetchRemoteConfigValues(): Promise<RemoteConfigValues | nu
dappsFilterEnabled: flags.dappsFilterEnabled.asBoolean(),
dappsSearchEnabled: flags.dappsSearchEnabled.asBoolean(),
requireCPV: flags.requireCPV.asBoolean(),
odisV1EOL: flags.odisV1EOL.asBoolean(),
}
}

Expand Down
1 change: 1 addition & 0 deletions src/firebase/remoteConfigValuesDefaults.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,5 @@ export const REMOTE_CONFIG_VALUES_DEFAULTS: Omit<
dappsFilterEnabled: false,
dappsSearchEnabled: false,
requireCPV: false,
odisV1EOL: false,
}
1 change: 1 addition & 0 deletions src/firebase/remoteConfigValuesDefaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,5 @@ export const REMOTE_CONFIG_VALUES_DEFAULTS: Omit<
dappsFilterEnabled: false,
dappsSearchEnabled: false,
requireCPV: false,
odisV1EOL: false,
}
7 changes: 7 additions & 0 deletions src/identity/contactMapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { showErrorOrFallback } from 'src/alert/actions'
import { IdentityEvents } from 'src/analytics/Events'
import ValoraAnalytics from 'src/analytics/ValoraAnalytics'
import { ErrorMessages } from 'src/app/ErrorMessages'
import { odisV1EOLSelector } from 'src/app/selectors'
import { fetchLostAccounts } from 'src/firebase/firebase'
import {
Actions,
Expand Down Expand Up @@ -221,6 +222,12 @@ function* getAccountAddresses(e164Number: string) {
}

export function* fetchWalletAddressesDecentralized(e164Number: string) {
// once odis v1 is EOL'ed, we can remove this whole path for fetching wallet addresses
const odisV1EOL = yield select(odisV1EOLSelector)
if (odisV1EOL) {
return []
}

const contractKit = yield call(getContractKit)
const accountsWrapper: AccountsWrapper = yield call([
contractKit.contracts,
Expand Down
1 change: 1 addition & 0 deletions src/redux/migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1097,4 +1097,5 @@ export const migrations = {
},
}),
119: (state: any) => state,
120: (state: any) => state,
}
3 changes: 2 additions & 1 deletion src/redux/store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ describe('store state', () => {
Object {
"_persist": Object {
"rehydrated": true,
"version": 119,
"version": 120,
},
"account": Object {
"acceptedTerms": false,
Expand Down Expand Up @@ -155,6 +155,7 @@ describe('store state', () => {
"minVersion": null,
"networkTimeoutSeconds": 30,
"numberVerified": false,
"odisV1EOL": false,
"paymentDeepLinkHandler": "",
"phoneNumberVerified": false,
"pincodeUseExpandedBlocklist": false,
Expand Down
2 changes: 1 addition & 1 deletion src/redux/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const persistConfig: PersistConfig<RootState> = {
key: 'root',
// default is -1, increment as we make migrations
// See https://github.com/valora-inc/wallet/tree/main/WALLET.md#redux-state-migration
version: 119,
version: 120,
keyPrefix: `reduxStore-`, // the redux-persist default is `persist:` which doesn't work with some file systems.
storage: FSStorage(),
blacklist: ['networkInfo', 'alert', 'imports', 'swap'],
Expand Down
4 changes: 4 additions & 0 deletions test/RootStateSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2464,6 +2464,9 @@
"numberVerified": {
"type": "boolean"
},
"odisV1EOL": {
"type": "boolean"
},
"paymentDeepLinkHandler": {
"$ref": "#/definitions/PaymentDeepLinkHandler"
},
Expand Down Expand Up @@ -2565,6 +2568,7 @@
"minVersion",
"networkTimeoutSeconds",
"numberVerified",
"odisV1EOL",
"paymentDeepLinkHandler",
"phoneNumberVerified",
"pincodeUseExpandedBlocklist",
Expand Down
14 changes: 13 additions & 1 deletion test/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2148,6 +2148,18 @@ export const v119Schema = {
},
}

export const v120Schema = {
...v119Schema,
_persist: {
...v119Schema._persist,
version: 120,
},
app: {
...v119Schema.app,
odisV1EOL: false,
},
}

export function getLatestSchema(): Partial<RootState> {
return v119Schema as Partial<RootState>
return v120Schema as Partial<RootState>
}