Skip to content

Commit 5fc2bf1

Browse files
authored
Add MessageDispatcher class that queues messages when WebView is unavailable (#451)
* Fixing crypto issues in react-native * Add MessageDispatcher class that queues messages when WebView is unavailable * Fix integration tests failing due to leaked message provider timers * Add retry for flaky integration tests hitting external APIs * Handle duplicate credentials on test retry in range-proofs * Make all addCredential calls retry-safe across integration tests * Address PR feedback and fix integration test stability * Add delay between test retries to avoid 429 rate limiting
1 parent b7295d9 commit 5fc2bf1

14 files changed

Lines changed: 473 additions & 46 deletions

integration-tests/cheqd-credentials.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { IWallet } from '@docknetwork/wallet-sdk-core/lib/types';
22
import { createVerificationController } from '@docknetwork/wallet-sdk-core/src/verification-controller';
33
import { CheqdCredentialNonZKP, CheqdCredentialZKP } from './data/credentials/cheqd-credentials';
4-
import { closeWallet, createNewWallet, getCredentialProvider, getWallet } from './helpers';
4+
import { addCredentialIfNotExists, closeWallet, createNewWallet, getCredentialProvider, getWallet } from './helpers';
55
import { ProofTemplateIds, createProofRequest } from './helpers/certs-helpers';
66

77
describe('Cheq integration tests', () => {
@@ -12,7 +12,7 @@ describe('Cheq integration tests', () => {
1212
it('should verify a non ZKP cheqd credential', async () => {
1313
const wallet: IWallet = await getWallet();
1414

15-
getCredentialProvider().addCredential(CheqdCredentialNonZKP);
15+
await addCredentialIfNotExists(CheqdCredentialNonZKP);
1616

1717
const proofRequest = await createProofRequest(
1818
ProofTemplateIds.ANY_CREDENTIAL,

integration-tests/credentials.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
UniversityDegreeCredentialBBS,
66
} from './data/credentials';
77
import {
8+
addCredentialIfNotExists,
89
cleanup,
910
closeWallet,
1011
getCredentialProvider,
@@ -29,7 +30,7 @@ describe('Credentials', () => {
2930

3031
it('expect to import credentials', async () => {
3132
for (const credentialJSON of allCredentials) {
32-
await getCredentialProvider().addCredential(credentialJSON);
33+
await addCredentialIfNotExists(credentialJSON);
3334
const credential = await getCredentialProvider().getById(
3435
credentialJSON.id,
3536
);
@@ -46,15 +47,15 @@ describe('Credentials', () => {
4647
`${credentialUrl}?p=${btoa(password)}`,
4748
);
4849

49-
await getCredentialProvider().addCredential(credential);
50+
await addCredentialIfNotExists(credential);
5051

5152
const result: any = await getCredentialProvider().isValid(credential);
5253

5354
expect(result.status).toBe('verified');
5455
});
5556

5657
it('should get status of bbs revokable credential - cheqd issuer', async () => {
57-
await getCredentialProvider().addCredential(CheqdRevocationCredential);
58+
await addCredentialIfNotExists(CheqdRevocationCredential);
5859

5960
const result: any = await getCredentialProvider().isValid(
6061
CheqdRevocationCredential,

integration-tests/helpers/wallet-helpers.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ export function getCredentialProvider(): ICredentialProvider {
8686
return credentialProvider;
8787
}
8888

89+
export async function addCredentialIfNotExists(credential: any) {
90+
try {
91+
return await credentialProvider.addCredential(credential);
92+
} catch (err) {
93+
if (!err.message?.includes('already exists')) throw err;
94+
}
95+
}
96+
8997
export async function setNetwork(networkId) {
9098
return Promise.resolve(wallet.setNetwork(networkId));
9199
}
@@ -122,15 +130,24 @@ export async function getDocumentsByType(type) {
122130
return wallet.getDocumentsByType(type);
123131
}
124132

125-
export async function closeWallet(wallet?: IWallet) {
126-
if (!wallet) {
127-
wallet = await getWallet();
133+
export async function closeWallet(walletToClose?: IWallet) {
134+
if (!walletToClose) {
135+
walletToClose = await getWallet();
136+
}
137+
138+
if (messageProvider) {
139+
messageProvider.stop();
140+
}
141+
142+
if (walletToClose.networkCheckInterval) {
143+
clearInterval(walletToClose.networkCheckInterval);
144+
walletToClose.networkCheckInterval = undefined;
128145
}
129146

130147
return new Promise(res => {
131148
setTimeout(async () => {
132149
try {
133-
wallet.dataStore.db.destroy();
150+
walletToClose.dataStore.db.destroy();
134151
await blockchainService.disconnect();
135152
} catch (err) {
136153
console.error(err);

integration-tests/sd-jwt.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
UniversityDegreeCredentialBBS,
77
} from './data/credentials';
88
import {
9+
addCredentialIfNotExists,
910
cleanup,
1011
closeWallet,
1112
getCredentialProvider,
@@ -26,8 +27,8 @@ describe('SD JWT Credentials', () => {
2627

2728
wallet = await getWallet();
2829

29-
const result = await getCredentialProvider().addCredential(jwt);
30-
credentialId = result.id;
30+
const result = await addCredentialIfNotExists(jwt);
31+
credentialId = result?.id;
3132
});
3233

3334
it('expect to import SD-JWT credential', async () => {

integration-tests/switch-wallet.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {
2+
addCredentialIfNotExists,
23
closeWallet,
3-
getCredentialProvider,
44
getDocumentsByType,
55
getWallet,
66
setNetwork,
@@ -17,7 +17,7 @@ describe('Switch wallet', () => {
1717

1818
it('expect to maintain separate document stores when switching between networks', async () => {
1919
await setNetwork('testnet');
20-
await getCredentialProvider().addCredential(BasicCredential);
20+
await addCredentialIfNotExists(BasicCredential);
2121

2222
const testnetCredentials = await getDocumentsByType('VerifiableCredential');
2323
expect(testnetCredentials.length).toBe(1);

integration-tests/verification-flow/bbs-plus-revocation.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {IWallet} from '@docknetwork/wallet-sdk-core/lib/types';
22
import {
3+
addCredentialIfNotExists,
34
closeWallet,
45
getCredentialProvider,
56
getWallet,
@@ -12,7 +13,7 @@ describe('BBS+ revocation', () => {
1213
it('should verify a revokable bbs+ credential', async () => {
1314
const wallet: IWallet = await getWallet();
1415

15-
getCredentialProvider().addCredential(bbsPlusRevocationCredential);
16+
await addCredentialIfNotExists(bbsPlusRevocationCredential);
1617

1718
const proofRequest = await createProofRequest(
1819
ProofTemplateIds.ANY_CREDENTIAL,
@@ -59,7 +60,7 @@ describe('BBS+ revocation', () => {
5960
it('should verify a revokable bbs+ credential with an updated witness', async () => {
6061
const wallet: IWallet = await getWallet();
6162

62-
getCredentialProvider().addCredential(credentialWithUpdatedWitness);
63+
await addCredentialIfNotExists(credentialWithUpdatedWitness);
6364

6465
const proofRequest = await createProofRequest(
6566
ProofTemplateIds.ANY_CREDENTIAL,

integration-tests/verification-flow/cheqd-revocation.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {IWallet} from '@docknetwork/wallet-sdk-core/lib/types';
22
import {
3+
addCredentialIfNotExists,
34
closeWallet,
45
getCredentialProvider,
56
getWallet,
@@ -12,7 +13,7 @@ describe('BBS+ revocation cheqd', () => {
1213
it('should verify a revokable bbs+ credential issued on cheqd', async () => {
1314
const wallet: IWallet = await getWallet();
1415

15-
getCredentialProvider().addCredential(cheqdRevocationCredential);
16+
await addCredentialIfNotExists(cheqdRevocationCredential);
1617

1718
const proofRequest = await createProofRequest(
1819
ProofTemplateIds.ANY_CREDENTIAL,

integration-tests/verification-flow/range-proofs.test.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {IWallet} from '@docknetwork/wallet-sdk-core/lib/types';
22
import {
3+
addCredentialIfNotExists,
34
closeWallet,
4-
getCredentialProvider,
55
getWallet,
66
} from '../helpers/wallet-helpers';
77
import {createVerificationController} from '@docknetwork/wallet-sdk-core/src/verification-controller';
@@ -29,7 +29,7 @@ describe('Range proofs verification', () => {
2929
`${credentialUrl}?p=${btoa(password)}`,
3030
);
3131

32-
getCredentialProvider().addCredential(credential);
32+
await addCredentialIfNotExists(credential);
3333

3434
await controller.start({
3535
template: proofRequest.qr,
@@ -80,7 +80,7 @@ describe('Range proofs verification', () => {
8080
`${credentialUrl}?p=${btoa(password)}`,
8181
);
8282

83-
getCredentialProvider().addCredential(credential);
83+
await addCredentialIfNotExists(credential);
8484

8585
await controller.start({
8686
template: proofRequest.qr,
@@ -135,11 +135,7 @@ describe('Range proofs verification', () => {
135135
`${credentialUrl}?p=${btoa(password)}`,
136136
);
137137

138-
try {
139-
await getCredentialProvider().addCredential(credential);
140-
} catch(err) {
141-
console.error('Credential already added');
142-
}
138+
await addCredentialIfNotExists(credential);
143139

144140
// pexToBounds should skip issuanceDate
145141
// There is an SDK limitation that prevents us from sharing the actual issuanceDate

integration-tests/verification-flow/vpi-verification.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {IWallet} from '@docknetwork/wallet-sdk-core/lib/types';
22
import {
3+
addCredentialIfNotExists,
34
closeWallet,
45
getCredentialProvider,
56
getWallet,
@@ -75,7 +76,7 @@ describe('VPI verification', () => {
7576
it('should verify a vpi credential', async () => {
7677
const wallet: IWallet = await getWallet();
7778

78-
getCredentialProvider().addCredential(credential);
79+
await addCredentialIfNotExists(credential);
7980

8081
const proofRequest = await createProofRequest(
8182
ProofTemplateIds.ANY_CREDENTIAL,

packages/core/src/message-provider.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,14 +243,30 @@ export function createMessageProvider({
243243
}
244244

245245
let listenerIntervalId = null;
246+
let processMessageTimeoutId = null;
247+
let stopped = false;
246248

247249
const processMessageInterval = 3000;
248250

249251
async function processMessageRecurrentJob() {
250252
try {
251253
await processDIDCommMessages();
252254
} finally {
253-
setTimeout(processMessageRecurrentJob, processMessageInterval);
255+
if (!stopped) {
256+
processMessageTimeoutId = setTimeout(processMessageRecurrentJob, processMessageInterval);
257+
}
258+
}
259+
}
260+
261+
function stop() {
262+
stopped = true;
263+
if (listenerIntervalId) {
264+
clearInterval(listenerIntervalId);
265+
listenerIntervalId = null;
266+
}
267+
if (processMessageTimeoutId) {
268+
clearTimeout(processMessageTimeoutId);
269+
processMessageTimeoutId = null;
254270
}
255271
}
256272

@@ -333,12 +349,20 @@ export function createMessageProvider({
333349
*/
334350
startAutoFetch(timeout = 2000) {
335351
clearInterval(listenerIntervalId);
352+
stopped = false;
336353
listenerIntervalId = setInterval(async () => {
337-
await fetchMessages();
338-
await processDIDCommMessages();
354+
try {
355+
await fetchMessages();
356+
await processDIDCommMessages();
357+
} catch (err) {
358+
logger.debug(`Auto-fetch error: ${err.message}`);
359+
}
339360
}, timeout);
340361

341-
return () => clearInterval(listenerIntervalId);
362+
return () => {
363+
clearInterval(listenerIntervalId);
364+
listenerIntervalId = null;
365+
};
342366
},
343367
/**
344368
* Clears all cached messages from the wallet
@@ -410,5 +434,6 @@ export function createMessageProvider({
410434
* console.log('Message marked as read');
411435
*/
412436
markMessageAsRead,
437+
stop,
413438
} as any;
414439
}

0 commit comments

Comments
 (0)