Skip to content

Commit a6d9bc2

Browse files
authored
Merge pull request #7 from algorandfoundation/feat/passkey-store-liquid-auth
feat: passkey store with liquid auth
2 parents 9f992ef + 0f6df24 commit a6d9bc2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+3819
-248
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React from 'react';
2+
import { render } from '@testing-library/react-native';
3+
import AccountsScreen from '../app/accounts';
4+
import PasskeysScreen from '../app/passkeys';
5+
import IdentitiesScreen from '../app/identities';
6+
import ConnectionsScreen from '../app/connections';
7+
8+
// Mock expo-router
9+
jest.mock('expo-router', () => ({
10+
useRouter: () => ({
11+
push: jest.fn(),
12+
back: jest.fn(),
13+
}),
14+
Stack: {
15+
Screen: () => null,
16+
},
17+
}));
18+
19+
// Mock useProvider hook
20+
jest.mock('@/hooks/useProvider', () => ({
21+
useProvider: () => ({
22+
identities: [{ did: 'did:key:123' }],
23+
accounts: [{ address: 'ADDR123', balance: BigInt(100) }],
24+
passkeys: [{ id: 'cred123', name: 'Test Passkey', createdAt: new Date().getTime() }],
25+
sessions: [{ id: 'sess123', origin: 'example.com' }],
26+
passkey: {
27+
store: {
28+
removePasskey: jest.fn(),
29+
},
30+
},
31+
}),
32+
}));
33+
34+
// Mock MaterialIcons
35+
jest.mock('@expo/vector-icons', () => ({
36+
MaterialIcons: 'MaterialIcons',
37+
}));
38+
39+
describe('Collection Screens', () => {
40+
it('renders AccountsScreen correctly', () => {
41+
const { getByText, getAllByText } = render(<AccountsScreen />);
42+
expect(getByText('ADDR123')).toBeTruthy();
43+
expect(getAllByText('$100').length).toBeGreaterThanOrEqual(1);
44+
});
45+
46+
it('renders PasskeysScreen correctly', () => {
47+
const { getByText } = render(<PasskeysScreen />);
48+
expect(getByText('Test Passkey')).toBeTruthy();
49+
expect(getByText('ID: cred123')).toBeTruthy();
50+
});
51+
52+
it('renders IdentitiesScreen correctly', () => {
53+
const { getByText } = render(<IdentitiesScreen />);
54+
expect(getByText('did:key:123')).toBeTruthy();
55+
});
56+
57+
it('renders ConnectionsScreen correctly', () => {
58+
const { getByText } = render(<ConnectionsScreen />);
59+
expect(getByText('example.com')).toBeTruthy();
60+
});
61+
});

