Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Commit 0db2b18

Browse files
mmyyrroonnavkos
andauthored
Fix 7055 one of with scalar value and string (#7173)
* code work * add test * add more test * update change log * refine change log * refine test --------- Co-authored-by: Oleksii Kosynskyi <[email protected]>
1 parent 8b435c1 commit 0db2b18

File tree

3 files changed

+87
-1
lines changed

3 files changed

+87
-1
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2650,6 +2650,12 @@ If there are any bugs, improvements, optimizations or any new feature proposal f
26502650

26512651
## [Unreleased]
26522652

2653+
### Fixed
2654+
2655+
#### web3-utils
2656+
2657+
- Fixed format schema with `oneOf` doesn't work correctly (#7055)
2658+
26532659
### Added
26542660

26552661
#### web3-eth-accounts

packages/web3-utils/src/formatter.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ export const convertScalarValue = (value: unknown, ethType: string, format: Data
131131
throw new FormatterError(`Invalid format: ${String(format.bytes)}`);
132132
}
133133
}
134+
135+
if (baseType === 'string') {
136+
return String(value);
137+
}
138+
134139
} catch (error) {
135140
// If someone didn't use `eth` keyword we can return original value
136141
// as the scope of this code is formatting not validation
@@ -289,7 +294,7 @@ export const convert = (
289294
} else {
290295
for (const [key, value] of Object.entries(object)) {
291296
dataPath.push(key);
292-
const schemaProp = findSchemaByDataPath(schema, dataPath, oneOfPath);
297+
let schemaProp = findSchemaByDataPath(schema, dataPath, oneOfPath);
293298

294299
// If value is a scaler value
295300
if (isNullish(schemaProp)) {
@@ -322,6 +327,20 @@ export const convert = (
322327
continue;
323328
}
324329

330+
// The following code is basically saying:
331+
// if the schema specifies oneOf, then we are to loop
332+
// over each possible schema and check if they type of the schema specifies format
333+
// and if so we use the oneOfSchemaProp as the schema for formatting
334+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
335+
if ((schemaProp?.format === undefined) && (schemaProp?.oneOf !== undefined)) {
336+
for (const [_index, oneOfSchemaProp] of schemaProp.oneOf.entries()) {
337+
if ((oneOfSchemaProp?.format !== undefined)) {
338+
schemaProp = oneOfSchemaProp;
339+
break;
340+
}
341+
};
342+
}
343+
325344
object[key] = convertScalarValue(value, schemaProp.format as string, format);
326345

327346
dataPath.pop();

packages/web3-utils/test/unit/formatter.test.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,17 @@ describe('formatter', () => {
479479
).toEqual(new Uint8Array([16, 11, 202]));
480480
});
481481
});
482+
483+
describe('string', () => {
484+
it('should format string for 123', () => {
485+
expect(
486+
format({ format: 'string' }, 123, {
487+
number: FMT_NUMBER.STR,
488+
bytes: FMT_BYTES.HEX,
489+
}),
490+
).toBe('123');
491+
});
492+
});
482493
});
483494

484495
describe('array values', () => {
@@ -827,6 +838,56 @@ describe('formatter', () => {
827838

828839
expect(result).toEqual(expected);
829840
});
841+
842+
it('should format object with oneOf', () => {
843+
const schema = {
844+
type: 'object',
845+
properties: {
846+
from: {
847+
format: 'address',
848+
},
849+
to: {
850+
oneOf: [{ format: 'string' }, { type: 'null' }],
851+
},
852+
},
853+
};
854+
855+
const data ={
856+
from: '0x7ed0e85b8e1e925600b4373e6d108f34ab38a401',
857+
to: 123,
858+
}
859+
;
860+
861+
const result = { from: '0x7ed0e85b8e1e925600b4373e6d108f34ab38a401', to: '123' };
862+
863+
expect(
864+
format(schema, data, { number: FMT_NUMBER.HEX, bytes: FMT_BYTES.HEX }),
865+
).toEqual(result);
866+
});
867+
868+
it('should format object with oneOf when property is undefined', () => {
869+
const schema = {
870+
type: 'object',
871+
properties: {
872+
from: {
873+
format: 'address',
874+
},
875+
to: {
876+
oneOf: [{ format: 'string' }, { type: 'null' }],
877+
},
878+
},
879+
};
880+
881+
const data ={
882+
from: '0x7ed0e85b8e1e925600b4373e6d108f34ab38a401'
883+
};
884+
885+
const result = { from: '0x7ed0e85b8e1e925600b4373e6d108f34ab38a401'};
886+
887+
expect(
888+
format(schema, data, { number: FMT_NUMBER.HEX, bytes: FMT_BYTES.HEX }),
889+
).toEqual(result);
890+
});
830891
});
831892
describe('isDataFormat', () => {
832893
describe('valid cases', () => {

0 commit comments

Comments
 (0)