Skip to content

Commit bcb7899

Browse files
committed
Use crypto.getRandomValues for salt. Use helper utils to validate bigint values.
1 parent b9f6fcc commit bcb7899

10 files changed

Lines changed: 105 additions & 59 deletions

File tree

packages/gator-permissions-snap/snap.manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"url": "https://github.com/MetaMask/snap-7715-permissions.git"
88
},
99
"source": {
10-
"shasum": "OuArP0RAiIuuilf8/74gv9GSFwhcUnQqC1xbLAvXpLk=",
10+
"shasum": "PoFMZl7wTNzoiX+wVkMk8Gwmhxd4el+wY1HHBX0XjGs=",
1111
"location": {
1212
"npm": {
1313
"filePath": "dist/bundle.js",

packages/gator-permissions-snap/src/core/permissionRequestLifecycleOrchestrator.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,7 @@ export class PermissionRequestLifecycleOrchestrator {
234234
validBefore,
235235
);
236236

237-
// use a random salt to ensure unique delegation
238-
const saltBytes = new Uint8Array(32);
239-
for (let i = 0; i < 32; i++) {
240-
saltBytes[i] = Math.floor(Math.random() * 256);
241-
}
237+
const saltBytes = crypto.getRandomValues(new Uint8Array(32));
242238
const salt = bytesToHex(saltBytes);
243239

244240
const delegation = {

packages/gator-permissions-snap/src/permissions/erc20TokenStream/validation.ts

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { PermissionRequest } from '@metamask/7715-permissions-shared/types';
22
import { extractZodError } from '@metamask/7715-permissions-shared/utils';
3+
import { validateHexInteger } from '../validation';
34

45
import type {
56
Erc20TokenStreamPermission,
@@ -16,30 +17,30 @@ import { zErc20TokenStreamPermission } from './types';
1617
function validatePermissionData(permission: Erc20TokenStreamPermission): true {
1718
const { initialAmount, maxAmount, amountPerSecond, startTime, tokenAddress } =
1819
permission.data;
19-
const bigIntAmountPerSecond = BigInt(amountPerSecond);
2020

21-
if (maxAmount) {
22-
if (BigInt(maxAmount) === 0n) {
23-
throw new Error('Invalid maxAmount: must be a positive number');
24-
}
25-
}
21+
validateHexInteger({
22+
name: 'maxAmount',
23+
value: maxAmount,
24+
required: false,
25+
allowZero: false,
26+
});
2627

27-
if (initialAmount) {
28-
const bigIntInitialAmount = BigInt(initialAmount);
29-
if (bigIntInitialAmount === 0n) {
30-
throw new Error('Invalid initialAmount: must be greater than zero');
31-
}
32-
if (maxAmount) {
33-
if (BigInt(maxAmount) < bigIntInitialAmount) {
34-
throw new Error(
35-
'Invalid maxAmount: must be greater than initialAmount',
36-
);
37-
}
38-
}
39-
}
28+
validateHexInteger({
29+
name: 'initialAmount',
30+
value: initialAmount,
31+
required: false,
32+
allowZero: false,
33+
});
34+
35+
validateHexInteger({
36+
name: 'amountPerSecond',
37+
value: amountPerSecond,
38+
required: true,
39+
allowZero: false,
40+
});
4041

41-
if (bigIntAmountPerSecond === 0n) {
42-
throw new Error('Invalid amountPerSecond: must be a positive number');
42+
if (initialAmount && maxAmount && BigInt(maxAmount) < BigInt(initialAmount)) {
43+
throw new Error('Invalid maxAmount: must be greater than initialAmount');
4344
}
4445

4546
if (startTime <= 0) {

packages/gator-permissions-snap/src/permissions/nativeTokenPeriodic/validation.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { PermissionRequest } from '@metamask/7715-permissions-shared/types';
22
import { extractZodError } from '@metamask/7715-permissions-shared/utils';
3+
import { validateHexInteger } from '../validation';
34

45
import type {
56
NativeTokenPeriodicPermission,
@@ -17,11 +18,13 @@ function validatePermissionData(
1718
permission: NativeTokenPeriodicPermission,
1819
): true {
1920
const { periodAmount, periodDuration, startTime } = permission.data;
20-
const bigIntPeriodAmount = BigInt(periodAmount);
2121

22-
if (bigIntPeriodAmount === 0n) {
23-
throw new Error('Invalid periodAmount: must be a positive number');
24-
}
22+
validateHexInteger({
23+
name: 'periodAmount',
24+
value: periodAmount,
25+
required: true,
26+
allowZero: false,
27+
});
2528

2629
if (periodDuration <= 0) {
2730
throw new Error('Invalid periodDuration: must be a positive number');

packages/gator-permissions-snap/src/permissions/nativeTokenStream/validation.ts

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { PermissionRequest } from '@metamask/7715-permissions-shared/types';
22
import { extractZodError } from '@metamask/7715-permissions-shared/utils';
3+
import { validateHexInteger } from '../validation';
34

45
import type {
56
NativeTokenStreamPermission,
@@ -16,30 +17,30 @@ import { zNativeTokenStreamPermission } from './types';
1617
function validatePermissionData(permission: NativeTokenStreamPermission): true {
1718
const { initialAmount, maxAmount, amountPerSecond, startTime } =
1819
permission.data;
19-
const bigIntAmountPerSecond = BigInt(amountPerSecond);
2020

21-
if (maxAmount) {
22-
if (BigInt(maxAmount) === 0n) {
23-
throw new Error('Invalid maxAmount: must be a positive number');
24-
}
25-
}
21+
validateHexInteger({
22+
name: 'maxAmount',
23+
value: maxAmount,
24+
required: false,
25+
allowZero: false,
26+
});
2627

27-
if (initialAmount) {
28-
const bigIntInitialAmount = BigInt(initialAmount);
29-
if (bigIntInitialAmount === 0n) {
30-
throw new Error('Invalid initialAmount: must be greater than zero');
31-
}
32-
if (maxAmount) {
33-
if (BigInt(maxAmount) < bigIntInitialAmount) {
34-
throw new Error(
35-
'Invalid maxAmount: must be greater than initialAmount',
36-
);
37-
}
38-
}
39-
}
28+
validateHexInteger({
29+
name: 'initialAmount',
30+
value: initialAmount,
31+
required: false,
32+
allowZero: false,
33+
});
34+
35+
validateHexInteger({
36+
name: 'amountPerSecond',
37+
value: amountPerSecond,
38+
required: true,
39+
allowZero: false,
40+
});
4041

41-
if (bigIntAmountPerSecond === 0n) {
42-
throw new Error('Invalid amountPerSecond: must be a positive number');
42+
if (initialAmount && maxAmount && BigInt(maxAmount) < BigInt(initialAmount)) {
43+
throw new Error('Invalid maxAmount: must be greater than initialAmount');
4344
}
4445

4546
if (startTime <= 0) {
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Hex } from 'viem';
2+
3+
/**
4+
* Validates a hex integer value with configurable constraints.
5+
*
6+
* @param params - The validation parameters.
7+
* @param params.name - The name of the value being validated, used in error messages.
8+
* @param params.value - The hex value to validate.
9+
* @param params.allowZero - Whether zero values are allowed.
10+
* @param params.required - Whether the value is required (must be defined).
11+
* @throws {Error} If the value fails validation.
12+
*/
13+
export function validateHexInteger({
14+
name,
15+
value,
16+
allowZero,
17+
required,
18+
}: {
19+
name: string;
20+
value: Hex | undefined;
21+
allowZero: boolean;
22+
required: boolean;
23+
}) {
24+
if (value === undefined || value === null) {
25+
if (!required) {
26+
return;
27+
}
28+
29+
throw new Error(`Invalid ${name}: must be defined`);
30+
}
31+
let parsedValue: bigint;
32+
33+
try {
34+
parsedValue = BigInt(value);
35+
} catch (error) {
36+
throw new Error(`Invalid ${name}: must be a valid hex integer`);
37+
}
38+
39+
if (parsedValue === 0n && !allowZero) {
40+
throw new Error(`Invalid ${name}: must be greater than 0`);
41+
}
42+
43+
return parsedValue;
44+
}

packages/gator-permissions-snap/test/permissions/erc20TokenStream/validation.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ describe('erc20TokenStream:validation', () => {
7272
};
7373

7474
expect(() => parseAndValidatePermission(zeroMaxAmountRequest)).toThrow(
75-
'Invalid maxAmount: must be a positive number',
75+
'Invalid maxAmount: must be greater than 0',
7676
);
7777
});
7878

@@ -110,7 +110,7 @@ describe('erc20TokenStream:validation', () => {
110110

111111
expect(() =>
112112
parseAndValidatePermission(zeroInitialAmountRequest),
113-
).toThrow('Invalid initialAmount: must be greater than zero');
113+
).toThrow('Invalid initialAmount: must be greater than 0');
114114
});
115115

116116
it('should allow missing initialAmount', () => {
@@ -146,7 +146,7 @@ describe('erc20TokenStream:validation', () => {
146146

147147
expect(() =>
148148
parseAndValidatePermission(zeroAmountPerSecondRequest),
149-
).toThrow('Invalid amountPerSecond: must be a positive number');
149+
).toThrow('Invalid amountPerSecond: must be greater than 0');
150150
});
151151
});
152152

packages/gator-permissions-snap/test/permissions/nativeTokenPeriodic/validation.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ describe('nativeTokenPeriodic:validation', () => {
7373

7474
expect(() =>
7575
parseAndValidatePermission(zeroPeriodAmountRequest),
76-
).toThrow('Invalid periodAmount: must be a positive number');
76+
).toThrow('Invalid periodAmount: must be greater than 0');
7777
});
7878
});
7979

packages/gator-permissions-snap/test/permissions/nativeTokenStream/validation.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ describe('nativeTokenStream:validation', () => {
6969
};
7070

7171
expect(() => parseAndValidatePermission(zeroMaxAmountRequest)).toThrow(
72-
'Invalid maxAmount: must be a positive number',
72+
'Invalid maxAmount: must be greater than 0',
7373
);
7474
});
7575

@@ -107,7 +107,7 @@ describe('nativeTokenStream:validation', () => {
107107

108108
expect(() =>
109109
parseAndValidatePermission(zeroInitialAmountRequest),
110-
).toThrow('Invalid initialAmount: must be greater than zero');
110+
).toThrow('Invalid initialAmount: must be greater than 0');
111111
});
112112

113113
it('should allow missing initialAmount', () => {
@@ -143,7 +143,7 @@ describe('nativeTokenStream:validation', () => {
143143

144144
expect(() =>
145145
parseAndValidatePermission(zeroAmountPerSecondRequest),
146-
).toThrow('Invalid amountPerSecond: must be a positive number');
146+
).toThrow('Invalid amountPerSecond: must be greater than 0');
147147
});
148148
});
149149

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './origin';
2+
export * from './validation';

0 commit comments

Comments
 (0)