Skip to content

Commit 455a29b

Browse files
Merge pull request #207 from ElrondNetwork/hotfix-PR-198
Redo PR #198 for erdjs 9x.
2 parents 22bbcc4 + 30d1a41 commit 455a29b

File tree

10 files changed

+133
-64
lines changed

10 files changed

+133
-64
lines changed

.github/workflows/erdjs-publish.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ jobs:
2222
echo "" >> notes.txt
2323
2424
RELEASE_TAG=v$(node -p "require('./package.json').version")
25-
gh release create $RELEASE_TAG --target=$GITHUB_SHA --title="$RELEASE_TAG" --generate-notes --notes-file=notes.txt
25+
gh release create --prerelease $RELEASE_TAG --target=$GITHUB_SHA --title="$RELEASE_TAG" --generate-notes --notes-file=notes.txt
2626
2727
- run: npm ci
2828
- run: npm test
2929

3030
- name: Publish to npmjs
3131
env:
3232
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
33-
run: npm publish --access=public
33+
run: npm publish --access=public --tag=older

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@elrondnetwork/erdjs",
3-
"version": "9.2.5",
3+
"version": "9.2.6",
44
"description": "Smart Contracts interaction framework",
55
"main": "out/index.js",
66
"types": "out/index.d.js",

src/smartcontracts/typesystem/abiRegistry.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,19 @@ describe("test abi registry", () => {
9292
);
9393
assert.equal(result.valueOf().name, "SendTransferExecute");
9494
});
95+
96+
it("should load ABI containing arrayN and nested structs", async () => {
97+
let registry = await loadAbiRegistry(["src/testdata/array-in-nested-structs.abi.json"]);
98+
let dummyType = registry.getStruct("Dummy");
99+
let fooType = registry.getStruct("Foo");
100+
let barType = registry.getStruct("Bar");
101+
let fooTypeFromBarType = <StructType>barType.getFieldDefinition("foo")!.type;
102+
let dummyTypeFromFooTypeFromBarType = <StructType>fooTypeFromBarType.getFieldDefinition("dummy")!.type;
103+
104+
assert.equal(dummyType.getClassName(), StructType.ClassName);
105+
assert.equal(fooType.getClassName(), StructType.ClassName);
106+
assert.equal(barType.getClassName(), StructType.ClassName);
107+
assert.isTrue(fooType == fooTypeFromBarType);
108+
assert.isTrue(dummyType == dummyTypeFromFooTypeFromBarType);
109+
});
95110
});

