wallet-stack 1.0.0-alpha.132 → 1.0.0-alpha.133

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/locales/base/translation.json +5 -0
  2. package/package.json +1 -2
  3. package/src/analytics/Events.tsx +3 -10
  4. package/src/analytics/Properties.tsx +9 -25
  5. package/src/analytics/docs.ts +11 -8
  6. package/src/app/ErrorMessages.ts +0 -7
  7. package/src/identity/actions.ts +1 -97
  8. package/src/identity/contactMapping.test.ts +3 -28
  9. package/src/identity/contactMapping.ts +2 -88
  10. package/src/identity/reducer.ts +0 -77
  11. package/src/identity/saga.ts +2 -85
  12. package/src/identity/selectors.ts +0 -2
  13. package/src/images/Images.ts +2 -0
  14. package/src/images/assets/minipay.png +0 -0
  15. package/src/images/assets/minipay@1.5x.png +0 -0
  16. package/src/images/assets/minipay@2x.png +0 -0
  17. package/src/images/assets/minipay@3x.png +0 -0
  18. package/src/images/assets/minipay@4x.png +0 -0
  19. package/src/images/assets/valora.png +0 -0
  20. package/src/images/assets/valora@1.5x.png +0 -0
  21. package/src/images/assets/valora@2x.png +0 -0
  22. package/src/images/assets/valora@3x.png +0 -0
  23. package/src/images/assets/valora@4x.png +0 -0
  24. package/src/index.d.ts +0 -1
  25. package/src/navigator/Navigator.tsx +4 -14
  26. package/src/navigator/Screens.tsx +1 -2
  27. package/src/navigator/types.tsx +4 -6
  28. package/src/qrcode/utils.test.tsx +4 -96
  29. package/src/qrcode/utils.ts +5 -114
  30. package/src/redux/migrations.test.ts +13 -0
  31. package/src/redux/migrations.ts +4 -0
  32. package/src/redux/store.test.ts +1 -2
  33. package/src/redux/store.ts +1 -1
  34. package/src/send/SelectRecipientAddress.test.tsx +146 -0
  35. package/src/send/SelectRecipientAddress.tsx +166 -0
  36. package/src/send/SendSelectRecipient.test.tsx +16 -87
  37. package/src/send/SendSelectRecipient.tsx +12 -27
  38. package/src/send/actions.ts +0 -26
  39. package/src/send/saga.ts +1 -6
  40. package/src/components/AccountNumberCard.tsx +0 -23
  41. package/src/components/ErrorMessageInline.tsx +0 -78
  42. package/src/components/SingleDigitInput.tsx +0 -53
  43. package/src/icons/HamburgerCard.tsx +0 -55
  44. package/src/identity/saga.test.ts +0 -103
  45. package/src/identity/secureSend.ts +0 -171
  46. package/src/send/ValidateRecipientAccount.test.tsx +0 -182
  47. package/src/send/ValidateRecipientAccount.tsx +0 -392
  48. package/src/send/ValidateRecipientIntro.test.tsx +0 -61
  49. package/src/send/ValidateRecipientIntro.tsx +0 -136
  50. package/src/send/__snapshots__/ValidateRecipientAccount.test.tsx.snap +0 -777
@@ -1,94 +1,16 @@
1
- import { showErrorInline } from 'src/alert/actions'
2
- import { SendEvents } from 'src/analytics/Events'
3
- import AppAnalytics from 'src/analytics/AppAnalytics'
4
- import { ErrorMessages } from 'src/app/ErrorMessages'
5
- import {
6
- Actions,
7
- ValidateRecipientAddressAction,
8
- validateRecipientAddressSuccess,
9
- } from 'src/identity/actions'
10
1
  import {
11
2
  doImportContactsWrapper,
12
3
  fetchAddressVerificationSaga,
13
4
  fetchAddressesAndValidateSaga,
14
5
  saveContacts,
15
6
  } from 'src/identity/contactMapping'
