wallet-stack 1.0.0-alpha.130 → 1.0.0-alpha.131
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.
|
@@ -2269,7 +2269,8 @@
|
|
|
2269
2269
|
"insufficientBalanceWarning": {
|
|
2270
2270
|
"title": "You need more {{tokenSymbol}}",
|
|
2271
2271
|
"description": "Insufficient {{tokenSymbol}} balance. Try a smaller amount or choose a different asset."
|
|
2272
|
-
}
|
|
2272
|
+
},
|
|
2273
|
+
"miniPayFilterChip": "MiniPay supported"
|
|
2273
2274
|
},
|
|
2274
2275
|
"jumpstartIntro": {
|
|
2275
2276
|
"title": "Share crypto like a text",
|
package/package.json
CHANGED
|
@@ -258,7 +258,7 @@ describe('SendEnterAmount', () => {
|
|
|
258
258
|
</Provider>
|
|
259
259
|
)
|
|
260
260
|
|
|
261
|
-
expect(getByText('
|
|
261
|
+
expect(getByText('sendEnterAmountScreen.miniPayFilterChip')).toBeTruthy()
|
|
262
262
|
|
|
263
263
|
const tokenBottomSheet = getAllByTestId('TokenBottomSheet')[0]
|
|
264
264
|
const tokens = within(tokenBottomSheet).getAllByTestId('TokenBalanceItem')
|
|
@@ -291,7 +291,7 @@ describe('SendEnterAmount', () => {
|
|
|
291
291
|
</Provider>
|
|
292
292
|
)
|
|
293
293
|
|
|
294
|
-
fireEvent.press(getByText('
|
|
294
|
+
fireEvent.press(getByText('sendEnterAmountScreen.miniPayFilterChip'))
|
|
295
295
|
|
|
296
296
|
const tokenBottomSheet = getAllByTestId('TokenBottomSheet')[0]
|
|
297
297
|
const tokens = within(tokenBottomSheet).getAllByTestId('TokenBalanceItem')
|
|
@@ -305,7 +305,7 @@ describe('SendEnterAmount', () => {
|
|
|
305
305
|
</Provider>
|
|
306
306
|
)
|
|
307
307
|
|
|
308
|
-
expect(queryByText('
|
|
308
|
+
expect(queryByText('sendEnterAmountScreen.miniPayFilterChip')).toBeFalsy()
|
|
309
309
|
})
|
|
310
310
|
|
|
311
311
|
it('should include isMiniPayRecipient in send_amount_continue analytics', async () => {
|
|
@@ -2,6 +2,7 @@ import Clipboard from '@react-native-clipboard/clipboard'
|
|
|
2
2
|
import { act, fireEvent, render, waitFor } from '@testing-library/react-native'
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import { Provider } from 'react-redux'
|
|
5
|
+
import Share from 'react-native-share'
|
|
5
6
|
import AppAnalytics from 'src/analytics/AppAnalytics'
|
|
6
7
|
import { SendEvents } from 'src/analytics/Events'
|
|
7
8
|
import { SendOrigin } from 'src/analytics/types'
|
|
@@ -351,6 +352,77 @@ describe('SendSelectRecipient', () => {
|
|
|
351
352
|
expect(getByTestId('SendOrInviteButton')).toBeTruthy()
|
|
352
353
|
})
|
|
353
354
|
|
|
355
|
+
it('opens the platform share sheet and tracks the press analytic before awaiting when inviting an unverified phone number', async () => {
|
|
356
|
+
const shareUrl = 'https://example.test/invite'
|
|
357
|
+
jest.mocked(getAppConfig).mockReturnValue({
|
|
358
|
+
displayName: 'Test App',
|
|
359
|
+
deepLinkUrlScheme: 'testapp',
|
|
360
|
+
registryName: 'test',
|
|
361
|
+
experimental: {
|
|
362
|
+
phoneNumberVerification: true,
|
|
363
|
+
inviteFriends: { shareUrl },
|
|
364
|
+
},
|
|
365
|
+
})
|
|
366
|
+
jest
|
|
367
|
+
.mocked(getRecipientVerificationStatus)
|
|
368
|
+
.mockReturnValue(RecipientVerificationStatus.UNVERIFIED)
|
|
369
|
+
|
|
370
|
+
let resolveShare!: (value: {
|
|
371
|
+
success: boolean
|
|
372
|
+
dismissedAction: boolean
|
|
373
|
+
message: string
|
|
374
|
+
}) => void
|
|
375
|
+
const sharePromise = new Promise<{
|
|
376
|
+
success: boolean
|
|
377
|
+
dismissedAction: boolean
|
|
378
|
+
message: string
|
|
379
|
+
}>((resolve) => {
|
|
380
|
+
resolveShare = resolve
|
|
381
|
+
})
|
|
382
|
+
jest.mocked(Share.open).mockReturnValueOnce(sharePromise)
|
|
383
|
+
|
|
384
|
+
const store = createMockStore(storeWithPhoneVerified)
|
|
385
|
+
|
|
386
|
+
const { getByTestId } = render(
|
|
387
|
+
<Provider store={store}>
|
|
388
|
+
<SendSelectRecipient {...mockScreenProps({})} />
|
|
389
|
+
</Provider>
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
const searchInput = getByTestId('SendSelectRecipientSearchInput')
|
|
393
|
+
await act(() => {
|
|
394
|
+
fireEvent.changeText(searchInput, mockE164Number2Invite)
|
|
395
|
+
})
|
|
396
|
+
await act(() => {
|
|
397
|
+
fireEvent.press(getByTestId('RecipientItem'))
|
|
398
|
+
})
|
|
399
|
+
|
|
400
|
+
const button = getByTestId('SendOrInviteButton')
|
|
401
|
+
expect(button).toHaveTextContent('sendSelectRecipient.buttons.invite', { exact: false })
|
|
402
|
+
|
|
403
|
+
await act(() => {
|
|
404
|
+
fireEvent.press(button)
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
// Analytics fires synchronously on tap, before the share sheet resolves
|
|
408
|
+
expect(AppAnalytics.track).toHaveBeenCalledWith(SendEvents.send_select_recipient_invite_press, {
|
|
409
|
+
recipientType: RecipientType.PhoneNumber,
|
|
410
|
+
})
|
|
411
|
+
expect(Share.open).toHaveBeenCalledWith(
|
|
412
|
+
expect.objectContaining({
|
|
413
|
+
message: expect.stringContaining(shareUrl),
|
|
414
|
+
url: shareUrl,
|
|
415
|
+
failOnCancel: false,
|
|
416
|
+
})
|
|
417
|
+
)
|
|
418
|
+
expect(navigate).not.toHaveBeenCalled()
|
|
419
|
+
|
|
420
|
+
await act(async () => {
|
|
421
|
+
resolveShare({ success: true, dismissedAction: false, message: '' })
|
|
422
|
+
await sharePromise
|
|
423
|
+
})
|
|
424
|
+
})
|
|
425
|
+
|
|
354
426
|
it('shows unknown address info text when searching for unknown address after making address verification request', async () => {
|
|
355
427
|
jest
|
|
356
428
|
.mocked(getRecipientVerificationStatus)
|
|
@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'
|
|
|
4
4
|
import { StyleSheet, Text, View } from 'react-native'
|
|
5
5
|
import { getFontScaleSync } from 'react-native-device-info'
|
|
6
6
|
import { SafeAreaView } from 'react-native-safe-area-context'
|
|
7
|
-
import Share
|
|
7
|
+
import Share from 'react-native-share'
|
|
8
8
|
import { isAddressFormat } from 'src/account/utils'
|
|
9
9
|
import AppAnalytics from 'src/analytics/AppAnalytics'
|
|
10
10
|
import { SendEvents } from 'src/analytics/Events'
|
|
@@ -326,22 +326,24 @@ function SendSelectRecipient({ route }: Props) {
|
|
|
326
326
|
// Invites
|
|
327
327
|
if (shouldInviteRecipient) {
|
|
328
328
|
if (!shareUrl) {
|
|
329
|
-
Logger.warn('SendSelectRecipient', 'No share URL found for invite
|
|
329
|
+
Logger.warn('SendSelectRecipient', 'No share URL found for invite')
|
|
330
330
|
return
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
-
const shareOptions: ShareSingleOptions = {
|
|
334
|
-
social: Social.Sms,
|
|
335
|
-
recipient: recipient.e164PhoneNumber,
|
|
336
|
-
message: t('inviteWithSmsMessage.shareMessage', { shareUrl }),
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
await Share.shareSingle(shareOptions)
|
|
340
|
-
|
|
341
333
|
AppAnalytics.track(SendEvents.send_select_recipient_invite_press, {
|
|
342
334
|
recipientType: recipient.recipientType,
|
|
343
335
|
})
|
|
344
336
|
|
|
337
|
+
try {
|
|
338
|
+
await Share.open({
|
|
339
|
+
message: t('inviteWithSmsMessage.shareMessage', { shareUrl }),
|
|
340
|
+
url: shareUrl,
|
|
341
|
+
failOnCancel: false,
|
|
342
|
+
})
|
|
343
|
+
} catch (error) {
|
|
344
|
+
Logger.warn('SendSelectRecipient', 'Share sheet failed', error)
|
|
345
|
+
}
|
|
346
|
+
|
|
345
347
|
return
|
|
346
348
|
}
|
|
347
349
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useTranslation } from 'react-i18next'
|
|
1
2
|
import { BooleanFilterChip } from 'src/components/FilterChipsCarousel'
|
|
2
3
|
import { getDynamicConfigParams } from 'src/statsig'
|
|
3
4
|
import { DynamicConfigs } from 'src/statsig/constants'
|
|
@@ -18,6 +19,8 @@ export default function useSendFilterChips({
|
|
|
18
19
|
filterChips: BooleanFilterChip<TokenBalance>[]
|
|
19
20
|
defaultToken: TokenBalance | undefined
|
|
20
21
|
} {
|
|
22
|
+
const { t } = useTranslation()
|
|
23
|
+
|
|
21
24
|
const { miniPayTokenIds: configTokenIds } = getDynamicConfigParams(
|
|
22
25
|
DynamicConfigs[StatsigDynamicConfigs.SEND_CONFIG]
|
|
23
26
|
)
|
|
@@ -27,7 +30,7 @@ export default function useSendFilterChips({
|
|
|
27
30
|
? [
|
|
28
31
|
{
|
|
29
32
|
id: 'minipay',
|
|
30
|
-
name: '
|
|
33
|
+
name: t('sendEnterAmountScreen.miniPayFilterChip'),
|
|
31
34
|
filterFn: (token: TokenBalance) => miniPayTokenIds.includes(token.tokenId),
|
|
32
35
|
isSelected: true,
|
|
33
36
|
},
|