Skip to content

Commit 69ecba9

Browse files
committed
Improve info validation
1 parent 2aa85d5 commit 69ecba9

File tree

3 files changed

+112
-15
lines changed

3 files changed

+112
-15
lines changed

jest.config.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ const baseConfig = {
4545
// An object that configures minimum threshold enforcement for coverage results
4646
coverageThreshold: {
4747
global: {
48-
branches: 61.49,
49-
functions: 62.92,
50-
lines: 64.82,
51-
statements: 64.95,
48+
branches: 62.37,
49+
functions: 63.73,
50+
lines: 64.93,
51+
statements: 65.06,
5252
},
5353
},
5454

src/EIP6963.test.ts

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,76 @@ const getProviderInfo = () => ({
77
uuid: '1449211e-5560-4235-9ab1-582cbe2b165f',
88
});
99

10+
const providerInfoValidationError = () =>
11+
new Error(
12+
'Invalid EIP-6963 provider info. See https://eips.ethereum.org/EIPS/eip-6963 for requirements.',
13+
);
14+
1015
describe('EIP6963', () => {
1116
describe('announceProvider', () => {
12-
it('throws if the UUID is invalid', () => {
13-
['foo', null, undefined, Symbol('bar')].forEach((invalidUuid) => {
14-
const provider: any = { name: 'test' };
15-
const providerDetail = { info: getProviderInfo(), provider };
16-
providerDetail.info.uuid = invalidUuid as any;
17-
18-
expect(() => announceProvider(providerDetail)).toThrow(
19-
new Error('Invalid `uuid` field. Must be a v4 UUID.'),
17+
describe('provider info validation', () => {
18+
it('throws if the info is not a plain object', () => {
19+
[null, undefined, Symbol('bar'), []].forEach((invalidUuid) => {
20+
const provider: any = { name: 'test' };
21+
const providerDetail = { info: getProviderInfo(), provider };
22+
providerDetail.info.uuid = invalidUuid as any;
23+
24+
expect(() => announceProvider(providerDetail)).toThrow(
25+
providerInfoValidationError(),
26+
);
27+
});
28+
});
29+
30+
it('throws if the `icon` field is invalid', () => {
31+
[null, undefined, '', 'not-a-url', Symbol('bar')].forEach(
32+
(invalidUuid) => {
33+
const provider: any = { name: 'test' };
34+
const providerDetail = { info: getProviderInfo(), provider };
35+
providerDetail.info.uuid = invalidUuid as any;
36+
37+
expect(() => announceProvider(providerDetail)).toThrow(
38+
providerInfoValidationError(),
39+
);
40+
},
2041
);
2142
});
22-
});
2343

44+
it('throws if the `name` field is invalid', () => {
45+
[null, undefined, '', {}, [], Symbol('bar')].forEach((invalidUuid) => {
46+
const provider: any = { name: 'test' };
47+
const providerDetail = { info: getProviderInfo(), provider };
48+
providerDetail.info.uuid = invalidUuid as any;
49+
50+
expect(() => announceProvider(providerDetail)).toThrow(
51+
providerInfoValidationError(),
52+
);
53+
});
54+
});
55+
56+
it('throws if the `uuid` field is invalid', () => {
57+
[null, undefined, '', 'foo', Symbol('bar')].forEach((invalidUuid) => {
58+
const provider: any = { name: 'test' };
59+
const providerDetail = { info: getProviderInfo(), provider };
60+
providerDetail.info.uuid = invalidUuid as any;
61+
62+
expect(() => announceProvider(providerDetail)).toThrow(
63+
providerInfoValidationError(),
64+
);
65+
});
66+
});
67+
68+
it('throws if the `walletId` field is invalid', () => {
69+
[null, undefined, '', {}, [], Symbol('bar')].forEach((invalidUuid) => {
70+
const provider: any = { name: 'test' };
71+
const providerDetail = { info: getProviderInfo(), provider };
72+
providerDetail.info.uuid = invalidUuid as any;
73+
74+
expect(() => announceProvider(providerDetail)).toThrow(
75+
providerInfoValidationError(),
76+
);
77+
});
78+
});
79+
});
2480
it('should announce a provider', () => {
2581
const provider: any = { name: 'test' };
2682
const providerDetail = { info: getProviderInfo(), provider };

src/EIP6963.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,10 @@ export function announceProvider({
9292
info,
9393
provider,
9494
}: EIP6963ProviderDetail): void {
95-
if (typeof info.uuid !== 'string' || !UUID_V4_REGEX.test(info.uuid)) {
96-
throw new Error('Invalid `uuid` field. Must be a v4 UUID.');
95+
if (!isValidInfo(info)) {
96+
throw new Error(
97+
'Invalid EIP-6963 provider info. See https://eips.ethereum.org/EIPS/eip-6963 for requirements.',
98+
);
9799
}
98100

99101
const _announceProvider = () =>
@@ -111,3 +113,42 @@ export function announceProvider({
111113
},
112114
);
113115
}
116+
117+
/**
118+
* Validates an {@link EIP6963ProviderInfo} object.
119+
*
120+
* @param info - The {@link EIP6963ProviderInfo} to validate.
121+
* @returns Whether the {@link EIP6963ProviderInfo} is valid.
122+
*/
123+
function isValidInfo(info: unknown): info is EIP6963ProviderInfo {
124+
if (!isObject(info)) {
125+
return false;
126+
}
127+
128+
return (
129+
typeof info.icon === 'string' &&
130+
isValidUrl(info.icon) &&
131+
typeof info.name === 'string' &&
132+
Boolean(info.name) &&
133+
typeof info.uuid === 'string' &&
134+
UUID_V4_REGEX.test(info.uuid) &&
135+
typeof info.walletId === 'string' &&
136+
Boolean(info.walletId)
137+
);
138+
}
139+
140+
/**
141+
* Checks if a string is a valid URL.
142+
*
143+
* @param url - The string to check.
144+
* @returns Whether the string is a valid URL.
145+
*/
146+
function isValidUrl(url: string) {
147+
try {
148+
// eslint-disable-next-line no-new
149+
new URL(url);
150+
return true;
151+
} catch (error) {
152+
return false;
153+
}
154+
}

0 commit comments

Comments
 (0)