16
- import { AddressValidationType } from 'src/identity/reducer'
17
- import { validateAndReturnMatch } from 'src/identity/secureSend'
18
- import { e164NumberToAddressSelector } from 'src/identity/selectors'
19
- import { recipientHasNumber } from 'src/recipients/recipient'
7
+ import { Actions } from 'src/identity/actions'
20
8
  import Logger from 'src/utils/Logger'
21
- import { ensureError } from 'src/utils/ensureError'
22
9
  import { safely } from 'src/utils/safely'
23
- import { currentAccountSelector } from 'src/web3/selectors'
24
- import { cancelled, put, select, spawn, takeEvery, takeLatest, takeLeading } from 'typed-redux-saga'
10
+ import { cancelled, spawn, takeEvery, takeLatest, takeLeading } from 'typed-redux-saga'
25
11
 
26
12
  const TAG = 'identity/saga'
27
13
 
28
- export function* validateRecipientAddressSaga({
29
- userInputOfFullAddressOrLastFourDigits,
30
- addressValidationType,
31
- recipient,
32
- requesterAddress,
33
- }: ValidateRecipientAddressAction) {
34
- Logger.debug(TAG, 'Starting Recipient Address Validation')
35
- try {
36
- if (!recipientHasNumber(recipient)) {
37
- throw Error(`Invalid recipient type for Secure Send, does not have e164Number`)
38
- }
39
-
40
- const userAddress = yield* select(currentAccountSelector)
41
- if (!userAddress) {
42
- // This should never happen
43
- throw Error(`No userAddress set`)
44
- }
45
- const e164NumberToAddress = yield* select(e164NumberToAddressSelector)
46
- const { e164PhoneNumber } = recipient
47
- const possibleRecievingAddresses = e164NumberToAddress[e164PhoneNumber]
48
-
49
- // Should never happen - Secure Send is initiated to deal with
50
- // there being several possible addresses
51
- if (!possibleRecievingAddresses) {
52
- throw Error('There are no possible recipient addresses to validate against')
53
- }
54
-
55
- // E164NumberToAddress in redux store only holds verified addresses
56
- // Need to add the requester address to the option set in the event
57
- // a request is coming from an unverified account
58
- if (requesterAddress && !possibleRecievingAddresses.includes(requesterAddress)) {
59
- possibleRecievingAddresses.push(requesterAddress)
60
- }
61
-
62
- const validatedAddress = validateAndReturnMatch(
63
- userInputOfFullAddressOrLastFourDigits,
64
- possibleRecievingAddresses,
65
- userAddress,
66
- addressValidationType
67
- )
68
-
69
- AppAnalytics.track(SendEvents.send_secure_complete, {
70
- confirmByScan: false,
71
- partialAddressValidation: addressValidationType === AddressValidationType.PARTIAL,
72
- })
73
-
74
- yield* put(validateRecipientAddressSuccess(e164PhoneNumber, validatedAddress))
75
- } catch (err) {
76
- const error = ensureError(err)
77
- AppAnalytics.track(SendEvents.send_secure_incorrect, {
78
- confirmByScan: false,
79
- partialAddressValidation: addressValidationType === AddressValidationType.PARTIAL,
80
- error: error.message,
81
- })
82
-
83
- Logger.error(TAG, 'validateRecipientAddressSaga/Address validation error: ', error)
84
- if (Object.values(ErrorMessages).includes(error.message as ErrorMessages)) {
85
- yield* put(showErrorInline(error.message as ErrorMessages))
86
- } else {
87
- yield* put(showErrorInline(ErrorMessages.ADDRESS_VALIDATION_ERROR))
88
- }
89
- }
90
- }
91
-
92
14
  function* watchContactMapping() {
93
15
  yield* takeLeading(Actions.IMPORT_CONTACTS, safely(doImportContactsWrapper))
94
16
  yield* takeLatest(
@@ -97,10 +19,6 @@ function* watchContactMapping() {
97
19
  )
98
20
  }
99
21
 
100
- export function* watchValidateRecipientAddress() {
101
- yield* takeLatest(Actions.VALIDATE_RECIPIENT_ADDRESS, safely(validateRecipientAddressSaga))
102
- }
103
-
104
22
  function* watchFetchAddressVerification() {
105
23
  yield* takeEvery(Actions.FETCH_ADDRESS_VERIFICATION_STATUS, safely(fetchAddressVerificationSaga))
106
24
  }
@@ -109,7 +27,6 @@ export function* identitySaga() {
109
27
  Logger.debug(TAG, 'Initializing identity sagas')
110
28
  try {
111
29
  yield* spawn(watchContactMapping)
112
- yield* spawn(watchValidateRecipientAddress)
113
30
  yield* spawn(watchFetchAddressVerification)
114
31
  yield* spawn(saveContacts) // save contacts on app start
115
32
  } catch (error) {
@@ -5,8 +5,6 @@ export const addressToVerificationStatusSelector = (state: RootState) =>
5
5
  state.identity.addressToVerificationStatus
6
6
  export const addressToE164NumberSelector = (state: RootState) => state.identity.addressToE164Number
7
7
  export const addressToVerifiedBySelector = (state: RootState) => state.identity.addressToVerifiedBy
8
- export const secureSendPhoneNumberMappingSelector = (state: RootState) =>
9
- state.identity.secureSendPhoneNumberMapping
10
8
  export const importContactsProgressSelector = (state: RootState) =>
11
9
  state.identity.importContactsProgress
12
10
  export const addressToDisplayNameSelector = (state: RootState) =>
@@ -16,7 +16,9 @@ export const fiatExchange = require('src/images/assets/fiat-exchange.png')
16
16
  export const getVerified = require('src/images/assets/get-verified.png')
17
17
  export const inviteModal = require('src/images/assets/invite-modal.png')
18
18
  export const learnCelo = require('src/images/assets/learn-celo.png')
19
+ export const miniPay = require('src/images/assets/minipay.png')
19
20
  export const pointsCardBackground = require('src/images/assets/points-card-background.png')
20
21
  export const pointsIllustration = require('src/images/assets/points-illustration.png')
22
+ export const valora = require('src/images/assets/valora.png')
21
23
  export const walletSafe = require('src/images/assets/wallet-safe.png')
22
24
  export const earnCardBackground = require('src/images/assets/earn-card-background.png')
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/src/index.d.ts CHANGED
@@ -6,7 +6,6 @@ declare module '*.json' {
6
6
  declare module '*.png'
7
7
  declare module '*.jpg'
8
8
 
9
- declare module 'dot-prop-immutable'
10
9
  declare module 'svgs'
11
10
  declare module 'react-native-languages'
12
11
  declare module 'react-native-version-check'
@@ -102,16 +102,11 @@ import PointsIntro from 'src/points/PointsIntro'
102
102
  import { NavigatorScreen } from 'src/public/navigate'
103
103
  import { RootState } from 'src/redux/reducers'
104
104
  import { store } from 'src/redux/store'
105
+ import SelectRecipientAddress from 'src/send/SelectRecipientAddress'
105
106
  import SendConfirmation, { sendConfirmationScreenNavOptions } from 'src/send/SendConfirmation'
106
107
  import SendEnterAmount from 'src/send/SendEnterAmount'
107
108
  import SendInvite from 'src/send/SendInvite'
108
109
  import SendSelectRecipient from 'src/send/SendSelectRecipient'
109
- import ValidateRecipientAccount, {
110
- validateRecipientAccountScreenNavOptions,
111
- } from 'src/send/ValidateRecipientAccount'
112
- import ValidateRecipientIntro, {
113
- validateRecipientIntroScreenNavOptions,
114
- } from 'src/send/ValidateRecipientIntro'
115
110
  import { getFeatureGate } from 'src/statsig'
116
111
  import { StatsigFeatureGates } from 'src/statsig/types'
117
112
  import styles from 'src/styles/styles'
@@ -243,14 +238,9 @@ const sendScreens = (Navigator: typeof Stack) => (
243
238
  options={sendConfirmationScreenNavOptions as NativeStackNavigationOptions}
244
239
  />
245
240
  <Navigator.Screen
246
- name={Screens.ValidateRecipientIntro}
247
- component={ValidateRecipientIntro}
248
- options={validateRecipientIntroScreenNavOptions}
249
- />
250
- <Navigator.Screen
251
- name={Screens.ValidateRecipientAccount}
252
- component={ValidateRecipientAccount}
253
- options={validateRecipientAccountScreenNavOptions}
241
+ name={Screens.SelectRecipientAddress}
242
+ component={SelectRecipientAddress}
243
+ options={SelectRecipientAddress.navigationOptions as NativeStackNavigationOptions}
254
244
  />
255
245
  <Navigator.Screen
256
246
  name={Screens.SendEnterAmount}
@@ -76,6 +76,7 @@ export enum Screens {
76
76
  SelectLocalCurrency = 'SelectLocalCurrency',
77
77
  SelectProvider = 'SelectProvider',
78
78
  SendInvite = 'SendInvite',
79
+ SelectRecipientAddress = 'SelectRecipientAddress',
79
80
  SendSelectRecipient = 'SendSelectRecipient',
80
81
  SendConfirmation = 'SendConfirmation',
81
82
  SendEnterAmount = 'SendEnterAmount',
@@ -95,8 +96,6 @@ export enum Screens {
95
96
  TokenImport = 'TokenImport',
96
97
  TransactionDetailsScreen = 'TransactionDetailsScreen',
97
98
  UpgradeScreen = 'UpgradeScreen',
98
- ValidateRecipientAccount = 'ValidateRecipientAccount',
99
- ValidateRecipientIntro = 'ValidateRecipientIntro',
100
99
  VerificationCodeInputScreen = 'VerificationCodeInputScreen',
101
100
  VerificationStartScreen = 'VerificationStartScreen',
102
101
  WalletConnectRequest = 'WalletConnectRequest',
@@ -9,7 +9,7 @@ import { KeylessBackupFlow, KeylessBackupOrigin } from 'src/keylessBackup/types'
9
9
  import { Screens } from 'src/navigator/Screens'
10
10
  import { Nft } from 'src/nfts/types'
11
11
  import { EarnPosition } from 'src/positions/types'
12
- import { Recipient } from 'src/recipients/recipient'
12
+ import { MobileRecipient, Recipient } from 'src/recipients/recipient'
13
13
  import { QrCode, TransactionDataInput } from 'src/send/types'
14
14
  import type { SwapTransaction } from 'src/swap/types'
15
15
  import type { SerializedTokenBalance } from 'src/tokens/slice'
@@ -45,10 +45,9 @@ type SendEnterAmountParams = {
45
45
  isMiniPayRecipient?: boolean
46
46
  }
47
47
 
48
- interface ValidateRecipientParams {
49
- requesterAddress?: string
48
+ interface SelectRecipientAddressParams {
49
+ recipient: MobileRecipient
50
50
  origin: SendOrigin
51
- recipient: Recipient
52
51
  forceTokenId?: boolean
53
52
  defaultTokenIdOverride?: string
54
53
  }
@@ -262,6 +261,7 @@ export type StackParamList = {
262
261
  }
263
262
  }
264
263
  [Screens.SendInvite]: { recipient: Recipient; shareUrl: string }
264
+ [Screens.SelectRecipientAddress]: SelectRecipientAddressParams
265
265
  [Screens.SendSelectRecipient]:
266
266
  | {
267
267
  forceTokenId?: boolean
@@ -301,8 +301,6 @@ export type StackParamList = {
301
301
  transaction: TokenTransaction
302
302
  }
303
303
  [Screens.UpgradeScreen]: undefined
304
- [Screens.ValidateRecipientIntro]: ValidateRecipientParams
305
- [Screens.ValidateRecipientAccount]: ValidateRecipientParams
306
304
  [Screens.VerificationStartScreen]:
307
305
  | {
308
306
  hasOnboarded?: boolean
@@ -3,45 +3,32 @@ import * as React from 'react'
3
3
  import 'react-native'
4
4
  import { View } from 'react-native'
5
5
  import { expectSaga } from 'redux-saga-test-plan'
6
- import { call, select } from 'redux-saga-test-plan/matchers'
6
+ import { select } from 'redux-saga-test-plan/matchers'
7
7
  import { showError } from 'src/alert/actions'
8
8
  import AppAnalytics from 'src/analytics/AppAnalytics'
9
9
  import { QrScreenEvents } from 'src/analytics/Events'
10
10
  import { HooksEnablePreviewOrigin, SendOrigin } from 'src/analytics/types'
11
11
  import { ErrorMessages } from 'src/app/ErrorMessages'
12
12
  import { DEEP_LINK_URL_SCHEME } from 'src/config'
13
- import {
14
- e164NumberToAddressSelector,
15
- secureSendPhoneNumberMappingSelector,
16
- } from 'src/identity/selectors'
13
+ import { e164NumberToAddressSelector } from 'src/identity/selectors'
17
14
  import { navigate } from 'src/navigator/NavigationService'
18
15
  import { Screens } from 'src/navigator/Screens'
19
16
  import { handleEnableHooksPreviewDeepLink } from 'src/positions/saga'
20
17
  import { allowHooksPreviewSelector } from 'src/positions/selectors'
21
18
  import { urlFromUriData } from 'src/qrcode/schema'
22
- import {
23
- QRCodeTypes,
24
- handleQRCodeDefault,
25
- handleQRCodeSecureSend,
26
- handleSecureSend,
27
- useQRContent,
28
- } from 'src/qrcode/utils'
19
+ import { QRCodeTypes, handleQRCodeDefault, useQRContent } from 'src/qrcode/utils'
29
20
  import { RecipientType } from 'src/recipients/recipient'
30
21
  import { recipientInfoSelector } from 'src/recipients/reducer'
31
- import { handleQRCodeDetected, handleQRCodeDetectedSecureSend } from 'src/send/actions'
22
+ import { handleQRCodeDetected } from 'src/send/actions'
32
23
  import { QrCode } from 'src/send/types'
33
24
  import { createMockStore } from 'test/utils'
34
25
  import {
35
26
  mockAccount,
36
- mockAccount2,
37
27
  mockAccount3,
38
28
  mockE164Number,
39
29
  mockE164Number3,
40
- mockE164NumberToAddress,
41
- mockEthTokenId,
42
30
  mockName,
43
31
  mockQrCodeData,
44
- mockRecipient,
45
32
  mockRecipientInfo,
46
33
  } from 'test/values'
47
34
 
@@ -212,82 +199,3 @@ describe('handleQRCodeDefault', () => {
212
199
  expect(AppAnalytics.track).toHaveBeenCalledWith(QrScreenEvents.qr_scanned, qrCode)
213
200
  })
214
201
  })
215
-
216
- describe('handleQRCodeSecureSend', () => {
217
- it('handles a valid address and navigates to send enter amount when there is no transaction data', async () => {
218
- const data: QrCode = { type: QRCodeTypes.QR_CODE, data: mockAccount }
219
- await expectSaga(
220
- handleQRCodeSecureSend,
221
- handleQRCodeDetectedSecureSend(data, mockRecipient, mockAccount2, false, mockEthTokenId)
222
- )
223
- .provide([
224
- [select(e164NumberToAddressSelector), mockE164NumberToAddress],
225
- [
226
- select(secureSendPhoneNumberMappingSelector),
227
- {
228
- [mockRecipient.e164PhoneNumber]: {
229
- address: mockAccount,
230
- addressValidationType: undefined,
231
- },
232
- },
233
- ],
234
- [
235
- call(
236
- handleSecureSend,
237
- mockAccount.toLowerCase(),
238
- mockE164NumberToAddress,
239
- mockRecipient,
240
- mockAccount2
241
- ),
242
- true,
243
- ],
244
- ])
245
- .run()
246
- expect(navigate).toHaveBeenCalledWith(Screens.SendEnterAmount, {
247
- origin: SendOrigin.AppSendFlow,
248
- recipient: {
249
- ...mockRecipient,
250
- address: mockAccount,
251
- },
252
- isFromScan: true,
253
- forceTokenId: false,
254
- defaultTokenIdOverride: mockEthTokenId,
255
- })
256
- expect(AppAnalytics.track).toHaveBeenCalledWith(QrScreenEvents.qr_scanned, data)
257
- })
258
- it('handles an invalid address', async () => {
259
- const data: QrCode = { type: QRCodeTypes.QR_CODE, data: 'invalid-address' }
260
- await expectSaga(
261
- handleQRCodeSecureSend,
262
- handleQRCodeDetectedSecureSend(data, mockRecipient, mockAccount2)
263
- )
264
- .provide([[select(e164NumberToAddressSelector), mockE164NumberToAddress]])
265
- .put(showError(ErrorMessages.QR_FAILED_INVALID_ADDRESS))
266
- .run()
267
- expect(navigate).not.toHaveBeenCalled()
268
- expect(AppAnalytics.track).toHaveBeenCalledWith(QrScreenEvents.qr_scanned, data)
269
- })
270
- it('handles failed address lookup', async () => {
271
- const data: QrCode = { type: QRCodeTypes.QR_CODE, data: mockAccount }
272
- await expectSaga(
273
- handleQRCodeSecureSend,
274
- handleQRCodeDetectedSecureSend(data, mockRecipient, mockAccount2)
275
- )
276
- .provide([
277
- [select(e164NumberToAddressSelector), mockE164NumberToAddress],
278
- [
279
- call(
280
- handleSecureSend,
281
- mockAccount.toLowerCase(),
282
- mockE164NumberToAddress,
283
- mockRecipient,
284
- mockAccount2
285
- ),
286
- false,
287
- ],
288
- ])
289
- .run()
290
- expect(navigate).not.toHaveBeenCalled()
291
- expect(AppAnalytics.track).toHaveBeenCalledWith(QrScreenEvents.qr_scanned, data)
292
- })
293
- })
@@ -1,40 +1,18 @@
1
1
  import * as RNFS from '@valora/react-native-fs'
2
2
  import { useMemo } from 'react'
3
3
  import Share from 'react-native-share'
4
- import { showError, showMessage } from 'src/alert/actions'
4
+ import { showError } from 'src/alert/actions'
5
5
  import AppAnalytics from 'src/analytics/AppAnalytics'
6
- import { QrScreenEvents, SendEvents } from 'src/analytics/Events'
7
- import {
8
- HooksEnablePreviewOrigin,
9
- SendOrigin,
10
- WalletConnectPairingOrigin,
11
- } from 'src/analytics/types'
6
+ import { QrScreenEvents } from 'src/analytics/Events'
7
+ import { HooksEnablePreviewOrigin, WalletConnectPairingOrigin } from 'src/analytics/types'
12
8
  import { ErrorMessages } from 'src/app/ErrorMessages'
13
9
  import { DEEP_LINK_URL_SCHEME } from 'src/config'
14
- import { validateRecipientAddressSuccess } from 'src/identity/actions'
15
- import { E164NumberToAddressType } from 'src/identity/reducer'
16
- import { getSecureSendAddress } from 'src/identity/secureSend'
17
- import {
18
- e164NumberToAddressSelector,
19
- secureSendPhoneNumberMappingSelector,
20
- } from 'src/identity/selectors'
21
- import { navigate } from 'src/navigator/NavigationService'
22
- import { Screens } from 'src/navigator/Screens'
23
10
  import { handleEnableHooksPreviewDeepLink } from 'src/positions/saga'
24
11
  import { allowHooksPreviewSelector } from 'src/positions/selectors'
25
12
  import { UriData, uriDataFromUrl } from 'src/qrcode/schema'
26
- import {
27
- Recipient,
28
- RecipientInfo,
29
- getRecipientFromAddress,
30
- recipientHasNumber,
31
- } from 'src/recipients/recipient'
13
+ import { RecipientInfo, getRecipientFromAddress } from 'src/recipients/recipient'
32
14
  import { recipientInfoSelector } from 'src/recipients/reducer'
33
- import {
34
- HandleQRCodeDetectedAction,
35
- HandleQRCodeDetectedSecureSendAction,
36
- SVG,
37
- } from 'src/send/actions'
15
+ import { HandleQRCodeDetectedAction, SVG } from 'src/send/actions'
38
16
  import { QrCode } from 'src/send/types'
39
17
  import { handleSendPaymentData } from 'src/send/utils'
40
18
  import Logger from 'src/utils/Logger'
@@ -85,48 +63,6 @@ export async function shareSVGImage(svg: SVG) {
85
63
  })
86
64
  }
87
65
 
88
- export function* handleSecureSend(
89
- address: string,
90
- e164NumberToAddress: E164NumberToAddressType,
91
- recipient: Recipient,
92
- requesterAddress?: string
93
- ) {
94
- if (!recipientHasNumber(recipient)) {
95
- throw Error('Invalid recipient type for Secure Send, has no mobile number')
96
- }
97
-
98
- const userScannedAddress = address.toLowerCase()
99
- const { e164PhoneNumber } = recipient
100
- const possibleReceivingAddresses = e164NumberToAddress[e164PhoneNumber]
101
- // This should never happen. Secure Send is triggered when there are
102
- // multiple addresses for a given phone number
103
- if (!possibleReceivingAddresses) {
104
- throw Error("No addresses associated with recipient's phone number")
105
- }
106
-
107
- // Need to add the requester address to the option set in the event
108
- // a request is coming from an unverified account
109
- if (requesterAddress && !possibleReceivingAddresses.includes(requesterAddress)) {
110
- possibleReceivingAddresses.push(requesterAddress)
111
- }
112
- const possibleReceivingAddressesFormatted = possibleReceivingAddresses.map((addr) =>
113
- addr.toLowerCase()
114
- )
115
- if (!possibleReceivingAddressesFormatted.includes(userScannedAddress)) {
116
- const error = ErrorMessages.QR_FAILED_INVALID_RECIPIENT
117
- AppAnalytics.track(SendEvents.send_secure_incorrect, {
118
- confirmByScan: true,
119
- error,
120
- })
121
- yield* put(showMessage(error))
122
- return false
123
- }
124
-
125
- AppAnalytics.track(SendEvents.send_secure_complete, { confirmByScan: true })
126
- yield* put(validateRecipientAddressSuccess(e164PhoneNumber, userScannedAddress))
127
- return true
128
- }
129
-
130
66
  function* extractQRAddressData(qrCode: QrCode) {
131
67
  // strip network prefix if present
132
68
  const qrAddress = qrCode.data.split(':').at(-1) || qrCode.data
@@ -183,48 +119,3 @@ export function* handleQRCodeDefault({
183
119
  defaultTokenIdOverride,
184
120
  })
185
121
  }
186
-
187
- export function* handleQRCodeSecureSend({
188
- qrCode,
189
- requesterAddress,
190
- recipient,
191
- forceTokenId,
192
- defaultTokenIdOverride,
193
- }: HandleQRCodeDetectedSecureSendAction) {
194
- const e164NumberToAddress = yield* select(e164NumberToAddressSelector)
195
- AppAnalytics.track(QrScreenEvents.qr_scanned, qrCode)
196
-
197
- const qrData = yield* call(extractQRAddressData, qrCode)
198
- if (!qrData) {
199
- return
200
- }
201
-
202
- const success: boolean = yield* call(
203
- handleSecureSend,
204
- qrData.address,
205
- e164NumberToAddress,
206
- recipient,
207
- requesterAddress
208
- )
209
- if (!success) {
210
- return
211
- }
212
-
213
- const secureSendPhoneNumberMapping = yield* select(secureSendPhoneNumberMappingSelector)
214
- const address = getSecureSendAddress(recipient, secureSendPhoneNumberMapping)
215
- if (!address) {
216
- // should never happen b/c if handleSecureSend succeeds then address should be there
217
- Logger.error(TAG, `No secure send address found for recipient ${recipient}`)
218
- return
219
- }
220
- navigate(Screens.SendEnterAmount, {
221
- origin: SendOrigin.AppSendFlow,
222
- recipient: {
223
- ...recipient,
224
- address,
225
- },
226
- isFromScan: true,
227
- forceTokenId,
228
- defaultTokenIdOverride,
229
- })
230
- }
@@ -68,6 +68,7 @@ import {
68
68
  v251Schema,
69
69
  v253Schema,
70
70
  v254Schema,
71
+ v255Schema,
71
72
  v28Schema,
72
73
  v2Schema,
73
74
  v35Schema,
@@ -1946,4 +1947,16 @@ describe('Redux persist migrations', () => {
1946
1947
  const migratedSchema = migrations[255](oldSchema)
1947
1948
  expect(migratedSchema.identity.addressToVerifiedBy).toStrictEqual({})
1948
1949
  })
1950
+
1951
+ it('works from 255 to 256', () => {
1952
+ const oldSchema = {
1953
+ ...v255Schema,
1954
+ identity: {
1955
+ ...v255Schema.identity,
1956
+ secureSendPhoneNumberMapping: { '+14155550000': {} },
1957
+ },
1958
+ }
1959
+ const migratedSchema = migrations[256](oldSchema)
1960
+ expect(migratedSchema.identity.secureSendPhoneNumberMapping).toBeUndefined()
1961
+ })
1949
1962
  })
@@ -2077,4 +2077,8 @@ export const migrations = {
2077
2077
  addressToVerifiedBy: {},
2078
2078
  },
2079
2079
  }),
2080
+ 256: (state: any) => ({
2081
+ ...state,
2082
+ identity: _.omit(state.identity, 'secureSendPhoneNumberMapping'),
2083
+ }),
2080
2084
  }
@@ -143,7 +143,7 @@ describe('store state', () => {
143
143
  {
144
144
  "_persist": {
145
145
  "rehydrated": true,
146
- "version": 255,
146
+ "version": 256,
147
147
  },
148
148
  "account": {
149
149
  "acceptedTerms": false,
@@ -254,7 +254,6 @@ describe('store state', () => {
254
254
  "total": 0,
255
255
  },
256
256
  "lastSavedContactsHash": null,
257
- "secureSendPhoneNumberMapping": {},
258
257
  "shouldRefreshStoredPasswordHash": true,
259
258
  },
260
259
  "imports": {
@@ -30,7 +30,7 @@ const persistConfig: PersistConfig<ReducersRootState> = {
30
30
  key: 'root',
31
31
  // default is -1, increment as we make migrations
32
32
  // See https://github.com/valora-xyz/wallet/tree/main/WALLET.md#redux-state-migration
33
- version: 255,
33
+ version: 256,
34
34
  keyPrefix: `reduxStore-`, // the redux-persist default is `persist:` which doesn't work with some file systems.
35
35
  storage: FSStorage(),
36
36
  blacklist: ['networkInfo', 'alert', 'imports', 'keylessBackup', transactionFeedV2Api.reducerPath],