src/smartcontracts/typesystem/abiRegistry.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,13 @@ export class AbiRegistry {
102102
* The result is an equivalent, more explicit ABI registry.
103103
*/
104104
remapToKnownTypes(): AbiRegistry {
105-
let mapper = new TypeMapper(this.customTypes);
105+
let mapper = new TypeMapper([]);
106106
let newCustomTypes: CustomType[] = [];
107107
let newInterfaces: ContractInterface[] = [];
108108
// First, remap custom types (actually, under the hood, this will remap types of struct fields)
109109
for (const type of this.customTypes) {
110110
const mappedTyped = mapper.mapType(type);
111111
newCustomTypes.push(mappedTyped);
112-
mapper.feedCustomType(mappedTyped);
113112
}
114113
// Then, remap types of all endpoint parameters.
115114
// But we'll use an enhanced mapper, that takes into account the results from the previous step.

src/smartcontracts/typesystem/enum.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,13 @@ export class EnumVariantDefinition {
5656
return new EnumVariantDefinition(json.name, json.discriminant, definitions);
5757
}
5858

59-
getFieldsDefinitions() {
59+
getFieldsDefinitions(): FieldDefinition[] {
6060
return this.fieldsDefinitions;
6161
}
62+
63+
getFieldDefinition(name: string): FieldDefinition | undefined {
64+
return this.fieldsDefinitions.find(item => item.name == name);
65+
}
6266
}
6367

6468
export class EnumValue extends TypedValue {

src/smartcontracts/typesystem/struct.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ export class StructType extends CustomType {
1919
return new StructType(json.name, definitions);
2020
}
2121

22-
getFieldsDefinitions() {
22+
getFieldsDefinitions(): FieldDefinition[] {
2323
return this.fieldsDefinitions;
2424
}
25+
26+
getFieldDefinition(name: string): FieldDefinition | undefined {
27+
return this.fieldsDefinitions.find(item => item.name == name);
28+
}
2529
}
2630

2731
// TODO: implement setField(), convenience method.

src/smartcontracts/typesystem/typeMapper.ts

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ type TypeFactory = (...typeParameters: Type[]) => Type;
3535
export class TypeMapper {
3636
private readonly openTypesFactories: Map<string, TypeFactory>;
3737
private readonly closedTypesMap: Map<string, Type>;
38+
private readonly learnedTypesMap: Map<string, Type>;
3839

39-
constructor(customTypes: CustomType[] = []) {
40+
constructor(learnedTypes: CustomType[] = []) {
4041
this.openTypesFactories = new Map<string, TypeFactory>([
4142
["Option", (...typeParameters: Type[]) => new OptionType(typeParameters[0])],
4243
["List", (...typeParameters: Type[]) => new ListType(typeParameters[0])],
@@ -61,7 +62,7 @@ export class TypeMapper {
6162
["tuple7", (...typeParameters: Type[]) => new TupleType(...typeParameters)],
6263
["tuple8", (...typeParameters: Type[]) => new TupleType(...typeParameters)],
6364
// Known-length arrays.
64-
// TODO: Handle these in typeExpressionParser, perhaps?
65+
// TODO: Handle these in typeExpressionParser!
6566
["array20", (...typeParameters: Type[]) => new ArrayVecType(20, typeParameters[0])],
6667
["array32", (...typeParameters: Type[]) => new ArrayVecType(32, typeParameters[0])],
6768
["array46", (...typeParameters: Type[]) => new ArrayVecType(46, typeParameters[0])],
@@ -93,14 +94,41 @@ export class TypeMapper {
9394
["AsyncCall", new NothingType()]
9495
]);
9596

96-
for (const customType of customTypes) {
97-
this.closedTypesMap.set(customType.getName(), customType);
97+
this.learnedTypesMap = new Map<string, Type>();
98+
99+
// Boostrap from previously learned types, if any.
100+
for (const type of learnedTypes) {
101+
this.learnedTypesMap.set(type.getName(), type);
102+
}
103+
}
104+
105+
mapType(type: Type): Type {
106+
let mappedType = this.mapRecursiveType(type);
107+
if (mappedType) {
108+
// We do not learn generic types (that also have type parameters)
109+
if (!mappedType.isGenericType()) {
110+
this.learnType(mappedType);
111+
}
112+
113+
return mappedType;
98114
}
115+
116+
throw new errors.ErrTypingSystem(`Cannot map the type "${type.getName()}" to a known type`);
99117
}
100118

101119
mapRecursiveType(type: Type): Type | null {
102120
let isGeneric = type.isGenericType();
103121

122+
let previouslyLearnedType = this.learnedTypesMap.get(type.getName());
123+
if (previouslyLearnedType) {
124+
return previouslyLearnedType;
125+
}
126+
127+
let knownClosedType = this.closedTypesMap.get(type.getName());
128+
if (knownClosedType) {
129+
return knownClosedType;
130+
}
131+
104132
if (type.hasExactClass(EnumType.ClassName)) {
105133
// This will call mapType() recursively, for all the enum variant fields.
106134
return this.mapEnumType(<EnumType>type);
@@ -115,27 +143,13 @@ export class TypeMapper {
115143
// This will call mapType() recursively, for all the type parameters.
116144
return this.mapGenericType(type);
117145
}
118-
119-
return null;
120-
}
121-
122-
mapType(type: Type): Type {
123-
let mappedType = this.mapRecursiveType(type);
124-
if (mappedType !== null) {
125-
return mappedType;
126-
}
127-
128-
let knownClosedType = this.closedTypesMap.get(type.getName());
129-
if (!knownClosedType) {
130-
throw new errors.ErrTypingSystem(`Cannot map the type "${type.getName()}" to a known type`);
131-
}
132146

133-
return this.mapRecursiveType(knownClosedType) ?? knownClosedType;
147+
return null;
134148
}
135149

136-
feedCustomType(type: Type): void {
137-
this.closedTypesMap.delete(type.getName());
138-
this.closedTypesMap.set(type.getName(), type);
150+
private learnType(type: Type): void {
151+
this.learnedTypesMap.delete(type.getName());
152+
this.learnedTypesMap.set(type.getName(), type);
139153
}
140154

141155
private mapStructType(type: StructType): StructType {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "ArraysSample",
3+
"endpoints": [],
4+
"types": {
5+
"Dummy": {
6+
"type": "struct",
7+
"fields": [
8+
{
9+
"name": "raw",
10+
"type": "array20<u8>"
11+
}
12+
]
13+
},
14+
"Foo": {
15+
"type": "struct",
16+
"fields": [
17+
{
18+
"name": "dummy",
19+
"type": "Dummy"
20+
}
21+
]
22+
},
23+
"Bar": {
24+
"type": "struct",
25+
"fields": [
26+
{
27+
"name": "foo",
28+
"type": "Foo"
29+
}
30+
]
31+
}
32+
}
33+
}

src/testdata/esdt-nft-marketplace.abi.json

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,40 @@
403403
],
404404
"hasCallback": false,
405405
"types": {
406+
"EsdtToken": {
407+
"type": "struct",
408+
"fields": [
409+
{
410+
"name": "token_type",
411+
"type": "TokenIdentifier"
412+
},
413+
{
414+
"name": "nonce",
415+
"type": "u64"
416+
}
417+
]
418+
},
419+
"AuctionType": {
420+
"type": "enum",
421+
"variants": [
422+
{
423+
"name": "None",
424+
"discriminant": 0
425+
},
426+
{
427+
"name": "Nft",
428+
"discriminant": 1
429+
},
430+
{
431+
"name": "SftAll",
432+
"discriminant": 2
433+
},
434+
{
435+
"name": "SftOnePerPayment",
436+
"discriminant": 3
437+
}
438+
]
439+
},
406440
"Auction": {
407441
"type": "struct",
408442
"fields": [
@@ -459,40 +493,6 @@
459493
"type": "BigUint"
460494
}
461495
]
462-
},
463-
"AuctionType": {
464-
"type": "enum",
465-
"variants": [
466-
{
467-
"name": "None",
468-
"discriminant": 0
469-
},
470-
{
471-
"name": "Nft",
472-
"discriminant": 1
473-
},
474-
{
475-
"name": "SftAll",
476-
"discriminant": 2
477-
},
478-
{
479-
"name": "SftOnePerPayment",
480-
"discriminant": 3
481-
}
482-
]
483-
},
484-
"EsdtToken": {
485-
"type": "struct",
486-
"fields": [
487-
{
488-
"name": "token_type",
489-
"type": "TokenIdentifier"
490-
},
491-
{
492-
"name": "nonce",
493-
"type": "u64"
494-
}
495-
]
496496
}
497497
}
498498
}

0 commit comments

Comments
 (0)