__tests__/LandingScreen-test.tsx

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ jest.mock('expo-constants', () => ({
2020
primaryColor: '#3B82F6',
2121
secondaryColor: '#E1EFFF',
2222
accentColor: '#10B981',
23-
welcomeMessage: 'Your identity, rewarded.',
24-
showRewards: true,
25-
showFeeDelegation: true,
26-
showIdentityManagement: true,
23+
welcomeMessage: 'Your identity, connected.',
24+
showAccounts: true,
25+
showPasskeys: true,
26+
showIdentities: true,
27+
showConnections: true,
2728
},
2829
},
2930
},
@@ -32,11 +33,14 @@ jest.mock('expo-constants', () => ({
3233
// Mock useProvider hook
3334
jest.mock('@/hooks/useProvider', () => ({
3435
useProvider: () => ({
35-
key: null,
36-
identity: null,
37-
account: null,
36+
key: { store: { clear: jest.fn() } },
37+
identity: { store: { clear: jest.fn() } },
38+
account: { store: { clear: jest.fn() } },
39+
passkey: { store: { clear: jest.fn() } },
3840
identities: [{ did: 'did:key:z6Mkh...' }],
3941
accounts: [{ address: 'ADDR123...', balance: 100 }],
42+
passkeys: [],
43+
sessions: [],
4044
}),
4145
}));
4246

@@ -50,7 +54,7 @@ describe('<LandingScreen />', () => {
5054
const { getByText } = render(<LandingScreen />);
5155

5256
// Check for welcome message
53-
expect(getByText('Your identity, rewarded.')).toBeTruthy();
57+
expect(getByText('Your identity, connected.')).toBeTruthy();
5458

5559
// Check for balance (mocked as 100)
5660
expect(getByText('$100')).toBeTruthy();
@@ -61,10 +65,12 @@ describe('<LandingScreen />', () => {
6165
});
6266

6367
it('renders provider services when enabled', () => {
64-
const { getByText } = render(<LandingScreen />);
68+
const { getByText, getAllByText } = render(<LandingScreen />);
6569

66-
expect(getByText('Rewards')).toBeTruthy();
67-
expect(getByText('Free Fees')).toBeTruthy();
68-
expect(getByText('Security')).toBeTruthy();
70+
expect(getByText('Accounts')).toBeTruthy();
71+
expect(getByText('Passkeys')).toBeTruthy();
72+
expect(getByText('Identities')).toBeTruthy();
73+
expect(getByText('Connections')).toBeTruthy();
74+
expect(getAllByText('0 Total').length).toBeGreaterThanOrEqual(1);
6975
});
7076
});

__tests__/OnboardingScreen-test.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ jest.mock('@scure/bip39', () => ({
4848
wordlist: { english: [] },
4949
}));
5050

51+
// Mock react-native-passkey-autofill
52+
jest.mock('@algorandfoundation/react-native-passkey-autofill', () => ({
53+
setHdRootKeyId: jest.fn().mockResolvedValue(undefined),
54+
setMasterKey: jest.fn().mockResolvedValue(undefined),
55+
}));
56+
5157
// Mock Reanimated
5258
jest.mock('react-native-reanimated', () => {
5359
const Reanimated = require('react-native-reanimated/mock');

__tests__/SeedPhrase-test.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { render, fireEvent } from '@testing-library/react-native';
2+
import { render, fireEvent, act } from '@testing-library/react-native';
33
import SeedPhrase from '../components/SeedPhrase';
44

55
// Mocking Reanimated because it often has issues in Jest environments
@@ -9,6 +9,10 @@ jest.mock('react-native-reanimated', () => {
99
return Reanimated;
1010
});
1111

12+
jest.mock('@expo/vector-icons', () => ({
13+
MaterialIcons: 'MaterialIcons',
14+
}));
15+
1216
describe('<SeedPhrase />', () => {
1317
const mockPhrase = ['apple', 'banana', 'cherry', 'date', 'elderberry', 'fig', 'grape', 'honeydew', 'iceberg', 'jackfruit', 'kiwi', 'lemon'];
1418
const primaryColor = '#3B82F6';
@@ -71,7 +75,9 @@ describe('<SeedPhrase />', () => {
7175
);
7276

7377
const input = getByPlaceholderText('Word #1');
74-
fireEvent.changeText(input, 'test');
78+
act(() => {
79+
fireEvent.changeText(input, 'test');
80+
});
7581

7682
expect(onInputChange).toHaveBeenCalledWith(0, 'test');
7783
});

app.json

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,34 @@
44
"slug": "rocca",
55
"version": "1.0.0",
66
"orientation": "portrait",
7-
"icon": "./assets/images/icon.png",
87
"scheme": "rocca",
98
"userInterfaceStyle": "automatic",
109
"newArchEnabled": true,
1110
"ios": {
1211
"supportsTablet": true,
1312
"bundleIdentifier": "com.anonymous.rocca"
1413
},
14+
"icon": "./assets/icon.png",
15+
"splash": {
16+
"image": "./assets/splash.png",
17+
"resizeMode": "contain",
18+
"backgroundColor": "#ffffff"
19+
},
1520
"android": {
1621
"adaptiveIcon": {
17-
"backgroundColor": "#E6F4FE",
18-
"foregroundImage": "./assets/images/android-icon-foreground.png",
19-
"backgroundImage": "./assets/images/android-icon-background.png",
20-
"monochromeImage": "./assets/images/android-icon-monochrome.png"
22+
"foregroundImage": "./assets/adaptive-icon.png",
23+
"backgroundColor": "#ffffff"
2124
},
2225
"edgeToEdgeEnabled": true,
2326
"predictiveBackGestureEnabled": false,
2427
"package": "com.anonymous.rocca"
2528
},
2629
"web": {
2730
"output": "static",
28-
"favicon": "./assets/images/favicon.png"
31+
"favicon": "./assets/favicon.png"
2932
},
3033
"plugins": [
34+
"./plugins/expo-rocca-plugin",
3135
"expo-router",
3236
[
3337
"expo-splash-screen",
@@ -40,6 +44,22 @@
4044
"backgroundColor": "#000000"
4145
}
4246
}
47+
],
48+
[
49+
"expo-build-properties",
50+
{
51+
"android": {
52+
"compileSdkVersion": 35
53+
}
54+
}
55+
],
56+
"@config-plugins/react-native-webrtc",
57+
[
58+
"@algorandfoundation/react-native-passkey-autofill",
59+
{
60+
"site": "https://fido.shore-tech.net",
61+
"label": "Rocca Wallet"
62+
}
4363
]
4464
],
4565
"experiments": {
@@ -52,11 +72,12 @@
5272
"primaryColor": "#3B82F6",
5373
"secondaryColor": "#E1EFFF",
5474
"accentColor": "#10B981",
55-
"welcomeMessage": "Your identity, rewarded.",
75+
"welcomeMessage": "Your identity, connected.",
5676
"logo": "",
57-
"showRewards": true,
58-
"showFeeDelegation": true,
59-
"showIdentityManagement": true
77+
"showAccounts": true,
78+
"showPasskeys": true,
79+
"showIdentities": true,
80+
"showConnections": true
6081
},
6182
"router": {},
6283
"eas": {

0 commit comments

Comments
 (0)